Revision: 179 http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=179&view=rev Author: yurand Date: 2008-09-19 21:29:46 +0000 (Fri, 19 Sep 2008)
Log Message: ----------- VC: svn diff output is relative to svn base directory now, added unittests
Modified Paths: -------------- trunk/geanyvc/Makefile.am trunk/geanyvc/configure.in trunk/geanyvc/geanyvc.c trunk/geanyvc/geanyvc.h trunk/geanyvc/po/POTFILES.in trunk/geanyvc/vc_bzr.c trunk/geanyvc/vc_cvs.c trunk/geanyvc/vc_git.c trunk/geanyvc/vc_hg.c trunk/geanyvc/vc_svk.c trunk/geanyvc/vc_svn.c
Added Paths: ----------- trunk/geanyvc/po/POTFILES.skip trunk/geanyvc/tests/ trunk/geanyvc/tests/Makefile.am trunk/geanyvc/tests/unittests.c trunk/geanyvc/utils.c
Modified: trunk/geanyvc/Makefile.am =================================================================== --- trunk/geanyvc/Makefile.am 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/Makefile.am 2008-09-19 21:29:46 UTC (rev 179) @@ -1,5 +1,5 @@ ## Makefile.am -- Process this file with automake to produce Makefile.in -SUBDIRS = po +SUBDIRS = po tests
EXTRA_DIST = \ autogen.sh \ @@ -16,7 +16,7 @@ noinst_HEADERS = geanyvc.h
lib_LTLIBRARIES = geanyvc.la -geanyvc_la_SOURCES = geanyvc.c externdiff.c vc_git.c vc_cvs.c vc_svn.c vc_svk.c vc_bzr.c vc_hg.c +geanyvc_la_SOURCES = geanyvc.c externdiff.c utils.c vc_git.c vc_cvs.c vc_svn.c vc_svk.c vc_bzr.c vc_hg.c geanyvc_la_LDFLAGS = -module -avoid-version geanyvc_la_LIBADD = @GEANY_LIBS@
Modified: trunk/geanyvc/configure.in =================================================================== --- trunk/geanyvc/configure.in 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/configure.in 2008-09-19 21:29:46 UTC (rev 179) @@ -81,6 +81,7 @@ AC_OUTPUT([ Makefile po/Makefile.in +tests/Makefile ])
echo "----------------------------------------"
Modified: trunk/geanyvc/geanyvc.c =================================================================== --- trunk/geanyvc/geanyvc.c 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/geanyvc.c 2008-09-19 21:29:46 UTC (rev 179) @@ -86,12 +86,24 @@ static GSList *VC = NULL;
/* The addresses of these strings act as enums, their contents are not used. */ -const gchar DIRNAME[] = "*DIRNAME*"; -const gchar FILENAME[] = "*FILENAME*"; +/* absolute path dirname of file */ +const gchar ABS_DIRNAME[] = "*ABS_DIRNAME*"; +/* absolute path filename of file */ +const gchar ABS_FILENAME[] = "*ABS_FILENAME*";; + +/* path to directory from base vc directory */ +const gchar BASE_DIRNAME[] = "*BASE_DIRNAME*"; +/* path to file from base vc directory */ const gchar BASE_FILENAME[] = "*BASE_FILENAME*"; + +/* basename of file */ +const gchar BASENAME[] = "*BASENAME*"; +/* list with absolute file names*/ const gchar FILE_LIST[] = "*FILE_LIST*"; +/* message */ const gchar MESSAGE[] = "*MESSAGE*";
+ /* this string is used when action require to run several commands */ const gchar CMD_SEPARATOR[] = "*CMD-SEPARATOR*"; const gchar CMD_FUNCTION[] = "*CUSTOM_FUNCTION*"; @@ -102,8 +114,6 @@ const gchar FILE_STATUS_DELETED[] = "Deleted"; const gchar FILE_STATUS_UNKNOWN[] = "Unknown";
-void *NO_ENV[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - static void registrate();
GSList * @@ -238,35 +248,36 @@ if (vc) { if (cmd) - return vc->commands[cmd_type]; + return vc->commands[cmd_type].command; else - return vc->envs[cmd_type]; + return vc->commands[cmd_type].env; } return NULL; }
/* Get list of commands for given command spec*/ static GSList * -get_cmd(const gchar ** argv, const gchar * filename, GSList * filelist, const gchar * message) +get_cmd(const gchar ** argv, const gchar * dir, const gchar * filename, GSList * filelist, + const gchar * message) { gint i, j; gint len = 0; gchar **ret; - gchar *dir; + gchar *abs_dir; gchar *base_filename; + gchar *base_dirname; + gchar *basename; GSList *head = NULL; GSList *tmp; GString *repl;
if (g_file_test(filename, G_FILE_TEST_IS_DIR)) - { - dir = g_strdup(filename); - } + abs_dir = g_strdup(filename); else - { - dir = g_path_get_dirname(filename); - } - base_filename = g_path_get_basename(filename); + abs_dir = g_path_get_dirname(filename); + basename = g_path_get_basename(filename); + base_filename = get_relative_path(dir, filename); + base_dirname = get_relative_path(dir, abs_dir);
while (1) { @@ -294,18 +305,26 @@ j = -1; head = g_slist_append(head, ret); } - else if (argv[i] == DIRNAME) + else if (argv[i] == ABS_DIRNAME) { - ret[j] = p_utils->get_locale_from_utf8(dir); + ret[j] = p_utils->get_locale_from_utf8(abs_dir); } - else if (argv[i] == FILENAME) + else if (argv[i] == ABS_FILENAME) { ret[j] = p_utils->get_locale_from_utf8(filename); } + else if (argv[i] == BASE_DIRNAME) + { + ret[j] = p_utils->get_locale_from_utf8(base_dirname); + } else if (argv[i] == BASE_FILENAME) { ret[j] = p_utils->get_locale_from_utf8(base_filename); } + else if (argv[i] == BASENAME) + { + ret[j] = p_utils->get_locale_from_utf8(basename); + } else if (argv[i] == FILE_LIST) { for (tmp = filelist; tmp != NULL; tmp = g_slist_next(tmp)) @@ -322,15 +341,17 @@ else { repl = g_string_new(argv[i]); - p_utils->string_replace_all(repl, P_DIRNAME, dir); - p_utils->string_replace_all(repl, P_FILENAME, filename); - p_utils->string_replace_all(repl, P_BASE_FILENAME, base_filename); + p_utils->string_replace_all(repl, P_ABS_DIRNAME, abs_dir); + p_utils->string_replace_all(repl, P_ABS_FILENAME, filename); + p_utils->string_replace_all(repl, P_BASENAME, basename); ret[j] = g_string_free(repl, FALSE); setptr(ret[j], p_utils->get_locale_from_utf8(ret[j])); } } - g_free(dir); + g_free(abs_dir); + g_free(base_dirname); g_free(base_filename); + g_free(basename); return head; }
@@ -371,6 +392,7 @@ /* * Execute command by command spec, return std_out std_err * + * @dir - start directory of command * @argv - command spec * @env - envirounment * @std_out - if not NULL here will be returned standard output converted to utf8 of last command in spec @@ -382,15 +404,16 @@ * @return - exit code of last command in spec */ gint -execute_custom_command(const gchar ** argv, const gchar ** env, gchar ** std_out, gchar ** std_err, - const gchar * filename, GSList * list, const gchar * message) +execute_custom_command(const gchar * dir, const gchar ** argv, const gchar ** env, gchar ** std_out, + gchar ** std_err, const gchar * filename, GSList * list, + const gchar * message) { gint exit_code; - gchar *dir; GString *tmp; GSList *cur; - GSList *largv = get_cmd(argv, filename, list, message); + GSList *largv = get_cmd(argv, dir, filename, list, message); GError *error = NULL; + printf("%s\n", __FUNCTION__);
if (std_out) *std_out = NULL; @@ -402,15 +425,6 @@ return 0; }
- if (g_file_test(filename, G_FILE_TEST_IS_DIR)) - { - dir = g_strdup(filename); - } - else - { - dir = g_path_get_dirname(filename); - } - for (cur = largv; cur != NULL; cur = g_slist_next(cur)) { argv = cur->data; @@ -479,7 +493,6 @@ } g_strfreev(cur->data); } - g_free(dir); g_slist_free(largv); return exit_code; } @@ -488,20 +501,39 @@ execute_command(const VC_RECORD * vc, gchar ** std_out, gchar ** std_err, const gchar * filename, gint cmd, GSList * list, const gchar * message) { + gchar *dir; + gint ret; + if (std_out) *std_out = NULL; if (std_err) *std_err = NULL;
- if (((gchar **) vc->commands[cmd])[0] == CMD_FUNCTION) + if (vc->commands[cmd].function) { - typedef gint(*cmd_function) (gchar **, gchar **, const gchar *, GSList *, - const gchar *); - return ((cmd_function *) vc->commands[cmd])[1] (std_out, std_err, filename, list, - message); + return vc->commands[cmd].function(std_out, std_err, filename, list, message); } - return execute_custom_command(vc->commands[cmd], vc->envs[cmd], std_out, std_err, filename, - list, message); + + if (vc->commands[cmd].startdir == VC_COMMAND_STARTDIR_FILE) + { + if (g_file_test(filename, G_FILE_TEST_IS_DIR)) + dir = g_strdup(filename); + else + dir = g_path_get_dirname(filename); + } + else if (vc->commands[cmd].startdir == VC_COMMAND_STARTDIR_BASE) + { + dir = vc->get_base_dir(filename); + } + else + { + fprintf(stderr, "geanyvc: unknown startdir type: %d\n", vc->commands[cmd].startdir); + } + + ret = execute_custom_command(dir, vc->commands[cmd].command, vc->commands[cmd].env, std_out, + std_err, filename, list, message); + g_free(dir); + return ret; }
/* Callback if menu item for a single file was activated */ @@ -631,35 +663,38 @@ }
-/* Callback if menu item for the current project was activated */ +/* Callback if menu item for the base directory was activated */ static void -vcdiff_project_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, G_GNUC_UNUSED gpointer gdata) +vcdiff_basedir_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, G_GNUC_UNUSED gpointer gdata) { gchar *text = NULL; gchar *name; + gchar *basedir; + gchar *base_name; const VC_RECORD *vc; GeanyDocument *doc;
- GeanyProject *project = geany->app->project; - doc = p_document->get_current(); + g_return_if_fail(doc != NULL && doc->file_name != NULL);
- g_return_if_fail(geany->app->project != NULL && NZV(geany->app->project->base_path)); - if (doc && doc->changed && doc->file_name != NULL) { p_document->save_file(doc, FALSE); }
- vc = find_vc(geany->app->project->base_path); + vc = find_vc(doc->file_name); g_return_if_fail(vc);
- execute_command(vc, &text, NULL, geany->app->project->base_path, VC_COMMAND_DIFF_DIR, NULL, - NULL); + basedir = vc->get_base_dir(doc->file_name); + g_return_if_fail(basedir); + + execute_command(vc, &text, NULL, basedir, VC_COMMAND_DIFF_DIR, NULL, NULL); if (text) { - name = g_strconcat(project->name, ".vc.diff", NULL); + base_name = g_path_get_dirname(doc->file_name); + name = g_strconcat(base_name, ".vc.diff", NULL); show_output(text, name, NULL); + g_free(base_name); g_free(text); g_free(name); } @@ -667,6 +702,7 @@ { p_ui->set_statusbar(FALSE, _("No changes were made.")); } + g_free(basedir); }
static void @@ -745,24 +781,29 @@ }
static void -vclog_project_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, G_GNUC_UNUSED gpointer gdata) +vclog_basedir_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, G_GNUC_UNUSED gpointer gdata) { gchar *text = NULL; const VC_RECORD *vc; - GeanyProject *project = geany->app->project; + GeanyDocument *doc; + gchar *basedir;
- g_return_if_fail(project != NULL && NZV(geany->app->project->base_path)); + doc = p_document->get_current(); + g_return_if_fail(doc != NULL && doc->file_name != NULL);
- vc = find_vc(geany->app->project->base_path); + vc = find_vc(doc->file_name); g_return_if_fail(vc);
- execute_command(vc, &text, NULL, geany->app->project->base_path, VC_COMMAND_LOG_DIR, NULL, - NULL); + basedir = vc->get_base_dir(doc->file_name); + g_return_if_fail(basedir); + + execute_command(vc, &text, NULL, basedir, VC_COMMAND_LOG_DIR, NULL, NULL); if (text) { show_output(text, "*VC-LOG*", NULL); g_free(text); } + g_free(basedir); }
/* Show status from the current directory */ @@ -1403,11 +1444,11 @@
static GtkWidget *menu_vc_diff_file = NULL; static GtkWidget *menu_vc_diff_dir = NULL; -static GtkWidget *menu_vc_diff_project = NULL; +static GtkWidget *menu_vc_diff_basedir = NULL; static GtkWidget *menu_vc_blame = NULL; static GtkWidget *menu_vc_log_file = NULL; static GtkWidget *menu_vc_log_dir = NULL; -static GtkWidget *menu_vc_log_project = NULL; +static GtkWidget *menu_vc_log_basedir = NULL; static GtkWidget *menu_vc_status = NULL; static GtkWidget *menu_vc_revert_file = NULL; static GtkWidget *menu_vc_add_file = NULL; @@ -1418,10 +1459,8 @@ update_menu_items() { GeanyDocument *doc; - GeanyProject *project = geany->app->project;
gboolean have_file; - gboolean p_have_vc = FALSE; gboolean d_have_vc = FALSE; gboolean f_have_vc = FALSE;
@@ -1441,19 +1480,15 @@ g_free(dir); }
- if (project != NULL && NZV(geany->app->project->base_path) && - find_cmd_env(VC_COMMAND_DIFF_DIR, TRUE, geany->app->project->base_path)) - p_have_vc = TRUE; - gtk_widget_set_sensitive(menu_vc_diff_file, f_have_vc); gtk_widget_set_sensitive(menu_vc_diff_dir, d_have_vc); - gtk_widget_set_sensitive(menu_vc_diff_project, p_have_vc); + gtk_widget_set_sensitive(menu_vc_diff_basedir, d_have_vc);
gtk_widget_set_sensitive(menu_vc_blame, f_have_vc);
gtk_widget_set_sensitive(menu_vc_log_file, f_have_vc); gtk_widget_set_sensitive(menu_vc_log_dir, d_have_vc); - gtk_widget_set_sensitive(menu_vc_log_project, p_have_vc); + gtk_widget_set_sensitive(menu_vc_log_basedir, d_have_vc);
gtk_widget_set_sensitive(menu_vc_status, d_have_vc);
@@ -1782,7 +1817,8 @@ REGISTER_VC(HG, enable_hg); }
-static void locale_init(void) +static void +locale_init(void) { #ifdef ENABLE_NLS gchar *locale_dir = NULL; @@ -1853,13 +1889,13 @@ G_CALLBACK(vcdiff_dir_activated), NULL);
// Project - menu_vc_diff_project = gtk_menu_item_new_with_mnemonic(_("Diff From Current Project")); - gtk_container_add(GTK_CONTAINER(menu_vc_menu), menu_vc_diff_project); - gtk_tooltips_set_tip(tooltips, menu_vc_diff_project, - _("Make a diff from the current project's base path"), NULL); + menu_vc_diff_basedir = gtk_menu_item_new_with_mnemonic(_("Diff From Base Directory")); + gtk_container_add(GTK_CONTAINER(menu_vc_menu), menu_vc_diff_basedir); + gtk_tooltips_set_tip(tooltips, menu_vc_diff_basedir, + _("Make a diff from the top VC directory"), NULL);
- g_signal_connect((gpointer) menu_vc_diff_project, "activate", - G_CALLBACK(vcdiff_project_activated), NULL); + g_signal_connect((gpointer) menu_vc_diff_basedir, "activate", + G_CALLBACK(vcdiff_basedir_activated), NULL);
gtk_container_add(GTK_CONTAINER(menu_vc_menu), gtk_separator_menu_item_new());
@@ -1891,13 +1927,13 @@ g_signal_connect((gpointer) menu_vc_log_dir, "activate", G_CALLBACK(vclog_dir_activated), NULL);
- menu_vc_log_project = gtk_menu_item_new_with_mnemonic(_("Log Of Current Project")); - gtk_container_add(GTK_CONTAINER(menu_vc_menu), menu_vc_log_project); - gtk_tooltips_set_tip(tooltips, menu_vc_log_project, - _("Shows the log of the current project"), NULL); + menu_vc_log_basedir = gtk_menu_item_new_with_mnemonic(_("Log Of Base Directory")); + gtk_container_add(GTK_CONTAINER(menu_vc_menu), menu_vc_log_basedir); + gtk_tooltips_set_tip(tooltips, menu_vc_log_basedir, + _("Shows the log of the top VC directory"), NULL);
- g_signal_connect((gpointer) menu_vc_log_project, "activate", - G_CALLBACK(vclog_project_activated), NULL); + g_signal_connect((gpointer) menu_vc_log_basedir, "activate", + G_CALLBACK(vclog_basedir_activated), NULL);
gtk_container_add(GTK_CONTAINER(menu_vc_menu), gtk_separator_menu_item_new());
Modified: trunk/geanyvc/geanyvc.h =================================================================== --- trunk/geanyvc/geanyvc.h 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/geanyvc.h 2008-09-19 21:29:46 UTC (rev 179) @@ -38,20 +38,47 @@ VC_COMMAND_COUNT };
-#define P_DIRNAME "*<?geanyvcDIRNAME>*" -#define P_FILENAME "*<?geanyvcFILENAME>*" -#define P_BASE_FILENAME "*<?geanyvcBASE_FILENAME>*" +/* + * VC_COMMAND_STARTDIR_BASE - command strat dir will be VC base directory + * VC_COMMAND_STARTDIR_FILE - command start dir will be taken as basename + * of file, or directory itself if file is + * directory + */ +enum +{ + VC_COMMAND_STARTDIR_BASE, + VC_COMMAND_STARTDIR_FILE +};
+#define P_ABS_DIRNAME "*<?geanyvcDIRNAME>*" +#define P_ABS_FILENAME "*<?geanyvcFILENAME>*" +#define P_BASENAME "*<?geanyvcBASE_FILENAME>*" + /* The addresses of these strings act as enums, their contents are not used. */ -extern const gchar DIRNAME[]; -extern const gchar FILENAME[]; + + +/* absolute path dirname of file */ +extern const gchar ABS_DIRNAME[]; +/* absolute path filename of file */ +extern const gchar ABS_FILENAME[]; + +/* path to directory from base vc directory */ +extern const gchar BASE_DIRNAME[]; +/* path to file from base vc directory */ extern const gchar BASE_FILENAME[]; + +/* basename of file */ +extern const gchar BASENAME[]; +/* list with absolute file names*/ extern const gchar FILE_LIST[]; +/* message */ extern const gchar MESSAGE[];
+ + + /* this string is used when action require to run several commands */ extern const gchar CMD_SEPARATOR[]; -extern const gchar CMD_FUNCTION[];
extern const gchar FILE_STATUS_MODIFIED[]; extern const gchar FILE_STATUS_ADDED[]; @@ -59,17 +86,26 @@ extern const gchar FILE_STATUS_UNKNOWN[];
gint -execute_custom_command(const gchar ** argv, const gchar ** env, gchar ** std_out, gchar ** std_err, - const gchar * filename, GSList * list, const gchar * message); +execute_custom_command(const gchar * dir, const gchar ** argv, const gchar ** env, gchar ** std_out, + gchar ** std_err, const gchar * filename, GSList * list, + const gchar * message);
gboolean find_dir(const gchar * filename, const char *find, gboolean recursive); gchar *find_subdir_path(const gchar * filename, const gchar * subdir);
+typedef struct _VC_COMMAND +{ + gint startdir; + const gchar **command; + const gchar **env; + gint(*function) (gchar **, gchar **, const gchar *, GSList *, const gchar *); +} VC_COMMAND; + typedef struct _VC_RECORD { - void **commands; - void **envs; + const VC_COMMAND *commands; const gchar *program; + gchar *(*get_base_dir) (const gchar * path); gboolean(*in_vc) (const gchar * path); // check if file in VC GSList *(*get_commit_files) (const gchar * dir); } VC_RECORD; @@ -85,10 +121,16 @@
/* Blank functions and values */ GSList *get_commit_files_null(const gchar * dir); -extern void *NO_ENV[]; +extern const gchar *NO_ENV[];
/* External diff viewer */ const gchar *get_external_diff_viewer(); void vc_external_diff(const gchar * src, const gchar * dest);
+/* utils.c */ +gchar *normpath(const gchar * filename); +gchar *get_full_path(const gchar * location, const gchar * path); +gchar *get_relative_path(const gchar * location, const gchar * path); + + #endif // __GEANYVC_HEADER__
Modified: trunk/geanyvc/po/POTFILES.in =================================================================== --- trunk/geanyvc/po/POTFILES.in 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/po/POTFILES.in 2008-09-19 21:29:46 UTC (rev 179) @@ -5,4 +5,5 @@ vc_git.c vc_hg.c vc_svk.c -vc_svn.c \ No newline at end of file +vc_svn.c +utils.c
Added: trunk/geanyvc/po/POTFILES.skip =================================================================== --- trunk/geanyvc/po/POTFILES.skip (rev 0) +++ trunk/geanyvc/po/POTFILES.skip 2008-09-19 21:29:46 UTC (rev 179) @@ -0,0 +1 @@ +commit.glade
Added: trunk/geanyvc/tests/Makefile.am =================================================================== --- trunk/geanyvc/tests/Makefile.am (rev 0) +++ trunk/geanyvc/tests/Makefile.am 2008-09-19 21:29:46 UTC (rev 179) @@ -0,0 +1,15 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +#SUBDIRS = tests + +INCLUDES = -I.. + +if UNITTESTS +TESTS=unittests +noinst_PROGRAMS=unittests +unittests_SOURCES = unittests.c \ + ../utils.c + +AM_CFLAGS = @CHECK_CFLAGS@ @GEANY_CFLAGS@ -DLOCALEDIR=""$(localedir)"" -DUNITTESTS + +unittests_LDADD = @GEANY_LIBS@ $(INTLLIBS) @CHECK_LIBS@ +endif
Added: trunk/geanyvc/tests/unittests.c =================================================================== --- trunk/geanyvc/tests/unittests.c (rev 0) +++ trunk/geanyvc/tests/unittests.c 2008-09-19 21:29:46 UTC (rev 179) @@ -0,0 +1,30 @@ +#include <stdlib.h> +#include <stdio.h> +#include <check.h> +#include <string.h> + +#include <gtk/gtk.h> +#include "geany.h" + +extern TCase *utils_test_case_create(); + +Suite * +my_suite(void) +{ + Suite *s = suite_create("VC"); + TCase *tc_utils = utils_test_case_create(); + suite_add_tcase(s, tc_utils); + return s; +} + +int +main(void) +{ + int nf; + Suite *s = my_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + nf = srunner_ntests_failed(sr); + srunner_free(sr); + return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +}
Added: trunk/geanyvc/utils.c =================================================================== --- trunk/geanyvc/utils.c (rev 0) +++ trunk/geanyvc/utils.c 2008-09-19 21:29:46 UTC (rev 179) @@ -0,0 +1,171 @@ +/* + * + * Copyright 2008 Yura Siamashka yurand2@gmail.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include <string.h> +#include <glib.h> + +#include "geany.h" +#include "utils.h" +#include "plugindata.h" +#include "pluginmacros.h" + +extern GeanyData *geany_data; +extern GeanyFunctions *geany_functions; + + +/* Normalize a pathname. This collapses redundant separators and up-level references so that A//B, A/./B + * and A/foo/../B all become A/B. It does not normalize the case. On Windows, it converts forward + * slashes to backward slashes. It should be understood that this may change the meaning of the + * path if it contains symbolic links! + */ +gchar * +normpath(const gchar * filename) +{ + gchar **v; + gchar **p; + gchar **out; + gchar **pout; + gchar *ret; + + if (!filename || strlen(filename) == 0) + return g_strdup("."); + v = g_strsplit_set(filename, "/\", -1); + if (!g_strv_length(v)) + return g_strdup("."); + + out = g_malloc0(sizeof(gchar *) * (g_strv_length(v) + 2)); + pout = out; + + if (filename[0] == '.' && strcmp(v[0], ".") == 0) + { + *pout = strdup("."); + pout++; + } + else if (filename[0] == '/') + { + *pout = strdup("/"); + pout++; + } + + for (p = v; *p; p++) + { + if (strcmp(*p, ".") == 0 || strcmp(*p, "") == 0) + { + continue; + } + else if (strcmp(*p, "..") == 0) + { + if (pout != out) + { + pout--; + if (strcmp(*pout, "..") != 0) + { + g_free(*pout); + *pout = NULL; + continue; + } + pout++; + } + } + *pout++ = g_strdup(*p); + } + + ret = g_build_filenamev(out); + + g_strfreev(out); + g_strfreev(v); + return ret; +} + +gchar * +get_full_path(const gchar * location, const gchar * path) +{ + gchar *dir; + + dir = g_path_get_dirname(location); + setptr(dir, g_build_filename(dir, path, NULL)); + setptr(dir, normpath(dir)); + return dir; +} + +gchar * +get_relative_path(const gchar * location, const gchar * path) +{ + gchar *dir; + gchar *pth; + gchar *ret = NULL; + + gint plen; + gint dlen; + + if (!g_path_is_absolute(path)) + { + return g_strdup(path); + } + + dir = normpath(location); + pth = normpath(path); + + plen = strlen(pth); + dlen = strlen(dir); + + if (strstr(pth, dir) == pth) + { + if (plen > dlen) + { + ret = g_strdup(path + strlen(dir) + 1); + } + else if (plen == dlen) + { + ret = g_strdup("."); + } + } + g_free(dir); + g_free(pth); + return ret; +} + + +#ifdef UNITTESTS +#include <check.h> + +START_TEST(test_get_relative_path) +{ + gchar *path; + path = get_relative_path("/a/b", "/a/b/c"); + fail_unless(strcmp(path, "c") == 0, "expected: "c", get "%s"\n", path); + g_free(path); + + path = get_relative_path("/a/b", "/a/b"); + fail_unless(strcmp(path, ".") == 0, "expected: ".", get "%s"\n", path); + g_free(path); +} + +END_TEST; + + +TCase * +utils_test_case_create() +{ + TCase *tc_utils = tcase_create("utils"); + tcase_add_test(tc_utils, test_get_relative_path); + return tc_utils; +} + + +#endif
Modified: trunk/geanyvc/vc_bzr.c =================================================================== --- trunk/geanyvc/vc_bzr.c 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/vc_bzr.c 2008-09-19 21:29:46 UTC (rev 179) @@ -35,31 +35,83 @@ extern GeanyData *geany_data;
-static const gchar *BZR_CMD_DIFF_FILE[] = { "bzr", "diff", BASE_FILENAME, NULL }; -static const gchar *BZR_CMD_DIFF_DIR[] = { "bzr", "diff", DIRNAME, NULL }; -static const gchar *BZR_CMD_REVERT_FILE[] = { "bzr", "revert", BASE_FILENAME, NULL }; +static const gchar *BZR_CMD_DIFF_FILE[] = { "bzr", "diff", BASENAME, NULL }; +static const gchar *BZR_CMD_DIFF_DIR[] = { "bzr", "diff", ABS_DIRNAME, NULL }; +static const gchar *BZR_CMD_REVERT_FILE[] = { "bzr", "revert", BASENAME, NULL }; static const gchar *BZR_CMD_STATUS[] = { "bzr", "status", NULL }; -static const gchar *BZR_CMD_ADD[] = { "bzr", "add", BASE_FILENAME, NULL }; -static const gchar *BZR_CMD_REMOVE[] = { "bzr", "remove", BASE_FILENAME, NULL }; -static const gchar *BZR_CMD_LOG_FILE[] = { "bzr", "log", BASE_FILENAME, NULL }; -static const gchar *BZR_CMD_LOG_DIR[] = { "bzr", "log", DIRNAME, NULL }; +static const gchar *BZR_CMD_ADD[] = { "bzr", "add", BASENAME, NULL }; +static const gchar *BZR_CMD_REMOVE[] = { "bzr", "remove", BASENAME, NULL }; +static const gchar *BZR_CMD_LOG_FILE[] = { "bzr", "log", BASENAME, NULL }; +static const gchar *BZR_CMD_LOG_DIR[] = { "bzr", "log", ABS_DIRNAME, NULL }; static const gchar *BZR_CMD_COMMIT[] = { "bzr", "commit", "-m", MESSAGE, FILE_LIST, NULL }; -static const gchar *BZR_CMD_BLAME[] = { "bzr", "blame", "--all", "--long", BASE_FILENAME, NULL }; -static const gchar *BZR_CMD_SHOW[] = { "bzr", "cat", BASE_FILENAME, NULL }; +static const gchar *BZR_CMD_BLAME[] = { "bzr", "blame", "--all", "--long", BASENAME, NULL }; +static const gchar *BZR_CMD_SHOW[] = { "bzr", "cat", BASENAME, NULL };
-static void *BZR_COMMANDS[VC_COMMAND_COUNT] = { BZR_CMD_DIFF_FILE, - BZR_CMD_DIFF_DIR, - BZR_CMD_REVERT_FILE, - BZR_CMD_STATUS, - BZR_CMD_ADD, - BZR_CMD_REMOVE, - BZR_CMD_LOG_FILE, - BZR_CMD_LOG_DIR, - BZR_CMD_COMMIT, - BZR_CMD_BLAME, - BZR_CMD_SHOW +static const VC_COMMAND commands[] = { + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_DIFF_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_DIFF_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_REVERT_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_STATUS, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_ADD, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_REMOVE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_LOG_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_LOG_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_COMMIT, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_BLAME, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = BZR_CMD_SHOW, + .env = NULL, + .function = NULL} };
+ +static gchar * +get_base_dir(const gchar * path) +{ + return find_subdir_path(path, ".bzr"); +} + static gboolean in_vc_bzr(const gchar * filename) { @@ -80,7 +132,7 @@ base_name = g_path_get_basename(filename); argv[2] = base_name;
- exit_code = execute_custom_command((const gchar **) argv, NULL, &std_output, NULL, + exit_code = execute_custom_command(dir, (const gchar **) argv, NULL, &std_output, NULL, dir, NULL, NULL);
if (NZV(std_output)) @@ -123,7 +175,7 @@
g_return_val_if_fail(base_dir, NULL);
- execute_custom_command(argv, NULL, &txt, NULL, base_dir, NULL, NULL); + execute_custom_command(base_dir, argv, NULL, &txt, NULL, base_dir, NULL, NULL); if (!NZV(txt)) { g_free(base_dir); @@ -207,4 +259,10 @@ return ret; }
-VC_RECORD VC_BZR = { BZR_COMMANDS, NO_ENV, "bzr", in_vc_bzr, get_commit_files_bzr }; +VC_RECORD VC_BZR = { + .commands = commands, + .program = "bzr", + .get_base_dir = get_base_dir, + .in_vc = in_vc_bzr, + .get_commit_files = get_commit_files_bzr, +};
Modified: trunk/geanyvc/vc_cvs.c =================================================================== --- trunk/geanyvc/vc_cvs.c 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/vc_cvs.c 2008-09-19 21:29:46 UTC (rev 179) @@ -40,25 +40,82 @@ static const gchar *CVS_CMD_LOG_DIR[] = { "cvs", "log", NULL }; static const gchar *CVS_CMD_COMMIT[] = { "cvs", NULL }; static const gchar *CVS_CMD_BLAME[] = { "cvs", "annotate", BASE_FILENAME, NULL }; +static const gchar *CVS_CMD_SHOW[] = { "cvs", NULL };
-static void *CVS_COMMANDS[VC_COMMAND_COUNT] = { CVS_CMD_DIFF_FILE, - CVS_CMD_DIFF_DIR, - CVS_CMD_REVERT_FILE, - CVS_CMD_STATUS, - CVS_CMD_ADD, - CVS_CMD_REMOVE, - CVS_CMD_LOG_FILE, - CVS_CMD_LOG_DIR, - CVS_CMD_COMMIT, - CVS_CMD_BLAME, - NULL +static const VC_COMMAND commands[] = { + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_DIFF_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_DIFF_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_REVERT_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_STATUS, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_ADD, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_REMOVE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_LOG_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_LOG_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_COMMIT, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_BLAME, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = CVS_CMD_SHOW, + .env = NULL, + .function = NULL} };
+static gchar * +get_base_dir(const gchar * path) +{ + return find_subdir_path(path, "CVS"); +} + static gboolean in_vc_cvs(const gchar * filename) { return find_dir(filename, "CVS", FALSE); }
- -VC_RECORD VC_CVS = { CVS_COMMANDS, NO_ENV, "cvs", in_vc_cvs, get_commit_files_null }; +VC_RECORD VC_CVS = { + .commands = commands, + .program = "cvs", + .get_base_dir = get_base_dir, + .in_vc = in_vc_cvs, + .get_commit_files = get_commit_files_null, +};
Modified: trunk/geanyvc/vc_git.c =================================================================== --- trunk/geanyvc/vc_git.c 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/vc_git.c 2008-09-19 21:29:46 UTC (rev 179) @@ -34,12 +34,17 @@
extern GeanyData *geany_data;
+static gchar * +get_base_dir(const gchar * path) +{ + return find_subdir_path(path, ".git"); +}
static gint git_commit(G_GNUC_UNUSED gchar ** std_out, G_GNUC_UNUSED gchar ** std_err, const gchar * filename, GSList * list, const gchar * message) { - gchar *base_dir = find_subdir_path(filename, ".git"); + gchar *base_dir = get_base_dir(filename); gint len = strlen(base_dir); GSList *commit = NULL; GSList *tmp = NULL; @@ -53,7 +58,7 @@ commit = g_slist_prepend(commit, (gchar *) tmp->data + len + 1); }
- ret = execute_custom_command(argv, NULL, NULL, NULL, base_dir, commit, message); + ret = execute_custom_command(base_dir, argv, NULL, NULL, NULL, base_dir, commit, message); g_slist_free(commit); g_free(base_dir); return ret; @@ -64,7 +69,7 @@ git_show(gchar ** std_out, gchar ** std_err, const gchar * filename, GSList * list, const gchar * message) { - gchar *base_dir = find_subdir_path(filename, ".git"); + gchar *base_dir = get_base_dir(filename); gint len = strlen(base_dir); const gchar *argv[] = { "git", "show", NULL, NULL }; gint ret; @@ -73,7 +78,8 @@
argv[2] = g_strdup_printf("HEAD:%s", filename + len + 1);
- ret = execute_custom_command(argv, GIT_ENV_SHOW, std_out, std_err, base_dir, list, message); + ret = execute_custom_command(base_dir, argv, GIT_ENV_SHOW, std_out, std_err, base_dir, list, + message); g_free(base_dir); g_free((gchar *) argv[2]); return ret; @@ -81,20 +87,18 @@
-static const gchar *GIT_CMD_DIFF_FILE[] = { "git", "diff", "HEAD", "--", BASE_FILENAME, NULL }; +static const gchar *GIT_CMD_DIFF_FILE[] = { "git", "diff", "HEAD", "--", BASENAME, NULL }; static const gchar *GIT_CMD_DIFF_DIR[] = { "git", "diff", "HEAD", NULL }; -static const gchar *GIT_CMD_REVERT_FILE[] = { "git", "checkout", "--", BASE_FILENAME, NULL }; +static const gchar *GIT_CMD_REVERT_FILE[] = { "git", "checkout", "--", BASENAME, NULL }; static const gchar *GIT_CMD_STATUS[] = { "git", "status", NULL }; -static const gchar *GIT_CMD_ADD[] = { "git", "add", "--", BASE_FILENAME, NULL }; +static const gchar *GIT_CMD_ADD[] = { "git", "add", "--", BASENAME, NULL }; static const gchar *GIT_CMD_REMOVE[] = - { "git", "rm", "-f", "--", BASE_FILENAME, CMD_SEPARATOR, "git", "reset", "HEAD", "--", - BASE_FILENAME, NULL + { "git", "rm", "-f", "--", BASENAME, CMD_SEPARATOR, "git", "reset", "HEAD", "--", + BASENAME, NULL }; -static const gchar *GIT_CMD_LOG_FILE[] = { "git", "log", "--", BASE_FILENAME, NULL }; +static const gchar *GIT_CMD_LOG_FILE[] = { "git", "log", "--", BASENAME, NULL }; static const gchar *GIT_CMD_LOG_DIR[] = { "git", "log", NULL }; -static const void *GIT_CMD_COMMIT[] = { CMD_FUNCTION, git_commit }; -static const gchar *GIT_CMD_BLAME[] = { "git", "blame", "--", BASE_FILENAME, NULL }; -static const void *GIT_CMD_SHOW[] = { CMD_FUNCTION, git_show }; +static const gchar *GIT_CMD_BLAME[] = { "git", "blame", "--", BASENAME, NULL };
static const gchar *GIT_ENV_DIFF_FILE[] = { "PAGER=cat", NULL }; static const gchar *GIT_ENV_DIFF_DIR[] = { "PAGER=cat", NULL }; @@ -106,34 +110,64 @@ static const gchar *GIT_ENV_LOG_DIR[] = { "PAGER=cat", NULL }; static const gchar *GIT_ENV_BLAME[] = { "PAGER=cat", NULL };
-#define GIT_ENV_COMMIT NULL - -static void *GIT_COMMANDS[VC_COMMAND_COUNT] = { GIT_CMD_DIFF_FILE, - GIT_CMD_DIFF_DIR, - GIT_CMD_REVERT_FILE, - GIT_CMD_STATUS, - GIT_CMD_ADD, - GIT_CMD_REMOVE, - GIT_CMD_LOG_FILE, - GIT_CMD_LOG_DIR, - GIT_CMD_COMMIT, - GIT_CMD_BLAME, - GIT_CMD_SHOW +static const VC_COMMAND commands[] = { + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_DIFF_FILE, + .env = GIT_ENV_DIFF_FILE, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_DIFF_DIR, + .env = GIT_ENV_DIFF_DIR, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_REVERT_FILE, + .env = GIT_ENV_REVERT_FILE, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_STATUS, + .env = GIT_ENV_STATUS, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_ADD, + .env = GIT_ENV_ADD, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_REMOVE, + .env = GIT_ENV_REMOVE, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_LOG_FILE, + .env = GIT_ENV_LOG_FILE, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_LOG_DIR, + .env = GIT_ENV_LOG_DIR, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = NULL, + .env = NULL, + .function = git_commit}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = GIT_CMD_BLAME, + .env = GIT_ENV_BLAME, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = NULL, + .env = GIT_ENV_SHOW, + .function = git_show} };
-static void *GIT_ENV[] = { GIT_ENV_DIFF_FILE, - GIT_ENV_DIFF_DIR, - GIT_ENV_REVERT_FILE, - GIT_ENV_STATUS, - GIT_ENV_ADD, - GIT_ENV_REMOVE, - GIT_ENV_LOG_FILE, - GIT_ENV_LOG_DIR, - GIT_ENV_COMMIT, - GIT_ENV_BLAME, - GIT_ENV_SHOW -}; - static gboolean in_vc_git(const gchar * filename) { @@ -154,7 +188,7 @@ base_name = g_path_get_basename(filename); argv[3] = base_name;
- exit_code = execute_custom_command((const gchar **) argv, NULL, &std_output, NULL, + exit_code = execute_custom_command(dir, (const gchar **) argv, NULL, &std_output, NULL, dir, NULL, NULL); if (NZV(std_output)) { @@ -218,8 +252,8 @@ g_return_val_if_fail(base_dir, NULL);
exit_code = - execute_custom_command((const gchar **) argv, (const gchar **) env, &std_out, NULL, - base_dir, NULL, NULL); + execute_custom_command(base_dir, (const gchar **) argv, (const gchar **) env, + &std_out, NULL, base_dir, NULL, NULL); g_return_val_if_fail(std_out, NULL);
ret = parse_git_status(ret, base_dir, std_out, "modified:", FILE_STATUS_MODIFIED); @@ -232,4 +266,10 @@ return ret; }
-VC_RECORD VC_GIT = { GIT_COMMANDS, GIT_ENV, "git", in_vc_git, get_commit_files_git }; +VC_RECORD VC_GIT = { + .commands = commands, + .program = "git", + .get_base_dir = get_base_dir, + .in_vc = in_vc_git, + .get_commit_files = get_commit_files_git, +};
Modified: trunk/geanyvc/vc_hg.c =================================================================== --- trunk/geanyvc/vc_hg.c 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/vc_hg.c 2008-09-19 21:29:46 UTC (rev 179) @@ -35,31 +35,82 @@ extern GeanyData *geany_data;
-static const gchar *HG_CMD_DIFF_FILE[] = { "hg", "diff", FILENAME, NULL }; -static const gchar *HG_CMD_DIFF_DIR[] = { "hg", "diff", DIRNAME, NULL }; -static const gchar *HG_CMD_REVERT_FILE[] = { "hg", "revert", BASE_FILENAME, NULL }; +static const gchar *HG_CMD_DIFF_FILE[] = { "hg", "diff", ABS_FILENAME, NULL }; +static const gchar *HG_CMD_DIFF_DIR[] = { "hg", "diff", ABS_DIRNAME, NULL }; +static const gchar *HG_CMD_REVERT_FILE[] = { "hg", "revert", BASENAME, NULL }; static const gchar *HG_CMD_STATUS[] = { "hg", "status", NULL }; -static const gchar *HG_CMD_ADD[] = { "hg", "add", BASE_FILENAME, NULL }; -static const gchar *HG_CMD_REMOVE[] = { "hg", "remove", BASE_FILENAME, NULL }; -static const gchar *HG_CMD_LOG_FILE[] = { "hg", "log", BASE_FILENAME, NULL }; -static const gchar *HG_CMD_LOG_DIR[] = { "hg", "log", DIRNAME, NULL }; +static const gchar *HG_CMD_ADD[] = { "hg", "add", BASENAME, NULL }; +static const gchar *HG_CMD_REMOVE[] = { "hg", "remove", BASENAME, NULL }; +static const gchar *HG_CMD_LOG_FILE[] = { "hg", "log", BASENAME, NULL }; +static const gchar *HG_CMD_LOG_DIR[] = { "hg", "log", ABS_DIRNAME, NULL }; static const gchar *HG_CMD_COMMIT[] = { "hg", "commit", "-m", MESSAGE, FILE_LIST, NULL }; -static const gchar *HG_CMD_BLAME[] = { "hg", "annotate", BASE_FILENAME, NULL }; -static const gchar *HG_CMD_SHOW[] = { "hg", "cat", BASE_FILENAME, NULL }; +static const gchar *HG_CMD_BLAME[] = { "hg", "annotate", BASENAME, NULL }; +static const gchar *HG_CMD_SHOW[] = { "hg", "cat", BASENAME, NULL };
-static void *HG_COMMANDS[] = { HG_CMD_DIFF_FILE, - HG_CMD_DIFF_DIR, - HG_CMD_REVERT_FILE, - HG_CMD_STATUS, - HG_CMD_ADD, - HG_CMD_REMOVE, - HG_CMD_LOG_FILE, - HG_CMD_LOG_DIR, - HG_CMD_COMMIT, - HG_CMD_BLAME, - HG_CMD_SHOW +static const VC_COMMAND commands[] = { + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_DIFF_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_DIFF_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_REVERT_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_STATUS, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_ADD, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_REMOVE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_LOG_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_LOG_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_COMMIT, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_BLAME, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = HG_CMD_SHOW, + .env = NULL, + .function = NULL} };
+static gchar * +get_base_dir(const gchar * path) +{ + return find_subdir_path(path, ".hg"); +} + static gboolean in_vc_hg(const gchar * filename) { @@ -80,7 +131,7 @@ base_name = g_path_get_basename(filename); argv[3] = base_name;
- exit_code = execute_custom_command((const gchar **) argv, NULL, &std_output, NULL, + exit_code = execute_custom_command(dir, (const gchar **) argv, NULL, &std_output, NULL, dir, NULL, NULL); if (NZV(std_output)) { @@ -119,7 +170,7 @@
g_return_val_if_fail(base_dir, NULL);
- execute_custom_command(argv, NULL, &txt, NULL, base_dir, NULL, NULL); + execute_custom_command(base_dir, argv, NULL, &txt, NULL, base_dir, NULL, NULL); if (!NZV(txt)) { g_free(base_dir); @@ -181,4 +232,10 @@ return ret; }
-VC_RECORD VC_HG = { HG_COMMANDS, NO_ENV, "hg", in_vc_hg, get_commit_files_hg }; +VC_RECORD VC_HG = { + .commands = commands, + .program = "hg", + .get_base_dir = get_base_dir, + .in_vc = in_vc_hg, + .get_commit_files = get_commit_files_hg, +};
Modified: trunk/geanyvc/vc_svk.c =================================================================== --- trunk/geanyvc/vc_svk.c 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/vc_svk.c 2008-09-19 21:29:46 UTC (rev 179) @@ -35,31 +35,85 @@ extern GeanyData *geany_data;
-static const gchar *SVK_CMD_DIFF_FILE[] = { "svk", "diff", FILENAME, NULL }; -static const gchar *SVK_CMD_DIFF_DIR[] = { "svk", "diff", DIRNAME, NULL }; -static const gchar *SVK_CMD_REVERT_FILE[] = { "svk", "revert", BASE_FILENAME, NULL }; +static const gchar *SVK_CMD_DIFF_FILE[] = { "svk", "diff", ABS_FILENAME, NULL }; +static const gchar *SVK_CMD_DIFF_DIR[] = { "svk", "diff", ABS_DIRNAME, NULL }; +static const gchar *SVK_CMD_REVERT_FILE[] = { "svk", "revert", BASENAME, NULL }; static const gchar *SVK_CMD_STATUS[] = { "svk", "status", NULL }; -static const gchar *SVK_CMD_ADD[] = { "svk", "add", BASE_FILENAME, NULL }; -static const gchar *SVK_CMD_REMOVE[] = { "svk", "remove", BASE_FILENAME, NULL }; -static const gchar *SVK_CMD_LOG_FILE[] = { "svk", "log", BASE_FILENAME, NULL }; -static const gchar *SVK_CMD_LOG_DIR[] = { "svk", "log", DIRNAME, NULL }; +static const gchar *SVK_CMD_ADD[] = { "svk", "add", BASENAME, NULL }; +static const gchar *SVK_CMD_REMOVE[] = { "svk", "remove", BASENAME, NULL }; +static const gchar *SVK_CMD_LOG_FILE[] = { "svk", "log", BASENAME, NULL }; +static const gchar *SVK_CMD_LOG_DIR[] = { "svk", "log", ABS_DIRNAME, NULL }; static const gchar *SVK_CMD_COMMIT[] = { "svk", "commit", "-m", MESSAGE, FILE_LIST, NULL }; -static const gchar *SVK_CMD_BLAME[] = { "svk", "blame", BASE_FILENAME, NULL }; -static const gchar *SVK_CMD_SHOW[] = { "svk", "cat", BASE_FILENAME, NULL }; +static const gchar *SVK_CMD_BLAME[] = { "svk", "blame", BASENAME, NULL }; +static const gchar *SVK_CMD_SHOW[] = { "svk", "cat", BASENAME, NULL };
-static void *SVK_COMMANDS[] = { SVK_CMD_DIFF_FILE, - SVK_CMD_DIFF_DIR, - SVK_CMD_REVERT_FILE, - SVK_CMD_STATUS, - SVK_CMD_ADD, - SVK_CMD_REMOVE, - SVK_CMD_LOG_FILE, - SVK_CMD_LOG_DIR, - SVK_CMD_COMMIT, - SVK_CMD_BLAME, - SVK_CMD_SHOW + +static const VC_COMMAND commands[] = { + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_DIFF_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_DIFF_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_REVERT_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_STATUS, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_ADD, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_REMOVE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_LOG_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_LOG_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_COMMIT, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_BLAME, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVK_CMD_SHOW, + .env = NULL, + .function = NULL} };
+ +static gchar * +get_base_dir(const gchar * path) +{ + // NOT IMPLEMENTED + return NULL; +} + static gboolean in_vc_svk(const gchar * filename) { @@ -72,8 +126,9 @@
if (g_file_test(filename, G_FILE_TEST_IS_DIR)) { - exit_code = execute_custom_command((const gchar **) argv, NULL, NULL, NULL, - filename, NULL, NULL); + exit_code = + execute_custom_command(filename, (const gchar **) argv, NULL, NULL, NULL, + filename, NULL, NULL);
} else @@ -83,7 +138,7 @@
argv[2] = base_name;
- exit_code = execute_custom_command((const gchar **) argv, NULL, NULL, NULL, + exit_code = execute_custom_command(dir, (const gchar **) argv, NULL, NULL, NULL, dir, NULL, NULL);
g_free(dir); @@ -120,7 +175,7 @@ gchar *filename; const char *argv[] = { "svk", "status", NULL };
- execute_custom_command(argv, NULL, &txt, NULL, dir, NULL, NULL); + execute_custom_command(dir, argv, NULL, &txt, NULL, dir, NULL, NULL); if (!NZV(txt)) return NULL; p = txt; @@ -194,5 +249,10 @@ return ret; }
- -VC_RECORD VC_SVK = { SVK_COMMANDS, NO_ENV, "svk", in_vc_svk, get_commit_files_svk }; +VC_RECORD VC_SVK = { + .commands = commands, + .program = "svk", + .get_base_dir = get_base_dir, + .in_vc = in_vc_svk, + .get_commit_files = get_commit_files_svk, +};
Modified: trunk/geanyvc/vc_svn.c =================================================================== --- trunk/geanyvc/vc_svn.c 2008-09-18 12:13:16 UTC (rev 178) +++ trunk/geanyvc/vc_svn.c 2008-09-19 21:29:46 UTC (rev 179) @@ -35,32 +35,85 @@ extern GeanyData *geany_data;
-static const gchar *SVN_CMD_DIFF_FILE[] = { "svn", "diff", "--non-interactive", FILENAME, NULL }; -static const gchar *SVN_CMD_DIFF_DIR[] = { "svn", "diff", "--non-interactive", DIRNAME, NULL }; -static const gchar *SVN_CMD_REVERT_FILE[] = { "svn", "revert", BASE_FILENAME, NULL }; +static const gchar *SVN_CMD_DIFF_FILE[] = + { "svn", "diff", "--non-interactive", BASE_FILENAME, NULL }; +static const gchar *SVN_CMD_DIFF_DIR[] = { "svn", "diff", "--non-interactive", BASE_DIRNAME, NULL }; +static const gchar *SVN_CMD_REVERT_FILE[] = { "svn", "revert", BASENAME, NULL }; static const gchar *SVN_CMD_STATUS[] = { "svn", "status", NULL }; -static const gchar *SVN_CMD_ADD[] = { "svn", "add", BASE_FILENAME, NULL }; -static const gchar *SVN_CMD_REMOVE[] = { "svn", "rm", BASE_FILENAME, NULL }; -static const gchar *SVN_CMD_LOG_FILE[] = { "svn", "log", BASE_FILENAME, NULL }; -static const gchar *SVN_CMD_LOG_DIR[] = { "svn", "log", DIRNAME, NULL }; +static const gchar *SVN_CMD_ADD[] = { "svn", "add", BASENAME, NULL }; +static const gchar *SVN_CMD_REMOVE[] = { "svn", "rm", BASENAME, NULL }; +static const gchar *SVN_CMD_LOG_FILE[] = { "svn", "log", BASENAME, NULL }; +static const gchar *SVN_CMD_LOG_DIR[] = { "svn", "log", ABS_DIRNAME, NULL }; static const gchar *SVN_CMD_COMMIT[] = { "svn", "commit", "--non-interactive", "-m", MESSAGE, FILE_LIST, NULL }; -static const gchar *SVN_CMD_BLAME[] = { "svn", "blame", BASE_FILENAME, NULL }; -static const gchar *SVN_CMD_SHOW[] = { "svn", "cat", BASE_FILENAME, NULL }; +static const gchar *SVN_CMD_BLAME[] = { "svn", "blame", BASENAME, NULL }; +static const gchar *SVN_CMD_SHOW[] = { "svn", "cat", BASENAME, NULL };
-static void *SVN_COMMANDS[] = { SVN_CMD_DIFF_FILE, - SVN_CMD_DIFF_DIR, - SVN_CMD_REVERT_FILE, - SVN_CMD_STATUS, - SVN_CMD_ADD, - SVN_CMD_REMOVE, - SVN_CMD_LOG_FILE, - SVN_CMD_LOG_DIR, - SVN_CMD_COMMIT, - SVN_CMD_BLAME, - SVN_CMD_SHOW +static const VC_COMMAND commands[] = { + { + .startdir = VC_COMMAND_STARTDIR_BASE, + .command = SVN_CMD_DIFF_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_BASE, + .command = SVN_CMD_DIFF_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_REVERT_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_STATUS, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_ADD, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_REMOVE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_LOG_FILE, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_LOG_DIR, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_COMMIT, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_BLAME, + .env = NULL, + .function = NULL}, + { + .startdir = VC_COMMAND_STARTDIR_FILE, + .command = SVN_CMD_SHOW, + .env = NULL, + .function = NULL} };
+static gchar * +get_base_dir(const gchar * path) +{ + // NOT IMPLEMENTED + return find_subdir_path(path, ".svn"); +} + static gboolean in_vc_svn(const gchar * filename) { @@ -81,7 +134,7 @@ base_name = g_path_get_basename(filename); argv[3] = base_name;
- exit_code = execute_custom_command((const gchar **) argv, NULL, &std_output, NULL, + exit_code = execute_custom_command(dir, (const gchar **) argv, NULL, &std_output, NULL, dir, NULL, NULL); if (NZV(std_output)) { @@ -116,7 +169,7 @@ gchar *filename; const char *argv[] = { "svn", "status", NULL };
- execute_custom_command(argv, NULL, &txt, NULL, dir, NULL, NULL); + execute_custom_command(dir, argv, NULL, &txt, NULL, dir, NULL, NULL); if (!NZV(txt)) return NULL; p = txt; @@ -190,4 +243,10 @@ return ret; }
-VC_RECORD VC_SVN = { SVN_COMMANDS, NO_ENV, "svn", in_vc_svn, get_commit_files_svn }; +VC_RECORD VC_SVN = { + .commands = commands, + .program = "svn", + .get_base_dir = get_base_dir, + .in_vc = in_vc_svn, + .get_commit_files = get_commit_files_svn, +};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.