aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorFrancesco Potortì2001-01-25 18:19:57 +0000
committerFrancesco Potortì2001-01-25 18:19:57 +0000
commitb2521b0abb548d8c60f68a61989dfd5c15166a14 (patch)
tree4710bd1dcc5ffe9570466d536bcdd36f2003380f /lib-src
parentd22a24fa26ce2ac0cd91c19bd0e2f7e95feee9f3 (diff)
downloademacs-b2521b0abb548d8c60f68a61989dfd5c15166a14.tar.gz
emacs-b2521b0abb548d8c60f68a61989dfd5c15166a14.zip
Many small improvements in tagging accuracy and capability,
better tagging of DEFUNs, code cleanups. 2001-01-25 Francesco Potorti` <pot@potorti.it> * etags.c (struct tok): Renamed from struct token. (token): Renamed from tok. (structtype): Make it a local variable. [DEBUG]: Use assert. (xrnew): Change the synopsis. (typedefs_or_cplusplus): Renamed from typedefs_and_cplusplus. (grow_linebuffer): Don't call xrnew when not needed. (token): buffer renamed to line. (C_entries): Three calls to inibuffer moved here from main. (C_entries): Removed all references to var methodlen, delete it. (linebuffer_setlen): Was grow_buffer, now also sets len. (consider_token, C_entries, Pascal_functions): Use it. (C_entries): Preventing problems relative to extern "C". (C_entries): Can tag more than one variable or func separated by comma when --declarations is used. (C_entries): More accurate tagging of members and declarations. (yacc_rules): Was global, made local to C_entries. (next_token_is_func): Removed. (fvdef): New constants fdefunkey, fdefunname. (consider_token, C_entries): Use them. (C_entries): Build proper lisp names for Emacs DEFUNs.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/etags.c516
1 files changed, 283 insertions, 233 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 17aeeb8733f..f9e43625996 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -24,20 +24,25 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 * Fortran added by Jim Kleckner. 24 * Fortran added by Jim Kleckner.
25 * Ed Pelegri-Llopart added C typedefs. 25 * Ed Pelegri-Llopart added C typedefs.
26 * Gnu Emacs TAGS format and modifications by RMS? 26 * Gnu Emacs TAGS format and modifications by RMS?
27 * Sam Kendall added C++. 27 * 199x Sam Kendall added C++.
28 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells. 28 * 1993 Francesco Potortì reorganised C and C++ based on work by Joe Wells.
29 * Regexp tags by Tom Tromey. 29 * 1994 Regexp tags by Tom Tromey.
30 * 2001 Nested classes by Francesco Potortì based on work by Mykola Dzyuba.
30 * 31 *
31 * Francesco Potorti` (pot@gnu.org) is the current maintainer. 32 * Francesco Potortì <pot@gnu.org> has maintained it since 1993.
32 */ 33 */
33 34
34char pot_etags_version[] = "@(#) pot revision number is 13.48"; 35char pot_etags_version[] = "@(#) pot number is $Revision: 13.59 $";
35 36
36#define TRUE 1 37#define TRUE 1
37#define FALSE 0 38#define FALSE 0
38 39
39#ifndef DEBUG 40#ifdef DEBUG
40# define DEBUG FALSE 41# undef DEBUG
42# define DEBUG TRUE
43#else
44# define DEBUG FALSE
45# define NDEBUG /* disable assert */
41#endif 46#endif
42 47
43#if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C)) 48#if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
@@ -111,6 +116,7 @@ char pot_etags_version[] = "@(#) pot revision number is 13.48";
111#ifndef errno 116#ifndef errno
112 extern int errno; 117 extern int errno;
113#endif 118#endif
119#include <assert.h>
114#include <sys/types.h> 120#include <sys/types.h>
115#include <sys/stat.h> 121#include <sys/stat.h>
116 122
@@ -154,11 +160,10 @@ char pot_etags_version[] = "@(#) pot revision number is 13.48";
154#define C_STAR 0x00003 /* C* */ 160#define C_STAR 0x00003 /* C* */
155#define C_JAVA 0x00005 /* JAVA */ 161#define C_JAVA 0x00005 /* JAVA */
156#define YACC 0x10000 /* yacc file */ 162#define YACC 0x10000 /* yacc file */
163#define PUREC (!(c_ext & ~YACC)) /* no extensions (apart from possibly yacc) */
157 164
158#define streq(s,t) ((DEBUG && (s) == NULL && (t) == NULL \ 165#define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
159 && (abort (), 1)) || !strcmp (s, t)) 166#define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
160#define strneq(s,t,n) ((DEBUG && (s) == NULL && (t) == NULL \
161 && (abort (), 1)) || !strncmp (s, t, n))
162 167
163#define CHARS 256 /* 2^sizeof(char) */ 168#define CHARS 256 /* 2^sizeof(char) */
164#define CHAR(x) ((unsigned int)(x) & (CHARS - 1)) 169#define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
@@ -181,17 +186,18 @@ char pot_etags_version[] = "@(#) pot revision number is 13.48";
181 * xnew, xrnew -- allocate, reallocate storage 186 * xnew, xrnew -- allocate, reallocate storage
182 * 187 *
183 * SYNOPSIS: Type *xnew (int n, Type); 188 * SYNOPSIS: Type *xnew (int n, Type);
184 * Type *xrnew (OldPointer, int n, Type); 189 * void xrnew (OldPointer, int n, Type);
185 */ 190 */
186#ifdef chkmalloc 191#if DEBUG
187# include "chkmalloc.h" 192# include "chkmalloc.h"
188# define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \ 193# define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
189 (n) * sizeof (Type))) 194 (n) * sizeof (Type)))
190# define xrnew(op,n,Type) ((Type *) trace_realloc (__FILE__, __LINE__, \ 195# define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
191 (op), (n) * sizeof (Type))) 196 (char *) (op), (n) * sizeof (Type)))
192#else 197#else
193# define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) 198# define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
194# define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type))) 199# define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
200 (char *) (op), (n) * sizeof (Type)))
195#endif 201#endif
196 202
197typedef int bool; 203typedef int bool;
@@ -288,7 +294,7 @@ static void free_patterns P_((void));
288#endif /* ETAGS_REGEXPS */ 294#endif /* ETAGS_REGEXPS */
289static void error P_((const char *, const char *)); 295static void error P_((const char *, const char *));
290static void suggest_asking_for_help P_((void)); 296static void suggest_asking_for_help P_((void));
291static void fatal P_((char *, char *)); 297void fatal P_((char *, char *));
292static void pfatal P_((char *)); 298static void pfatal P_((char *));
293static void add_node P_((node *, node **)); 299static void add_node P_((node *, node **));
294 300
@@ -315,7 +321,7 @@ static char *absolute_filename P_((char *, char *));
315static char *absolute_dirname P_((char *, char *)); 321static char *absolute_dirname P_((char *, char *));
316static bool filename_is_absolute P_((char *f)); 322static bool filename_is_absolute P_((char *f));
317static void canonicalize_filename P_((char *)); 323static void canonicalize_filename P_((char *));
318static void grow_linebuffer P_((linebuffer *, int)); 324static void linebuffer_setlen P_((linebuffer *, int));
319long *xmalloc P_((unsigned int)); 325long *xmalloc P_((unsigned int));
320long *xrealloc P_((char *, unsigned int)); 326long *xrealloc P_((char *, unsigned int));
321 327
@@ -339,12 +345,6 @@ char *dbp; /* pointer to start of current tag */
339node *head; /* the head of the binary tree of tags */ 345node *head; /* the head of the binary tree of tags */
340 346
341linebuffer lb; /* the current line */ 347linebuffer lb; /* the current line */
342linebuffer token_name; /* used by C_entries as a temporary area */
343struct
344{
345 long linepos;
346 linebuffer lb; /* used by C_entries instead of lb */
347} lbs[2];
348 348
349/* boolean "functions" (see init) */ 349/* boolean "functions" (see init) */
350bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS]; 350bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
@@ -363,7 +363,7 @@ char
363bool append_to_tagfile; /* -a: append to tags */ 363bool append_to_tagfile; /* -a: append to tags */
364/* The following four default to TRUE for etags, but to FALSE for ctags. */ 364/* The following four default to TRUE for etags, but to FALSE for ctags. */
365bool typedefs; /* -t: create tags for C and Ada typedefs */ 365bool typedefs; /* -t: create tags for C and Ada typedefs */
366bool typedefs_and_cplusplus; /* -T: create tags for C typedefs, level */ 366bool typedefs_or_cplusplus; /* -T: create tags for C typedefs, level */
367 /* 0 struct/enum/union decls, and C++ */ 367 /* 0 struct/enum/union decls, and C++ */
368 /* member functions. */ 368 /* member functions. */
369bool constantypedefs; /* -d: create tags for C #define, enum */ 369bool constantypedefs; /* -d: create tags for C #define, enum */
@@ -574,6 +574,7 @@ language lang_names [] =
574 { "none", just_read_file }, /* regexp matching only */ 574 { "none", just_read_file }, /* regexp matching only */
575 { NULL, NULL } /* end of list */ 575 { NULL, NULL } /* end of list */
576}; 576};
577
577 578
578static void 579static void
579print_language_names () 580print_language_names ()
@@ -938,7 +939,7 @@ main (argc, argv)
938 */ 939 */
939 if (!CTAGS) 940 if (!CTAGS)
940 { 941 {
941 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE; 942 typedefs = typedefs_or_cplusplus = constantypedefs = TRUE;
942 globals = TRUE; 943 globals = TRUE;
943 members = FALSE; 944 members = FALSE;
944 } 945 }
@@ -1034,7 +1035,7 @@ main (argc, argv)
1034 typedefs = TRUE; 1035 typedefs = TRUE;
1035 break; 1036 break;
1036 case 'T': 1037 case 'T':
1037 typedefs = typedefs_and_cplusplus = TRUE; 1038 typedefs = typedefs_or_cplusplus = TRUE;
1038 break; 1039 break;
1039#if (!CTAGS) 1040#if (!CTAGS)
1040 /* Etags options */ 1041 /* Etags options */
@@ -1085,9 +1086,6 @@ main (argc, argv)
1085 init (); /* set up boolean "functions" */ 1086 init (); /* set up boolean "functions" */
1086 1087
1087 initbuffer (&lb); 1088 initbuffer (&lb);
1088 initbuffer (&token_name);
1089 initbuffer (&lbs[0].lb);
1090 initbuffer (&lbs[1].lb);
1091 initbuffer (&filename_lb); 1089 initbuffer (&filename_lb);
1092 1090
1093 if (!CTAGS) 1091 if (!CTAGS)
@@ -1219,7 +1217,7 @@ main (argc, argv)
1219 * return a pointer into FILE where the compressor-specific 1217 * return a pointer into FILE where the compressor-specific
1220 * extension begins. If no compressor is found, NULL is returned 1218 * extension begins. If no compressor is found, NULL is returned
1221 * and EXTPTR is not significant. 1219 * and EXTPTR is not significant.
1222 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> 1220 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1223 */ 1221 */
1224static compressor * 1222static compressor *
1225get_compressor_from_suffix (file, extptr) 1223get_compressor_from_suffix (file, extptr)
@@ -1606,6 +1604,7 @@ find_entries (file, inf)
1606 } 1604 }
1607 return; 1605 return;
1608} 1606}
1607
1609 1608
1610/* Record a tag. */ 1609/* Record a tag. */
1611static void 1610static void
@@ -1659,10 +1658,9 @@ pfnote (name, is_func, linestart, linelen, lno, cno)
1659 add_node (np, &head); 1658 add_node (np, &head);
1660} 1659}
1661 1660
1662/* Date: Wed, 22 Jan 1997 02:56:31 -0500 [last amended 18 Sep 1997] 1661/*
1663 * From: Sam Kendall <kendall@mv.mv.com> 1662 * TAGS format specification
1664 * Subject: Proposal for firming up the TAGS format specification 1663 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1665 * To: F.Potorti@cnuce.cnr.it
1666 * 1664 *
1667 * pfnote should emit the optimized form [unnamed tag] only if: 1665 * pfnote should emit the optimized form [unnamed tag] only if:
1668 * 1. name does not contain any of the characters " \t\r\n(),;"; 1666 * 1. name does not contain any of the characters " \t\r\n(),;";
@@ -1802,6 +1800,7 @@ add_node (np, cur_node_p)
1802 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right); 1800 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right);
1803 } 1801 }
1804} 1802}
1803
1805 1804
1806static void 1805static void
1807put_entries (np) 1806put_entries (np)
@@ -1910,6 +1909,7 @@ total_size_of_entries (np)
1910 1909
1911 return total; 1910 return total;
1912} 1911}
1912
1913 1913
1914/* 1914/*
1915 * The C symbol tables. 1915 * The C symbol tables.
@@ -2164,14 +2164,17 @@ C_symtype (str, len, c_ext)
2164 return st_none; 2164 return st_none;
2165 return se->type; 2165 return se->type;
2166} 2166}
2167
2167 2168
2168 /* 2169/*
2169 * C functions and variables are recognized using a simple 2170 * C functions and variables are recognized using a simple
2170 * finite automaton. fvdef is its state variable. 2171 * finite automaton. fvdef is its state variable.
2171 */ 2172 */
2172enum 2173enum
2173{ 2174{
2174 fvnone, /* nothing seen */ 2175 fvnone, /* nothing seen */
2176 fdefunkey, /* Emacs DEFUN keyword seen */
2177 fdefunname, /* Emacs DEFUN name seen */
2175 foperator, /* func: operator keyword seen (cplpl) */ 2178 foperator, /* func: operator keyword seen (cplpl) */
2176 fvnameseen, /* function or variable name seen */ 2179 fvnameseen, /* function or variable name seen */
2177 fstartlist, /* func: just after open parenthesis */ 2180 fstartlist, /* func: just after open parenthesis */
@@ -2183,10 +2186,10 @@ enum
2183 2186
2184bool fvextern; /* func or var: extern keyword seen; */ 2187bool fvextern; /* func or var: extern keyword seen; */
2185 2188
2186 /* 2189/*
2187 * typedefs are recognized using a simple finite automaton. 2190 * typedefs are recognized using a simple finite automaton.
2188 * typdef is its state variable. 2191 * typdef is its state variable.
2189 */ 2192 */
2190enum 2193enum
2191{ 2194{
2192 tnone, /* nothing seen */ 2195 tnone, /* nothing seen */
@@ -2197,12 +2200,11 @@ enum
2197 tignore /* junk after typedef tag */ 2200 tignore /* junk after typedef tag */
2198} typdef; 2201} typdef;
2199 2202
2200 2203/*
2201 /* 2204 * struct-like structures (enum, struct and union) are recognized
2202 * struct-like structures (enum, struct and union) are recognized 2205 * using another simple finite automaton. `structdef' is its state
2203 * using another simple finite automaton. `structdef' is its state 2206 * variable.
2204 * variable. 2207 */
2205 */
2206enum 2208enum
2207{ 2209{
2208 snone, /* nothing seen yet */ 2210 snone, /* nothing seen yet */
@@ -2213,12 +2215,10 @@ enum
2213} structdef; 2215} structdef;
2214 2216
2215/* 2217/*
2216 * When structdef is stagseen, scolonseen, or sinbody, structtag is the 2218 * When structdef is stagseen, scolonseen, or sinbody, structtype is the
2217 * struct tag, and structtype is the type of the preceding struct-like 2219 * type of the preceding struct-like keyword.
2218 * keyword.
2219 */ 2220 */
2220char *structtag = "<uninited>"; 2221char *structtag = "<uninited>";
2221enum sym_type structtype;
2222 2222
2223/* 2223/*
2224 * When objdef is different from onone, objtag is the name of the class. 2224 * When objdef is different from onone, objtag is the name of the class.
@@ -2238,7 +2238,7 @@ enum
2238 2238
2239/* 2239/*
2240 * State machine for Objective C protocols and implementations. 2240 * State machine for Objective C protocols and implementations.
2241 * Tom R.Hageman <tom@basil.icce.rug.nl> 2241 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2242 */ 2242 */
2243enum 2243enum
2244{ 2244{
@@ -2261,34 +2261,16 @@ enum
2261 * Use this structure to keep info about the token read, and how it 2261 * Use this structure to keep info about the token read, and how it
2262 * should be tagged. Used by the make_C_tag function to build a tag. 2262 * should be tagged. Used by the make_C_tag function to build a tag.
2263 */ 2263 */
2264typedef struct 2264struct tok
2265{ 2265{
2266 bool valid; 2266 bool valid;
2267 char *str;
2268 bool named; 2267 bool named;
2269 int linelen; 2268 int linelen;
2270 int lineno; 2269 int lineno;
2271 long linepos; 2270 long linepos;
2272 char *buffer; 2271 char *line;
2273} token; 2272} token; /* latest token read */
2274 2273linebuffer token_name; /* its name */
2275token tok; /* latest token read */
2276
2277/*
2278 * Set this to TRUE, and the next token considered is called a function.
2279 * Used only for GNU emacs's function-defining macros.
2280 */
2281bool next_token_is_func;
2282
2283/*
2284 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
2285 */
2286bool yacc_rules;
2287
2288/*
2289 * methodlen is the length of the method name stored in token_name.
2290 */
2291int methodlen;
2292 2274
2293static bool consider_token P_((char *, int, int, int, int, int, bool *)); 2275static bool consider_token P_((char *, int, int, int, int, int, bool *));
2294static void make_C_tag P_((bool)); 2276static void make_C_tag P_((bool));
@@ -2308,7 +2290,6 @@ static void make_C_tag P_((bool));
2308 * definedef IN OUT 2290 * definedef IN OUT
2309 * typdef IN OUT 2291 * typdef IN OUT
2310 * objdef IN OUT 2292 * objdef IN OUT
2311 * next_token_is_func IN OUT
2312 */ 2293 */
2313 2294
2314static bool 2295static bool
@@ -2321,7 +2302,13 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2321 int parlev; /* IN: parenthesis level */ 2302 int parlev; /* IN: parenthesis level */
2322 bool *is_func_or_var; /* OUT: function or variable found */ 2303 bool *is_func_or_var; /* OUT: function or variable found */
2323{ 2304{
2324 enum sym_type toktype = C_symtype (str, len, c_ext); 2305 /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
2306 structtype is the type of the preceding struct-like keyword. */
2307 static enum sym_type structtype;
2308 static enum sym_type toktype;
2309
2310
2311 toktype = C_symtype (str, len, c_ext);
2325 2312
2326 /* 2313 /*
2327 * Advance the definedef state machine. 2314 * Advance the definedef state machine.
@@ -2330,6 +2317,11 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2330 { 2317 {
2331 case dnone: 2318 case dnone:
2332 /* We're not on a preprocessor line. */ 2319 /* We're not on a preprocessor line. */
2320 if (toktype == st_C_gnumacro)
2321 {
2322 fvdef = fdefunkey;
2323 return FALSE;
2324 }
2333 break; 2325 break;
2334 case dsharpseen: 2326 case dsharpseen:
2335 if (toktype == st_C_define) 2327 if (toktype == st_C_define)
@@ -2415,7 +2407,7 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2415 case st_C_struct: 2407 case st_C_struct:
2416 case st_C_enum: 2408 case st_C_enum:
2417 if (typdef == tkeyseen 2409 if (typdef == tkeyseen
2418 || (typedefs_and_cplusplus && cblev == 0 && structdef == snone)) 2410 || (typedefs_or_cplusplus && cblev == 0 && structdef == snone))
2419 { 2411 {
2420 structdef = skeyseen; 2412 structdef = skeyseen;
2421 structtype = toktype; 2413 structtype = toktype;
@@ -2438,34 +2430,6 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2438 if (typdef != tnone) 2430 if (typdef != tnone)
2439 definedef = dnone; 2431 definedef = dnone;
2440 2432
2441 /* Detect GNU macros.
2442
2443 Writers of emacs code are recommended to put the
2444 first two args of a DEFUN on the same line.
2445
2446 The DEFUN macro, used in emacs C source code, has a first arg
2447 that is a string (the lisp function name), and a second arg that
2448 is a C function name. Since etags skips strings, the second arg
2449 is tagged. This is unfortunate, as it would be better to tag the
2450 first arg. The simplest way to deal with this problem would be
2451 to name the tag with a name built from the function name, by
2452 removing the initial 'F' character and substituting '-' for '_'.
2453 Anyway, this assumes that the conventions of naming lisp
2454 functions will never change. Currently, this method is not
2455 implemented. */
2456 if (definedef == dnone && toktype == st_C_gnumacro)
2457 {
2458 next_token_is_func = TRUE;
2459 return FALSE;
2460 }
2461 if (next_token_is_func)
2462 {
2463 next_token_is_func = FALSE;
2464 fvdef = fignore;
2465 *is_func_or_var = TRUE;
2466 return TRUE;
2467 }
2468
2469 /* Detect Objective C constructs. */ 2433 /* Detect Objective C constructs. */
2470 switch (objdef) 2434 switch (objdef)
2471 { 2435 {
@@ -2501,11 +2465,9 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2501 if (parlev == 0) 2465 if (parlev == 0)
2502 { 2466 {
2503 objdef = omethodtag; 2467 objdef = omethodtag;
2504 methodlen = len; 2468 linebuffer_setlen (&token_name, len);
2505 grow_linebuffer (&token_name, methodlen + 1);
2506 strncpy (token_name.buffer, str, len); 2469 strncpy (token_name.buffer, str, len);
2507 token_name.buffer[methodlen] = '\0'; 2470 token_name.buffer[len] = '\0';
2508 token_name.len = methodlen;
2509 return TRUE; 2471 return TRUE;
2510 } 2472 }
2511 return FALSE; 2473 return FALSE;
@@ -2517,10 +2479,8 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2517 if (parlev == 0) 2479 if (parlev == 0)
2518 { 2480 {
2519 objdef = omethodtag; 2481 objdef = omethodtag;
2520 methodlen += len; 2482 linebuffer_setlen (&token_name, token_name.len + len);
2521 grow_linebuffer (&token_name, methodlen + 1);
2522 strncat (token_name.buffer, str, len); 2483 strncat (token_name.buffer, str, len);
2523 token_name.len = methodlen;
2524 return TRUE; 2484 return TRUE;
2525 } 2485 }
2526 return FALSE; 2486 return FALSE;
@@ -2565,8 +2525,13 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2565 } 2525 }
2566 if (constantypedefs && structdef == sinbody && structtype == st_C_enum) 2526 if (constantypedefs && structdef == sinbody && structtype == st_C_enum)
2567 return TRUE; 2527 return TRUE;
2568 if (fvdef == fvnone) 2528 switch (fvdef)
2569 { 2529 {
2530 case fdefunkey:
2531 fvdef = fdefunname; /* GNU macro */
2532 *is_func_or_var = TRUE;
2533 return TRUE;
2534 case fvnone:
2570 fvdef = fvnameseen; /* function or variable */ 2535 fvdef = fvnameseen; /* function or variable */
2571 *is_func_or_var = TRUE; 2536 *is_func_or_var = TRUE;
2572 return TRUE; 2537 return TRUE;
@@ -2577,20 +2542,24 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2577 return FALSE; 2542 return FALSE;
2578} 2543}
2579 2544
2545
2580/* 2546/*
2581 * C_entries () 2547 * C_entries often keeps pointers to tokens or lines which are older than
2582 * This routine finds functions, variables, typedefs, 2548 * the line currently read. By keeping two line buffers, and switching
2583 * #define's, enum constants and struct/union/enum definitions in 2549 * them at end of line, it is possible to use those pointers.
2584 * C syntax and adds them to the list.
2585 */ 2550 */
2551struct
2552{
2553 long linepos;
2554 linebuffer lb;
2555} lbs[2];
2556
2586#define current_lb_is_new (newndx == curndx) 2557#define current_lb_is_new (newndx == curndx)
2587#define switch_line_buffers() (curndx = 1 - curndx) 2558#define switch_line_buffers() (curndx = 1 - curndx)
2588 2559
2589#define curlb (lbs[curndx].lb) 2560#define curlb (lbs[curndx].lb)
2590#define othlb (lbs[1-curndx].lb)
2591#define newlb (lbs[newndx].lb) 2561#define newlb (lbs[newndx].lb)
2592#define curlinepos (lbs[curndx].linepos) 2562#define curlinepos (lbs[curndx].linepos)
2593#define othlinepos (lbs[1-curndx].linepos)
2594#define newlinepos (lbs[newndx].linepos) 2563#define newlinepos (lbs[newndx].linepos)
2595 2564
2596#define CNL_SAVE_DEFINEDEF() \ 2565#define CNL_SAVE_DEFINEDEF() \
@@ -2607,10 +2576,10 @@ do { \
2607#define CNL() \ 2576#define CNL() \
2608do { \ 2577do { \
2609 CNL_SAVE_DEFINEDEF(); \ 2578 CNL_SAVE_DEFINEDEF(); \
2610 if (savetok.valid) \ 2579 if (savetoken.valid) \
2611 { \ 2580 { \
2612 tok = savetok; \ 2581 token = savetoken; \
2613 savetok.valid = FALSE; \ 2582 savetoken.valid = FALSE; \
2614 } \ 2583 } \
2615 definedef = dnone; \ 2584 definedef = dnone; \
2616} while (0) 2585} while (0)
@@ -2620,9 +2589,9 @@ static void
2620make_C_tag (isfun) 2589make_C_tag (isfun)
2621 bool isfun; 2590 bool isfun;
2622{ 2591{
2623 /* This function should never be called when tok.valid is FALSE, but 2592 /* This function should never be called when token.valid is FALSE, but
2624 we must protect against invalid input or internal errors. */ 2593 we must protect against invalid input or internal errors. */
2625 if (tok.valid) 2594 if (DEBUG || token.valid)
2626 { 2595 {
2627 if (traditional_tag_style) 2596 if (traditional_tag_style)
2628 { 2597 {
@@ -2630,21 +2599,29 @@ make_C_tag (isfun)
2630 which uses the new method for naming tags (see new_pfnote). */ 2599 which uses the new method for naming tags (see new_pfnote). */
2631 char *name = NULL; 2600 char *name = NULL;
2632 2601
2633 if (CTAGS || tok.named) 2602 if (CTAGS || token.named)
2634 name = savestr (token_name.buffer); 2603 {
2604 name = savestr (token_name.buffer);
2605 if (!token.valid)
2606 name = concat (name, "##invalid##", "");
2607 }
2635 pfnote (name, isfun, 2608 pfnote (name, isfun,
2636 tok.buffer, tok.linelen, tok.lineno, tok.linepos); 2609 token.line, token.linelen, token.lineno, token.linepos);
2637 } 2610 }
2638 else 2611 else
2639 new_pfnote (token_name.buffer, token_name.len, isfun, 2612 new_pfnote (token_name.buffer, token_name.len, isfun,
2640 tok.buffer, tok.linelen, tok.lineno, tok.linepos); 2613 token.line, token.linelen, token.lineno, token.linepos);
2641 tok.valid = FALSE; 2614 token.valid = FALSE;
2642 } 2615 }
2643 else if (DEBUG)
2644 abort ();
2645} 2616}
2646 2617
2647 2618
2619/*
2620 * C_entries ()
2621 * This routine finds functions, variables, typedefs,
2622 * #define's, enum constants and struct/union/enum definitions in
2623 * C syntax and adds them to the list.
2624 */
2648static void 2625static void
2649C_entries (c_ext, inf) 2626C_entries (c_ext, inf)
2650 int c_ext; /* extension of C */ 2627 int c_ext; /* extension of C */
@@ -2660,10 +2637,15 @@ C_entries (c_ext, inf)
2660 int cblev; /* current curly brace level */ 2637 int cblev; /* current curly brace level */
2661 int parlev; /* current parenthesis level */ 2638 int parlev; /* current parenthesis level */
2662 bool incomm, inquote, inchar, quotednl, midtoken; 2639 bool incomm, inquote, inchar, quotednl, midtoken;
2663 bool purec, cplpl, cjava; 2640 bool cplpl, cjava;
2664 token savetok; /* token saved during preprocessor handling */ 2641 bool yacc_rules; /* in the rules part of a yacc file */
2642 struct tok savetoken; /* token saved during preprocessor handling */
2665 2643
2666 2644
2645 initbuffer (&token_name);
2646 initbuffer (&lbs[0].lb);
2647 initbuffer (&lbs[1].lb);
2648
2667 tokoff = toklen = 0; /* keep compiler quiet */ 2649 tokoff = toklen = 0; /* keep compiler quiet */
2668 curndx = newndx = 0; 2650 curndx = newndx = 0;
2669 lineno = 0; 2651 lineno = 0;
@@ -2673,12 +2655,11 @@ C_entries (c_ext, inf)
2673 2655
2674 fvdef = fvnone; fvextern = FALSE; typdef = tnone; 2656 fvdef = fvnone; fvextern = FALSE; typdef = tnone;
2675 structdef = snone; definedef = dnone; objdef = onone; 2657 structdef = snone; definedef = dnone; objdef = onone;
2676 next_token_is_func = yacc_rules = FALSE; 2658 yacc_rules = FALSE;
2677 midtoken = inquote = inchar = incomm = quotednl = FALSE; 2659 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2678 tok.valid = savetok.valid = FALSE; 2660 token.valid = savetoken.valid = FALSE;
2679 cblev = 0; 2661 cblev = 0;
2680 parlev = 0; 2662 parlev = 0;
2681 purec = !(c_ext & ~YACC); /* no extensions (apart from possibly yacc) */
2682 cplpl = (c_ext & C_PLPL) == C_PLPL; 2663 cplpl = (c_ext & C_PLPL) == C_PLPL;
2683 cjava = (c_ext & C_JAVA) == C_JAVA; 2664 cjava = (c_ext & C_JAVA) == C_JAVA;
2684 if (cjava) 2665 if (cjava)
@@ -2686,6 +2667,7 @@ C_entries (c_ext, inf)
2686 else 2667 else
2687 { qualifier = "::"; qlen = 2; } 2668 { qualifier = "::"; qlen = 2; }
2688 2669
2670
2689 while (!feof (inf)) 2671 while (!feof (inf))
2690 { 2672 {
2691 c = *lp++; 2673 c = *lp++;
@@ -2756,8 +2738,14 @@ C_entries (c_ext, inf)
2756 { 2738 {
2757 case '"': 2739 case '"':
2758 inquote = TRUE; 2740 inquote = TRUE;
2759 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore) 2741 switch (fvdef)
2760 { 2742 {
2743 case fdefunkey:
2744 case finlist:
2745 case fignore:
2746 case vignore:
2747 break;
2748 default:
2761 fvextern = FALSE; 2749 fvextern = FALSE;
2762 fvdef = fvnone; 2750 fvdef = fvnone;
2763 } 2751 }
@@ -2791,7 +2779,6 @@ C_entries (c_ext, inf)
2791 lp++; 2779 lp++;
2792 definedef = dnone; fvdef = fvnone; fvextern = FALSE; 2780 definedef = dnone; fvdef = fvnone; fvextern = FALSE;
2793 typdef = tnone; structdef = snone; 2781 typdef = tnone; structdef = snone;
2794 next_token_is_func = FALSE;
2795 midtoken = inquote = inchar = incomm = quotednl = FALSE; 2782 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2796 cblev = 0; 2783 cblev = 0;
2797 yacc_rules = !yacc_rules; 2784 yacc_rules = !yacc_rules;
@@ -2828,20 +2815,19 @@ C_entries (c_ext, inf)
2828 2815
2829 2816
2830 /* Consider token only if some complicated conditions are satisfied. */ 2817 /* Consider token only if some complicated conditions are satisfied. */
2831 if ((definedef != dnone 2818 if (typdef != tignore
2832 || (cblev == 0 && structdef != scolonseen)
2833 || (cblev == 1 && cplpl && structdef == sinbody)
2834 || (structdef == sinbody && purec))
2835 && typdef != tignore
2836 && definedef != dignorerest 2819 && definedef != dignorerest
2837 && fvdef != finlist) 2820 && fvdef != finlist
2821 && (definedef != dnone
2822 || (cblev == 0 && structdef != scolonseen)
2823 || (cblev == 1 && cplpl && structdef == sinbody)
2824 || (PUREC && structdef == sinbody))
2825 )
2838 { 2826 {
2839 if (midtoken) 2827 if (midtoken)
2840 { 2828 {
2841 if (endtoken (c)) 2829 if (endtoken (c))
2842 { 2830 {
2843 bool funorvar = FALSE;
2844
2845 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1])) 2831 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1]))
2846 { 2832 {
2847 /* 2833 /*
@@ -2852,10 +2838,12 @@ C_entries (c_ext, inf)
2852 lp += 2; 2838 lp += 2;
2853 toklen += 2; 2839 toklen += 2;
2854 c = lp[-1]; 2840 c = lp[-1];
2855 goto intok; 2841 goto intoken;
2856 } 2842 }
2857 else 2843 else
2858 { 2844 {
2845 bool funorvar = FALSE;
2846
2859 if (yacc_rules 2847 if (yacc_rules
2860 || consider_token (newlb.buffer + tokoff, toklen, c, 2848 || consider_token (newlb.buffer + tokoff, toklen, c,
2861 c_ext, cblev, parlev, &funorvar)) 2849 c_ext, cblev, parlev, &funorvar))
@@ -2872,63 +2860,84 @@ C_entries (c_ext, inf)
2872 c = *lp++; 2860 c = *lp++;
2873 toklen += lp - oldlp; 2861 toklen += lp - oldlp;
2874 } 2862 }
2875 tok.named = FALSE; 2863 token.named = FALSE;
2876 if (!purec 2864 if (!PUREC
2877 && funorvar 2865 && funorvar
2878 && definedef == dnone 2866 && definedef == dnone
2879 && structdef == sinbody) 2867 && structdef == sinbody)
2880 /* function or var defined in C++ class body */ 2868 /* function or var defined in C++ class body */
2881 { 2869 {
2882 int len = strlen (structtag) + qlen + toklen; 2870 int len = strlen (structtag) + qlen + toklen;
2883 grow_linebuffer (&token_name, len + 1); 2871 linebuffer_setlen (&token_name, len);
2884 strcpy (token_name.buffer, structtag); 2872 strcpy (token_name.buffer, structtag);
2885 strcat (token_name.buffer, qualifier); 2873 strcat (token_name.buffer, qualifier);
2886 strncat (token_name.buffer, 2874 strncat (token_name.buffer,
2887 newlb.buffer + tokoff, toklen); 2875 newlb.buffer + tokoff, toklen);
2888 token_name.len = len; 2876 token.named = TRUE;
2889 tok.named = TRUE;
2890 } 2877 }
2891 else if (objdef == ocatseen) 2878 else if (objdef == ocatseen)
2892 /* Objective C category */ 2879 /* Objective C category */
2893 { 2880 {
2894 int len = strlen (objtag) + 2 + toklen; 2881 int len = strlen (objtag) + 2 + toklen;
2895 grow_linebuffer (&token_name, len + 1); 2882 linebuffer_setlen (&token_name, len);
2896 strcpy (token_name.buffer, objtag); 2883 strcpy (token_name.buffer, objtag);
2897 strcat (token_name.buffer, "("); 2884 strcat (token_name.buffer, "(");
2898 strncat (token_name.buffer, 2885 strncat (token_name.buffer,
2899 newlb.buffer + tokoff, toklen); 2886 newlb.buffer + tokoff, toklen);
2900 strcat (token_name.buffer, ")"); 2887 strcat (token_name.buffer, ")");
2901 token_name.len = len; 2888 token.named = TRUE;
2902 tok.named = TRUE;
2903 } 2889 }
2904 else if (objdef == omethodtag 2890 else if (objdef == omethodtag
2905 || objdef == omethodparm) 2891 || objdef == omethodparm)
2906 /* Objective C method */ 2892 /* Objective C method */
2907 { 2893 {
2908 tok.named = TRUE; 2894 token.named = TRUE;
2895 }
2896 else if (fvdef == fdefunname)
2897 {
2898 bool defun = (newlb.buffer[tokoff] == 'F');
2899 int off = tokoff;
2900 int len = toklen;
2901
2902 /* Rewrite the tag so that emacs lisp DEFUNs
2903 can be found by their elisp name */
2904 if (defun)
2905 {
2906 off += 1;
2907 len -= 1;
2908 }
2909 len = toklen;
2910 linebuffer_setlen (&token_name, len);
2911 strncpy (token_name.buffer,
2912 newlb.buffer + off, len);
2913 token_name.buffer[len] = '\0';
2914 if (defun)
2915 while (--len >= 0)
2916 if (token_name.buffer[len] == '_')
2917 token_name.buffer[len] = '-';
2918 token.named = defun;
2909 } 2919 }
2910 else 2920 else
2911 { 2921 {
2912 grow_linebuffer (&token_name, toklen + 1); 2922 linebuffer_setlen (&token_name, toklen);
2913 strncpy (token_name.buffer, 2923 strncpy (token_name.buffer,
2914 newlb.buffer + tokoff, toklen); 2924 newlb.buffer + tokoff, toklen);
2915 token_name.buffer[toklen] = '\0'; 2925 token_name.buffer[toklen] = '\0';
2916 token_name.len = toklen;
2917 /* Name macros and members. */ 2926 /* Name macros and members. */
2918 tok.named = (structdef == stagseen 2927 token.named = (structdef == stagseen
2919 || typdef == ttypeseen 2928 || typdef == ttypeseen
2920 || typdef == tend 2929 || typdef == tend
2921 || (funorvar 2930 || (funorvar
2922 && definedef == dignorerest) 2931 && definedef == dignorerest)
2923 || (funorvar 2932 || (funorvar
2924 && definedef == dnone 2933 && definedef == dnone
2925 && structdef == sinbody)); 2934 && structdef == sinbody));
2926 } 2935 }
2927 tok.lineno = lineno; 2936 token.lineno = lineno;
2928 tok.linelen = tokoff + toklen + 1; 2937 token.linelen = tokoff + toklen + 1;
2929 tok.buffer = newlb.buffer; 2938 token.line = newlb.buffer;
2930 tok.linepos = newlinepos; 2939 token.linepos = newlinepos;
2931 tok.valid = TRUE; 2940 token.valid = TRUE;
2932 2941
2933 if (definedef == dnone 2942 if (definedef == dnone
2934 && (fvdef == fvnameseen 2943 && (fvdef == fvnameseen
@@ -2947,7 +2956,7 @@ C_entries (c_ext, inf)
2947 } 2956 }
2948 } /* if (endtoken (c)) */ 2957 } /* if (endtoken (c)) */
2949 else if (intoken (c)) 2958 else if (intoken (c))
2950 intok: 2959 intoken:
2951 { 2960 {
2952 toklen++; 2961 toklen++;
2953 continue; 2962 continue;
@@ -2975,7 +2984,7 @@ C_entries (c_ext, inf)
2975 structdef = snone; 2984 structdef = snone;
2976 break; 2985 break;
2977 case dsharpseen: 2986 case dsharpseen:
2978 savetok = tok; 2987 savetoken = token;
2979 } 2988 }
2980 if (!yacc_rules || lp == newlb.buffer + 1) 2989 if (!yacc_rules || lp == newlb.buffer + 1)
2981 { 2990 {
@@ -3004,10 +3013,8 @@ C_entries (c_ext, inf)
3004 case omethodtag: 3013 case omethodtag:
3005 case omethodparm: 3014 case omethodparm:
3006 objdef = omethodcolon; 3015 objdef = omethodcolon;
3007 methodlen += 1; 3016 linebuffer_setlen (&token_name, token_name.len + 1);
3008 grow_linebuffer (&token_name, methodlen + 1);
3009 strcat (token_name.buffer, ":"); 3017 strcat (token_name.buffer, ":");
3010 token_name.len = methodlen;
3011 break; 3018 break;
3012 } 3019 }
3013 if (structdef == stagseen) 3020 if (structdef == stagseen)
@@ -3031,15 +3038,6 @@ C_entries (c_ext, inf)
3031 case ';': 3038 case ';':
3032 if (definedef != dnone) 3039 if (definedef != dnone)
3033 break; 3040 break;
3034 if (cblev == 0)
3035 switch (typdef)
3036 {
3037 case tend:
3038 make_C_tag (FALSE); /* a typedef */
3039 /* FALLTHRU */
3040 default:
3041 typdef = tnone;
3042 }
3043 switch (fvdef) 3041 switch (fvdef)
3044 { 3042 {
3045 case fignore: 3043 case fignore:
@@ -3050,20 +3048,31 @@ C_entries (c_ext, inf)
3050 make_C_tag (FALSE); /* a variable */ 3048 make_C_tag (FALSE); /* a variable */
3051 fvextern = FALSE; 3049 fvextern = FALSE;
3052 fvdef = fvnone; 3050 fvdef = fvnone;
3053 tok.valid = FALSE; 3051 token.valid = FALSE;
3054 break; 3052 break;
3055 case flistseen: 3053 case flistseen:
3056 if (declarations && (cblev == 0 || cblev == 1)) 3054 if ((declarations && typdef == tnone && cblev == 0)
3055 || (members && cblev == 1))
3057 make_C_tag (TRUE); /* a function declaration */ 3056 make_C_tag (TRUE); /* a function declaration */
3058 /* FALLTHRU */ 3057 /* FALLTHRU */
3059 default: 3058 default:
3060 fvextern = FALSE; 3059 fvextern = FALSE;
3061 fvdef = fvnone; 3060 fvdef = fvnone;
3062 /* The following instruction invalidates the token. 3061 if (typdef != tend)
3063 Probably the token should be invalidated in all 3062 /* The following instruction invalidates the token.
3064 other cases where some state machine is reset. */ 3063 Probably the token should be invalidated in all other
3065 tok.valid = FALSE; 3064 cases where some state machine is reset prematurely. */
3065 token.valid = FALSE;
3066 } 3066 }
3067 if (cblev == 0)
3068 switch (typdef)
3069 {
3070 case tend:
3071 make_C_tag (FALSE); /* a typedef */
3072 /* FALLTHRU */
3073 default:
3074 typdef = tnone;
3075 }
3067 if (structdef == stagseen) 3076 if (structdef == stagseen)
3068 structdef = snone; 3077 structdef = snone;
3069 break; 3078 break;
@@ -3080,16 +3089,27 @@ C_entries (c_ext, inf)
3080 } 3089 }
3081 switch (fvdef) 3090 switch (fvdef)
3082 { 3091 {
3092 case fdefunkey:
3083 case foperator: 3093 case foperator:
3084 case finlist: 3094 case finlist:
3085 case fignore: 3095 case fignore:
3086 case vignore: 3096 case vignore:
3087 break; 3097 break;
3088 case fvnameseen: 3098 case fdefunname:
3089 if ((members && cblev == 1) 3099 fvdef = fignore;
3090 || (globals && cblev == 0 && (!fvextern || declarations)))
3091 make_C_tag (FALSE); /* a variable */
3092 break; 3100 break;
3101 case flistseen: /* a function */
3102 if (!declarations)
3103 {
3104 fvdef = fvnone;
3105 break;
3106 }
3107 /* FALLTHRU */
3108 case fvnameseen: /* a variable */
3109 if ((members && structdef == sinbody && cblev == 1)
3110 || (globals && cblev == 0 && (!fvextern || declarations)))
3111 make_C_tag (FALSE);
3112 /* FALLTHRU */
3093 default: 3113 default:
3094 fvdef = fvnone; 3114 fvdef = fvnone;
3095 } 3115 }
@@ -3132,7 +3152,7 @@ C_entries (c_ext, inf)
3132 { 3152 {
3133 case fvnameseen: 3153 case fvnameseen:
3134 if (typdef == ttypeseen 3154 if (typdef == ttypeseen
3135 && tok.valid 3155 && token.valid
3136 && *lp != '*' 3156 && *lp != '*'
3137 && structdef != sinbody) 3157 && structdef != sinbody)
3138 { 3158 {
@@ -3182,22 +3202,10 @@ C_entries (c_ext, inf)
3182 break; 3202 break;
3183 if (typdef == ttypeseen) 3203 if (typdef == ttypeseen)
3184 typdef = tinbody; 3204 typdef = tinbody;
3185 switch (structdef)
3186 {
3187 case skeyseen: /* unnamed struct */
3188 structdef = sinbody;
3189 structtag = "_anonymous_";
3190 break;
3191 case stagseen:
3192 case scolonseen: /* named struct */
3193 structdef = sinbody;
3194 make_C_tag (FALSE); /* a struct */
3195 break;
3196 }
3197 switch (fvdef) 3205 switch (fvdef)
3198 { 3206 {
3199 case flistseen: 3207 case flistseen:
3200 make_C_tag (TRUE); /* a function */ 3208 make_C_tag (TRUE); /* a function */
3201 /* FALLTHRU */ 3209 /* FALLTHRU */
3202 case fignore: 3210 case fignore:
3203 fvdef = fvnone; 3211 fvdef = fvnone;
@@ -3220,6 +3228,18 @@ C_entries (c_ext, inf)
3220 cblev = -1; 3228 cblev = -1;
3221 } 3229 }
3222 } 3230 }
3231 switch (structdef)
3232 {
3233 case skeyseen: /* unnamed struct */
3234 structdef = sinbody;
3235 structtag = "_anonymous_";
3236 break;
3237 case stagseen:
3238 case scolonseen: /* named struct */
3239 structdef = sinbody;
3240 make_C_tag (FALSE); /* a struct */
3241 break;
3242 }
3223 cblev++; 3243 cblev++;
3224 break; 3244 break;
3225 case '*': 3245 case '*':
@@ -3312,6 +3332,10 @@ C_entries (c_ext, inf)
3312 } /* switch (c) */ 3332 } /* switch (c) */
3313 3333
3314 } /* while not eof */ 3334 } /* while not eof */
3335
3336 free (token_name.buffer);
3337 free (lbs[0].lb.buffer);
3338 free (lbs[1].lb.buffer);
3315} 3339}
3316 3340
3317/* 3341/*
@@ -3364,6 +3388,7 @@ Yacc_entries (inf)
3364{ 3388{
3365 C_entries (YACC, inf); 3389 C_entries (YACC, inf);
3366} 3390}
3391
3367 3392
3368/* A useful macro. */ 3393/* A useful macro. */
3369#define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \ 3394#define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
@@ -3390,6 +3415,7 @@ just_read_file (inf)
3390 LOOP_ON_INPUT_LINES (inf, lb, dummy) 3415 LOOP_ON_INPUT_LINES (inf, lb, dummy)
3391 continue; 3416 continue;
3392} 3417}
3418
3393 3419
3394/* Fortran parsing */ 3420/* Fortran parsing */
3395 3421
@@ -3535,10 +3561,11 @@ Fortran_functions (inf)
3535 } 3561 }
3536 } 3562 }
3537} 3563}
3564
3538 3565
3539/* 3566/*
3540 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be>, 1998-04-24
3541 * Ada parsing 3567 * Ada parsing
3568 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be> (1998)
3542 */ 3569 */
3543 3570
3544static void adagetit P_((FILE *, char *)); 3571static void adagetit P_((FILE *, char *));
@@ -3703,6 +3730,7 @@ Ada_funcs (inf)
3703 } /* advance char */ 3730 } /* advance char */
3704 } /* advance line */ 3731 } /* advance line */
3705} 3732}
3733
3706 3734
3707/* 3735/*
3708 * Bob Weiner, Motorola Inc., 4/3/94 3736 * Bob Weiner, Motorola Inc., 4/3/94
@@ -3734,12 +3762,14 @@ Asm_labels (inf)
3734 } 3762 }
3735 } 3763 }
3736} 3764}
3765
3737 3766
3738/* 3767/*
3739 * Perl support by Bart Robinson <lomew@cs.utah.edu> 3768 * Perl support
3740 * enhanced by Michael Ernst <mernst@alum.mit.edu>
3741 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/ 3769 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3742 * Perl variable names: /^(my|local).../ 3770 * Perl variable names: /^(my|local).../
3771 * Bart Robinson <lomew@cs.utah.edu> (1995)
3772 * Michael Ernst <mernst@alum.mit.edu> (1997)
3743 */ 3773 */
3744static void 3774static void
3745Perl_functions (inf) 3775Perl_functions (inf)
@@ -3802,10 +3832,12 @@ Perl_functions (inf)
3802 } 3832 }
3803 } 3833 }
3804} 3834}
3835
3805 3836
3806/* 3837/*
3807 * Python support by Eric S. Raymond <esr@thyrsus.com> 3838 * Python support
3808 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/ 3839 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
3840 * Eric S. Raymond <esr@thyrsus.com> (1997)
3809 */ 3841 */
3810static void 3842static void
3811Python_functions (inf) 3843Python_functions (inf)
@@ -3841,6 +3873,7 @@ Python_functions (inf)
3841 } 3873 }
3842 } 3874 }
3843} 3875}
3876
3844 3877
3845/* Idea by Corny de Souza 3878/* Idea by Corny de Souza
3846 * Cobol tag functions 3879 * Cobol tag functions
@@ -3870,9 +3903,11 @@ Cobol_paragraphs (inf)
3870 lb.buffer, ep - lb.buffer + 1, lineno, linecharno); 3903 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
3871 } 3904 }
3872} 3905}
3906
3873 3907
3874/* 3908/*
3875 * Makefile support 3909 * Makefile support
3910 * Idea by Assar Westerlund <assar@sics.se> (2001)
3876 */ 3911 */
3877static void 3912static void
3878Makefile_targets (inf) 3913Makefile_targets (inf)
@@ -3891,6 +3926,7 @@ Makefile_targets (inf)
3891 lb.buffer, bp - lb.buffer + 1, lineno, linecharno); 3926 lb.buffer, bp - lb.buffer + 1, lineno, linecharno);
3892 } 3927 }
3893} 3928}
3929
3894 3930
3895/* Added by Mosur Mohan, 4/22/88 */ 3931/* Added by Mosur Mohan, 4/22/88 */
3896/* Pascal parsing */ 3932/* Pascal parsing */
@@ -4037,7 +4073,7 @@ Pascal_functions (inf)
4037 continue; 4073 continue;
4038 4074
4039 /* save all values for later tagging */ 4075 /* save all values for later tagging */
4040 grow_linebuffer (&tline, lb.len + 1); 4076 linebuffer_setlen (&tline, lb.len);
4041 strcpy (tline.buffer, lb.buffer); 4077 strcpy (tline.buffer, lb.buffer);
4042 save_lineno = lineno; 4078 save_lineno = lineno;
4043 save_lcno = linecharno; 4079 save_lcno = linecharno;
@@ -4073,9 +4109,10 @@ Pascal_functions (inf)
4073 4109
4074 free (tline.buffer); 4110 free (tline.buffer);
4075} 4111}
4112
4076 4113
4077/* 4114/*
4078 * lisp tag functions 4115 * Lisp tag functions
4079 * look for (def or (DEF, quote or QUOTE 4116 * look for (def or (DEF, quote or QUOTE
4080 */ 4117 */
4081 4118
@@ -4169,13 +4206,14 @@ Lisp_functions (inf)
4169 } 4206 }
4170 } 4207 }
4171} 4208}
4209
4172 4210
4173/* 4211/*
4174 * Postscript tag functions 4212 * Postscript tag functions
4175 * Just look for lines where the first character is '/' 4213 * Just look for lines where the first character is '/'
4176 * Richard Mlynarik <mly@adoc.xerox.com>
4177 * Also look at "defineps" for PSWrap 4214 * Also look at "defineps" for PSWrap
4178 * suggested by Masatake YAMATO <masata-y@is.aist-nara.ac.jp> 4215 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4216 * Ideas by Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4179 */ 4217 */
4180static void 4218static void
4181Postscript_functions (inf) 4219Postscript_functions (inf)
@@ -4244,6 +4282,7 @@ Scheme_functions (inf)
4244 } 4282 }
4245 } 4283 }
4246} 4284}
4285
4247 4286
4248/* Find tags in TeX and LaTeX input files. */ 4287/* Find tags in TeX and LaTeX input files. */
4249 4288
@@ -4426,6 +4465,7 @@ TEX_Token (cp)
4426 return i; 4465 return i;
4427 return -1; 4466 return -1;
4428} 4467}
4468
4429 4469
4430/* Texinfo support. Dave Love, Mar. 2000. */ 4470/* Texinfo support. Dave Love, Mar. 2000. */
4431static void 4471static void
@@ -4449,6 +4489,7 @@ Texinfo_nodes (inf)
4449 } 4489 }
4450 } 4490 }
4451} 4491}
4492
4452 4493
4453/* 4494/*
4454 * Prolog support (rewritten) by Anders Lindgren, Mar. 96 4495 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
@@ -4487,7 +4528,7 @@ Prolog_functions (inf)
4487 if (last == NULL) 4528 if (last == NULL)
4488 last = xnew(len + 1, char); 4529 last = xnew(len + 1, char);
4489 else if (len + 1 > allocated) 4530 else if (len + 1 > allocated)
4490 last = xrnew (last, len + 1, char); 4531 xrnew (last, len + 1, char);
4491 allocated = len + 1; 4532 allocated = len + 1;
4492 strncpy (last, cp, len); 4533 strncpy (last, cp, len);
4493 last[len] = '\0'; 4534 last[len] = '\0';
@@ -4614,6 +4655,7 @@ prolog_atom (s, pos)
4614 else 4655 else
4615 return -1; 4656 return -1;
4616} 4657}
4658
4617 4659
4618/* 4660/*
4619 * Support for Erlang -- Anders Lindgren, Feb 1996. 4661 * Support for Erlang -- Anders Lindgren, Feb 1996.
@@ -4662,7 +4704,7 @@ Erlang_functions (inf)
4662 if (last == NULL) 4704 if (last == NULL)
4663 last = xnew (len + 1, char); 4705 last = xnew (len + 1, char);
4664 else if (len + 1 > allocated) 4706 else if (len + 1 > allocated)
4665 last = xrnew (last, len + 1, char); 4707 xrnew (last, len + 1, char);
4666 allocated = len + 1; 4708 allocated = len + 1;
4667 strncpy (last, cp, len); 4709 strncpy (last, cp, len);
4668 last[len] = '\0'; 4710 last[len] = '\0';
@@ -4791,6 +4833,7 @@ erlang_atom (s, pos)
4791 else 4833 else
4792 return -1; 4834 return -1;
4793} 4835}
4836
4794 4837
4795#ifdef ETAGS_REGEXPS 4838#ifdef ETAGS_REGEXPS
4796 4839
@@ -4999,7 +5042,6 @@ substitute (in, out, regs)
4999 for (t = result; *out != '\0'; out++) 5042 for (t = result; *out != '\0'; out++)
5000 if (*out == '\\' && ISDIGIT (*++out)) 5043 if (*out == '\\' && ISDIGIT (*++out))
5001 { 5044 {
5002 /* Using "dig2" satisfies my debugger. Bleah. */
5003 dig = *out - '0'; 5045 dig = *out - '0';
5004 diglen = regs->end[dig] - regs->start[dig]; 5046 diglen = regs->end[dig] - regs->start[dig];
5005 strncpy (t, in + regs->start[dig], diglen); 5047 strncpy (t, in + regs->start[dig], diglen);
@@ -5009,8 +5051,7 @@ substitute (in, out, regs)
5009 *t++ = *out; 5051 *t++ = *out;
5010 *t = '\0'; 5052 *t = '\0';
5011 5053
5012 if (DEBUG && (t > result + size || t - result != (int)strlen (result))) 5054 assert (t <= result + size && t - result == (int)strlen (result));
5013 abort ();
5014 5055
5015 return result; 5056 return result;
5016} 5057}
@@ -5030,6 +5071,7 @@ free_patterns ()
5030 } 5071 }
5031 return; 5072 return;
5032} 5073}
5074
5033 5075
5034static void 5076static void
5035get_tag (bp) 5077get_tag (bp)
@@ -5054,8 +5096,10 @@ static void
5054initbuffer (lbp) 5096initbuffer (lbp)
5055 linebuffer *lbp; 5097 linebuffer *lbp;
5056{ 5098{
5057 lbp->size = 200; 5099 lbp->size = (DEBUG) ? 3 : 200;
5058 lbp->buffer = xnew (200, char); 5100 lbp->buffer = xnew (lbp->size, char);
5101 lbp->buffer[0] = '\0';
5102 lbp->len = 0;
5059} 5103}
5060 5104
5061/* 5105/*
@@ -5087,7 +5131,7 @@ readline_internal (lbp, stream)
5087 { 5131 {
5088 /* We're at the end of linebuffer: expand it. */ 5132 /* We're at the end of linebuffer: expand it. */
5089 lbp->size *= 2; 5133 lbp->size *= 2;
5090 buffer = xrnew (buffer, lbp->size, char); 5134 xrnew (buffer, lbp->size, char);
5091 p += buffer - lbp->buffer; 5135 p += buffer - lbp->buffer;
5092 pend = buffer + lbp->size; 5136 pend = buffer + lbp->size;
5093 lbp->buffer = buffer; 5137 lbp->buffer = buffer;
@@ -5188,6 +5232,7 @@ readline (lbp, stream)
5188 5232
5189 return result; 5233 return result;
5190} 5234}
5235
5191 5236
5192/* 5237/*
5193 * Return a pointer to a space of size strlen(cp)+1 allocated 5238 * Return a pointer to a space of size strlen(cp)+1 allocated
@@ -5280,7 +5325,7 @@ skip_non_spaces (cp)
5280} 5325}
5281 5326
5282/* Print error message and exit. */ 5327/* Print error message and exit. */
5283static void 5328void
5284fatal (s1, s2) 5329fatal (s1, s2)
5285 char *s1, *s2; 5330 char *s1, *s2;
5286{ 5331{
@@ -5336,6 +5381,7 @@ concat (s1, s2, s3)
5336 5381
5337 return result; 5382 return result;
5338} 5383}
5384
5339 5385
5340/* Does the same work as the system V getcwd, but does not need to 5386/* Does the same work as the system V getcwd, but does not need to
5341 guess the buffer size in advance. */ 5387 guess the buffer size in advance. */
@@ -5360,6 +5406,7 @@ etags_getcwd ()
5360 5406
5361#else /* not HAVE_GETCWD */ 5407#else /* not HAVE_GETCWD */
5362#ifdef MSDOS 5408#ifdef MSDOS
5409
5363 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */ 5410 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
5364 5411
5365 getwd (path); 5412 getwd (path);
@@ -5541,15 +5588,18 @@ canonicalize_filename (fn)
5541#endif 5588#endif
5542} 5589}
5543 5590
5544/* Increase the size of a linebuffer. */ 5591/* Set the minimum size of a string contained in a linebuffer. */
5545static void 5592static void
5546grow_linebuffer (lbp, toksize) 5593linebuffer_setlen (lbp, toksize)
5547 linebuffer *lbp; 5594 linebuffer *lbp;
5548 int toksize; 5595 int toksize;
5549{ 5596{
5550 while (lbp->size < toksize) 5597 while (lbp->size <= toksize)
5551 lbp->size *= 2; 5598 {
5552 lbp->buffer = xrnew (lbp->buffer, lbp->size, char); 5599 lbp->size *= 2;
5600 xrnew (lbp->buffer, lbp->size, char);
5601 }
5602 lbp->len = toksize;
5553} 5603}
5554 5604
5555/* Like malloc but get fatal error if memory is exhausted. */ 5605/* Like malloc but get fatal error if memory is exhausted. */