comparison lib-src/etags.c @ 90573:858cb33ae39d

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 357-381) - Merge from gnus--rel--5.10 - Update from CVS - Merge from erc--emacs--21 * gnus--rel--5.10 (patch 116-122) - Update from CVS - Merge from emacs--devo--0 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-98
author Miles Bader <miles@gnu.org>
date Thu, 03 Aug 2006 11:45:23 +0000
parents 8a8e69664178 15be100e5afb
children 7f3f771c85fa
comparison
equal deleted inserted replaced
90572:ab9b8d043c39 90573:858cb33ae39d
39 * If you want to add support for a new language, start by looking at the LUA 39 * If you want to add support for a new language, start by looking at the LUA
40 * language, which is the simplest. Alternatively, consider shipping a 40 * language, which is the simplest. Alternatively, consider shipping a
41 * configuration file containing regexp definitions for etags. 41 * configuration file containing regexp definitions for etags.
42 */ 42 */
43 43
44 char pot_etags_version[] = "@(#) pot revision number is 17.18"; 44 char pot_etags_version[] = "@(#) pot revision number is 17.20";
45 45
46 #define TRUE 1 46 #define TRUE 1
47 #define FALSE 0 47 #define FALSE 0
48 48
49 #ifdef DEBUG 49 #ifdef DEBUG
57 #ifdef HAVE_CONFIG_H 57 #ifdef HAVE_CONFIG_H
58 # include <config.h> 58 # include <config.h>
59 /* On some systems, Emacs defines static as nothing for the sake 59 /* On some systems, Emacs defines static as nothing for the sake
60 of unexec. We don't want that here since we don't use unexec. */ 60 of unexec. We don't want that here since we don't use unexec. */
61 # undef static 61 # undef static
62 # define ETAGS_REGEXPS /* use the regexp features */ 62 # ifndef PTR /* for XEmacs */
63 # define LONG_OPTIONS /* accept long options */
64 # ifndef PTR /* for Xemacs */
65 # define PTR void * 63 # define PTR void *
66 # endif 64 # endif
67 # ifndef __P /* for Xemacs */ 65 # ifndef __P /* for XEmacs */
68 # define __P(args) args 66 # define __P(args) args
69 # endif 67 # endif
70 #else /* no config.h */ 68 #else /* no config.h */
71 # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C)) 69 # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
72 # define __P(args) args /* use prototypes */ 70 # define __P(args) args /* use prototypes */
80 78
81 #ifndef _GNU_SOURCE 79 #ifndef _GNU_SOURCE
82 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */ 80 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
83 #endif 81 #endif
84 82
85 #ifdef LONG_OPTIONS 83 /* WIN32_NATIVE is for XEmacs.
86 # undef LONG_OPTIONS
87 # define LONG_OPTIONS TRUE
88 #else
89 # define LONG_OPTIONS FALSE
90 #endif
91
92 /* WIN32_NATIVE is for Xemacs.
93 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */ 84 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */
94 #ifdef WIN32_NATIVE 85 #ifdef WIN32_NATIVE
95 # undef MSDOS 86 # undef MSDOS
96 # undef WINDOWSNT 87 # undef WINDOWSNT
97 # define WINDOWSNT 88 # define WINDOWSNT
165 156
166 #if !defined (S_ISREG) && defined (S_IFREG) 157 #if !defined (S_ISREG) && defined (S_IFREG)
167 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 158 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
168 #endif 159 #endif
169 160
170 #if LONG_OPTIONS 161 #ifdef NO_LONG_OPTIONS /* define this if you don't have GNU getopt */
171 # include <getopt.h> 162 # define NO_LONG_OPTIONS TRUE
172 #else
173 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr) 163 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
174 extern char *optarg; 164 extern char *optarg;
175 extern int optind, opterr; 165 extern int optind, opterr;
176 #endif /* LONG_OPTIONS */ 166 #else
177 167 # define NO_LONG_OPTIONS FALSE
178 #ifdef ETAGS_REGEXPS 168 # include <getopt.h>
179 # ifndef HAVE_CONFIG_H /* this is a standalone compilation */ 169 #endif /* NO_LONG_OPTIONS */
180 # ifdef __CYGWIN__ /* compiling on Cygwin */ 170
171 #ifndef HAVE_CONFIG_H /* this is a standalone compilation */
172 # ifdef __CYGWIN__ /* compiling on Cygwin */
181 !!! NOTICE !!! 173 !!! NOTICE !!!
182 the regex.h distributed with Cygwin is not compatible with etags, alas! 174 the regex.h distributed with Cygwin is not compatible with etags, alas!
183 If you want regular expression support, you should delete this notice and 175 If you want regular expression support, you should delete this notice and
184 arrange to use the GNU regex.h and regex.c. 176 arrange to use the GNU regex.h and regex.c.
185 # endif
186 # endif 177 # endif
187 # include <regex.h> 178 #endif
188 #endif /* ETAGS_REGEXPS */ 179 #include <regex.h>
189 180
190 /* Define CTAGS to make the program "ctags" compatible with the usual one. 181 /* Define CTAGS to make the program "ctags" compatible with the usual one.
191 Leave it undefined to make the program "etags", which makes emacs-style 182 Leave it undefined to make the program "etags", which makes emacs-style
192 tag tables and tags typedefs, #defines and struct/union/enum by default. */ 183 tag tables and tags typedefs, #defines and struct/union/enum by default. */
193 #ifdef CTAGS 184 #ifdef CTAGS
310 } arg_type; /* argument type */ 301 } arg_type; /* argument type */
311 language *lang; /* language associated with the argument */ 302 language *lang; /* language associated with the argument */
312 char *what; /* the argument itself */ 303 char *what; /* the argument itself */
313 } argument; 304 } argument;
314 305
315 #ifdef ETAGS_REGEXPS
316 /* Structure defining a regular expression. */ 306 /* Structure defining a regular expression. */
317 typedef struct regexp 307 typedef struct regexp
318 { 308 {
319 struct regexp *p_next; /* pointer to next in list */ 309 struct regexp *p_next; /* pointer to next in list */
320 language *lang; /* if set, use only for this language */ 310 language *lang; /* if set, use only for this language */
325 bool error_signaled; /* already signaled for this regexp */ 315 bool error_signaled; /* already signaled for this regexp */
326 bool force_explicit_name; /* do not allow implict tag name */ 316 bool force_explicit_name; /* do not allow implict tag name */
327 bool ignore_case; /* ignore case when matching */ 317 bool ignore_case; /* ignore case when matching */
328 bool multi_line; /* do a multi-line match on the whole file */ 318 bool multi_line; /* do a multi-line match on the whole file */
329 } regexp; 319 } regexp;
330 #endif /* ETAGS_REGEXPS */
331 320
332 321
333 /* Many compilers barf on this: 322 /* Many compilers barf on this:
334 Lang_function Ada_funcs; 323 Lang_function Ada_funcs;
335 so let's write it this way */ 324 so let's write it this way */
373 static void readline __P((linebuffer *, FILE *)); 362 static void readline __P((linebuffer *, FILE *));
374 static long readline_internal __P((linebuffer *, FILE *)); 363 static long readline_internal __P((linebuffer *, FILE *));
375 static bool nocase_tail __P((char *)); 364 static bool nocase_tail __P((char *));
376 static void get_tag __P((char *, char **)); 365 static void get_tag __P((char *, char **));
377 366
378 #ifdef ETAGS_REGEXPS
379 static void analyse_regex __P((char *)); 367 static void analyse_regex __P((char *));
380 static void free_regexps __P((void)); 368 static void free_regexps __P((void));
381 static void regex_tag_multiline __P((void)); 369 static void regex_tag_multiline __P((void));
382 #endif /* ETAGS_REGEXPS */
383 static void error __P((const char *, const char *)); 370 static void error __P((const char *, const char *));
384 static void suggest_asking_for_help __P((void)); 371 static void suggest_asking_for_help __P((void));
385 void fatal __P((char *, char *)); 372 void fatal __P((char *, char *));
386 static void pfatal __P((char *)); 373 static void pfatal __P((char *));
387 static void add_node __P((node *, node **)); 374 static void add_node __P((node *, node **));
483 #endif 470 #endif
484 471
485 #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */ 472 #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
486 static bool parsing_stdin; /* --parse-stdin used */ 473 static bool parsing_stdin; /* --parse-stdin used */
487 474
488 #ifdef ETAGS_REGEXPS
489 static regexp *p_head; /* list of all regexps */ 475 static regexp *p_head; /* list of all regexps */
490 static bool need_filebuf; /* some regexes are multi-line */ 476 static bool need_filebuf; /* some regexes are multi-line */
491 #else 477
492 # define need_filebuf FALSE
493 #endif /* ETAGS_REGEXPS */
494
495 #if LONG_OPTIONS
496 static struct option longopts[] = 478 static struct option longopts[] =
497 { 479 {
498 { "append", no_argument, NULL, 'a' }, 480 { "append", no_argument, NULL, 'a' },
499 { "packages-only", no_argument, &packages_only, TRUE }, 481 { "packages-only", no_argument, &packages_only, TRUE },
500 { "c++", no_argument, NULL, 'C' }, 482 { "c++", no_argument, NULL, 'C' },
505 { "ignore-indentation", no_argument, NULL, 'I' }, 487 { "ignore-indentation", no_argument, NULL, 'I' },
506 { "language", required_argument, NULL, 'l' }, 488 { "language", required_argument, NULL, 'l' },
507 { "members", no_argument, &members, TRUE }, 489 { "members", no_argument, &members, TRUE },
508 { "no-members", no_argument, &members, FALSE }, 490 { "no-members", no_argument, &members, FALSE },
509 { "output", required_argument, NULL, 'o' }, 491 { "output", required_argument, NULL, 'o' },
510 #ifdef ETAGS_REGEXPS
511 { "regex", required_argument, NULL, 'r' }, 492 { "regex", required_argument, NULL, 'r' },
512 { "no-regex", no_argument, NULL, 'R' }, 493 { "no-regex", no_argument, NULL, 'R' },
513 { "ignore-case-regex", required_argument, NULL, 'c' }, 494 { "ignore-case-regex", required_argument, NULL, 'c' },
514 #endif /* ETAGS_REGEXPS */
515 { "parse-stdin", required_argument, NULL, STDIN }, 495 { "parse-stdin", required_argument, NULL, STDIN },
516 { "version", no_argument, NULL, 'V' }, 496 { "version", no_argument, NULL, 'V' },
517 497
518 #if CTAGS /* Ctags options */ 498 #if CTAGS /* Ctags options */
519 { "backward-search", no_argument, NULL, 'B' }, 499 { "backward-search", no_argument, NULL, 'B' },
531 { "no-globals", no_argument, &globals, FALSE }, 511 { "no-globals", no_argument, &globals, FALSE },
532 { "include", required_argument, NULL, 'i' }, 512 { "include", required_argument, NULL, 'i' },
533 #endif 513 #endif
534 { NULL } 514 { NULL }
535 }; 515 };
536 #endif /* LONG_OPTIONS */
537 516
538 static compressor compressors[] = 517 static compressor compressors[] =
539 { 518 {
540 { "z", "gzip -d -c"}, 519 { "z", "gzip -d -c"},
541 { "Z", "gzip -d -c"}, 520 { "Z", "gzip -d -c"},
679 "m", /* Objective C file */ 658 "m", /* Objective C file */
680 NULL }; 659 NULL };
681 static char Objc_help [] = 660 static char Objc_help [] =
682 "In Objective C code, tags include Objective C definitions for classes,\n\ 661 "In Objective C code, tags include Objective C definitions for classes,\n\
683 class categories, methods and protocols. Tags for variables and\n\ 662 class categories, methods and protocols. Tags for variables and\n\
684 functions in classes are named `CLASS::VARIABLE' and `CLASS::FUNCTION'."; 663 functions in classes are named `CLASS::VARIABLE' and `CLASS::FUNCTION'.\n\
664 (Use --help --lang=c --lang=objc --lang=java for full help.)";
685 665
686 static char *Pascal_suffixes [] = 666 static char *Pascal_suffixes [] =
687 { "p", "pas", NULL }; 667 { "p", "pas", NULL };
688 static char Pascal_help [] = 668 static char Pascal_help [] =
689 "In Pascal code, the tags are the functions and procedures defined\n\ 669 "In Pascal code, the tags are the functions and procedures defined\n\
690 in the file."; 670 in the file.";
671 /* " // this is for working around an Emacs highlighting bug... */
691 672
692 static char *Perl_suffixes [] = 673 static char *Perl_suffixes [] =
693 { "pl", "pm", NULL }; 674 { "pl", "pm", NULL };
694 static char *Perl_interpreters [] = 675 static char *Perl_interpreters [] =
695 { "perl", "@PERL@", NULL }; 676 { "perl", "@PERL@", NULL };
883 exit (EXIT_SUCCESS); 864 exit (EXIT_SUCCESS);
884 865
885 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\ 866 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
886 \n\ 867 \n\
887 These are the options accepted by %s.\n", progname, progname); 868 These are the options accepted by %s.\n", progname, progname);
888 if (LONG_OPTIONS) 869 if (NO_LONG_OPTIONS)
870 puts ("WARNING: long option names do not work with this executable,\n\
871 as it is not linked with GNU getopt.");
872 else
889 puts ("You may use unambiguous abbreviations for the long option names."); 873 puts ("You may use unambiguous abbreviations for the long option names.");
890 else
891 puts ("Long option names do not work with this executable, as it is not\n\
892 linked with GNU getopt.");
893 puts (" A - as file name means read names from stdin (one per line).\n\ 874 puts (" A - as file name means read names from stdin (one per line).\n\
894 Absolute names are stored in the output file as they are.\n\ 875 Absolute names are stored in the output file as they are.\n\
895 Relative ones are stored relative to the output file's directory.\n"); 876 Relative ones are stored relative to the output file's directory.\n");
896 877
897 puts ("-a, --append\n\ 878 puts ("-a, --append\n\
947 Do not create tag entries for global variables in some\n\ 928 Do not create tag entries for global variables in some\n\
948 languages. This makes the tags file smaller."); 929 languages. This makes the tags file smaller.");
949 puts ("--members\n\ 930 puts ("--members\n\
950 Create tag entries for members of structures in some languages."); 931 Create tag entries for members of structures in some languages.");
951 932
952 #ifdef ETAGS_REGEXPS
953 puts ("-r REGEXP, --regex=REGEXP or --regex=@regexfile\n\ 933 puts ("-r REGEXP, --regex=REGEXP or --regex=@regexfile\n\
954 Make a tag for each line matching a regular expression pattern\n\ 934 Make a tag for each line matching a regular expression pattern\n\
955 in the following files. {LANGUAGE}REGEXP uses REGEXP for LANGUAGE\n\ 935 in the following files. {LANGUAGE}REGEXP uses REGEXP for LANGUAGE\n\
956 files only. REGEXFILE is a file containing one REGEXP per line.\n\ 936 files only. REGEXFILE is a file containing one REGEXP per line.\n\
957 REGEXP takes the form /TAGREGEXP/TAGNAME/MODS, where TAGNAME/ is\n\ 937 REGEXP takes the form /TAGREGEXP/TAGNAME/MODS, where TAGNAME/ is\n\
962 MODS are optional one-letter modifiers: `i' means to ignore case,\n\ 942 MODS are optional one-letter modifiers: `i' means to ignore case,\n\
963 `m' means to allow multi-line matches, `s' implies `m' and\n\ 943 `m' means to allow multi-line matches, `s' implies `m' and\n\
964 causes dot to match any character, including newline."); 944 causes dot to match any character, including newline.");
965 puts ("-R, --no-regex\n\ 945 puts ("-R, --no-regex\n\
966 Don't create tags from regexps for the following files."); 946 Don't create tags from regexps for the following files.");
967 #endif /* ETAGS_REGEXPS */
968 puts ("-I, --ignore-indentation\n\ 947 puts ("-I, --ignore-indentation\n\
969 In C and C++ do not assume that a closing brace in the first\n\ 948 In C and C++ do not assume that a closing brace in the first\n\
970 column is the final brace of a function or structure definition."); 949 column is the final brace of a function or structure definition.");
971 puts ("-o FILE, --output=FILE\n\ 950 puts ("-o FILE, --output=FILE\n\
972 Write the tags to FILE."); 951 Write the tags to FILE.");
1192 globals = TRUE; 1171 globals = TRUE;
1193 } 1172 }
1194 1173
1195 /* When the optstring begins with a '-' getopt_long does not rearrange the 1174 /* When the optstring begins with a '-' getopt_long does not rearrange the
1196 non-options arguments to be at the end, but leaves them alone. */ 1175 non-options arguments to be at the end, but leaves them alone. */
1197 optstring = "-"; 1176 optstring = concat (NO_LONG_OPTIONS ? "" : "-",
1198 #ifdef ETAGS_REGEXPS 1177 "ac:Cf:Il:o:r:RSVhH",
1199 optstring = "-r:Rc:";
1200 #endif /* ETAGS_REGEXPS */
1201 if (!LONG_OPTIONS)
1202 optstring += 1; /* remove the initial '-' */
1203 optstring = concat (optstring,
1204 "aCf:Il:o:SVhH",
1205 (CTAGS) ? "BxdtTuvw" : "Di:"); 1178 (CTAGS) ? "BxdtTuvw" : "Di:");
1206 1179
1207 while ((opt = getopt_long (argc, argv, optstring, longopts, NULL)) != EOF) 1180 while ((opt = getopt_long (argc, argv, optstring, longopts, NULL)) != EOF)
1208 switch (opt) 1181 switch (opt)
1209 { 1182 {
1373 switch (argbuffer[i].arg_type) 1346 switch (argbuffer[i].arg_type)
1374 { 1347 {
1375 case at_language: 1348 case at_language:
1376 lang = argbuffer[i].lang; 1349 lang = argbuffer[i].lang;
1377 break; 1350 break;
1378 #ifdef ETAGS_REGEXPS
1379 case at_regexp: 1351 case at_regexp:
1380 analyse_regex (argbuffer[i].what); 1352 analyse_regex (argbuffer[i].what);
1381 break; 1353 break;
1382 #endif
1383 case at_filename: 1354 case at_filename:
1384 #ifdef VMS 1355 #ifdef VMS
1385 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL) 1356 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL)
1386 { 1357 {
1387 if (got_err) 1358 if (got_err)
1417 process_file (stdin, this_file, lang); 1388 process_file (stdin, this_file, lang);
1418 break; 1389 break;
1419 } 1390 }
1420 } 1391 }
1421 1392
1422 #ifdef ETAGS_REGEXPS
1423 free_regexps (); 1393 free_regexps ();
1424 #endif /* ETAGS_REGEXPS */
1425 free (lb.buffer); 1394 free (lb.buffer);
1426 free (filebuf.buffer); 1395 free (filebuf.buffer);
1427 free (token_name.buffer); 1396 free (token_name.buffer);
1428 1397
1429 if (!CTAGS || cxref_style) 1398 if (!CTAGS || cxref_style)
1977 charno = 0; /* reset global char number */ 1946 charno = 0; /* reset global char number */
1978 linecharno = 0; /* reset global char number of line start */ 1947 linecharno = 0; /* reset global char number of line start */
1979 1948
1980 parser (inf); 1949 parser (inf);
1981 1950
1982 #ifdef ETAGS_REGEXPS
1983 regex_tag_multiline (); 1951 regex_tag_multiline ();
1984 #endif /* ETAGS_REGEXPS */
1985 } 1952 }
1986 1953
1987 1954
1988 /* 1955 /*
1989 * Check whether an implicitly named tag should be created, 1956 * Check whether an implicitly named tag should be created,
3237 int attrparlev; /* __attribute__ parenthesis level */ 3204 int attrparlev; /* __attribute__ parenthesis level */
3238 int templatelev; /* current template level */ 3205 int templatelev; /* current template level */
3239 int typdefbracelev; /* bracelev where a typedef struct body begun */ 3206 int typdefbracelev; /* bracelev where a typedef struct body begun */
3240 bool incomm, inquote, inchar, quotednl, midtoken; 3207 bool incomm, inquote, inchar, quotednl, midtoken;
3241 bool yacc_rules; /* in the rules part of a yacc file */ 3208 bool yacc_rules; /* in the rules part of a yacc file */
3242 struct tok savetoken; /* token saved during preprocessor handling */ 3209 struct tok savetoken = {0}; /* token saved during preprocessor handling */
3243 3210
3244 3211
3245 linebuffer_init (&lbs[0].lb); 3212 linebuffer_init (&lbs[0].lb);
3246 linebuffer_init (&lbs[1].lb); 3213 linebuffer_init (&lbs[1].lb);
3247 if (cstack.size == 0) 3214 if (cstack.size == 0)
5733 5700
5734 return pos; 5701 return pos;
5735 } 5702 }
5736 5703
5737 5704
5738 #ifdef ETAGS_REGEXPS
5739
5740 static char *scan_separators __P((char *)); 5705 static char *scan_separators __P((char *));
5741 static void add_regex __P((char *, language *)); 5706 static void add_regex __P((char *, language *));
5742 static char *substitute __P((char *, char *, struct re_registers *)); 5707 static char *substitute __P((char *, char *, struct re_registers *));
5743 5708
5744 /* 5709 /*
6138 break; 6103 break;
6139 } 6104 }
6140 } 6105 }
6141 } 6106 }
6142 } 6107 }
6143
6144 #endif /* ETAGS_REGEXPS */
6145 6108
6146 6109
6147 static bool 6110 static bool
6148 nocase_tail (cp) 6111 nocase_tail (cp)
6149 char *cp; 6112 char *cp;
6403 discard_until_line_directive = FALSE; 6366 discard_until_line_directive = FALSE;
6404 return; 6367 return;
6405 } 6368 }
6406 } /* if #line directives should be considered */ 6369 } /* if #line directives should be considered */
6407 6370
6408 #ifdef ETAGS_REGEXPS
6409 { 6371 {
6410 int match; 6372 int match;
6411 regexp *rp; 6373 regexp *rp;
6412 char *name; 6374 char *name;
6413 6375
6460 lbp->buffer, match, lineno, linecharno); 6422 lbp->buffer, match, lineno, linecharno);
6461 break; 6423 break;
6462 } 6424 }
6463 } 6425 }
6464 } 6426 }
6465 #endif /* ETAGS_REGEXPS */
6466 } 6427 }
6467 6428
6468 6429
6469 /* 6430 /*
6470 * Return a pointer to a space of size strlen(cp)+1 allocated 6431 * Return a pointer to a space of size strlen(cp)+1 allocated
6621 6582
6622 static void 6583 static void
6623 suggest_asking_for_help () 6584 suggest_asking_for_help ()
6624 { 6585 {
6625 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n", 6586 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n",
6626 progname, LONG_OPTIONS ? "--help" : "-h"); 6587 progname, NO_LONG_OPTIONS ? "-h" : "--help");
6627 exit (EXIT_FAILURE); 6588 exit (EXIT_FAILURE);
6628 } 6589 }
6629 6590
6630 /* Print error message. `s1' is printf control string, `s2' is arg for it. */ 6591 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
6631 static void 6592 static void