comparison lib-src/etags.c @ 90234:b1c1fc853d2f

Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-86 Merge from emacs--cvs-trunk--0 Patches applied: * emacs--cvs-trunk--0 (patch 562-568) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 125-128) - Merge from emacs--cvs-trunk--0 - Update from CVS
author Miles Bader <miles@gnu.org>
date Fri, 30 Sep 2005 11:43:45 +0000
parents 2d92f5c9d6ae fbae8bd411de
children 0ca0d9181b5e
comparison
equal deleted inserted replaced
90233:ee12d75eb214 90234:b1c1fc853d2f
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.5"; 44 char pot_etags_version[] = "@(#) pot revision number is 17.14";
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
341 static void Cjava_entries __P((FILE *)); 341 static void Cjava_entries __P((FILE *));
342 static void Cobol_paragraphs __P((FILE *)); 342 static void Cobol_paragraphs __P((FILE *));
343 static void Cplusplus_entries __P((FILE *)); 343 static void Cplusplus_entries __P((FILE *));
344 static void Cstar_entries __P((FILE *)); 344 static void Cstar_entries __P((FILE *));
345 static void Erlang_functions __P((FILE *)); 345 static void Erlang_functions __P((FILE *));
346 static void Forth_words __P((FILE *));
346 static void Fortran_functions __P((FILE *)); 347 static void Fortran_functions __P((FILE *));
347 static void HTML_labels __P((FILE *)); 348 static void HTML_labels __P((FILE *));
348 static void Lisp_functions __P((FILE *)); 349 static void Lisp_functions __P((FILE *));
349 static void Lua_functions __P((FILE *)); 350 static void Lua_functions __P((FILE *));
350 static void Makefile_targets __P((FILE *)); 351 static void Makefile_targets __P((FILE *));
487 #endif /* ETAGS_REGEXPS */ 488 #endif /* ETAGS_REGEXPS */
488 489
489 #if LONG_OPTIONS 490 #if LONG_OPTIONS
490 static struct option longopts[] = 491 static struct option longopts[] =
491 { 492 {
493 { "append", no_argument, NULL, 'a' },
492 { "packages-only", no_argument, &packages_only, TRUE }, 494 { "packages-only", no_argument, &packages_only, TRUE },
493 { "c++", no_argument, NULL, 'C' }, 495 { "c++", no_argument, NULL, 'C' },
494 { "declarations", no_argument, &declarations, TRUE }, 496 { "declarations", no_argument, &declarations, TRUE },
495 { "no-line-directive", no_argument, &no_line_directive, TRUE }, 497 { "no-line-directive", no_argument, &no_line_directive, TRUE },
496 { "help", no_argument, NULL, 'h' }, 498 { "help", no_argument, NULL, 'h' },
506 { "ignore-case-regex", required_argument, NULL, 'c' }, 508 { "ignore-case-regex", required_argument, NULL, 'c' },
507 #endif /* ETAGS_REGEXPS */ 509 #endif /* ETAGS_REGEXPS */
508 { "parse-stdin", required_argument, NULL, STDIN }, 510 { "parse-stdin", required_argument, NULL, STDIN },
509 { "version", no_argument, NULL, 'V' }, 511 { "version", no_argument, NULL, 'V' },
510 512
511 #if CTAGS /* Etags options */ 513 #if CTAGS /* Ctags options */
512 { "backward-search", no_argument, NULL, 'B' }, 514 { "backward-search", no_argument, NULL, 'B' },
513 { "cxref", no_argument, NULL, 'x' }, 515 { "cxref", no_argument, NULL, 'x' },
514 { "defines", no_argument, NULL, 'd' }, 516 { "defines", no_argument, NULL, 'd' },
515 { "globals", no_argument, &globals, TRUE }, 517 { "globals", no_argument, &globals, TRUE },
516 { "typedefs", no_argument, NULL, 't' }, 518 { "typedefs", no_argument, NULL, 't' },
517 { "typedefs-and-c++", no_argument, NULL, 'T' }, 519 { "typedefs-and-c++", no_argument, NULL, 'T' },
518 { "update", no_argument, NULL, 'u' }, 520 { "update", no_argument, NULL, 'u' },
519 { "vgrind", no_argument, NULL, 'v' }, 521 { "vgrind", no_argument, NULL, 'v' },
520 { "no-warn", no_argument, NULL, 'w' }, 522 { "no-warn", no_argument, NULL, 'w' },
521 523
522 #else /* Ctags options */ 524 #else /* Etags options */
523 { "append", no_argument, NULL, 'a' },
524 { "no-defines", no_argument, NULL, 'D' }, 525 { "no-defines", no_argument, NULL, 'D' },
525 { "no-globals", no_argument, &globals, FALSE }, 526 { "no-globals", no_argument, &globals, FALSE },
526 { "include", required_argument, NULL, 'i' }, 527 { "include", required_argument, NULL, 'i' },
527 #endif 528 #endif
528 { NULL } 529 { NULL }
629 { "erl", "hrl", NULL }; 630 { "erl", "hrl", NULL };
630 static char Erlang_help [] = 631 static char Erlang_help [] =
631 "In Erlang code, the tags are the functions, records and macros\n\ 632 "In Erlang code, the tags are the functions, records and macros\n\
632 defined in the file."; 633 defined in the file.";
633 634
635 char *Forth_suffixes [] =
636 { "fth", "tok", NULL };
637 static char Forth_help [] =
638 "In Forth code, tags are words defined by `:',\n\
639 constant, code, create, defer, value, variable, buffer:, field.";
640
634 static char *Fortran_suffixes [] = 641 static char *Fortran_suffixes [] =
635 { "F", "f", "f90", "for", NULL }; 642 { "F", "f", "f90", "for", NULL };
636 static char Fortran_help [] = 643 static char Fortran_help [] =
637 "In Fortran code, functions, subroutines and block data are tags."; 644 "In Fortran code, functions, subroutines and block data are tags.";
638 645
776 { "c", default_C_help, default_C_entries, default_C_suffixes }, 783 { "c", default_C_help, default_C_entries, default_C_suffixes },
777 { "c++", Cplusplus_help, Cplusplus_entries, Cplusplus_suffixes }, 784 { "c++", Cplusplus_help, Cplusplus_entries, Cplusplus_suffixes },
778 { "c*", no_lang_help, Cstar_entries, Cstar_suffixes }, 785 { "c*", no_lang_help, Cstar_entries, Cstar_suffixes },
779 { "cobol", Cobol_help, Cobol_paragraphs, Cobol_suffixes }, 786 { "cobol", Cobol_help, Cobol_paragraphs, Cobol_suffixes },
780 { "erlang", Erlang_help, Erlang_functions, Erlang_suffixes }, 787 { "erlang", Erlang_help, Erlang_functions, Erlang_suffixes },
788 { "forth", Forth_help, Forth_words, Forth_suffixes },
781 { "fortran", Fortran_help, Fortran_functions, Fortran_suffixes }, 789 { "fortran", Fortran_help, Fortran_functions, Fortran_suffixes },
782 { "html", HTML_help, HTML_labels, HTML_suffixes }, 790 { "html", HTML_help, HTML_labels, HTML_suffixes },
783 { "java", Cjava_help, Cjava_entries, Cjava_suffixes }, 791 { "java", Cjava_help, Cjava_entries, Cjava_suffixes },
784 { "lisp", Lisp_help, Lisp_functions, Lisp_suffixes }, 792 { "lisp", Lisp_help, Lisp_functions, Lisp_suffixes },
785 { "lua", Lua_help, Lua_functions, Lua_suffixes }, 793 { "lua", Lua_help, Lua_functions, Lua_suffixes },
879 linked with GNU getopt."); 887 linked with GNU getopt.");
880 puts (" A - as file name means read names from stdin (one per line).\n\ 888 puts (" A - as file name means read names from stdin (one per line).\n\
881 Absolute names are stored in the output file as they are.\n\ 889 Absolute names are stored in the output file as they are.\n\
882 Relative ones are stored relative to the output file's directory.\n"); 890 Relative ones are stored relative to the output file's directory.\n");
883 891
884 if (!CTAGS) 892 puts ("-a, --append\n\
885 puts ("-a, --append\n\
886 Append tag entries to existing tags file."); 893 Append tag entries to existing tags file.");
887 894
888 puts ("--packages-only\n\ 895 puts ("--packages-only\n\
889 For Ada files, only generate tags for packages."); 896 For Ada files, only generate tags for packages.");
890 897
1178 { 1185 {
1179 typedefs = typedefs_or_cplusplus = constantypedefs = TRUE; 1186 typedefs = typedefs_or_cplusplus = constantypedefs = TRUE;
1180 globals = TRUE; 1187 globals = TRUE;
1181 } 1188 }
1182 1189
1190 /* When the optstring begins with a '-' getopt_long does not rearrange the
1191 non-options arguments to be at the end, but leaves them alone. */
1183 optstring = "-"; 1192 optstring = "-";
1184 #ifdef ETAGS_REGEXPS 1193 #ifdef ETAGS_REGEXPS
1185 optstring = "-r:Rc:"; 1194 optstring = "-r:Rc:";
1186 #endif /* ETAGS_REGEXPS */ 1195 #endif /* ETAGS_REGEXPS */
1187 if (!LONG_OPTIONS) 1196 if (!LONG_OPTIONS)
1188 optstring += 1; 1197 optstring += 1; /* remove the initial '-' */
1189 optstring = concat (optstring, 1198 optstring = concat (optstring,
1190 "Cf:Il:o:SVhH", 1199 "aCf:Il:o:SVhH",
1191 (CTAGS) ? "BxdtTuvw" : "aDi:"); 1200 (CTAGS) ? "BxdtTuvw" : "Di:");
1192 1201
1193 while ((opt = getopt_long (argc, argv, optstring, longopts, 0)) != EOF) 1202 while ((opt = getopt_long (argc, argv, optstring, longopts, NULL)) != EOF)
1194 switch (opt) 1203 switch (opt)
1195 { 1204 {
1196 case 0: 1205 case 0:
1197 /* If getopt returns 0, then it has already processed a 1206 /* If getopt returns 0, then it has already processed a
1198 long-named option. We should do nothing. */ 1207 long-named option. We should do nothing. */
1216 fatal ("cannot parse standard input more than once", (char *)NULL); 1225 fatal ("cannot parse standard input more than once", (char *)NULL);
1217 parsing_stdin = TRUE; 1226 parsing_stdin = TRUE;
1218 break; 1227 break;
1219 1228
1220 /* Common options. */ 1229 /* Common options. */
1230 case 'a': append_to_tagfile = TRUE; break;
1221 case 'C': cplusplus = TRUE; break; 1231 case 'C': cplusplus = TRUE; break;
1222 case 'f': /* for compatibility with old makefiles */ 1232 case 'f': /* for compatibility with old makefiles */
1223 case 'o': 1233 case 'o':
1224 if (tagfile) 1234 if (tagfile)
1225 { 1235 {
1265 case 'H': 1275 case 'H':
1266 help_asked = TRUE; 1276 help_asked = TRUE;
1267 break; 1277 break;
1268 1278
1269 /* Etags options */ 1279 /* Etags options */
1270 case 'a': append_to_tagfile = TRUE; break;
1271 case 'D': constantypedefs = FALSE; break; 1280 case 'D': constantypedefs = FALSE; break;
1272 case 'i': included_files[nincluded_files++] = optarg; break; 1281 case 'i': included_files[nincluded_files++] = optarg; break;
1273 1282
1274 /* Ctags options. */ 1283 /* Ctags options. */
1275 case 'B': searchar = '?'; break; 1284 case 'B': searchar = '?'; break;
1283 default: 1292 default:
1284 suggest_asking_for_help (); 1293 suggest_asking_for_help ();
1285 /* NOTREACHED */ 1294 /* NOTREACHED */
1286 } 1295 }
1287 1296
1297 /* No more options. Store the rest of arguments. */
1288 for (; optind < argc; optind++) 1298 for (; optind < argc; optind++)
1289 { 1299 {
1290 argbuffer[current_arg].arg_type = at_filename; 1300 argbuffer[current_arg].arg_type = at_filename;
1291 argbuffer[current_arg].what = argv[optind]; 1301 argbuffer[current_arg].what = argv[optind];
1292 ++current_arg; 1302 ++current_arg;
1411 free (filebuf.buffer); 1421 free (filebuf.buffer);
1412 free (token_name.buffer); 1422 free (token_name.buffer);
1413 1423
1414 if (!CTAGS || cxref_style) 1424 if (!CTAGS || cxref_style)
1415 { 1425 {
1416 put_entries (nodehead); /* write the remainig tags (ETAGS) */ 1426 put_entries (nodehead); /* write the remaining tags (ETAGS) */
1417 free_tree (nodehead); 1427 free_tree (nodehead);
1418 nodehead = NULL; 1428 nodehead = NULL;
1419 if (!CTAGS) 1429 if (!CTAGS)
1420 { 1430 {
1421 fdesc *fdp; 1431 fdesc *fdp;
1463 free_tree (nodehead); 1473 free_tree (nodehead);
1464 nodehead = NULL; 1474 nodehead = NULL;
1465 if (fclose (tagf) == EOF) 1475 if (fclose (tagf) == EOF)
1466 pfatal (tagfile); 1476 pfatal (tagfile);
1467 1477
1468 if (update) 1478 if (CTAGS)
1469 { 1479 if (append_to_tagfile || update)
1470 char cmd[2*BUFSIZ+10]; 1480 {
1471 sprintf (cmd, "sort -o %.*s %.*s", BUFSIZ, tagfile, BUFSIZ, tagfile); 1481 char cmd[2*BUFSIZ+10];
1472 exit (system (cmd)); 1482 sprintf (cmd, "sort -o %.*s %.*s", BUFSIZ, tagfile, BUFSIZ, tagfile);
1473 } 1483 exit (system (cmd));
1484 }
1474 return EXIT_SUCCESS; 1485 return EXIT_SUCCESS;
1475 } 1486 }
1476 1487
1477 1488
1478 /* 1489 /*
4073 && /* instructions at start of loop */ \ 4084 && /* instructions at start of loop */ \
4074 (readline (&line_buffer, file_pointer), \ 4085 (readline (&line_buffer, file_pointer), \
4075 char_pointer = line_buffer.buffer, \ 4086 char_pointer = line_buffer.buffer, \
4076 TRUE); \ 4087 TRUE); \
4077 ) 4088 )
4078 #define LOOKING_AT(cp, keyword) /* keyword is a constant string */ \ 4089
4079 (strneq ((cp), keyword, sizeof(keyword)-1) /* cp points at keyword */ \ 4090 #define LOOKING_AT(cp, kw) /* kw is the keyword, a literal string */ \
4080 && notinname ((cp)[sizeof(keyword)-1]) /* end of keyword */ \ 4091 ((assert("" kw), TRUE) /* syntax error if not a literal string */ \
4081 && ((cp) = skip_spaces((cp)+sizeof(keyword)-1))) /* skip spaces */ 4092 && strneq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \
4093 && notinname ((cp)[sizeof(kw)-1]) /* end of kw */ \
4094 && ((cp) = skip_spaces((cp)+sizeof(kw)-1))) /* skip spaces */
4095
4096 /* Similar to LOOKING_AT but does not use notinname, does not skip */
4097 #define LOOKING_AT_NOCASE(cp, kw) /* the keyword is a literal string */ \
4098 ((assert("" kw), TRUE) /* syntax error if not a literal string */ \
4099 && strncaseeq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \
4100 && ((cp) += sizeof(kw)-1)) /* skip spaces */
4082 4101
4083 /* 4102 /*
4084 * Read a file, but do no processing. This is used to do regexp 4103 * Read a file, but do no processing. This is used to do regexp
4085 * matching on files that have no language defined. 4104 * matching on files that have no language defined.
4086 */ 4105 */
4954 } 4973 }
4955 } 4974 }
4956 4975
4957 4976
4958 /* 4977 /*
4959 * Postscript tag functions 4978 * Postscript tags
4960 * Just look for lines where the first character is '/' 4979 * Just look for lines where the first character is '/'
4961 * Also look at "defineps" for PSWrap 4980 * Also look at "defineps" for PSWrap
4962 * Ideas by: 4981 * Ideas by:
4963 * Richard Mlynarik <mly@adoc.xerox.com> (1997) 4982 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4964 * Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999) 4983 * Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4985 } 5004 }
4986 } 5005 }
4987 5006
4988 5007
4989 /* 5008 /*
5009 * Forth tags
5010 * Ignore anything after \ followed by space or in ( )
5011 * Look for words defined by :
5012 * Look for constant, code, create, defer, value, and variable
5013 * OBP extensions: Look for buffer:, field,
5014 * Ideas by Eduardo Horvath <eeh@netbsd.org> (2004)
5015 */
5016 static void
5017 Forth_words (inf)
5018 FILE *inf;
5019 {
5020 register char *bp;
5021
5022 LOOP_ON_INPUT_LINES (inf, lb, bp)
5023 while ((bp = skip_spaces (bp))[0] != '\0')
5024 if (bp[0] == '\\' && iswhite(bp[1]))
5025 break; /* read next line */
5026 else if (bp[0] == '(' && iswhite(bp[1]))
5027 do /* skip to ) or eol */
5028 bp++;
5029 while (*bp != ')' && *bp != '\0');
5030 else if ((bp[0] == ':' && iswhite(bp[1]) && bp++)
5031 || LOOKING_AT_NOCASE (bp, "constant")
5032 || LOOKING_AT_NOCASE (bp, "code")
5033 || LOOKING_AT_NOCASE (bp, "create")
5034 || LOOKING_AT_NOCASE (bp, "defer")
5035 || LOOKING_AT_NOCASE (bp, "value")
5036 || LOOKING_AT_NOCASE (bp, "variable")
5037 || LOOKING_AT_NOCASE (bp, "buffer:")
5038 || LOOKING_AT_NOCASE (bp, "field"))
5039 get_tag (skip_spaces (bp), NULL); /* Yay! A definition! */
5040 else
5041 bp = skip_non_spaces (bp);
5042 }
5043
5044
5045 /*
4990 * Scheme tag functions 5046 * Scheme tag functions
4991 * look for (def... xyzzy 5047 * look for (def... xyzzy
4992 * (def... (xyzzy 5048 * (def... (xyzzy
4993 * (def ... ((...(xyzzy .... 5049 * (def ... ((...(xyzzy ....
4994 * (set! xyzzy 5050 * (set! xyzzy
4995 * Original code by Ken Haase (1985?) 5051 * Original code by Ken Haase (1985?)
4996 */ 5052 */
4997
4998 static void 5053 static void
4999 Scheme_functions (inf) 5054 Scheme_functions (inf)
5000 FILE *inf; 5055 FILE *inf;
5001 { 5056 {
5002 register char *bp; 5057 register char *bp;
5211 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 5266 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
5212 } 5267 }
5213 } 5268 }
5214 5269
5215 5270
5216 /* Similar to LOOKING_AT but does not use notinname, does not skip */
5217 #define LOOKING_AT_NOCASE(cp, kw) /* kw is a constant string */ \
5218 (strncaseeq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \
5219 && ((cp) += sizeof(kw)-1)) /* skip spaces */
5220
5221 /* 5271 /*
5222 * HTML support. 5272 * HTML support.
5223 * Contents of <title>, <h1>, <h2>, <h3> are tags. 5273 * Contents of <title>, <h1>, <h2>, <h3> are tags.
5224 * Contents of <a name=xxx> are tags with name xxx. 5274 * Contents of <a name=xxx> are tags with name xxx.
5225 * 5275 *
5432 5482
5433 if ((s[pos] == '.' 5483 if ((s[pos] == '.'
5434 || (s[pos] == '(' && (pos += 1)) 5484 || (s[pos] == '(' && (pos += 1))
5435 || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2))) 5485 || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2)))
5436 && (last == NULL /* save only the first clause */ 5486 && (last == NULL /* save only the first clause */
5437 || len != strlen (last) 5487 || len != (int)strlen (last)
5438 || !strneq (s, last, len))) 5488 || !strneq (s, last, len)))
5439 { 5489 {
5440 make_tag (s, len, TRUE, s, pos, lineno, linecharno); 5490 make_tag (s, len, TRUE, s, pos, lineno, linecharno);
5441 return len; 5491 return len;
5442 } 5492 }
6500 return (ISALPHA (*s1) && ISALPHA (*s2) 6550 return (ISALPHA (*s1) && ISALPHA (*s2)
6501 ? lowcase (*s1) - lowcase (*s2) 6551 ? lowcase (*s1) - lowcase (*s2)
6502 : *s1 - *s2); 6552 : *s1 - *s2);
6503 } 6553 }
6504 6554
6505 /* Skip spaces, return new pointer. */ 6555 /* Skip spaces (end of string is not space), return new pointer. */
6506 static char * 6556 static char *
6507 skip_spaces (cp) 6557 skip_spaces (cp)
6508 char *cp; 6558 char *cp;
6509 { 6559 {
6510 while (iswhite (*cp)) 6560 while (iswhite (*cp))
6511 cp++; 6561 cp++;
6512 return cp; 6562 return cp;
6513 } 6563 }
6514 6564
6515 /* Skip non spaces, return new pointer. */ 6565 /* Skip non spaces, except end of string, return new pointer. */
6516 static char * 6566 static char *
6517 skip_non_spaces (cp) 6567 skip_non_spaces (cp)
6518 char *cp; 6568 char *cp;
6519 { 6569 {
6520 while (*cp != '\0' && !iswhite (*cp)) 6570 while (*cp != '\0' && !iswhite (*cp))