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.
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,
41 #include "../src/global.h"
42 #include "../src/util.h" /* canonicalize_pathname() */
43 #include "../edit/etags.h"
45 /*** file scope functions **********************************************/
47 static gboolean
parse_define(char *buf
, char **long_name
, char **short_name
, long *line
)
49 enum {in_longname
, in_shortname
, in_shortname_first_char
, in_line
, finish
} def_state
= in_longname
;
51 static char longdef
[LONG_DEF_LEN
];
52 static char shortdef
[SHORT_DEF_LEN
];
53 static char linedef
[LINE_DEF_LEN
];
59 while ( !(c
=='\0' || c
=='\n') ) {
60 switch ( def_state
) {
64 } else if ( c
== 0x7F ) {
65 def_state
= in_shortname
;
67 if ( nlong
< LONG_DEF_LEN
- 1 ) {
72 case in_shortname_first_char
:
77 } else if ( c
== 0x01 ) {
80 if ( nshort
< SHORT_DEF_LEN
- 1 ) {
81 shortdef
[nshort
++] = c
;
82 def_state
= in_shortname
;
89 } else if ( c
== '\n' ) {
92 if ( nshort
< SHORT_DEF_LEN
- 1 ) {
93 shortdef
[nshort
++] = c
;
98 if ( c
== ',' || c
== '\n') {
100 } else if ( isdigit(c
) ) {
101 if ( nline
< LINE_DEF_LEN
- 1 ) {
102 linedef
[nline
++] = c
;
107 longdef
[nlong
] = '\0';
108 shortdef
[nshort
] = '\0';
109 linedef
[nline
] = '\0';
110 *long_name
= g_strdup (longdef
);
111 *short_name
= g_strdup (shortdef
);
112 *line
= atol (linedef
);
125 /*** public functions **************************************************/
127 int etags_set_definition_hash(const char *tagfile
, const char *start_path
,
128 const char *match_func
,
129 etags_hash_t
*def_hash
)
131 enum {start
, in_filename
, in_define
} state
= start
;
134 static char buf
[BUF_LARGE
];
136 char *longname
= NULL
;
137 char *shortname
= NULL
;
140 char *chekedstr
= NULL
;
142 int num
= 0; /* returned value */
144 char *filename
= NULL
;
146 if ( !match_func
|| !tagfile
)
149 /* open file with positions */
150 f
= fopen (tagfile
, "r");
154 while (fgets (buf
, sizeof (buf
), f
)) {
158 if ( buf
[0] == 0x0C ) {
163 pos
= strcspn(buf
, ",");
165 filename
= g_malloc (pos
+ 2);
166 g_strlcpy(filename
, (char *)buf
, pos
+ 1);
170 if ( buf
[0] == 0x0C ) {
174 /* check if the filename matches the define pos */
175 chekedstr
= strstr (buf
, match_func
);
177 parse_define (chekedstr
, &longname
, &shortname
, &line
);
178 if ( num
< MAX_DEFINITIONS
- 1 ) {
179 def_hash
[num
].filename_len
= strlen (filename
);
180 def_hash
[num
].fullpath
= g_build_filename ( start_path
, filename
, (char *) NULL
);
182 canonicalize_pathname (def_hash
[num
].fullpath
);
183 def_hash
[num
].filename
= g_strdup (filename
);
185 def_hash
[num
].short_define
= g_strdup (shortname
);
187 def_hash
[num
].short_define
= g_strdup (longname
);
189 def_hash
[num
].line
= line
;