~ubuntu-branches/debian/sid/geany-plugins/sid

« back to all changes in this revision

Viewing changes to geanyvc/src/vc_bzr.c

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2009-07-10 22:56:41 UTC
  • Revision ID: james.westby@ubuntu.com-20090710225641-xc1126t7pq0jmpos
Tags: upstream-0.17.1
ImportĀ upstreamĀ versionĀ 0.17.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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>
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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.
 
20
 */
 
21
 
 
22
#include <string.h>
 
23
 
 
24
#include "geany.h"
 
25
#include "support.h"
 
26
#include "plugindata.h"
 
27
#include "document.h"
 
28
#include "filetypes.h"
 
29
#include "utils.h"
 
30
#include "geanyfunctions.h"
 
31
 
 
32
#include "geanyvc.h"
 
33
 
 
34
extern GeanyData *geany_data;
 
35
 
 
36
 
 
37
static const gchar *BZR_CMD_DIFF_FILE[] = { "bzr", "diff", BASENAME, NULL };
 
38
static const gchar *BZR_CMD_DIFF_DIR[] = { "bzr", "diff", ABS_DIRNAME, NULL };
 
39
static const gchar *BZR_CMD_REVERT_FILE[] = { "bzr", "revert", BASENAME, NULL };
 
40
static const gchar *BZR_CMD_REVERT_DIR[] = { "bzr", "revert", BASE_DIRNAME, NULL };
 
41
static const gchar *BZR_CMD_STATUS[] = { "bzr", "status", NULL };
 
42
static const gchar *BZR_CMD_ADD[] = { "bzr", "add", BASENAME, NULL };
 
43
static const gchar *BZR_CMD_REMOVE[] = { "bzr", "remove", BASENAME, NULL };
 
44
static const gchar *BZR_CMD_LOG_FILE[] = { "bzr", "log", BASENAME, NULL };
 
45
static const gchar *BZR_CMD_LOG_DIR[] = { "bzr", "log", ABS_DIRNAME, NULL };
 
46
static const gchar *BZR_CMD_COMMIT[] = { "bzr", "commit", "-m", MESSAGE, FILE_LIST, NULL };
 
47
static const gchar *BZR_CMD_BLAME[] = { "bzr", "blame", "--all", "--long", BASENAME, NULL };
 
48
static const gchar *BZR_CMD_SHOW[] = { "bzr", "cat", BASENAME, NULL };
 
49
static const gchar *BZR_CMD_UPDATE[] = { "bzr", "pull", NULL };
 
50
 
 
51
static const VC_COMMAND commands[] = {
 
52
        {
 
53
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
54
         .command = BZR_CMD_DIFF_FILE,
 
55
         .env = NULL,
 
56
         .function = NULL},
 
57
        {
 
58
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
59
         .command = BZR_CMD_DIFF_DIR,
 
60
         .env = NULL,
 
61
         .function = NULL},
 
62
        {
 
63
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
64
         .command = BZR_CMD_REVERT_FILE,
 
65
         .env = NULL,
 
66
         .function = NULL},
 
67
        {
 
68
         .startdir = VC_COMMAND_STARTDIR_BASE,
 
69
         .command = BZR_CMD_REVERT_DIR,
 
70
         .env = NULL,
 
71
         .function = NULL},
 
72
        {
 
73
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
74
         .command = BZR_CMD_STATUS,
 
75
         .env = NULL,
 
76
         .function = NULL},
 
77
        {
 
78
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
79
         .command = BZR_CMD_ADD,
 
80
         .env = NULL,
 
81
         .function = NULL},
 
82
        {
 
83
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
84
         .command = BZR_CMD_REMOVE,
 
85
         .env = NULL,
 
86
         .function = NULL},
 
87
        {
 
88
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
89
         .command = BZR_CMD_LOG_FILE,
 
90
         .env = NULL,
 
91
         .function = NULL},
 
92
        {
 
93
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
94
         .command = BZR_CMD_LOG_DIR,
 
95
         .env = NULL,
 
96
         .function = NULL},
 
97
        {
 
98
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
99
         .command = BZR_CMD_COMMIT,
 
100
         .env = NULL,
 
101
         .function = NULL},
 
102
        {
 
103
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
104
         .command = BZR_CMD_BLAME,
 
105
         .env = NULL,
 
106
         .function = NULL},
 
107
        {
 
108
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
109
         .command = BZR_CMD_SHOW,
 
110
         .env = NULL,
 
111
         .function = NULL},
 
112
        {
 
113
         .startdir = VC_COMMAND_STARTDIR_BASE,
 
114
         .command = BZR_CMD_UPDATE,
 
115
         .env = NULL,
 
116
         .function = NULL}
 
117
};
 
118
 
 
119
 
 
120
static gchar *
 
121
get_base_dir(const gchar * path)
 
122
{
 
123
        return find_subdir_path(path, ".bzr");
 
124
}
 
125
 
 
126
static gboolean
 
127
in_vc_bzr(const gchar * filename)
 
128
{
 
129
        gint exit_code;
 
130
        gchar *argv[] = { "bzr", "log", NULL, NULL };
 
131
        gchar *dir;
 
132
        gchar *base_name;
 
133
        gboolean ret = FALSE;
 
134
        gchar *std_output;
 
135
 
 
136
        if (!find_dir(filename, ".bzr", TRUE))
 
137
                return FALSE;
 
138
 
 
139
        if (g_file_test(filename, G_FILE_TEST_IS_DIR))
 
140
                return TRUE;
 
141
 
 
142
        dir = g_path_get_dirname(filename);
 
143
        base_name = g_path_get_basename(filename);
 
144
        argv[2] = base_name;
 
145
 
 
146
        exit_code = execute_custom_command(dir, (const gchar **) argv, NULL, &std_output, NULL,
 
147
                                           filename, NULL, NULL);
 
148
 
 
149
        if (NZV(std_output))
 
150
        {
 
151
                ret = TRUE;
 
152
        }
 
153
        g_free(std_output);
 
154
 
 
155
        g_free(base_name);
 
156
        g_free(dir);
 
157
 
 
158
        return ret;
 
159
}
 
160
 
 
161
/* parse "bzr status --short" output, see "bzr help status-flags" for details */
 
162
static GSList *
 
163
get_commit_files_bzr(const gchar * dir)
 
164
{
 
165
        enum
 
166
        {
 
167
                FIRST_CHAR,
 
168
                SECOND_CHAR,
 
169
                THIRD_CHAR,
 
170
                SKIP_SPACE,
 
171
                FILE_NAME,
 
172
        };
 
173
 
 
174
        gchar *txt;
 
175
        GSList *ret = NULL;
 
176
        gint pstatus = FIRST_CHAR;
 
177
        const gchar *p;
 
178
        gchar *base_name;
 
179
        gchar *base_dir = find_subdir_path(dir, ".bzr");
 
180
        const gchar *start = NULL;
 
181
        CommitItem *item;
 
182
 
 
183
        const gchar *status;
 
184
        gchar *filename;
 
185
        const char *argv[] = { "bzr", "status", "--short", NULL };
 
186
 
 
187
        g_return_val_if_fail(base_dir, NULL);
 
188
 
 
189
        execute_custom_command(base_dir, argv, NULL, &txt, NULL, base_dir, NULL, NULL);
 
190
        if (!NZV(txt))
 
191
        {
 
192
                g_free(base_dir);
 
193
                g_free(txt);
 
194
                return NULL;
 
195
        }
 
196
        p = txt;
 
197
 
 
198
        while (*p)
 
199
        {
 
200
                if (*p == '\r')
 
201
                {
 
202
                }
 
203
                else if (pstatus == FIRST_CHAR)
 
204
                {
 
205
                        if (*p == '+')
 
206
                                status = FILE_STATUS_ADDED;
 
207
                        else if (*p == '-')
 
208
                                status = FILE_STATUS_DELETED;
 
209
                        // rename
 
210
                        //else if (*p == 'R')
 
211
                        else if (*p == '?')
 
212
                                status = FILE_STATUS_UNKNOWN;
 
213
                        // conflicts
 
214
                        //else if (*p == 'C')
 
215
                        // pending merge
 
216
                        //else if (*p == 'P')
 
217
                        pstatus = SECOND_CHAR;
 
218
                }
 
219
                else if (pstatus == SECOND_CHAR)
 
220
                {
 
221
                        if (*p == 'N')
 
222
                                status = FILE_STATUS_ADDED;
 
223
                        else if (*p == 'D')
 
224
                                status = FILE_STATUS_DELETED;
 
225
                        // file kind changed
 
226
                        //else if (*p == 'K')
 
227
                        else if (*p == 'M')
 
228
                                status = FILE_STATUS_MODIFIED;
 
229
                        pstatus = THIRD_CHAR;
 
230
                }
 
231
                else if (pstatus == THIRD_CHAR)
 
232
                {
 
233
                        // execute bit change
 
234
                        //if (*p == '*')
 
235
                        pstatus = SKIP_SPACE;
 
236
                }
 
237
                else if (pstatus == SKIP_SPACE)
 
238
                {
 
239
                        if (*p == ' ' || *p == '\t')
 
240
                        {
 
241
                        }
 
242
                        else
 
243
                        {
 
244
                                start = p;
 
245
                                pstatus = FILE_NAME;
 
246
                        }
 
247
                }
 
248
                else if (pstatus == FILE_NAME)
 
249
                {
 
250
                        if (*p == '\n')
 
251
                        {
 
252
                                if (status != FILE_STATUS_UNKNOWN)
 
253
                                {
 
254
                                        base_name = g_malloc0(p - start + 1);
 
255
                                        memcpy(base_name, start, p - start);
 
256
                                        filename = g_build_filename(base_dir, base_name, NULL);
 
257
                                        g_free(base_name);
 
258
                                        item = g_new(CommitItem, 1);
 
259
                                        item->status = status;
 
260
                                        item->path = filename;
 
261
                                        ret = g_slist_append(ret, item);
 
262
                                }
 
263
                                pstatus = FIRST_CHAR;
 
264
                        }
 
265
                }
 
266
                p++;
 
267
        }
 
268
        g_free(txt);
 
269
        g_free(base_dir);
 
270
        return ret;
 
271
}
 
272
 
 
273
VC_RECORD VC_BZR = {
 
274
        .commands = commands,
 
275
        .program = "bzr",
 
276
        .get_base_dir = get_base_dir,
 
277
        .in_vc = in_vc_bzr,
 
278
        .get_commit_files = get_commit_files_bzr,
 
279
};