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

« back to all changes in this revision

Viewing changes to geanyvc/src/vc_hg.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 *HG_CMD_DIFF_FILE[] = { "hg", "diff", ABS_FILENAME, NULL };
 
38
static const gchar *HG_CMD_DIFF_DIR[] = { "hg", "diff", ABS_DIRNAME, NULL };
 
39
static const gchar *HG_CMD_REVERT_FILE[] = { "hg", "revert", BASENAME, NULL };
 
40
static const gchar *HG_CMD_REVERT_DIR[] = { "hg", "revert", BASE_DIRNAME, NULL };
 
41
static const gchar *HG_CMD_STATUS[] = { "hg", "status", NULL };
 
42
static const gchar *HG_CMD_ADD[] = { "hg", "add", BASENAME, NULL };
 
43
static const gchar *HG_CMD_REMOVE[] = { "hg", "remove", BASENAME, NULL };
 
44
static const gchar *HG_CMD_LOG_FILE[] = { "hg", "log", BASENAME, NULL };
 
45
static const gchar *HG_CMD_LOG_DIR[] = { "hg", "log", ABS_DIRNAME, NULL };
 
46
static const gchar *HG_CMD_COMMIT[] = { "hg", "commit", "-m", MESSAGE, FILE_LIST, NULL };
 
47
static const gchar *HG_CMD_BLAME[] = { "hg", "annotate", BASENAME, NULL };
 
48
static const gchar *HG_CMD_SHOW[] = { "hg", "cat", BASENAME, NULL };
 
49
static const gchar *HG_CMD_UPDATE[] = { "hg", "pull", CMD_SEPARATOR, "hg", "update", NULL };
 
50
 
 
51
static const VC_COMMAND commands[] = {
 
52
        {
 
53
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
54
         .command = HG_CMD_DIFF_FILE,
 
55
         .env = NULL,
 
56
         .function = NULL},
 
57
        {
 
58
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
59
         .command = HG_CMD_DIFF_DIR,
 
60
         .env = NULL,
 
61
         .function = NULL},
 
62
        {
 
63
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
64
         .command = HG_CMD_REVERT_FILE,
 
65
         .env = NULL,
 
66
         .function = NULL},
 
67
        {
 
68
         .startdir = VC_COMMAND_STARTDIR_BASE,
 
69
         .command = HG_CMD_REVERT_DIR,
 
70
         .env = NULL,
 
71
         .function = NULL},
 
72
        {
 
73
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
74
         .command = HG_CMD_STATUS,
 
75
         .env = NULL,
 
76
         .function = NULL},
 
77
        {
 
78
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
79
         .command = HG_CMD_ADD,
 
80
         .env = NULL,
 
81
         .function = NULL},
 
82
        {
 
83
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
84
         .command = HG_CMD_REMOVE,
 
85
         .env = NULL,
 
86
         .function = NULL},
 
87
        {
 
88
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
89
         .command = HG_CMD_LOG_FILE,
 
90
         .env = NULL,
 
91
         .function = NULL},
 
92
        {
 
93
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
94
         .command = HG_CMD_LOG_DIR,
 
95
         .env = NULL,
 
96
         .function = NULL},
 
97
        {
 
98
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
99
         .command = HG_CMD_COMMIT,
 
100
         .env = NULL,
 
101
         .function = NULL},
 
102
        {
 
103
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
104
         .command = HG_CMD_BLAME,
 
105
         .env = NULL,
 
106
         .function = NULL},
 
107
        {
 
108
         .startdir = VC_COMMAND_STARTDIR_FILE,
 
109
         .command = HG_CMD_SHOW,
 
110
         .env = NULL,
 
111
         .function = NULL},
 
112
        {
 
113
         .startdir = VC_COMMAND_STARTDIR_BASE,
 
114
         .command = HG_CMD_UPDATE,
 
115
         .env = NULL,
 
116
         .function = NULL}
 
117
};
 
118
 
 
119
static gchar *
 
120
get_base_dir(const gchar * path)
 
121
{
 
122
        return find_subdir_path(path, ".hg");
 
123
}
 
124
 
 
125
static gboolean
 
126
in_vc_hg(const gchar * filename)
 
127
{
 
128
        gint exit_code;
 
129
        gchar *argv[] = { "hg", "status", "-mac", NULL, NULL };
 
130
        gchar *dir;
 
131
        gchar *base_name;
 
132
        gboolean ret = FALSE;
 
133
        gchar *std_output;
 
134
 
 
135
        if (!find_dir(filename, ".hg", TRUE))
 
136
                return FALSE;
 
137
 
 
138
        if (g_file_test(filename, G_FILE_TEST_IS_DIR))
 
139
                return TRUE;
 
140
 
 
141
        dir = g_path_get_dirname(filename);
 
142
        base_name = g_path_get_basename(filename);
 
143
        argv[3] = base_name;
 
144
 
 
145
        exit_code = execute_custom_command(dir, (const gchar **) argv, NULL, &std_output, NULL,
 
146
                                           dir, NULL, NULL);
 
147
        if (NZV(std_output))
 
148
        {
 
149
                ret = TRUE;
 
150
                g_free(std_output);
 
151
        }
 
152
 
 
153
        g_free(base_name);
 
154
        g_free(dir);
 
155
 
 
156
        return ret;
 
157
}
 
158
 
 
159
static GSList *
 
160
get_commit_files_hg(const gchar * dir)
 
161
{
 
162
        enum
 
163
        {
 
164
                FIRST_CHAR,
 
165
                SKIP_SPACE,
 
166
                FILE_NAME,
 
167
        };
 
168
 
 
169
        gchar *txt;
 
170
        GSList *ret = NULL;
 
171
        gint pstatus = FIRST_CHAR;
 
172
        const gchar *p;
 
173
        gchar *base_name;
 
174
        gchar *base_dir = find_subdir_path(dir, ".hg");
 
175
        const gchar *start = NULL;
 
176
        CommitItem *item;
 
177
 
 
178
        const gchar *status;
 
179
        gchar *filename;
 
180
        const char *argv[] = { "hg", "status", NULL };
 
181
 
 
182
        g_return_val_if_fail(base_dir, NULL);
 
183
 
 
184
        execute_custom_command(base_dir, argv, NULL, &txt, NULL, base_dir, NULL, NULL);
 
185
        if (!NZV(txt))
 
186
        {
 
187
                g_free(base_dir);
 
188
                g_free(txt);
 
189
                return NULL;
 
190
        }
 
191
        p = txt;
 
192
 
 
193
        while (*p)
 
194
        {
 
195
                if (*p == '\r')
 
196
                {
 
197
                }
 
198
                else if (pstatus == FIRST_CHAR)
 
199
                {
 
200
                        if (*p == 'A')
 
201
                                status = FILE_STATUS_ADDED;
 
202
                        else if (*p == 'R')
 
203
                                status = FILE_STATUS_DELETED;
 
204
                        else if (*p == 'M')
 
205
                                status = FILE_STATUS_MODIFIED;
 
206
                        else if (*p == '?')
 
207
                                status = FILE_STATUS_UNKNOWN;
 
208
                        pstatus = SKIP_SPACE;
 
209
                }
 
210
                else if (pstatus == SKIP_SPACE)
 
211
                {
 
212
                        if (*p == ' ' || *p == '\t')
 
213
                        {
 
214
                        }
 
215
                        else
 
216
                        {
 
217
                                start = p;
 
218
                                pstatus = FILE_NAME;
 
219
                        }
 
220
                }
 
221
                else if (pstatus == FILE_NAME)
 
222
                {
 
223
                        if (*p == '\n')
 
224
                        {
 
225
                                if (status != FILE_STATUS_UNKNOWN)
 
226
                                {
 
227
                                        base_name = g_malloc0(p - start + 1);
 
228
                                        memcpy(base_name, start, p - start);
 
229
                                        filename = g_build_filename(base_dir, base_name, NULL);
 
230
                                        g_free(base_name);
 
231
                                        item = g_new(CommitItem, 1);
 
232
                                        item->status = status;
 
233
                                        item->path = filename;
 
234
                                        ret = g_slist_append(ret, item);
 
235
                                }
 
236
                                pstatus = FIRST_CHAR;
 
237
                        }
 
238
                }
 
239
                p++;
 
240
        }
 
241
        g_free(txt);
 
242
        g_free(base_dir);
 
243
        return ret;
 
244
}
 
245
 
 
246
VC_RECORD VC_HG = {
 
247
        .commands = commands,
 
248
        .program = "hg",
 
249
        .get_base_dir = get_base_dir,
 
250
        .in_vc = in_vc_hg,
 
251
        .get_commit_files = get_commit_files_hg,
 
252
};