aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/ChangeLog13
-rw-r--r--lib-src/etags.c292
2 files changed, 176 insertions, 129 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 642f478272e..62d0e91f2f4 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,6 +1,17 @@
12002-06-06 Francesco Potorti` <pot@gnu.org> 12002-06-06 Francesco Potorti` <pot@gnu.org>
2 2
3 * etags.c (TeX_commands): Skip comments. 3 * etags.c New option --parse-stdin=FILE.
4 (enum arg_type): New label at_stdin.
5 (STDIN): New constant.
6 (parsing_stdin): New flag.
7 (longopts): New option --parse-stdin=NAME.
8 (print_help): Document it.
9 (main): Handle it.
10 (process_file): Split into process_file and process_file_name.
11 (process_file_name): New function.
12
13 * etags.c Improvements and bug squashing in TeX handling.
14 (TeX_commands): Skip comments.
4 (TEX_defenv): Now contains more contructs. 15 (TEX_defenv): Now contains more contructs.
5 (TEX_cmt): Make it a static char and move it before TeX_commands. 16 (TEX_cmt): Make it a static char and move it before TeX_commands.
6 (TeX_commands): Shorten the tag to the brace after the name. 17 (TeX_commands): Shorten the tag to the brace after the name.
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 628fe3a3977..8b5e85c1563 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -34,7 +34,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
34 * Francesco Potort́ <pot@gnu.org> has maintained it since 1993. 34 * Francesco Potort́ <pot@gnu.org> has maintained it since 1993.
35 */ 35 */
36 36
37char pot_etags_version[] = "@(#) pot revision number is 15.26"; 37char pot_etags_version[] = "@(#) pot revision number is 16.4";
38 38
39#define TRUE 1 39#define TRUE 1
40#define FALSE 0 40#define FALSE 0
@@ -289,7 +289,8 @@ typedef struct
289 at_language, /* a language specification */ 289 at_language, /* a language specification */
290 at_regexp, /* a regular expression */ 290 at_regexp, /* a regular expression */
291 at_icregexp, /* same, but with case ignored */ 291 at_icregexp, /* same, but with case ignored */
292 at_filename /* a file name */ 292 at_filename, /* a file name */
293 at_stdin /* read from stdin here */
293 } arg_type; /* argument type */ 294 } arg_type; /* argument type */
294 language *lang; /* language associated with the argument */ 295 language *lang; /* language associated with the argument */
295 char *what; /* the argument itself */ 296 char *what; /* the argument itself */
@@ -366,7 +367,8 @@ static void add_node __P((node *, node **));
366 367
367static void init __P((void)); 368static void init __P((void));
368static void initbuffer __P((linebuffer *)); 369static void initbuffer __P((linebuffer *));
369static void process_file __P((char *, language *)); 370static void process_file_name __P((char *, language *));
371static void process_file __P((FILE *, char *, language *));
370static void find_entries __P((FILE *)); 372static void find_entries __P((FILE *));
371static void free_tree __P((node *)); 373static void free_tree __P((node *));
372static void free_fdesc __P((fdesc *)); 374static void free_fdesc __P((fdesc *));
@@ -451,6 +453,9 @@ static bool cplusplus; /* .[hc] means C++, not C */
451static bool noindentypedefs; /* -I: ignore indentation in C */ 453static bool noindentypedefs; /* -I: ignore indentation in C */
452static bool packages_only; /* --packages-only: in Ada, only tag packages*/ 454static bool packages_only; /* --packages-only: in Ada, only tag packages*/
453 455
456#define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
457static bool parsing_stdin; /* --parse-stdin used */
458
454#ifdef ETAGS_REGEXPS 459#ifdef ETAGS_REGEXPS
455/* List of all regexps. */ 460/* List of all regexps. */
456static pattern *p_head; 461static pattern *p_head;
@@ -480,6 +485,7 @@ static struct option longopts[] =
480 { "no-regex", no_argument, NULL, 'R' }, 485 { "no-regex", no_argument, NULL, 'R' },
481 { "ignore-case-regex", required_argument, NULL, 'c' }, 486 { "ignore-case-regex", required_argument, NULL, 'c' },
482#endif /* ETAGS_REGEXPS */ 487#endif /* ETAGS_REGEXPS */
488 { "parse-stdin", required_argument, NULL, STDIN },
483 { "version", no_argument, NULL, 'V' }, 489 { "version", no_argument, NULL, 'V' },
484 490
485#if CTAGS /* Etags options */ 491#if CTAGS /* Etags options */
@@ -705,6 +711,9 @@ linked with GNU getopt.");
705Absolute names are stored in the output file as they are.\n\ 711Absolute names are stored in the output file as they are.\n\
706Relative ones are stored relative to the output file's directory.\n"); 712Relative ones are stored relative to the output file's directory.\n");
707 713
714 puts ("--parse-stdin=NAME\n\
715 Read from standard input and record tags as belonging to file NAME.");
716
708 if (!CTAGS) 717 if (!CTAGS)
709 puts ("-a, --append\n\ 718 puts ("-a, --append\n\
710 Append tag entries to existing tags file."); 719 Append tag entries to existing tags file.");
@@ -970,6 +979,9 @@ main (argc, argv)
970#ifdef VMS 979#ifdef VMS
971 bool got_err; 980 bool got_err;
972#endif 981#endif
982 char *optstring;
983 int opt;
984
973 985
974#ifdef DOS_NT 986#ifdef DOS_NT
975 _fmode = O_BINARY; /* all of files are treated as binary files */ 987 _fmode = O_BINARY; /* all of files are treated as binary files */
@@ -1004,109 +1016,108 @@ main (argc, argv)
1004 globals = TRUE; 1016 globals = TRUE;
1005 } 1017 }
1006 1018
1007 while (1) 1019 optstring = "-";
1008 {
1009 int opt;
1010 char *optstring = "-";
1011
1012#ifdef ETAGS_REGEXPS 1020#ifdef ETAGS_REGEXPS
1013 optstring = "-r:Rc:"; 1021 optstring = "-r:Rc:";
1014#endif /* ETAGS_REGEXPS */ 1022#endif /* ETAGS_REGEXPS */
1015
1016#ifndef LONG_OPTIONS 1023#ifndef LONG_OPTIONS
1017 optstring = optstring + 1; 1024 optstring = optstring + 1;
1018#endif /* LONG_OPTIONS */ 1025#endif /* LONG_OPTIONS */
1026 optstring = concat (optstring,
1027 "Cf:Il:o:SVhH",
1028 (CTAGS) ? "BxdtTuvw" : "aDi:");
1019 1029
1020 optstring = concat (optstring, 1030 while ((opt = getopt_long (argc, argv, optstring, longopts, 0)) != EOF)
1021 "Cf:Il:o:SVhH", 1031 switch (opt)
1022 (CTAGS) ? "BxdtTuvw" : "aDi:"); 1032 {
1023 1033 case 0:
1024 opt = getopt_long (argc, argv, optstring, longopts, 0); 1034 /* If getopt returns 0, then it has already processed a
1025 if (opt == EOF) 1035 long-named option. We should do nothing. */
1026 break; 1036 break;
1027 1037
1028 switch (opt) 1038 case 1:
1029 { 1039 /* This means that a file name has been seen. Record it. */
1030 case 0: 1040 argbuffer[current_arg].arg_type = at_filename;
1031 /* If getopt returns 0, then it has already processed a 1041 argbuffer[current_arg].what = optarg;
1032 long-named option. We should do nothing. */ 1042 ++current_arg;
1033 break; 1043 ++file_count;
1044 break;
1034 1045
1035 case 1: 1046 case STDIN:
1036 /* This means that a file name has been seen. Record it. */ 1047 /* Parse standard input. Idea by Vivek <vivek@etla.org>. */
1037 argbuffer[current_arg].arg_type = at_filename; 1048 argbuffer[current_arg].arg_type = at_stdin;
1038 argbuffer[current_arg].what = optarg; 1049 argbuffer[current_arg].what = optarg;
1039 ++current_arg; 1050 ++current_arg;
1040 ++file_count; 1051 ++file_count;
1041 break; 1052 parsing_stdin = TRUE;
1053 break;
1042 1054
1043 /* Common options. */ 1055 /* Common options. */
1044 case 'C': cplusplus = TRUE; break; 1056 case 'C': cplusplus = TRUE; break;
1045 case 'f': /* for compatibility with old makefiles */ 1057 case 'f': /* for compatibility with old makefiles */
1046 case 'o': 1058 case 'o':
1047 if (tagfile) 1059 if (tagfile)
1048 {
1049 error ("-o option may only be given once.", (char *)NULL);
1050 suggest_asking_for_help ();
1051 }
1052 tagfile = optarg;
1053 break;
1054 case 'I':
1055 case 'S': /* for backward compatibility */
1056 noindentypedefs = TRUE;
1057 break;
1058 case 'l':
1059 { 1060 {
1060 language *lang = get_language_from_langname (optarg); 1061 error ("-o option may only be given once.", (char *)NULL);
1061 if (lang != NULL) 1062 suggest_asking_for_help ();
1062 {
1063 argbuffer[current_arg].lang = lang;
1064 argbuffer[current_arg].arg_type = at_language;
1065 ++current_arg;
1066 }
1067 } 1063 }
1068 break; 1064 tagfile = optarg;
1069 case 'r': 1065 break;
1070 argbuffer[current_arg].arg_type = at_regexp; 1066 case 'I':
1071 argbuffer[current_arg].what = optarg; 1067 case 'S': /* for backward compatibility */
1072 ++current_arg; 1068 noindentypedefs = TRUE;
1073 break; 1069 break;
1074 case 'R': 1070 case 'l':
1075 argbuffer[current_arg].arg_type = at_regexp; 1071 {
1076 argbuffer[current_arg].what = NULL; 1072 language *lang = get_language_from_langname (optarg);
1077 ++current_arg; 1073 if (lang != NULL)
1078 break; 1074 {
1079 case 'c': 1075 argbuffer[current_arg].lang = lang;
1080 argbuffer[current_arg].arg_type = at_icregexp; 1076 argbuffer[current_arg].arg_type = at_language;
1081 argbuffer[current_arg].what = optarg; 1077 ++current_arg;
1082 ++current_arg; 1078 }
1083 break;
1084 case 'V':
1085 print_version ();
1086 break;
1087 case 'h':
1088 case 'H':
1089 print_help ();
1090 break;
1091
1092 /* Etags options */
1093 case 'a': append_to_tagfile = TRUE; break;
1094 case 'D': constantypedefs = FALSE; break;
1095 case 'i': included_files[nincluded_files++] = optarg; break;
1096
1097 /* Ctags options. */
1098 case 'B': searchar = '?'; break;
1099 case 'd': constantypedefs = TRUE; break;
1100 case 't': typedefs = TRUE; break;
1101 case 'T': typedefs = typedefs_or_cplusplus = TRUE; break;
1102 case 'u': update = TRUE; break;
1103 case 'v': vgrind_style = TRUE; /*FALLTHRU*/
1104 case 'x': cxref_style = TRUE; break;
1105 case 'w': no_warnings = TRUE; break;
1106 default:
1107 suggest_asking_for_help ();
1108 } 1079 }
1109 } 1080 break;
1081 case 'r':
1082 argbuffer[current_arg].arg_type = at_regexp;
1083 argbuffer[current_arg].what = optarg;
1084 ++current_arg;
1085 break;
1086 case 'R':
1087 argbuffer[current_arg].arg_type = at_regexp;
1088 argbuffer[current_arg].what = NULL;
1089 ++current_arg;
1090 break;
1091 case 'c':
1092 argbuffer[current_arg].arg_type = at_icregexp;
1093 argbuffer[current_arg].what = optarg;
1094 ++current_arg;
1095 break;
1096 case 'V':
1097 print_version ();
1098 break;
1099 case 'h':
1100 case 'H':
1101 print_help ();
1102 break;
1103
1104 /* Etags options */
1105 case 'a': append_to_tagfile = TRUE; break;
1106 case 'D': constantypedefs = FALSE; break;
1107 case 'i': included_files[nincluded_files++] = optarg; break;
1108
1109 /* Ctags options. */
1110 case 'B': searchar = '?'; break;
1111 case 'd': constantypedefs = TRUE; break;
1112 case 't': typedefs = TRUE; break;
1113 case 'T': typedefs = typedefs_or_cplusplus = TRUE; break;
1114 case 'u': update = TRUE; break;
1115 case 'v': vgrind_style = TRUE; /*FALLTHRU*/
1116 case 'x': cxref_style = TRUE; break;
1117 case 'w': no_warnings = TRUE; break;
1118 default:
1119 suggest_asking_for_help ();
1120 }
1110 1121
1111 for (; optind < argc; ++optind) 1122 for (; optind < argc; ++optind)
1112 { 1123 {
@@ -1199,14 +1210,23 @@ main (argc, argv)
1199 /* Input file named "-" means read file names from stdin 1210 /* Input file named "-" means read file names from stdin
1200 (one per line) and use them. */ 1211 (one per line) and use them. */
1201 if (streq (this_file, "-")) 1212 if (streq (this_file, "-"))
1202 while (readline_internal (&filename_lb, stdin) > 0) 1213 {
1203 process_file (filename_lb.buffer, lang); 1214 if (parsing_stdin)
1215 fatal ("cannot parse standard input AND read file names from it",
1216 (char *)NULL);
1217 while (readline_internal (&filename_lb, stdin) > 0)
1218 process_file_name (filename_lb.buffer, lang);
1219 }
1204 else 1220 else
1205 process_file (this_file, lang); 1221 process_file_name (this_file, lang);
1206#ifdef VMS 1222#ifdef VMS
1207 } 1223 }
1208#endif 1224#endif
1209 break; 1225 break;
1226 case at_stdin:
1227 this_file = argbuffer[i].what;
1228 process_file (stdin, this_file, lang);
1229 break;
1210 } 1230 }
1211 } 1231 }
1212 1232
@@ -1233,8 +1253,14 @@ main (argc, argv)
1233 char cmd[BUFSIZ]; 1253 char cmd[BUFSIZ];
1234 for (i = 0; i < current_arg; ++i) 1254 for (i = 0; i < current_arg; ++i)
1235 { 1255 {
1236 if (argbuffer[i].arg_type != at_filename) 1256 switch (argbuffer[i].arg_type)
1237 continue; 1257 {
1258 case at_filename:
1259 case at_stdin:
1260 break;
1261 default:
1262 continue; /* the for loop */
1263 }
1238 sprintf (cmd, 1264 sprintf (cmd,
1239 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS", 1265 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1240 tagfile, argbuffer[i].what, tagfile); 1266 tagfile, argbuffer[i].what, tagfile);
@@ -1391,20 +1417,18 @@ get_language_from_filename (file, case_sensitive)
1391 * This routine is called on each file argument. 1417 * This routine is called on each file argument.
1392 */ 1418 */
1393static void 1419static void
1394process_file (file, lang) 1420process_file_name (file, lang)
1395 char *file; 1421 char *file;
1396 language *lang; 1422 language *lang;
1397{ 1423{
1398 struct stat stat_buf; 1424 struct stat stat_buf;
1399 FILE *inf; 1425 FILE *inf;
1400 static const fdesc emptyfdesc;
1401 fdesc *fdp; 1426 fdesc *fdp;
1402 compressor *compr; 1427 compressor *compr;
1403 char *compressed_name, *uncompressed_name; 1428 char *compressed_name, *uncompressed_name;
1404 char *ext, *real_name; 1429 char *ext, *real_name;
1405 int retval; 1430 int retval;
1406 1431
1407
1408 canonicalize_filename (file); 1432 canonicalize_filename (file);
1409 if (streq (file, tagfile) && !streq (tagfile, "-")) 1433 if (streq (file, tagfile) && !streq (tagfile, "-"))
1410 { 1434 {
@@ -1499,24 +1523,50 @@ process_file (file, lang)
1499 goto cleanup; 1523 goto cleanup;
1500 } 1524 }
1501 1525
1526 process_file (inf, uncompressed_name, lang);
1527
1528 if (real_name == compressed_name)
1529 retval = pclose (inf);
1530 else
1531 retval = fclose (inf);
1532 if (retval < 0)
1533 pfatal (file);
1534
1535 cleanup:
1536 if (compressed_name) free (compressed_name);
1537 if (uncompressed_name) free (uncompressed_name);
1538 last_node = NULL;
1539 curfdp = NULL;
1540 return;
1541}
1542
1543static void
1544process_file (fh, fn, lang)
1545 FILE *fh;
1546 char *fn;
1547 language *lang;
1548{
1549 static const fdesc emptyfdesc;
1550 fdesc *fdp;
1551
1502 /* Create a new input file description entry. */ 1552 /* Create a new input file description entry. */
1503 fdp = xnew (1, fdesc); 1553 fdp = xnew (1, fdesc);
1504 *fdp = emptyfdesc; 1554 *fdp = emptyfdesc;
1505 fdp->next = fdhead; 1555 fdp->next = fdhead;
1506 fdp->infname = savestr (uncompressed_name); 1556 fdp->infname = savestr (fn);
1507 fdp->lang = lang; 1557 fdp->lang = lang;
1508 fdp->infabsname = absolute_filename (uncompressed_name, cwd); 1558 fdp->infabsname = absolute_filename (fn, cwd);
1509 fdp->infabsdir = absolute_dirname (uncompressed_name, cwd); 1559 fdp->infabsdir = absolute_dirname (fn, cwd);
1510 if (filename_is_absolute (uncompressed_name)) 1560 if (filename_is_absolute (fn))
1511 { 1561 {
1512 /* file is an absolute file name. Canonicalize it. */ 1562 /* An absolute file name. Canonicalize it. */
1513 fdp->taggedfname = absolute_filename (uncompressed_name, NULL); 1563 fdp->taggedfname = absolute_filename (fn, NULL);
1514 } 1564 }
1515 else 1565 else
1516 { 1566 {
1517 /* file is a file name relative to cwd. Make it relative 1567 /* A file name relative to cwd. Make it relative
1518 to the directory of the tags file. */ 1568 to the directory of the tags file. */
1519 fdp->taggedfname = relative_filename (uncompressed_name, tagfiledir); 1569 fdp->taggedfname = relative_filename (fn, tagfiledir);
1520 } 1570 }
1521 fdp->usecharno = TRUE; /* use char position when making tags */ 1571 fdp->usecharno = TRUE; /* use char position when making tags */
1522 fdp->prop = NULL; 1572 fdp->prop = NULL;
@@ -1524,14 +1574,7 @@ process_file (file, lang)
1524 fdhead = fdp; 1574 fdhead = fdp;
1525 curfdp = fdhead; /* the current file description */ 1575 curfdp = fdhead; /* the current file description */
1526 1576
1527 find_entries (inf); 1577 find_entries (fh);
1528
1529 if (real_name == compressed_name)
1530 retval = pclose (inf);
1531 else
1532 retval = fclose (inf);
1533 if (retval < 0)
1534 pfatal (file);
1535 1578
1536 /* If not Ctags, and if this is not metasource and if it contained no #line 1579 /* If not Ctags, and if this is not metasource and if it contained no #line
1537 directives, we can write the tags and free all nodes pointing to 1580 directives, we can write the tags and free all nodes pointing to
@@ -1566,13 +1609,6 @@ process_file (file, lang)
1566 prev->left = NULL; /* delete the pointer to the sublist */ 1609 prev->left = NULL; /* delete the pointer to the sublist */
1567 } 1610 }
1568 } 1611 }
1569
1570 cleanup:
1571 if (compressed_name) free (compressed_name);
1572 if (uncompressed_name) free (uncompressed_name);
1573 last_node = NULL;
1574 curfdp = NULL;
1575 return;
1576} 1612}
1577 1613
1578/* 1614/*
@@ -5029,7 +5065,7 @@ prolog_atom (s, pos)
5029 { 5065 {
5030 pos++; 5066 pos++;
5031 5067
5032 while (1) 5068 for (;;)
5033 { 5069 {
5034 if (s[pos] == '\'') 5070 if (s[pos] == '\'')
5035 { 5071 {
@@ -5208,7 +5244,7 @@ erlang_atom (s, pos)
5208 { 5244 {
5209 pos++; 5245 pos++;
5210 5246
5211 while (1) 5247 for (;;)
5212 { 5248 {
5213 if (s[pos] == '\'') 5249 if (s[pos] == '\'')
5214 { 5250 {
@@ -5542,7 +5578,7 @@ readline_internal (lbp, stream)
5542 5578
5543 pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */ 5579 pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */
5544 5580
5545 while (1) 5581 for (;;)
5546 { 5582 {
5547 register int c = getc (stream); 5583 register int c = getc (stream);
5548 if (p == pend) 5584 if (p == pend)