replace g_build_path("/" with g_build_filename
[geanyvc.git] / vc_bzr.c
blobce6a26dfaed189983f9c979ea3afaab986521f46
1 /*
2 * Copyright 2007 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
3 * Copyright 2007 Enrico Tröger <enrico.troeger@uvena.de>
4 * Copyright 2007 Nick Treleaven <nick.treleaven@btinternet.com>
5 * Copyright 2007 Yura Siamashka <yurand2@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "geany.h"
23 #include "support.h"
24 #include "plugindata.h"
25 #include "document.h"
26 #include "filetypes.h"
27 #include "utils.h"
28 #include "project.h"
29 #include "pluginmacros.h"
31 #include "geanyvc.h"
34 static const gchar *BZR_CMD_DIFF_FILE[] = { "bzr", "diff", BASE_FILENAME, NULL };
35 static const gchar *BZR_CMD_DIFF_DIR[] = { "bzr", "diff", DIRNAME, NULL };
36 static const gchar *BZR_CMD_REVERT_FILE[] = { "bzr", "revert", BASE_FILENAME, NULL };
37 static const gchar *BZR_CMD_STATUS[] = { "bzr", "status", NULL };
38 static const gchar *BZR_CMD_ADD[] = { "bzr", "add", BASE_FILENAME, NULL };
39 static const gchar *BZR_CMD_REMOVE[] = { "bzr", "remove", BASE_FILENAME, NULL };
40 static const gchar *BZR_CMD_LOG_FILE[] = { "bzr", "log", BASE_FILENAME, NULL };
41 static const gchar *BZR_CMD_LOG_DIR[] = { "bzr", "log", DIRNAME, NULL };
42 static const gchar *BZR_CMD_COMMIT[] = { "bzr", "commit", "-m", MESSAGE, FILE_LIST, NULL };
43 static const gchar *BZR_CMD_BLAME[] = { "bzr", "blame", "--all", "--long", BASE_FILENAME, NULL };
45 static void *BZR_COMMANDS[] = { BZR_CMD_DIFF_FILE,
46 BZR_CMD_DIFF_DIR,
47 BZR_CMD_REVERT_FILE,
48 BZR_CMD_STATUS,
49 BZR_CMD_ADD,
50 BZR_CMD_REMOVE,
51 BZR_CMD_LOG_FILE,
52 BZR_CMD_LOG_DIR,
53 BZR_CMD_COMMIT,
54 BZR_CMD_BLAME,
57 static gboolean
58 in_vc_bzr(const gchar * filename)
60 gint exit_code;
61 gchar *argv[] = { "bzr", "ls", NULL, NULL };
62 gchar *dir;
63 gchar *base_name;
64 gboolean ret = FALSE;
65 gchar *std_output;
67 if (!find_dir(filename, ".bzr", TRUE))
68 return FALSE;
70 if (g_file_test(filename, G_FILE_TEST_IS_DIR))
71 return TRUE;
73 dir = g_path_get_dirname(filename);
74 base_name = g_path_get_basename(filename);
75 argv[3] = base_name;
77 g_spawn_sync(dir, argv, NULL,
78 G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
79 NULL, NULL, &std_output, NULL, &exit_code, NULL);
80 if (NZV(std_output))
82 ret = TRUE;
83 g_free(std_output);
86 g_free(base_name);
87 g_free(dir);
89 return ret;
92 /* parse "bzr status --short" output, see "bzr help status-flags" for details */
93 static GSList *
94 get_commit_files_bzr(const gchar * dir)
96 enum
98 FIRST_CHAR,
99 SECOND_CHAR,
100 THIRD_CHAR,
101 SKIP_SPACE,
102 FILE_NAME,
105 gchar *txt;
106 GSList *ret = NULL;
107 gint pstatus = FIRST_CHAR;
108 const gchar *p;
109 gchar *base_name;
110 gchar *base_dir = find_subdir_path(dir, ".bzr");
111 const gchar *start = NULL;
112 CommitItem *item;
114 const gchar *status;
115 gchar *filename;
116 const char *argv[] = { "bzr", "status", "--short", NULL };
118 g_return_val_if_fail(base_dir, NULL);
120 execute_custom_command(argv, NULL, &txt, NULL, base_dir, NULL, NULL);
121 if (!NZV(txt))
123 g_free(base_dir);
124 g_free(txt);
125 return NULL;
127 p = txt;
129 while (*p)
131 if (*p == '\r')
134 else if (pstatus == FIRST_CHAR)
136 if (*p == '+')
137 status = FILE_STATUS_ADDED;
138 else if (*p == '-')
139 status = FILE_STATUS_DELETED;
140 // rename
141 //else if (*p == 'R')
142 else if (*p == '?')
143 status = FILE_STATUS_UNKNOWN;
144 // conflicts
145 //else if (*p == 'C')
146 // pending merge
147 //else if (*p == 'P')
148 pstatus = SECOND_CHAR;
150 else if (pstatus == SECOND_CHAR)
152 if (*p == 'N')
153 status = FILE_STATUS_ADDED;
154 else if (*p == 'D')
155 status = FILE_STATUS_DELETED;
156 // file kind changed
157 //else if (*p == 'K')
158 else if (*p == 'M')
159 status = FILE_STATUS_MODIFIED;
160 pstatus = THIRD_CHAR;
162 else if (pstatus == THIRD_CHAR)
164 // execute bit change
165 //if (*p == '*')
166 pstatus = SKIP_SPACE;
168 else if (pstatus == SKIP_SPACE)
170 if (*p == ' ' || *p == '\t')
173 else
175 start = p;
176 pstatus = FILE_NAME;
179 else if (pstatus == FILE_NAME)
181 if (*p == '\n')
183 if (status != FILE_STATUS_UNKNOWN)
185 base_name = g_malloc0(p - start + 1);
186 memcpy(base_name, start, p - start);
187 filename = g_build_filename(base_dir, base_name, NULL);
188 g_free(base_name);
189 item = g_new(CommitItem, 1);
190 item->status = status;
191 item->path = filename;
192 ret = g_slist_append(ret, item);
194 pstatus = FIRST_CHAR;
197 p++;
199 g_free(txt);
200 g_free(base_dir);
201 return ret;
204 VC_RECORD VC_BZR = { BZR_COMMANDS, NO_ENV, "bzr", in_vc_bzr, get_commit_files_bzr };