aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorFrancesco Potortì1995-12-07 09:10:54 +0000
committerFrancesco Potortì1995-12-07 09:10:54 +0000
commitd8913c1c1c382de36f85ded59aab03b637a08023 (patch)
tree41022477c739e604374834a3f203a8ccc6bcf801 /lib-src
parent1ff164dd43938c8d1f694fc956b643f9867b059d (diff)
downloademacs-d8913c1c1c382de36f85ded59aab03b637a08023.tar.gz
emacs-d8913c1c1c382de36f85ded59aab03b637a08023.zip
* etags.c (Cplusplus_suffixes): Add .M suffix for Objective C++.
(gperf): Added keywords for Objective C and GNU macros. (sym_type): Added values to account for Objective C and GNU macros. (begtk): The '@' character can start a token. (objdef, methodlen, objtag): New variables for Objective C. (consider_token, C_entries): Added code for Objective C. (plain_C_suffixes): Add .m and .lm for Objective C. (Yacc_suffixes): Add .ym for Objective yacc. (GROW_LINEBUFFER): New macro. (consider_token, C_entries, Pascal_functions): Use the new macro. (consider_token): Take one more argument. Caller changed. (consider_token): Use the hashing function to spot GNU macros. (C_entries): Consider // as a comment start even in plain C for the sake of Objective C parsing. (pfnote): Don't make a tag for ctags if there is no name. (getit, Asm_labels, Perl_functions, Pascal_functions, L_getit, get_scheme, prolog_getit): Name the tag in ctags mode. (pfnote): Truncate ctags lines to 50 chars, like it worked once. (Perl_interpreters): Accept "@PERL@" as an interpreter. (suggest_asking_for_help): New function. (main, get_language_from_name): Use suggest_asking_for_help. (main): Let get_language_from_name make language existence check. (streq, strneq): Check the arguments #if DEBUG.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/etags.c644
1 files changed, 417 insertions, 227 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 61218c90f1d..7a7c30b157d 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -25,17 +25,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 * Gnu Emacs TAGS format and modifications by RMS? 25 * Gnu Emacs TAGS format and modifications by RMS?
26 * Sam Kendall added C++. 26 * Sam Kendall added C++.
27 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells. 27 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells.
28#ifdef ETAGS_REGEXPS
29 * Regexp tags by Tom Tromey. 28 * Regexp tags by Tom Tromey.
30#endif
31 * 29 *
32 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 30 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer.
33 */ 31 */
34 32
35char pot_etags_version[] = "@(#) pot revision number is 11.45"; 33char pot_etags_version[] = "@(#) pot revision number is 11.53";
36 34
37#define TRUE 1 35#define TRUE 1
38#define FALSE 0 36#define FALSE 0
37
39#ifndef DEBUG 38#ifndef DEBUG
40# define DEBUG FALSE 39# define DEBUG FALSE
41#endif 40#endif
@@ -102,8 +101,8 @@ extern int errno;
102#define C_STAR 0x00003 /* C* */ 101#define C_STAR 0x00003 /* C* */
103#define YACC 0x10000 /* yacc file */ 102#define YACC 0x10000 /* yacc file */
104 103
105#define streq(s,t) (strcmp (s, t) == 0) 104#define streq(s,t) ((DEBUG &&!(s)&&!(t)&&(abort(),1)) || !strcmp(s,t))
106#define strneq(s,t,n) (strncmp (s, t, n) == 0) 105#define strneq(s,t,n) ((DEBUG &&!(s)&&!(t)&&(abort(),1)) || !strncmp(s,t,n))
107 106
108#define lowcase(c) tolower ((unsigned char)c) 107#define lowcase(c) tolower ((unsigned char)c)
109 108
@@ -129,7 +128,7 @@ extern int errno;
129typedef int logical; 128typedef int logical;
130 129
131typedef struct nd_st 130typedef struct nd_st
132{ /* sorting structure */ 131{ /* sorting structure */
133 char *name; /* function or type name */ 132 char *name; /* function or type name */
134 char *file; /* file name */ 133 char *file; /* file name */
135 logical is_func; /* use pattern or line no */ 134 logical is_func; /* use pattern or line no */
@@ -194,6 +193,7 @@ void add_regex ();
194#endif 193#endif
195void add_node (); 194void add_node ();
196void error (); 195void error ();
196void suggest_asking_for_help ();
197void fatal (), pfatal (); 197void fatal (), pfatal ();
198void find_entries (); 198void find_entries ();
199void free_tree (); 199void free_tree ();
@@ -228,6 +228,9 @@ NODE *head; /* the head of the binary tree of tags */
228 * `readline' reads a line from a stream into a linebuffer and works 228 * `readline' reads a line from a stream into a linebuffer and works
229 * regardless of the length of the line. 229 * regardless of the length of the line.
230 */ 230 */
231#define GROW_LINEBUFFER(buf,toksize) \
232while (buf.size < toksize) \
233 buf.buffer = (char *) xrealloc (buf.buffer, buf.size *= 2)
231struct linebuffer 234struct linebuffer
232{ 235{
233 long size; 236 long size;
@@ -235,7 +238,7 @@ struct linebuffer
235}; 238};
236 239
237struct linebuffer lb; /* the current line */ 240struct linebuffer lb; /* the current line */
238struct linebuffer token_name; /* used by C_entries as temporary area */ 241struct linebuffer token_name; /* used by C_entries as a temporary area */
239struct 242struct
240{ 243{
241 long linepos; 244 long linepos;
@@ -245,12 +248,14 @@ struct
245/* boolean "functions" (see init) */ 248/* boolean "functions" (see init) */
246logical _wht[0177], _etk[0177], _itk[0177], _btk[0177]; 249logical _wht[0177], _etk[0177], _itk[0177], _btk[0177];
247char 250char
248 *white = " \f\t\n\013", /* white chars */ 251 /* white chars */
249 *endtk = " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */ 252 *white = " \f\t\n\013",
250 /* token starting chars */ 253 /* token ending chars */
251 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~", 254 *endtk = " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?",
252 /* valid in-token chars */ 255 /* token starting chars */
253 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; 256 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
257 /* valid in-token chars */
258 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
254 259
255logical append_to_tagfile; /* -a: append to tags */ 260logical append_to_tagfile; /* -a: append to tags */
256/* The following three default to TRUE for etags, but to FALSE for ctags. */ 261/* The following three default to TRUE for etags, but to FALSE for ctags. */
@@ -334,52 +339,45 @@ char *Asm_suffixes [] = { "a", /* Unix assembler */
334char *default_C_suffixes [] = 339char *default_C_suffixes [] =
335 { "c", "h", NULL }; 340 { "c", "h", NULL };
336 341
337/* C++ file */ 342/* .M is for Objective C++ files. */
338char *Cplusplus_suffixes [] = 343char *Cplusplus_suffixes [] =
339 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx", NULL }; 344 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx", "M", NULL};
340 345
341/* C* file */
342char *Cstar_suffixes [] = 346char *Cstar_suffixes [] =
343 { "cs", "hs", NULL }; 347 { "cs", "hs", NULL };
344 348
345/* Fortran */
346char *Fortran_suffixes [] = 349char *Fortran_suffixes [] =
347 { "F", "f", "f90", "for", NULL }; 350 { "F", "f", "f90", "for", NULL };
348 351
349/* Lisp source code */
350char *Lisp_suffixes [] = 352char *Lisp_suffixes [] =
351 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL }; 353 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL };
352 354
353/* Pascal file */
354char *Pascal_suffixes [] = 355char *Pascal_suffixes [] =
355 { "p", "pas", NULL }; 356 { "p", "pas", NULL };
356 357
357/* Perl file */
358char *Perl_suffixes [] = 358char *Perl_suffixes [] =
359 { "pl", "pm", NULL }; 359 { "pl", "pm", NULL };
360char *Perl_interpreters [] = 360char *Perl_interpreters [] =
361 { "perl", NULL }; 361 { "perl", "@PERL@", NULL };
362 362
363/* Pro*C file. */
364char *plain_C_suffixes [] = 363char *plain_C_suffixes [] =
365 { "pc", NULL }; 364 { "pc", /* Pro*C file */
365 "m", /* Objective C file */
366 "lm", /* Objective lex file */
367 NULL };
366 368
367/* Prolog source code */
368char *Prolog_suffixes [] = 369char *Prolog_suffixes [] =
369 { "prolog", NULL }; 370 { "prolog", NULL };
370 371
371/* Scheme source code */ 372/* Can't do the `SCM' or `scm' prefix with a version number. */
372/* FIXME Can't do the `SCM' or `scm' prefix with a version number */
373char *Scheme_suffixes [] = 373char *Scheme_suffixes [] =
374 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "t", NULL }; 374 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "t", NULL };
375 375
376/* TeX/LaTeX source code */
377char *TeX_suffixes [] = 376char *TeX_suffixes [] =
378 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL }; 377 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL };
379 378
380/* Yacc file */
381char *Yacc_suffixes [] = 379char *Yacc_suffixes [] =
382 { "y", NULL }; 380 { "y", "ym", NULL }; /* .ym is Objective yacc file */
383 381
384/* Table of language names and corresponding functions, file suffixes 382/* Table of language names and corresponding functions, file suffixes
385 and interpreter names. 383 and interpreter names.
@@ -395,22 +393,22 @@ struct lang_entry
395 393
396struct lang_entry lang_names [] = 394struct lang_entry lang_names [] =
397{ 395{
398 { "asm", Asm_labels, Asm_suffixes }, 396 { "asm", Asm_labels, Asm_suffixes, NULL },
399 { "c", default_C_entries, default_C_suffixes }, 397 { "c", default_C_entries, default_C_suffixes, NULL },
400 { "c++", Cplusplus_entries, Cplusplus_suffixes }, 398 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL },
401 { "c*", Cstar_entries, Cstar_suffixes }, 399 { "c*", Cstar_entries, Cstar_suffixes, NULL },
402 { "fortran", Fortran_functions, Fortran_suffixes }, 400 { "fortran", Fortran_functions, Fortran_suffixes, NULL },
403 { "lisp", Lisp_functions, Lisp_suffixes }, 401 { "lisp", Lisp_functions, Lisp_suffixes, NULL },
404 { "pascal", Pascal_functions, Pascal_suffixes }, 402 { "pascal", Pascal_functions, Pascal_suffixes, NULL },
405 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters }, 403 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters },
406 { "proc", plain_C_entries, plain_C_suffixes }, 404 { "proc", plain_C_entries, plain_C_suffixes, NULL },
407 { "prolog", Prolog_functions, Prolog_suffixes }, 405 { "prolog", Prolog_functions, Prolog_suffixes, NULL },
408 { "scheme" , Scheme_functions, Scheme_suffixes }, 406 { "scheme", Scheme_functions, Scheme_suffixes, NULL },
409 { "tex", TeX_functions, TeX_suffixes }, 407 { "tex", TeX_functions, TeX_suffixes, NULL },
410 { "yacc", Yacc_entries, Yacc_suffixes }, 408 { "yacc", Yacc_entries, Yacc_suffixes, NULL },
411 { "auto", NULL }, /* default guessing scheme */ 409 { "auto", NULL }, /* default guessing scheme */
412 { "none", just_read_file }, /* regexp matching only */ 410 { "none", just_read_file }, /* regexp matching only */
413 { NULL, NULL } /* end of list */ 411 { NULL, NULL } /* end of list */
414}; 412};
415 413
416 414
@@ -763,7 +761,7 @@ main (argc, argv)
763 { 761 {
764 fprintf (stderr, "%s: -%c option may only be given once.\n", 762 fprintf (stderr, "%s: -%c option may only be given once.\n",
765 progname, opt); 763 progname, opt);
766 goto usage; 764 suggest_asking_for_help ();
767 } 765 }
768 tagfile = optarg; 766 tagfile = optarg;
769 break; 767 break;
@@ -773,12 +771,6 @@ main (argc, argv)
773 break; 771 break;
774 case 'l': 772 case 'l':
775 argbuffer[current_arg].function = get_language_from_name (optarg); 773 argbuffer[current_arg].function = get_language_from_name (optarg);
776 if (argbuffer[current_arg].function == NULL)
777 {
778 fprintf (stderr, "%s: language \"%s\" not recognized.\n",
779 progname, optarg);
780 goto usage;
781 }
782 argbuffer[current_arg].arg_type = at_language; 774 argbuffer[current_arg].arg_type = at_language;
783 ++current_arg; 775 ++current_arg;
784 break; 776 break;
@@ -831,7 +823,7 @@ main (argc, argv)
831 break; 823 break;
832#endif /* CTAGS */ 824#endif /* CTAGS */
833 default: 825 default:
834 goto usage; 826 suggest_asking_for_help ();
835 } 827 }
836 } 828 }
837 829
@@ -846,11 +838,7 @@ main (argc, argv)
846 if (nincluded_files == 0 && file_count == 0) 838 if (nincluded_files == 0 && file_count == 0)
847 { 839 {
848 fprintf (stderr, "%s: No input files specified.\n", progname); 840 fprintf (stderr, "%s: No input files specified.\n", progname);
849 841 suggest_asking_for_help ();
850 usage:
851 fprintf (stderr, "\tTry `%s --help' for a complete list of options.\n",
852 progname);
853 exit (BAD);
854 } 842 }
855 843
856 if (tagfile == NULL) 844 if (tagfile == NULL)
@@ -992,15 +980,22 @@ get_language_from_name (name)
992{ 980{
993 struct lang_entry *lang; 981 struct lang_entry *lang;
994 982
995 if (name == NULL) 983 if (name != NULL)
996 return NULL; 984 for (lang = lang_names; lang->name != NULL; lang++)
997 for (lang = lang_names; lang->name != NULL; lang++) 985 {
998 { 986 if (streq (name, lang->name))
999 if (streq (name, lang->name)) 987 return lang->function;
1000 return lang->function; 988 }
1001 }
1002 989
1003 return NULL; 990 fprintf (stderr, "%s: language \"%s\" not recognized.\n",
991 progname, optarg);
992 suggest_asking_for_help ();
993
994 /* This point should never be reached. The function should either
995 return a function pointer or never return. Note that a NULL
996 pointer cannot be considered as an error, as it means that the
997 language has not been explicitely imposed by the user ("auto"). */
998 return NULL; /* avoid warnings from compiler */
1004} 999}
1005 1000
1006 1001
@@ -1145,6 +1140,7 @@ find_entries (file, inf)
1145 NODE *old_last_node; 1140 NODE *old_last_node;
1146 extern NODE *last_node; 1141 extern NODE *last_node;
1147 1142
1143
1148 /* Memory leakage here: the memory block pointed by curfile is never 1144 /* Memory leakage here: the memory block pointed by curfile is never
1149 released. The amount of memory leaked here is the sum of the 1145 released. The amount of memory leaked here is the sum of the
1150 lengths of the input file names. */ 1146 lengths of the input file names. */
@@ -1222,14 +1218,19 @@ find_entries (file, inf)
1222/* Record a tag. */ 1218/* Record a tag. */
1223void 1219void
1224pfnote (name, is_func, linestart, linelen, lno, cno) 1220pfnote (name, is_func, linestart, linelen, lno, cno)
1225 char *name; /* tag name, if different from definition */ 1221 char *name; /* tag name, or NULL if unnamed */
1226 logical is_func; /* tag is a function */ 1222 logical is_func; /* tag is a function */
1227 char *linestart; /* start of the line where tag is */ 1223 char *linestart; /* start of the line where tag is */
1228 int linelen; /* length of the line where tag is */ 1224 int linelen; /* length of the line where tag is */
1229 int lno; /* line number */ 1225 int lno; /* line number */
1230 long cno; /* character number */ 1226 long cno; /* character number */
1231{ 1227{
1232 register NODE *np = xnew (1, NODE); 1228 register NODE *np;
1229
1230 if (CTAGS && name == NULL)
1231 return;
1232
1233 np = xnew (1, NODE);
1233 1234
1234 /* If ctags mode, change name "main" to M<thisfilename>. */ 1235 /* If ctags mode, change name "main" to M<thisfilename>. */
1235 if (CTAGS && !cxref_style && streq (name, "main")) 1236 if (CTAGS && !cxref_style && streq (name, "main"))
@@ -1253,7 +1254,15 @@ pfnote (name, is_func, linestart, linelen, lno, cno)
1253 uncomment the +1 below. */ 1254 uncomment the +1 below. */
1254 np->cno = cno /* + 1 */ ; 1255 np->cno = cno /* + 1 */ ;
1255 np->left = np->right = NULL; 1256 np->left = np->right = NULL;
1256 np->pat = savenstr (linestart, ((CTAGS && !cxref_style) ? 50 : linelen)); 1257 if (CTAGS && !cxref_style)
1258 {
1259 if (strlen (linestart) < 50)
1260 np->pat = concat (linestart, "$", "");
1261 else
1262 np->pat = savenstr (linestart, 50);
1263 }
1264 else
1265 np->pat = savenstr (linestart, linelen);
1257 1266
1258 add_node (np, &head); 1267 add_node (np, &head);
1259} 1268}
@@ -1369,36 +1378,44 @@ put_entries (node)
1369 fprintf (tagf, "%s\177%d,%d\n", 1378 fprintf (tagf, "%s\177%d,%d\n",
1370 node->pat, node->lno, node->cno); 1379 node->pat, node->lno, node->cno);
1371 } 1380 }
1372 else if (!cxref_style) 1381 else
1373 { 1382 {
1374 fprintf (tagf, "%s\t%s\t", 1383 if (node->name == NULL)
1375 node->name, node->file); 1384 error ("internal error: NULL name in ctags mode.", 0);
1376
1377 if (node->is_func)
1378 { /* a function */
1379 putc (searchar, tagf);
1380 putc ('^', tagf);
1381 1385
1382 for (sp = node->pat; *sp; sp++) 1386 if (cxref_style)
1383 { 1387 {
1384 if (*sp == '\\' || *sp == searchar) 1388 if (vgrind_style)
1385 putc ('\\', tagf); 1389 fprintf (stdout, "%s %s %d\n",
1386 putc (*sp, tagf); 1390 node->name, node->file, (node->lno + 63) / 64);
1387 } 1391 else
1388 putc (searchar, tagf); 1392 fprintf (stdout, "%-16s %3d %-16s %s\n",
1393 node->name, node->lno, node->file, node->pat);
1389 } 1394 }
1390 else 1395 else
1391 { /* a typedef; text pattern inadequate */ 1396 {
1392 fprintf (tagf, "%d", node->lno); 1397 fprintf (tagf, "%s\t%s\t", node->name, node->file);
1398
1399 if (node->is_func)
1400 { /* a function */
1401 putc (searchar, tagf);
1402 putc ('^', tagf);
1403
1404 for (sp = node->pat; *sp; sp++)
1405 {
1406 if (*sp == '\\' || *sp == searchar)
1407 putc ('\\', tagf);
1408 putc (*sp, tagf);
1409 }
1410 putc (searchar, tagf);
1411 }
1412 else
1413 { /* a typedef; text pattern inadequate */
1414 fprintf (tagf, "%d", node->lno);
1415 }
1416 putc ('\n', tagf);
1393 } 1417 }
1394 putc ('\n', tagf);
1395 } 1418 }
1396 else if (vgrind_style)
1397 fprintf (stdout, "%s %s %d\n",
1398 node->name, node->file, (node->lno + 63) / 64);
1399 else
1400 fprintf (stdout, "%-16s %3d %-16s %s\n",
1401 node->name, node->lno, node->file, node->pat);
1402 1419
1403 /* Output subentries that follow this one */ 1420 /* Output subentries that follow this one */
1404 put_entries (node->right); 1421 put_entries (node->right);
@@ -1454,7 +1471,8 @@ total_size_of_entries (node)
1454 */ 1471 */
1455enum sym_type 1472enum sym_type
1456{ 1473{
1457 st_none, st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec 1474 st_none, st_C_objprot, st_C_objimpl, st_C_objend, st_C_gnumacro,
1475 st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec,
1458}; 1476};
1459 1477
1460/* Feed stuff between (but not including) %[ and %] lines to: 1478/* Feed stuff between (but not including) %[ and %] lines to:
@@ -1462,6 +1480,10 @@ enum sym_type
1462%[ 1480%[
1463struct C_stab_entry { char *name; int c_ext; enum sym_type type; } 1481struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1464%% 1482%%
1483@interface, 0, st_C_objprot
1484@protocol, 0, st_C_objprot
1485@implementation,0, st_C_objimpl
1486@end, 0, st_C_objend
1465class, C_PLPL, st_C_struct 1487class, C_PLPL, st_C_struct
1466domain, C_STAR, st_C_struct 1488domain, C_STAR, st_C_struct
1467union, 0, st_C_struct 1489union, 0, st_C_struct
@@ -1483,6 +1505,15 @@ extern, 0, st_C_typespec
1483static, 0, st_C_typespec 1505static, 0, st_C_typespec
1484const, 0, st_C_typespec 1506const, 0, st_C_typespec
1485volatile, 0, st_C_typespec 1507volatile, 0, st_C_typespec
1508# DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1509DEFUN, 0, st_C_gnumacro
1510SYSCALL, 0, st_C_gnumacro
1511ENTRY, 0, st_C_gnumacro
1512PSEUDO, 0, st_C_gnumacro
1513# These are defined inside C functions, so currently they are not met.
1514# EXFUN used in glibc, DEFVAR_* in emacs.
1515#EXFUN, 0, st_C_gnumacro
1516#DEFVAR_, 0, st_C_gnumacro
1486%] 1517%]
1487and replace lines between %< and %> with its output. */ 1518and replace lines between %< and %> with its output. */
1488/*%<*/ 1519/*%<*/
@@ -1493,12 +1524,12 @@ and replace lines between %< and %> with its output. */
1493struct C_stab_entry { char *name; int c_ext; enum sym_type type; }; 1524struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
1494 1525
1495#define MIN_WORD_LENGTH 3 1526#define MIN_WORD_LENGTH 3
1496#define MAX_WORD_LENGTH 8 1527#define MAX_WORD_LENGTH 15
1497#define MIN_HASH_VALUE 10 1528#define MIN_HASH_VALUE 7
1498#define MAX_HASH_VALUE 62 1529#define MAX_HASH_VALUE 63
1499/* 1530/*
1500 21 keywords 1531 29 keywords
1501 53 is the maximum key range 1532 57 is the maximum key range
1502*/ 1533*/
1503 1534
1504static int 1535static int
@@ -1508,19 +1539,19 @@ hash (str, len)
1508{ 1539{
1509 static unsigned char hash_table[] = 1540 static unsigned char hash_table[] =
1510 { 1541 {
1511 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1542 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
1512 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1543 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
1513 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1544 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
1514 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1545 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
1515 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1546 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
1516 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1547 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
1517 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1548 63, 63, 63, 63, 17, 63, 63, 63, 4, 14,
1518 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1549 4, 63, 63, 63, 63, 63, 63, 63, 63, 63,
1519 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1550 8, 63, 63, 0, 23, 63, 63, 63, 63, 63,
1520 62, 62, 62, 62, 62, 62, 62, 2, 62, 7, 1551 63, 63, 63, 63, 63, 63, 63, 28, 63, 28,
1521 6, 9, 15, 30, 62, 24, 62, 62, 1, 24, 1552 10, 31, 27, 18, 63, 6, 63, 63, 26, 1,
1522 7, 27, 13, 62, 19, 26, 18, 27, 1, 62, 1553 11, 2, 29, 63, 29, 16, 26, 13, 15, 63,
1523 62, 62, 62, 62, 62, 62, 62, 62, 1554 63, 63, 63, 63, 63, 63, 63, 63,
1524 }; 1555 };
1525 return len + hash_table[str[2]] + hash_table[str[0]]; 1556 return len + hash_table[str[2]] + hash_table[str[0]];
1526} 1557}
@@ -1533,43 +1564,47 @@ in_word_set (str, len)
1533 1564
1534 static struct C_stab_entry wordlist[] = 1565 static struct C_stab_entry wordlist[] =
1535 { 1566 {
1536 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 1567 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1537 {"",}, 1568 {"SYSCALL", 0, st_C_gnumacro},
1538 {"volatile", 0, st_C_typespec}, 1569 {"",}, {"",}, {"",}, {"",}, {"",},
1539 {"",}, 1570 {"DEFUN", 0, st_C_gnumacro},
1540 {"long", 0, st_C_typespec},
1541 {"char", 0, st_C_typespec},
1542 {"class", C_PLPL, st_C_struct},
1543 {"",}, {"",}, {"",}, {"",},
1544 {"const", 0, st_C_typespec},
1545 {"",}, {"",}, {"",}, {"",},
1546 {"auto", 0, st_C_typespec},
1547 {"",}, {"",},
1548 {"define", 0, st_C_define},
1549 {"",},
1550 {"void", 0, st_C_typespec},
1551 {"",}, {"",}, {"",}, 1571 {"",}, {"",}, {"",},
1552 {"extern", 0, st_C_typespec},
1553 {"static", 0, st_C_typespec},
1554 {"",},
1555 {"domain", C_STAR, st_C_struct}, 1572 {"domain", C_STAR, st_C_struct},
1556 {"",}, 1573 {"",}, {"",}, {"",}, {"",}, {"",},
1557 {"typedef", 0, st_C_typedef}, 1574 {"short", 0, st_C_typespec},
1575 {"union", 0, st_C_struct},
1576 {"void", 0, st_C_typespec},
1577 {"",}, {"",},
1578 {"PSEUDO", 0, st_C_gnumacro},
1558 {"double", 0, st_C_typespec}, 1579 {"double", 0, st_C_typespec},
1559 {"enum", 0, st_C_enum}, 1580 {"",}, {"",},
1560 {"",}, {"",}, {"",}, {"",}, 1581 {"@end", 0, st_C_objend},
1582 {"@implementation", 0, st_C_objimpl},
1583 {"float", 0, st_C_typespec},
1561 {"int", 0, st_C_typespec}, 1584 {"int", 0, st_C_typespec},
1562 {"",}, 1585 {"",},
1563 {"float", 0, st_C_typespec}, 1586 {"unsigned", 0, st_C_typespec},
1587 {"@interface", 0, st_C_objprot},
1588 {"",},
1589 {"signed", 0, st_C_typespec},
1590 {"long", 0, st_C_typespec},
1591 {"ENTRY", 0, st_C_gnumacro},
1592 {"define", 0, st_C_define},
1593 {"const", 0, st_C_typespec},
1564 {"",}, {"",}, {"",}, 1594 {"",}, {"",}, {"",},
1595 {"enum", 0, st_C_enum},
1596 {"volatile", 0, st_C_typespec},
1597 {"static", 0, st_C_typespec},
1565 {"struct", 0, st_C_struct}, 1598 {"struct", 0, st_C_struct},
1566 {"",}, {"",}, {"",}, {"",}, 1599 {"",}, {"",}, {"",},
1567 {"union", 0, st_C_struct}, 1600 {"@protocol", 0, st_C_objprot},
1568 {"",},
1569 {"short", 0, st_C_typespec},
1570 {"",}, {"",}, 1601 {"",}, {"",},
1571 {"unsigned", 0, st_C_typespec}, 1602 {"auto", 0, st_C_typespec},
1572 {"signed", 0, st_C_typespec}, 1603 {"",},
1604 {"char", 0, st_C_typespec},
1605 {"class", C_PLPL, st_C_struct},
1606 {"typedef", 0, st_C_typedef},
1607 {"extern", 0, st_C_typespec},
1573 }; 1608 };
1574 1609
1575 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 1610 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
@@ -1580,7 +1615,7 @@ in_word_set (str, len)
1580 { 1615 {
1581 register char *s = wordlist[key].name; 1616 register char *s = wordlist[key].name;
1582 1617
1583 if (*s == *str && strneq (str + 1, s + 1, len - 1)) 1618 if (*s == *str && !strncmp (str + 1, s + 1, len - 1))
1584 return &wordlist[key]; 1619 return &wordlist[key];
1585 } 1620 }
1586 } 1621 }
@@ -1605,7 +1640,7 @@ C_symtype(str, len, c_ext)
1605 * C functions are recognized using a simple finite automaton. 1640 * C functions are recognized using a simple finite automaton.
1606 * funcdef is its state variable. 1641 * funcdef is its state variable.
1607 */ 1642 */
1608typedef enum 1643enum
1609{ 1644{
1610 fnone, /* nothing seen */ 1645 fnone, /* nothing seen */
1611 ftagseen, /* function-like tag seen */ 1646 ftagseen, /* function-like tag seen */
@@ -1613,23 +1648,21 @@ typedef enum
1613 finlist, /* in parameter list */ 1648 finlist, /* in parameter list */
1614 flistseen, /* after parameter list */ 1649 flistseen, /* after parameter list */
1615 fignore /* before open brace */ 1650 fignore /* before open brace */
1616} FUNCST; 1651} funcdef;
1617FUNCST funcdef;
1618 1652
1619 1653
1620 /* 1654 /*
1621 * typedefs are recognized using a simple finite automaton. 1655 * typedefs are recognized using a simple finite automaton.
1622 * typeddef is its state variable. 1656 * typeddef is its state variable.
1623 */ 1657 */
1624typedef enum 1658enum
1625{ 1659{
1626 tnone, /* nothing seen */ 1660 tnone, /* nothing seen */
1627 ttypedseen, /* typedef keyword seen */ 1661 ttypedseen, /* typedef keyword seen */
1628 tinbody, /* inside typedef body */ 1662 tinbody, /* inside typedef body */
1629 tend, /* just before typedef tag */ 1663 tend, /* just before typedef tag */
1630 tignore /* junk after typedef tag */ 1664 tignore /* junk after typedef tag */
1631} TYPEDST; 1665} typdef;
1632TYPEDST typdef;
1633 1666
1634 1667
1635 /* 1668 /*
@@ -1637,15 +1670,14 @@ TYPEDST typdef;
1637 * using another simple finite automaton. `structdef' is its state 1670 * using another simple finite automaton. `structdef' is its state
1638 * variable. 1671 * variable.
1639 */ 1672 */
1640typedef enum 1673enum
1641{ 1674{
1642 snone, /* nothing seen yet */ 1675 snone, /* nothing seen yet */
1643 skeyseen, /* struct-like keyword seen */ 1676 skeyseen, /* struct-like keyword seen */
1644 stagseen, /* struct-like tag seen */ 1677 stagseen, /* struct-like tag seen */
1645 scolonseen, /* colon seen after struct-like tag */ 1678 scolonseen, /* colon seen after struct-like tag */
1646 sinbody /* in struct body: recognize member func defs*/ 1679 sinbody /* in struct body: recognize member func defs*/
1647} STRUCTST; 1680} structdef;
1648STRUCTST structdef;
1649 1681
1650/* 1682/*
1651 * When structdef is stagseen, scolonseen, or sinbody, structtag is the 1683 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
@@ -1656,16 +1688,39 @@ char *structtag = "<uninited>";
1656enum sym_type structtype; 1688enum sym_type structtype;
1657 1689
1658/* 1690/*
1691 * When objdef is different from onone, objtag is the name of the class.
1692 */
1693char *objtag = "<uninited>";
1694
1695/*
1659 * Yet another little state machine to deal with preprocessor lines. 1696 * Yet another little state machine to deal with preprocessor lines.
1660 */ 1697 */
1661typedef enum 1698enum
1662{ 1699{
1663 dnone, /* nothing seen */ 1700 dnone, /* nothing seen */
1664 dsharpseen, /* '#' seen as first char on line */ 1701 dsharpseen, /* '#' seen as first char on line */
1665 ddefineseen, /* '#' and 'define' seen */ 1702 ddefineseen, /* '#' and 'define' seen */
1666 dignorerest /* ignore rest of line */ 1703 dignorerest /* ignore rest of line */
1667} DEFINEST; 1704} definedef;
1668DEFINEST definedef; 1705
1706/*
1707 * State machine for Objective C protocols and implementations.
1708 */
1709enum
1710{
1711 onone, /* nothing seen */
1712 oprotocol, /* @interface or @protocol seen */
1713 oimplementation, /* @implementations seen */
1714 otagseen, /* class name seen */
1715 oparenseen, /* parenthesis before category seen */
1716 ocatseen, /* category name seen */
1717 oinbody, /* in @implementation body */
1718 omethodsign, /* in @implementation body, after +/- */
1719 omethodtag, /* after method name */
1720 omethodcolon, /* after method colon */
1721 omethodparm, /* after method parameter */
1722 oignore, /* wait for @end */
1723} objdef;
1669 1724
1670/* 1725/*
1671 * Set this to TRUE, and the next token considered is called a function. 1726 * Set this to TRUE, and the next token considered is called a function.
@@ -1679,6 +1734,11 @@ logical next_token_is_func;
1679logical yacc_rules; 1734logical yacc_rules;
1680 1735
1681/* 1736/*
1737 * methodlen is the length of the method name stored in token_name.
1738 */
1739int methodlen;
1740
1741/*
1682 * consider_token () 1742 * consider_token ()
1683 * checks to see if the current token is at the start of a 1743 * checks to see if the current token is at the start of a
1684 * function, or corresponds to a typedef, or is a struct/union/enum 1744 * function, or corresponds to a typedef, or is a struct/union/enum
@@ -1697,16 +1757,18 @@ logical yacc_rules;
1697 * structdef IN OUT 1757 * structdef IN OUT
1698 * definedef IN OUT 1758 * definedef IN OUT
1699 * typdef IN OUT 1759 * typdef IN OUT
1760 * objdef IN OUT
1700 * next_token_is_func IN OUT 1761 * next_token_is_func IN OUT
1701 */ 1762 */
1702 1763
1703logical 1764logical
1704consider_token (str, len, c, c_ext, cblev, is_func) 1765consider_token (str, len, c, c_ext, cblev, parlev, is_func)
1705 register char *str; /* IN: token pointer */ 1766 register char *str; /* IN: token pointer */
1706 register int len; /* IN: token length */ 1767 register int len; /* IN: token length */
1707 register char c; /* IN: first char after the token */ 1768 register char c; /* IN: first char after the token */
1708 int c_ext; /* IN: C extensions mask */ 1769 int c_ext; /* IN: C extensions mask */
1709 int cblev; /* IN: curly brace level */ 1770 int cblev; /* IN: curly brace level */
1771 int parlev; /* IN: parenthesis level */
1710 logical *is_func; /* OUT: function found */ 1772 logical *is_func; /* OUT: function found */
1711{ 1773{
1712 enum sym_type toktype = C_symtype (str, len, c_ext); 1774 enum sym_type toktype = C_symtype (str, len, c_ext);
@@ -1831,22 +1893,11 @@ consider_token (str, len, c, c_ext, cblev, is_func)
1831 } 1893 }
1832 1894
1833 /* Detect GNU macros. */ 1895 /* Detect GNU macros. */
1834 if (definedef == dnone) 1896 if (definedef == dnone && toktype == st_C_gnumacro)
1835 if (strneq (str, "DEFUN", len) /* Used in emacs */ 1897 {
1836#if FALSE 1898 next_token_is_func = TRUE;
1837 These are defined inside C functions, so currently they 1899 return FALSE;
1838 are not met anyway. 1900 }
1839 || strneq (str, "EXFUN", len) /* Used in glibc */
1840 || strneq (str, "DEFVAR_", 7) /* Used in emacs */
1841#endif
1842 || strneq (str, "SYSCALL", len) /* Used in glibc (mach) */
1843 || strneq (str, "ENTRY", len) /* Used in glibc */
1844 || strneq (str, "PSEUDO", len)) /* Used in glibc */
1845
1846 {
1847 next_token_is_func = TRUE;
1848 return FALSE;
1849 }
1850 if (next_token_is_func) 1901 if (next_token_is_func)
1851 { 1902 {
1852 next_token_is_func = FALSE; 1903 next_token_is_func = FALSE;
@@ -1855,6 +1906,78 @@ consider_token (str, len, c, c_ext, cblev, is_func)
1855 return TRUE; 1906 return TRUE;
1856 } 1907 }
1857 1908
1909 /*
1910 * Detecting Objective C constructs.
1911 */
1912 switch (objdef)
1913 {
1914 case onone:
1915 switch (toktype)
1916 {
1917 case st_C_objprot:
1918 objdef = oprotocol;
1919 return FALSE;
1920 case st_C_objimpl:
1921 objdef = oimplementation;
1922 return FALSE;
1923 }
1924 break;
1925 case oimplementation:
1926 /* Save the class tag for functions that may be defined inside. */
1927 objtag = savenstr (str, len);
1928 objdef = oinbody;
1929 return FALSE;
1930 case oprotocol:
1931 /* Save the class tag for categories. */
1932 objtag = savenstr (str, len);
1933 objdef = otagseen;
1934 *is_func = TRUE;
1935 return TRUE;
1936 case oparenseen:
1937 objdef = ocatseen;
1938 *is_func = TRUE;
1939 return TRUE;
1940 case oinbody:
1941 break;
1942 case omethodsign:
1943 if (parlev == 0)
1944 {
1945 objdef = omethodtag;
1946 methodlen = len;
1947 GROW_LINEBUFFER (token_name, methodlen+1);
1948 strncpy (token_name.buffer, str, len);
1949 token_name.buffer[methodlen] = '\0';
1950 return TRUE;
1951 }
1952 return FALSE;
1953 case omethodcolon:
1954 if (parlev == 0)
1955 objdef = omethodparm;
1956 return FALSE;
1957 case omethodparm:
1958 if (parlev == 0)
1959 {
1960 objdef = omethodtag;
1961 methodlen =+ len;
1962 GROW_LINEBUFFER (token_name, methodlen+1);
1963 strncat (token_name.buffer, str, len);
1964 return TRUE;
1965 }
1966 return FALSE;
1967 case oignore:
1968 if (toktype == st_C_objend)
1969 {
1970 /* Memory leakage here: the string pointed by objtag is
1971 never released, because many tests would be needed to
1972 avoid breaking on incorrect input code. The amount of
1973 memory leaked here is the sum of the lenghts of the
1974 class tags.
1975 free (objtag); */
1976 objdef = onone;
1977 }
1978 return FALSE;
1979 }
1980
1858 /* A function? */ 1981 /* A function? */
1859 switch (toktype) 1982 switch (toktype)
1860 { 1983 {
@@ -1922,16 +2045,14 @@ do { \
1922 definedef = dnone; \ 2045 definedef = dnone; \
1923} while (0) 2046} while (0)
1924 2047
2048/* Ideally this macro should never be called wihen tok.valid is FALSE,
2049 but this would mean that the state machines always guess right. */
1925#define make_tag(isfun) do \ 2050#define make_tag(isfun) do \
1926{ \ 2051if (tok.valid) { \
1927 if (tok.valid) \ 2052 char *name = NULL; \
1928 { \ 2053 if (CTAGS || tok.named) \
1929 char *name = NULL; \ 2054 name = savestr (token_name.buffer); \
1930 if (tok.named) \ 2055 pfnote (name, isfun, tok.buffer, tok.linelen, tok.lineno, tok.linepos); \
1931 name = savestr (token_name.buffer); \
1932 pfnote (name, isfun, tok.buffer, tok.linelen, tok.lineno, tok.linepos); \
1933 } \
1934 else if (DEBUG) abort (); \
1935 tok.valid = FALSE; \ 2056 tok.valid = FALSE; \
1936} while (0) 2057} while (0)
1937 2058
@@ -1959,7 +2080,8 @@ C_entries (c_ext, inf)
1959 lp = curlb.buffer; 2080 lp = curlb.buffer;
1960 *lp = 0; 2081 *lp = 0;
1961 2082
1962 definedef = dnone; funcdef = fnone; typdef = tnone; structdef = snone; 2083 funcdef = fnone; typdef = tnone; structdef = snone;
2084 definedef = dnone; objdef = onone;
1963 next_token_is_func = yacc_rules = FALSE; 2085 next_token_is_func = yacc_rules = FALSE;
1964 midtoken = inquote = inchar = incomm = quotednl = FALSE; 2086 midtoken = inquote = inchar = incomm = quotednl = FALSE;
1965 tok.valid = savetok.valid = FALSE; 2087 tok.valid = savetok.valid = FALSE;
@@ -2052,9 +2174,9 @@ C_entries (c_ext, inf)
2052 incomm = TRUE; 2174 incomm = TRUE;
2053 continue; 2175 continue;
2054 } 2176 }
2055 else if (cplpl && *lp == '/') 2177 else if (/* cplpl && */ *lp == '/')
2056 { 2178 {
2057 c = 0; 2179 c = '\0';
2058 break; 2180 break;
2059 } 2181 }
2060 else 2182 else
@@ -2114,7 +2236,7 @@ C_entries (c_ext, inf)
2114 { 2236 {
2115 if (endtoken (c)) 2237 if (endtoken (c))
2116 { 2238 {
2117 if (cplpl && c == ':' && *lp == ':' && begtoken(*(lp + 1))) 2239 if (c == ':' && cplpl && *lp == ':' && begtoken(*(lp + 1)))
2118 { 2240 {
2119 /* 2241 /*
2120 * This handles :: in the middle, but not at the 2242 * This handles :: in the middle, but not at the
@@ -2128,37 +2250,43 @@ C_entries (c_ext, inf)
2128 logical is_func = FALSE; 2250 logical is_func = FALSE;
2129 2251
2130 if (yacc_rules 2252 if (yacc_rules
2131 || consider_token (newlb.buffer + tokoff, toklen, 2253 || consider_token (newlb.buffer + tokoff, toklen, c,
2132 c, c_ext, cblev, &is_func)) 2254 c_ext, cblev, parlev, &is_func))
2133 { 2255 {
2134 if (structdef == sinbody 2256 if (structdef == sinbody
2135 && definedef == dnone 2257 && definedef == dnone
2136 && is_func) 2258 && is_func)
2137 /* function defined in C++ class body */ 2259 /* function defined in C++ class body */
2138 { 2260 {
2139 int strsize = strlen(structtag) + 2 + toklen + 1; 2261 GROW_LINEBUFFER (token_name,
2140 while (token_name.size < strsize) 2262 strlen(structtag)+2+toklen+1);
2141 {
2142 token_name.size *= 2;
2143 token_name.buffer
2144 = (char *) xrealloc (token_name.buffer,
2145 token_name.size);
2146 }
2147 strcpy (token_name.buffer, structtag); 2263 strcpy (token_name.buffer, structtag);
2148 strcat (token_name.buffer, "::"); 2264 strcat (token_name.buffer, "::");
2149 strncat (token_name.buffer, 2265 strncat (token_name.buffer,
2150 newlb.buffer+tokoff, toklen); 2266 newlb.buffer+tokoff, toklen);
2151 tok.named = TRUE; 2267 tok.named = TRUE;
2152 } 2268 }
2269 else if (objdef == ocatseen)
2270 /* Objective C category */
2271 {
2272 GROW_LINEBUFFER (token_name,
2273 strlen(objtag)+2+toklen+1);
2274 strcpy (token_name.buffer, objtag);
2275 strcat (token_name.buffer, "(");
2276 strncat (token_name.buffer,
2277 newlb.buffer+tokoff, toklen);
2278 strcat (token_name.buffer, ")");
2279 tok.named = TRUE;
2280 }
2281 else if (objdef == omethodtag
2282 || objdef == omethodparm)
2283 /* Objective C method */
2284 {
2285 tok.named = TRUE;
2286 }
2153 else 2287 else
2154 { 2288 {
2155 while (token_name.size < toklen + 1) 2289 GROW_LINEBUFFER (token_name, toklen+1);
2156 {
2157 token_name.size *= 2;
2158 token_name.buffer
2159 = (char *) xrealloc (token_name.buffer,
2160 token_name.size);
2161 }
2162 strncpy (token_name.buffer, 2290 strncpy (token_name.buffer,
2163 newlb.buffer+tokoff, toklen); 2291 newlb.buffer+tokoff, toklen);
2164 token_name.buffer[toklen] = '\0'; 2292 token_name.buffer[toklen] = '\0';
@@ -2179,7 +2307,8 @@ C_entries (c_ext, inf)
2179 if (definedef == dnone 2307 if (definedef == dnone
2180 && (funcdef == ftagseen 2308 && (funcdef == ftagseen
2181 || structdef == stagseen 2309 || structdef == stagseen
2182 || typdef == tend)) 2310 || typdef == tend
2311 || objdef != onone))
2183 { 2312 {
2184 if (current_lb_is_new) 2313 if (current_lb_is_new)
2185 switch_line_buffers (); 2314 switch_line_buffers ();
@@ -2238,6 +2367,20 @@ C_entries (c_ext, inf)
2238 case ':': 2367 case ':':
2239 if (definedef != dnone) 2368 if (definedef != dnone)
2240 break; 2369 break;
2370 switch (objdef)
2371 {
2372 case otagseen:
2373 objdef = oignore;
2374 make_tag (TRUE);
2375 break;
2376 case omethodtag:
2377 case omethodparm:
2378 objdef = omethodcolon;
2379 methodlen += 1;
2380 GROW_LINEBUFFER (token_name, methodlen+1);
2381 strcat (token_name.buffer, ":");
2382 break;
2383 }
2241 if (structdef == stagseen) 2384 if (structdef == stagseen)
2242 structdef = scolonseen; 2385 structdef = scolonseen;
2243 else 2386 else
@@ -2281,6 +2424,14 @@ C_entries (c_ext, inf)
2281 case ',': 2424 case ',':
2282 if (definedef != dnone) 2425 if (definedef != dnone)
2283 break; 2426 break;
2427 switch (objdef)
2428 {
2429 case omethodtag:
2430 case omethodparm:
2431 make_tag (TRUE);
2432 objdef = oinbody;
2433 break;
2434 }
2284 if (funcdef != finlist && funcdef != fignore) 2435 if (funcdef != finlist && funcdef != fignore)
2285 funcdef = fnone; 2436 funcdef = fnone;
2286 if (structdef == stagseen) 2437 if (structdef == stagseen)
@@ -2303,6 +2454,8 @@ C_entries (c_ext, inf)
2303 case '(': 2454 case '(':
2304 if (definedef != dnone) 2455 if (definedef != dnone)
2305 break; 2456 break;
2457 if (objdef == otagseen && parlev == 0)
2458 objdef = oparenseen;
2306 switch (funcdef) 2459 switch (funcdef)
2307 { 2460 {
2308 case fnone: 2461 case fnone:
@@ -2333,6 +2486,11 @@ C_entries (c_ext, inf)
2333 case ')': 2486 case ')':
2334 if (definedef != dnone) 2487 if (definedef != dnone)
2335 break; 2488 break;
2489 if (objdef == ocatseen && parlev == 1)
2490 {
2491 make_tag (TRUE);
2492 objdef = oignore;
2493 }
2336 if (--parlev == 0) 2494 if (--parlev == 0)
2337 { 2495 {
2338 switch (funcdef) 2496 switch (funcdef)
@@ -2377,9 +2535,22 @@ C_entries (c_ext, inf)
2377 funcdef = fnone; 2535 funcdef = fnone;
2378 break; 2536 break;
2379 case fnone: 2537 case fnone:
2380 /* Neutralize `extern "C" {' grot and look inside structs. */ 2538 switch (objdef)
2381 if (cblev == 0 && structdef == snone && typdef == tnone) 2539 {
2382 cblev = -1; 2540 case otagseen:
2541 make_tag (TRUE);
2542 objdef = oignore;
2543 break;
2544 case omethodtag:
2545 case omethodparm:
2546 make_tag (TRUE);
2547 objdef = oinbody;
2548 break;
2549 default:
2550 /* Neutralize `extern "C" {' grot and look inside structs. */
2551 if (cblev == 0 && structdef == snone && typdef == tnone)
2552 cblev = -1;
2553 }
2383 } 2554 }
2384 cblev++; 2555 cblev++;
2385 break; 2556 break;
@@ -2415,8 +2586,15 @@ C_entries (c_ext, inf)
2415 structtag = "<error>"; 2586 structtag = "<error>";
2416 } 2587 }
2417 break; 2588 break;
2418 case '=': 2589 case '+':
2419 case '#': case '+': case '-': case '~': case '&': case '%': case '/': 2590 case '-':
2591 if (objdef == oinbody && cblev == 0)
2592 {
2593 objdef = omethodsign;
2594 break;
2595 }
2596 /* FALLTHRU */
2597 case '=': case '#': case '~': case '&': case '%': case '/':
2420 case '|': case '^': case '!': case '<': case '>': case '.': case '?': 2598 case '|': case '^': case '!': case '<': case '>': case '.': case '?':
2421 if (definedef != dnone) 2599 if (definedef != dnone)
2422 break; 2600 break;
@@ -2425,6 +2603,11 @@ C_entries (c_ext, inf)
2425 funcdef = fnone; 2603 funcdef = fnone;
2426 break; 2604 break;
2427 case '\0': 2605 case '\0':
2606 if (objdef == otagseen)
2607 {
2608 make_tag (TRUE);
2609 objdef = oignore;
2610 }
2428 /* If a macro spans multiple lines don't reset its state. */ 2611 /* If a macro spans multiple lines don't reset its state. */
2429 if (quotednl) 2612 if (quotednl)
2430 CNL_SAVE_DEFINEDEF; 2613 CNL_SAVE_DEFINEDEF;
@@ -2553,7 +2736,8 @@ getit (inf)
2553 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$'))); 2736 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$')));
2554 cp++) 2737 cp++)
2555 continue; 2738 continue;
2556 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 2739 pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE,
2740 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2557} 2741}
2558 2742
2559void 2743void
@@ -2669,7 +2853,7 @@ Asm_labels (inf)
2669 if (*cp == ':' || isspace (*cp)) 2853 if (*cp == ':' || isspace (*cp))
2670 { 2854 {
2671 /* Found end of label, so copy it and add it to the table. */ 2855 /* Found end of label, so copy it and add it to the table. */
2672 pfnote (NULL, TRUE, 2856 pfnote ((CTAGS) ? savenstr(lb.buffer, cp-lb.buffer) : NULL, TRUE,
2673 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 2857 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2674 } 2858 }
2675 } 2859 }
@@ -2702,7 +2886,7 @@ Perl_functions (inf)
2702 cp++; 2886 cp++;
2703 while (*cp && ! isspace(*cp) && *cp != '{') 2887 while (*cp && ! isspace(*cp) && *cp != '{')
2704 cp++; 2888 cp++;
2705 pfnote (NULL, TRUE, 2889 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : NULL, TRUE,
2706 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 2890 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2707 } 2891 }
2708 } 2892 }
@@ -2731,7 +2915,7 @@ Pascal_functions (inf)
2731 struct linebuffer tline; /* mostly copied from C_entries */ 2915 struct linebuffer tline; /* mostly copied from C_entries */
2732 long save_lcno; 2916 long save_lcno;
2733 int save_lineno, save_len; 2917 int save_lineno, save_len;
2734 char c; 2918 char c, *cp, *namebuf;
2735 2919
2736 logical /* each of these flags is TRUE iff: */ 2920 logical /* each of these flags is TRUE iff: */
2737 incomment, /* point is inside a comment */ 2921 incomment, /* point is inside a comment */
@@ -2845,32 +3029,27 @@ Pascal_functions (inf)
2845 { 3029 {
2846 found_tag = FALSE; 3030 found_tag = FALSE;
2847 verify_tag = FALSE; 3031 verify_tag = FALSE;
2848 pfnote (NULL, TRUE, 3032 pfnote (namebuf, TRUE,
2849 tline.buffer, save_len, save_lineno, save_lcno); 3033 tline.buffer, save_len, save_lineno, save_lcno);
2850 continue; 3034 continue;
2851 } 3035 }
2852 } 3036 }
2853 if (get_tagname) /* grab name of proc or fn */ 3037 if (get_tagname) /* grab name of proc or fn */
2854 { 3038 {
2855 int size;
2856
2857 if (*dbp == '\0') 3039 if (*dbp == '\0')
2858 continue; 3040 continue;
2859 3041
2860 /* save all values for later tagging */ 3042 /* save all values for later tagging */
2861 size = strlen (lb.buffer) + 1; 3043 GROW_LINEBUFFER (tline, strlen (lb.buffer) + 1);
2862 while (size > tline.size)
2863 {
2864 tline.size *= 2;
2865 tline.buffer = (char *) xrealloc (tline.buffer, tline.size);
2866 }
2867 strcpy (tline.buffer, lb.buffer); 3044 strcpy (tline.buffer, lb.buffer);
2868 save_lineno = lineno; 3045 save_lineno = lineno;
2869 save_lcno = linecharno; 3046 save_lcno = linecharno;
2870 3047
2871 /* grab block name */ 3048 /* grab block name */
2872 for (dbp++; *dbp && (!endtoken (*dbp)); dbp++) 3049 for (cp = dbp + 1; *cp && (!endtoken (*cp)); cp++)
2873 continue; 3050 continue;
3051 namebuf = (CTAGS) ? savenstr (dbp, cp-dbp) : NULL;
3052 dbp = cp; /* set dbp to e-o-token */
2874 save_len = dbp - lb.buffer + 1; 3053 save_len = dbp - lb.buffer + 1;
2875 get_tagname = FALSE; 3054 get_tagname = FALSE;
2876 found_tag = TRUE; 3055 found_tag = TRUE;
@@ -2943,7 +3122,8 @@ L_getit ()
2943 if (cp == dbp) 3122 if (cp == dbp)
2944 return; 3123 return;
2945 3124
2946 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 3125 pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE,
3126 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2947} 3127}
2948 3128
2949void 3129void
@@ -3060,7 +3240,8 @@ get_scheme ()
3060 *cp && *cp != '(' && *cp != ')' && !isspace (*cp); 3240 *cp && *cp != '(' && *cp != ')' && !isspace (*cp);
3061 cp++) 3241 cp++)
3062 continue; 3242 continue;
3063 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 3243 pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE,
3244 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3064} 3245}
3065 3246
3066/* Find tags in TeX and LaTeX input files. */ 3247/* Find tags in TeX and LaTeX input files. */
@@ -3319,7 +3500,8 @@ prolog_getit (s)
3319 else 3500 else
3320 s++; 3501 s++;
3321 } 3502 }
3322 pfnote (NULL, TRUE, save_s, s-save_s, lineno, linecharno); 3503 pfnote ((CTAGS) ? savenstr (save_s, s-save_s) : NULL, TRUE,
3504 save_s, s-save_s, lineno, linecharno);
3323} 3505}
3324 3506
3325/* It is assumed that prolog predicate starts from column 0. */ 3507/* It is assumed that prolog predicate starts from column 0. */
@@ -3604,10 +3786,10 @@ readline (linebuffer, stream)
3604 FILE *stream; 3786 FILE *stream;
3605{ 3787{
3606 /* Read new line. */ 3788 /* Read new line. */
3607 int i;
3608 long result = readline_internal (linebuffer, stream); 3789 long result = readline_internal (linebuffer, stream);
3609
3610#ifdef ETAGS_REGEXPS 3790#ifdef ETAGS_REGEXPS
3791 int i;
3792
3611 /* Match against all listed patterns. */ 3793 /* Match against all listed patterns. */
3612 for (i = 0; i < num_patterns; ++i) 3794 for (i = 0; i < num_patterns; ++i)
3613 { 3795 {
@@ -3754,6 +3936,14 @@ pfatal (s1)
3754 exit (BAD); 3936 exit (BAD);
3755} 3937}
3756 3938
3939void
3940suggest_asking_for_help ()
3941{
3942 fprintf (stderr, "\tTry `%s --help' for a complete list of options.\n",
3943 progname);
3944 exit (BAD);
3945}
3946
3757/* Print error message. `s1' is printf control string, `s2' is arg for it. */ 3947/* Print error message. `s1' is printf control string, `s2' is arg for it. */
3758void 3948void
3759error (s1, s2) 3949error (s1, s2)