Fix cursor position after execution of external script.
[pantumic.git] / src / editor / etags.c
blob60ef00426b8d1cb30b4f896e66a078db4901e837
1 /* editor C-code navigation via tags.
2 make TAGS file via command:
3 $ find . -type f -name "*.[ch]" | etags -l c --declarations -
5 or, if etags utility not installed:
6 $ find . -type f -name "*.[ch]" | ctags --c-kinds=+p --fields=+iaS --extra=+q -e -L-
8 Copyright (C) 2009 Free Software Foundation, Inc.
10 Authors:
11 Ilia Maslakov <il.smind@gmail.com>, 2009
12 Slava Zanko <slavazanko@gmail.com>, 2009
15 This file is part of the Midnight Commander.
17 The Midnight Commander is free software; you can redistribute it
18 and/or modify it under the terms of the GNU General Public License as
19 published by the Free Software Foundation; either version 2 of the
20 License, or (at your option) any later version.
22 The Midnight Commander is distributed in the hope that it will be
23 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
24 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
30 MA 02110-1301, USA.
33 #include <config.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <inttypes.h>
38 #include <string.h>
39 #include <ctype.h>
41 #include "lib/global.h"
42 #include "lib/util.h" /* canonicalize_pathname() */
44 #include "etags.h"
46 /*** global variables ****************************************************************************/
48 /*** file scope macro definitions ****************************************************************/
50 /*** file scope type declarations ****************************************************************/
52 /*** file scope variables ************************************************************************/
54 /*** file scope functions ************************************************************************/
55 /* --------------------------------------------------------------------------------------------- */
57 /* --------------------------------------------------------------------------------------------- */
58 /*** public functions ****************************************************************************/
59 /* --------------------------------------------------------------------------------------------- */
61 static gboolean
62 parse_define (char *buf, char **long_name, char **short_name, long *line)
64 enum
65 { in_longname, in_shortname, in_shortname_first_char, in_line, finish } def_state = in_longname;
67 static char longdef[LONG_DEF_LEN];
68 static char shortdef[SHORT_DEF_LEN];
69 static char linedef[LINE_DEF_LEN];
70 int nlong = 0;
71 int nshort = 0;
72 int nline = 0;
73 char c = *buf;
75 while (!(c == '\0' || c == '\n'))
77 switch (def_state)
79 case in_longname:
80 if (c == 0x01)
82 def_state = in_line;
84 else if (c == 0x7F)
86 def_state = in_shortname;
88 else
90 if (nlong < LONG_DEF_LEN - 1)
92 longdef[nlong++] = c;
95 break;
96 case in_shortname_first_char:
97 if (isdigit (c))
99 nshort = 0;
100 buf--;
101 def_state = in_line;
103 else if (c == 0x01)
105 def_state = in_line;
107 else
109 if (nshort < SHORT_DEF_LEN - 1)
111 shortdef[nshort++] = c;
112 def_state = in_shortname;
115 break;
116 case in_shortname:
117 if (c == 0x01)
119 def_state = in_line;
121 else if (c == '\n')
123 def_state = finish;
125 else
127 if (nshort < SHORT_DEF_LEN - 1)
129 shortdef[nshort++] = c;
132 break;
133 case in_line:
134 if (c == ',' || c == '\n')
136 def_state = finish;
138 else if (isdigit (c))
140 if (nline < LINE_DEF_LEN - 1)
142 linedef[nline++] = c;
145 break;
146 case finish:
147 longdef[nlong] = '\0';
148 shortdef[nshort] = '\0';
149 linedef[nline] = '\0';
150 *long_name = g_strdup (longdef);
151 *short_name = g_strdup (shortdef);
152 *line = atol (linedef);
153 return TRUE;
155 buf++;
156 c = *buf;
158 *long_name = NULL;
159 *short_name = NULL;
160 *line = 0;
161 return FALSE;
164 /* --------------------------------------------------------------------------------------------- */
165 /*** public functions ****************************************************************************/
166 /* --------------------------------------------------------------------------------------------- */
169 etags_set_definition_hash (const char *tagfile, const char *start_path,
170 const char *match_func, etags_hash_t * def_hash)
172 enum
173 { start, in_filename, in_define } state = start;
175 FILE *f;
176 static char buf[BUF_LARGE];
178 char *longname = NULL;
179 char *shortname = NULL;
180 long line;
182 char *chekedstr = NULL;
184 int num = 0; /* returned value */
185 int pos;
186 char *filename = NULL;
188 if (!match_func || !tagfile)
189 return 0;
191 /* open file with positions */
192 f = fopen (tagfile, "r");
193 if (f == NULL)
194 return 0;
196 while (fgets (buf, sizeof (buf), f))
199 switch (state)
201 case start:
202 if (buf[0] == 0x0C)
204 state = in_filename;
206 break;
207 case in_filename:
208 pos = strcspn (buf, ",");
209 g_free (filename);
210 filename = g_malloc (pos + 2);
211 g_strlcpy (filename, (char *) buf, pos + 1);
212 state = in_define;
213 break;
214 case in_define:
215 if (buf[0] == 0x0C)
217 state = in_filename;
218 break;
220 /* check if the filename matches the define pos */
221 chekedstr = strstr (buf, match_func);
222 if (chekedstr)
224 parse_define (chekedstr, &longname, &shortname, &line);
225 if (num < MAX_DEFINITIONS - 1)
227 def_hash[num].filename_len = strlen (filename);
228 def_hash[num].fullpath = g_build_filename (start_path, filename, (char *) NULL);
230 canonicalize_pathname (def_hash[num].fullpath);
231 def_hash[num].filename = g_strdup (filename);
232 if (shortname)
234 def_hash[num].short_define = g_strdup (shortname);
236 else
238 def_hash[num].short_define = g_strdup (longname);
240 def_hash[num].line = line;
241 g_free (shortname);
242 g_free (longname);
243 num++;
246 break;
250 g_free (filename);
251 fclose (f);
252 return num;
255 /* --------------------------------------------------------------------------------------------- */