aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorFrancesco Potortì1995-01-12 17:05:37 +0000
committerFrancesco Potortì1995-01-12 17:05:37 +0000
commit55597f90033a62b0ef759c28764739e891455784 (patch)
tree4fb6dce3ff7d3ae428f4373d4a1a712c57a2c4fe /lib-src
parentdc3247b34dc6ef9142fb01ef9a62fee02714068d (diff)
downloademacs-55597f90033a62b0ef759c28764739e891455784.tar.gz
emacs-55597f90033a62b0ef759c28764739e891455784.zip
Global polishing, some bugs corrected, dynamic allocation used instead
of fixed length static buffers in many places. * etags.c (FILEPOS, GET_CHARNO, GET_FILEPOS, max, LINENO): Deleted. (append_to_tagfile, typedefs, typedefs_and_cplusplus, constantypedefs, update, vgrind_style, no_warnings, cxref_style, cplusplus, noindentypedefs): Were int, now logical. (permit_duplicates): Was a var, now a #define. (filename_lb): Was global, now local to main. (main): Open the tag file when in cxref mode. Use a BUFSIZ size buffer for making the shell commands. Look at the return value from the system routine. Exit when cannot open the tag file. (process_file): Open the file and pass the FILE* to find_entries. (find_entries): Now void, because does not open the file itself. (pfnote): Recovering from lack of memory does not work. Removed. Use savenstr and simplify the code. (free_tree): Only free the name space if node is named. (structtag): Now a pointer, not a fixed length array of chars. (consider_token): Don't take a token as argument. Use savenstr when saving a tag in structtag. Callers changed. (TOKEN): Structure changed. Now used only in C_entries. (TOKEN_SAVED_P, SAVE_TOKEN, RESTORE_TOKEN): Deleted. (C_entries): nameb and savenameb deleted. Use dinamic allocation. (pfcnt): Deleted. Users updated. (getit, Asm_labels, Pascal_functions, L_getit, get_scheme, TEX_getit, prolog_getit): Use dinamic allocation for storing the tag instead of a fixed size buffer.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/etags.c652
1 files changed, 262 insertions, 390 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 4bccca0e3ad..6716e8da587 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -31,7 +31,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
31 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 31 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer.
32 */ 32 */
33 33
34char pot_etags_version[] = "@(#) pot revision number is 11.14"; 34char pot_etags_version[] = "@(#) pot revision number is 11.15";
35 35
36#ifdef MSDOS 36#ifdef MSDOS
37#include <fcntl.h> 37#include <fcntl.h>
@@ -71,7 +71,8 @@ extern int errno;
71#include <regex.h> 71#include <regex.h>
72#endif /* ETAGS_REGEXPS */ 72#endif /* ETAGS_REGEXPS */
73 73
74extern char *getenv (); 74#define TRUE 1
75#define FALSE 0
75 76
76/* Define CTAGS to make the program "ctags" compatible with the usual one. 77/* Define CTAGS to make the program "ctags" compatible with the usual one.
77 Let it undefined to make the program "etags", which makes emacs-style 78 Let it undefined to make the program "etags", which makes emacs-style
@@ -92,71 +93,29 @@ extern char *getenv ();
92#define BAD 1 93#define BAD 1
93#endif 94#endif
94 95
95/* 96/* C extensions. */
96 * The FILEPOS abstract type, which represents a position in a file, 97#define C_PLPL 0x00001 /* C++ */
97 * plus the following accessor functions: 98#define C_STAR 0x00003 /* C* */
98 * 99#define YACC 0x10000 /* yacc file */
99 * long GET_CHARNO (pos)
100 * returns absolute char number.
101 * void SET_FILEPOS (pos, fp, charno)
102 * FILE *fp; long charno;
103 * sets `pos' from the current file
104 * position of `fp' and from `charno',
105 * which must be the absolute character
106 * number corresponding to the current
107 * position of `fp'.
108 *
109 * The `pos' parameter is an lvalue expression of type FILEPOS.
110 * Parameters to the accessor functions are evaluated 0 or more times,
111 * and so must have no side effects.
112 *
113 * FILEPOS objects can also be assigned and passed to and from
114 * functions in the normal C manner.
115 *
116 * Implementation notes: the `+ 0' is to enforce rvalue-ness.
117 */
118
119#ifndef DEBUG
120#define DEBUG FALSE
121
122 /* real implementation */
123typedef long FILEPOS;
124#define GET_CHARNO(pos) ((pos) + 0)
125#define SET_FILEPOS(pos,fp,cno) ((void) ((pos) = (cno)))
126
127#else
128#undef DEBUG
129#define DEBUG TRUE
130
131 /* debugging implementation */
132typedef struct
133{
134 long charno;
135} FILEPOS;
136
137#define GET_CHARNO(pos) ((pos).charno + 0)
138#define SET_FILEPOS(pos,fp,cno) \
139 ((void) ((pos).charno = (cno), \
140 (cno) != ftell (fp) ? (error ("SET_FILEPOS inconsistency"), 0) \
141 : 0))
142#endif
143 100
144#define streq(s,t) (strcmp (s, t) == 0) 101#define streq(s,t) (strcmp (s, t) == 0)
145#define strneq(s,t,n) (strncmp (s, t, n) == 0) 102#define strneq(s,t,n) (strncmp (s, t, n) == 0)
146 103
147#define TRUE 1
148#define FALSE 0
149
150#define iswhite(arg) (_wht[arg]) /* T if char is white */ 104#define iswhite(arg) (_wht[arg]) /* T if char is white */
151#define begtoken(arg) (_btk[arg]) /* T if char can start token */ 105#define begtoken(arg) (_btk[arg]) /* T if char can start token */
152#define intoken(arg) (_itk[arg]) /* T if char can be in token */ 106#define intoken(arg) (_itk[arg]) /* T if char can be in token */
153#define endtoken(arg) (_etk[arg]) /* T if char ends tokens */ 107#define endtoken(arg) (_etk[arg]) /* T if char ends tokens */
154 108
155#define max(I1,I2) ((I1) > (I2) ? (I1) : (I2)) 109/*
110 * xnew -- allocate storage
111 *
112 * SYNOPSIS: Type *xnew (int n, Type);
113 */
114#define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
156 115
157typedef int logical; 116typedef int logical;
158 117
159struct nd_st 118typedef struct nd_st
160{ /* sorting structure */ 119{ /* sorting structure */
161 char *name; /* function or type name */ 120 char *name; /* function or type name */
162 char *file; /* file name */ 121 char *file; /* file name */
@@ -167,15 +126,9 @@ struct nd_st
167 long cno; /* character number line starts on */ 126 long cno; /* character number line starts on */
168 char *pat; /* search pattern */ 127 char *pat; /* search pattern */
169 struct nd_st *left, *right; /* left and right sons */ 128 struct nd_st *left, *right; /* left and right sons */
170}; 129} NODE;
171
172typedef struct nd_st NODE;
173
174/* boolean "functions" (see init) */
175logical _wht[0177], _etk[0177], _itk[0177], _btk[0177];
176 130
177char *cwd; /* current working directory */ 131extern char *getenv ();
178char *tagfiledir; /* directory of tagfile */
179 132
180char *concat (); 133char *concat ();
181char *savenstr (), *savestr (); 134char *savenstr (), *savestr ();
@@ -225,7 +178,7 @@ void add_regex ();
225void add_node (); 178void add_node ();
226void error (); 179void error ();
227void fatal (), pfatal (); 180void fatal (), pfatal ();
228logical find_entries (); 181void find_entries ();
229void free_tree (); 182void free_tree ();
230void getit (); 183void getit ();
231void init (); 184void init ();
@@ -235,52 +188,45 @@ void process_file ();
235void put_entries (); 188void put_entries ();
236void takeprec (); 189void takeprec ();
237 190
238/*
239 * MACRO
240 * xnew -- allocate storage
241 *
242 * SYNOPSIS
243 * Type *xnew (int n, Type);
244 */
245#define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
246
247/*
248 * Symbol table types.
249 */
250enum sym_type
251{
252 st_none, st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
253};
254 191
192char searchar = '/'; /* use /.../ searches */
255 193
194int lineno; /* line number of current line */
195long charno; /* current character number */
256 196
257typedef int LINENO; 197long linecharno; /* charno of start of line; not used by C,
258 198 but by every other language. */
259typedef struct
260{
261 char *p;
262 int len;
263 LINENO lineno;
264 logical named;
265} TOKEN;
266 199
267/* C extensions. 200char *curfile; /* current input file name */
268 */ 201char *tagfile; /* output file */
269#define C_PLPL 0x00001 /* C++ */ 202char *progname; /* name this program was invoked with */
270#define C_STAR 0x00003 /* C* */ 203char *cwd; /* current working directory */
271#define YACC 0x10000 /* yacc file */ 204char *tagfiledir; /* directory of tagfile */
272 205
273char searchar = '/'; /* use /.../ searches */ 206FILE *tagf; /* ioptr for tags file */
207NODE *head; /* the head of the binary tree of tags */
274 208
275LINENO lineno; /* line number of current line */ 209/*
276long charno; /* current character number */ 210 * A `struct linebuffer' is a structure which holds a line of text.
211 * `readline' reads a line from a stream into a linebuffer and works
212 * regardless of the length of the line.
213 */
214struct linebuffer
215{
216 long size;
217 char *buffer;
218};
277 219
278long linecharno; /* charno of start of line; not used by C, but 220struct linebuffer lb; /* the current line */
279 * by every other language. 221struct
280 */ 222{
223 long linepos;
224 struct linebuffer lb; /* used by C_entries instead of lb */
225} lbs[2];
281 226
282char *curfile, /* current input file name */ 227/* boolean "functions" (see init) */
283 *tagfile, /* output file */ 228logical _wht[0177], _etk[0177], _itk[0177], _btk[0177];
229char
284 *white = " \f\t\n\013", /* white chars */ 230 *white = " \f\t\n\013", /* white chars */
285 *endtk = " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */ 231 *endtk = " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */
286 /* token starting chars */ 232 /* token starting chars */
@@ -288,24 +234,22 @@ char *curfile, /* current input file name */
288 /* valid in-token chars */ 234 /* valid in-token chars */
289 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; 235 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
290 236
291int append_to_tagfile; /* -a: append to tags */ 237logical append_to_tagfile; /* -a: append to tags */
292/* The following three default to 1 for etags, but to 0 for ctags. */ 238/* The following three default to TRUE for etags, but to FALSE for ctags. */
293int typedefs; /* -t: create tags for typedefs */ 239logical typedefs; /* -t: create tags for typedefs */
294int typedefs_and_cplusplus; /* -T: create tags for typedefs, level */ 240logical typedefs_and_cplusplus; /* -T: create tags for typedefs, level */
295 /* 0 struct/enum/union decls, and C++ */ 241 /* 0 struct/enum/union decls, and C++ */
296 /* member functions. */ 242 /* member functions. */
297int constantypedefs; /* -d: create tags for C #define and enum */ 243logical constantypedefs; /* -d: create tags for C #define and enum */
298 /* constants. Enum consts not implemented. */ 244 /* constants. Enum consts not implemented. */
299 /* -D: opposite of -d. Default under ctags. */ 245 /* -D: opposite of -d. Default under ctags. */
300int update; /* -u: update tags */ 246logical update; /* -u: update tags */
301int vgrind_style; /* -v: create vgrind style index output */ 247logical vgrind_style; /* -v: create vgrind style index output */
302int no_warnings; /* -w: suppress warnings */ 248logical no_warnings; /* -w: suppress warnings */
303int cxref_style; /* -x: create cxref style output */ 249logical cxref_style; /* -x: create cxref style output */
304int cplusplus; /* .[hc] means C++, not C */ 250logical cplusplus; /* .[hc] means C++, not C */
305int noindentypedefs; /* -S: ignore indentation in C */ 251logical noindentypedefs; /* -S: ignore indentation in C */
306 252#define permit_duplicates TRUE /* allow duplicate tags */
307/* Name this program was invoked with. */
308char *progname;
309 253
310struct option longopts[] = 254struct option longopts[] =
311{ 255{
@@ -332,29 +276,6 @@ struct option longopts[] =
332 { 0 } 276 { 0 }
333}; 277};
334 278
335FILE *tagf; /* ioptr for tags file */
336NODE *head; /* the head of the binary tree of tags */
337logical permit_duplicates = TRUE; /* allow duplicate tags */
338
339/*
340 * A `struct linebuffer' is a structure which holds a line of text.
341 * `readline' reads a line from a stream into a linebuffer and works
342 * regardless of the length of the line.
343 */
344struct linebuffer
345{
346 long size;
347 char *buffer;
348};
349
350struct linebuffer lb; /* the current line */
351struct linebuffer filename_lb; /* used to read in filenames */
352struct
353{
354 FILEPOS linepos;
355 struct linebuffer lb; /* used by C_entries instead of lb */
356} lbs[2];
357
358#ifdef ETAGS_REGEXPS 279#ifdef ETAGS_REGEXPS
359/* Structure defining a regular expression. Elements are 280/* Structure defining a regular expression. Elements are
360 the compiled pattern, and the name string. */ 281 the compiled pattern, and the name string. */
@@ -754,13 +675,13 @@ main (argc, argv)
754 int argc; 675 int argc;
755 char *argv[]; 676 char *argv[];
756{ 677{
757 char cmd[100];
758 int i; 678 int i;
759 unsigned int nincluded_files = 0; 679 unsigned int nincluded_files = 0;
760 char **included_files = xnew (argc, char *); 680 char **included_files = xnew (argc, char *);
761 char *this_file; 681 char *this_file;
762 ARGUMENT *argbuffer; 682 ARGUMENT *argbuffer;
763 int current_arg = 0, file_count = 0; 683 int current_arg = 0, file_count = 0;
684 struct linebuffer filename_lb;
764#ifdef VMS 685#ifdef VMS
765 logical got_err; 686 logical got_err;
766#endif 687#endif
@@ -785,7 +706,7 @@ main (argc, argv)
785 * Also default is to find macro constants. 706 * Also default is to find macro constants.
786 */ 707 */
787 if (!CTAGS) 708 if (!CTAGS)
788 typedefs = typedefs_and_cplusplus = constantypedefs = 1; 709 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE;
789 710
790 while (1) 711 while (1)
791 { 712 {
@@ -812,16 +733,16 @@ main (argc, argv)
812 733
813 /* Common options. */ 734 /* Common options. */
814 case 'a': 735 case 'a':
815 append_to_tagfile++; 736 append_to_tagfile = TRUE;
816 break; 737 break;
817 case 'C': 738 case 'C':
818 cplusplus = 1; 739 cplusplus = TRUE;
819 break; 740 break;
820 case 'd': 741 case 'd':
821 constantypedefs = 1; 742 constantypedefs = TRUE;
822 break; 743 break;
823 case 'D': 744 case 'D':
824 constantypedefs = 0; 745 constantypedefs = FALSE;
825 break; 746 break;
826 case 'f': /* for compatibility with old makefiles */ 747 case 'f': /* for compatibility with old makefiles */
827 case 'o': 748 case 'o':
@@ -856,7 +777,7 @@ main (argc, argv)
856 break; 777 break;
857#endif /* ETAGS_REGEXPS */ 778#endif /* ETAGS_REGEXPS */
858 case 'S': 779 case 'S':
859 noindentypedefs++; 780 noindentypedefs = TRUE;
860 break; 781 break;
861 case 'V': 782 case 'V':
862 print_version (); 783 print_version ();
@@ -866,11 +787,10 @@ main (argc, argv)
866 print_help (); 787 print_help ();
867 break; 788 break;
868 case 't': 789 case 't':
869 typedefs++; 790 typedefs = TRUE;
870 break; 791 break;
871 case 'T': 792 case 'T':
872 typedefs++; 793 typedefs = typedefs_and_cplusplus = TRUE;
873 typedefs_and_cplusplus++;
874 break; 794 break;
875#if (!CTAGS) 795#if (!CTAGS)
876 /* Etags options */ 796 /* Etags options */
@@ -883,16 +803,16 @@ main (argc, argv)
883 searchar = '?'; 803 searchar = '?';
884 break; 804 break;
885 case 'u': 805 case 'u':
886 update++; 806 update = TRUE;
887 break; 807 break;
888 case 'v': 808 case 'v':
889 vgrind_style++; 809 vgrind_style = TRUE;
890 /*FALLTHRU*/ 810 /*FALLTHRU*/
891 case 'x': 811 case 'x':
892 cxref_style++; 812 cxref_style = TRUE;
893 break; 813 break;
894 case 'w': 814 case 'w':
895 no_warnings++; 815 no_warnings = TRUE;
896 break; 816 break;
897#endif /* CTAGS */ 817#endif /* CTAGS */
898 default: 818 default:
@@ -989,8 +909,6 @@ main (argc, argv)
989 { 909 {
990 while (!feof (stdin)) 910 while (!feof (stdin))
991 { 911 {
992 /* Use readline_internal so that regexp matching */
993 /* is not done on filenames. */
994 (void) readline_internal (&filename_lb, stdin); 912 (void) readline_internal (&filename_lb, stdin);
995 if (strlen (filename_lb.buffer) > 0) 913 if (strlen (filename_lb.buffer) > 0)
996 process_file (filename_lb.buffer); 914 process_file (filename_lb.buffer);
@@ -1010,40 +928,48 @@ main (argc, argv)
1010 while (nincluded_files-- > 0) 928 while (nincluded_files-- > 0)
1011 fprintf (tagf, "\f\n%s,include\n", *included_files++); 929 fprintf (tagf, "\f\n%s,include\n", *included_files++);
1012 930
1013 (void) fclose (tagf); 931 fclose (tagf);
1014 exit (GOOD); 932 exit (GOOD);
1015 } 933 }
1016 934
935 /* If CTAGS, we are here. process_file did not write the tags yet,
936 because we want them ordered. Let's do it now. */
1017 if (cxref_style) 937 if (cxref_style)
1018 { 938 {
939 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
940 if (tagf == NULL)
941 pfatal (tagfile);
1019 put_entries (head); 942 put_entries (head);
1020 exit (GOOD); 943 exit (GOOD);
1021 } 944 }
945
1022 if (update) 946 if (update)
1023 { 947 {
948 char cmd[BUFSIZ];
1024 for (i = 0; i < current_arg; ++i) 949 for (i = 0; i < current_arg; ++i)
1025 { 950 {
1026 if (argbuffer[i].arg_type == at_language) 951 if (argbuffer[i].arg_type != at_filename)
1027 continue; 952 continue;
1028 sprintf (cmd, 953 sprintf (cmd,
1029 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS", 954 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1030 tagfile, argbuffer[i].what, tagfile); 955 tagfile, argbuffer[i].what, tagfile);
1031 (void) system (cmd); 956 if (system (cmd) != GOOD)
957 fatal ("failed to execute shell command");
1032 } 958 }
1033 append_to_tagfile++; 959 append_to_tagfile = TRUE;
1034 } 960 }
961
1035 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); 962 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1036 if (tagf == NULL) 963 if (tagf == NULL)
1037 { 964 pfatal (tagfile);
1038 perror (tagfile);
1039 exit (GOOD);
1040 }
1041 put_entries (head); 965 put_entries (head);
1042 (void) fclose (tagf); 966 fclose (tagf);
967
1043 if (update) 968 if (update)
1044 { 969 {
970 char cmd[BUFSIZ];
1045 sprintf (cmd, "sort %s -o %s", tagfile, tagfile); 971 sprintf (cmd, "sort %s -o %s", tagfile, tagfile);
1046 (void) system (cmd); 972 exit (system (cmd));
1047 } 973 }
1048 exit (GOOD); 974 exit (GOOD);
1049} 975}
@@ -1080,6 +1006,7 @@ process_file (file)
1080 char *file; 1006 char *file;
1081{ 1007{
1082 struct stat stat_buf; 1008 struct stat stat_buf;
1009 FILE *inf;
1083 1010
1084 if (stat (file, &stat_buf) == 0 && !S_ISREG (stat_buf.st_mode)) 1011 if (stat (file, &stat_buf) == 0 && !S_ISREG (stat_buf.st_mode))
1085 { 1012 {
@@ -1091,10 +1018,15 @@ process_file (file)
1091 fprintf (stderr, "Skipping inclusion of %s in self.\n", file); 1018 fprintf (stderr, "Skipping inclusion of %s in self.\n", file);
1092 return; 1019 return;
1093 } 1020 }
1094 if (!find_entries (file)) 1021 inf = fopen (file, "r");
1022 if (inf == NULL)
1095 { 1023 {
1024 perror (file);
1096 return; 1025 return;
1097 } 1026 }
1027
1028 find_entries (file, inf);
1029
1098 if (!CTAGS) 1030 if (!CTAGS)
1099 { 1031 {
1100 char *filename; 1032 char *filename;
@@ -1151,22 +1083,16 @@ init ()
1151 * This routine opens the specified file and calls the function 1083 * This routine opens the specified file and calls the function
1152 * which finds the function and type definitions. 1084 * which finds the function and type definitions.
1153 */ 1085 */
1154logical 1086void
1155find_entries (file) 1087find_entries (file, inf)
1156 char *file; 1088 char *file;
1089 FILE *inf;
1157{ 1090{
1158 FILE *inf;
1159 char *cp; 1091 char *cp;
1160 struct lang_entry *lang; 1092 struct lang_entry *lang;
1161 NODE *old_last_node; 1093 NODE *old_last_node;
1162 extern NODE *last_node; 1094 extern NODE *last_node;
1163 1095
1164 inf = fopen (file, "r");
1165 if (inf == NULL)
1166 {
1167 perror (file);
1168 return FALSE;
1169 }
1170 curfile = savestr (file); 1096 curfile = savestr (file);
1171 cp = etags_strrchr (file, '.'); 1097 cp = etags_strrchr (file, '.');
1172 1098
@@ -1175,7 +1101,7 @@ find_entries (file)
1175 { 1101 {
1176 lang_func (inf); 1102 lang_func (inf);
1177 fclose (inf); 1103 fclose (inf);
1178 return TRUE; 1104 return;
1179 } 1105 }
1180 1106
1181 if (cp) 1107 if (cp)
@@ -1187,7 +1113,7 @@ find_entries (file)
1187 { 1113 {
1188 lang->function (inf); 1114 lang->function (inf);
1189 fclose (inf); 1115 fclose (inf);
1190 return TRUE; 1116 return;
1191 } 1117 }
1192 } 1118 }
1193 } 1119 }
@@ -1200,7 +1126,6 @@ find_entries (file)
1200 if (old_last_node == last_node) 1126 if (old_last_node == last_node)
1201 default_C_entries (inf); 1127 default_C_entries (inf);
1202 fclose (inf); 1128 fclose (inf);
1203 return TRUE;
1204} 1129}
1205 1130
1206/* Record a tag. */ 1131/* Record a tag. */
@@ -1208,48 +1133,33 @@ find_entries (file)
1208void 1133void
1209pfnote (name, is_func, named, linestart, linelen, lno, cno) 1134pfnote (name, is_func, named, linestart, linelen, lno, cno)
1210 char *name; /* tag name */ 1135 char *name; /* tag name */
1211 logical is_func; /* function or type name? */ 1136 logical is_func; /* tag is a function */
1212 logical named; /* tag different from text of definition? */ 1137 logical named; /* tag different from text of definition */
1213 char *linestart; 1138 char *linestart; /* start of the line where tag is */
1214 int linelen; 1139 int linelen; /* length of the line where tag is */
1215 int lno; 1140 int lno; /* line number */
1216 long cno; 1141 long cno; /* character number */
1217{ 1142{
1143 register NODE *np = xnew (1, NODE);
1218 register char *fp; 1144 register char *fp;
1219 register NODE *np;
1220 char tem[51];
1221 char c;
1222 1145
1223 np = xnew (1, NODE);
1224 if (np == NULL)
1225 {
1226 if (CTAGS)
1227 {
1228 /* It's okay to output early in etags -- it only disrupts the
1229 * character count of the tag entries, which is no longer used
1230 * by tags.el anyway.
1231 */
1232 error ("too many entries to sort", 0);
1233 }
1234 put_entries (head);
1235 free_tree (head);
1236 head = NULL;
1237 np = xnew (1, NODE);
1238 }
1239 /* If ctags mode, change name "main" to M<thisfilename>. */ 1146 /* If ctags mode, change name "main" to M<thisfilename>. */
1240 if (CTAGS && !cxref_style && streq (name, "main")) 1147 if (CTAGS && !cxref_style && streq (name, "main"))
1241 { 1148 {
1242 fp = etags_strrchr (curfile, '/'); 1149 fp = etags_strrchr (curfile, '/');
1243 name = concat ("M", fp == 0 ? curfile : fp + 1, ""); 1150 np->name = concat ("M", fp == 0 ? curfile : fp + 1, "");
1244 fp = etags_strrchr (name, '.'); 1151 fp = etags_strrchr (np->name, '.');
1245 if (fp && fp[1] != '\0' && fp[2] == '\0') 1152 if (fp && fp[1] != '\0' && fp[2] == '\0')
1246 *fp = 0; 1153 fp[0] = 0;
1247 named = TRUE; 1154 np->named = TRUE;
1155 }
1156 else
1157 {
1158 np->name = name;
1159 np->named = named;
1248 } 1160 }
1249 np->name = savestr (name);
1250 np->file = curfile; 1161 np->file = curfile;
1251 np->is_func = is_func; 1162 np->is_func = is_func;
1252 np->named = named;
1253 np->lno = lno; 1163 np->lno = lno;
1254 /* Our char numbers are 0-base, because of C language tradition? 1164 /* Our char numbers are 0-base, because of C language tradition?
1255 ctags compatibility? old versions compatibility? I don't know. 1165 ctags compatibility? old versions compatibility? I don't know.
@@ -1257,22 +1167,8 @@ pfnote (name, is_func, named, linestart, linelen, lno, cno)
1257 of the difference. If we wanted to have 1-based numbers, we would 1167 of the difference. If we wanted to have 1-based numbers, we would
1258 uncomment the +1 below. */ 1168 uncomment the +1 below. */
1259 np->cno = cno /* + 1 */ ; 1169 np->cno = cno /* + 1 */ ;
1260 np->left = np->right = 0; 1170 np->left = np->right = NULL;
1261 if (!CTAGS) 1171 np->pat = savenstr (linestart, ((CTAGS && !cxref_style) ? 50 : linelen));
1262 {
1263 c = linestart[linelen];
1264 linestart[linelen] = 0;
1265 }
1266 else if (cxref_style == 0)
1267 {
1268 sprintf (tem, strlen (linestart) < 50 ? "%s$" : "%.50s", linestart);
1269 linestart = tem;
1270 }
1271 np->pat = savestr (linestart);
1272 if (!CTAGS)
1273 {
1274 linestart[linelen] = c;
1275 }
1276 1172
1277 add_node (np, &head); 1173 add_node (np, &head);
1278} 1174}
@@ -1289,7 +1185,8 @@ free_tree (node)
1289 { 1185 {
1290 register NODE *node_right = node->right; 1186 register NODE *node_right = node->right;
1291 free_tree (node->left); 1187 free_tree (node->left);
1292 free (node->name); 1188 if (node->named)
1189 free (node->name);
1293 free (node->pat); 1190 free (node->pat);
1294 free ((char *) node); 1191 free ((char *) node);
1295 node = node_right; 1192 node = node_right;
@@ -1484,6 +1381,10 @@ total_size_of_entries (node)
1484/* 1381/*
1485 * The C symbol tables. 1382 * The C symbol tables.
1486 */ 1383 */
1384enum sym_type
1385{
1386 st_none, st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
1387};
1487 1388
1488/* Feed stuff between (but not including) %[ and %] lines to: 1389/* Feed stuff between (but not including) %[ and %] lines to:
1489 gperf -c -k1,3 -o -p -r -t 1390 gperf -c -k1,3 -o -p -r -t
@@ -1680,7 +1581,7 @@ STRUCTST structdef;
1680 * struct tag, and structtype is the type of the preceding struct-like 1581 * struct tag, and structtype is the type of the preceding struct-like
1681 * keyword. 1582 * keyword.
1682 */ 1583 */
1683char structtag[BUFSIZ]; 1584char *structtag = "<uninited>";
1684enum sym_type structtype; 1585enum sym_type structtype;
1685 1586
1686/* 1587/*
@@ -1729,14 +1630,15 @@ logical yacc_rules;
1729 */ 1630 */
1730 1631
1731logical 1632logical
1732consider_token (c, tokp, c_ext, cblev, is_func) 1633consider_token (str, len, c, c_ext, cblev, is_func)
1634 register char *str; /* IN: token pointer */
1635 register int len; /* IN: token length */
1733 register char c; /* IN: first char after the token */ 1636 register char c; /* IN: first char after the token */
1734 register TOKEN *tokp; /* IN: token pointer */
1735 int c_ext; /* IN: C extensions mask */ 1637 int c_ext; /* IN: C extensions mask */
1736 int cblev; /* IN: curly brace level */ 1638 int cblev; /* IN: curly brace level */
1737 logical *is_func; /* OUT: function found */ 1639 logical *is_func; /* OUT: function found */
1738{ 1640{
1739 enum sym_type toktype = C_symtype(tokp->p, tokp->len, c_ext); 1641 enum sym_type toktype = C_symtype (str, len, c_ext);
1740 1642
1741 /* 1643 /*
1742 * Advance the definedef state machine. 1644 * Advance the definedef state machine.
@@ -1840,15 +1742,12 @@ consider_token (c, tokp, c_ext, cblev, is_func)
1840 } 1742 }
1841 if (structdef == skeyseen) 1743 if (structdef == skeyseen)
1842 { 1744 {
1745 /* Save the tag for struct/union/class, for functions that may be
1746 defined inside. */
1843 if (structtype == st_C_struct) 1747 if (structtype == st_C_struct)
1844 { 1748 structtag = savenstr (str, len);
1845 strncpy (structtag, tokp->p, tokp->len);
1846 structtag[tokp->len] = '\0'; /* for struct/union/class */
1847 }
1848 else 1749 else
1849 { 1750 structtag = "<enum>";
1850 structtag[0] = '\0'; /* for enum (why is it treated differently?) */
1851 }
1852 structdef = stagseen; 1751 structdef = stagseen;
1853 return TRUE; 1752 return TRUE;
1854 } 1753 }
@@ -1862,16 +1761,16 @@ consider_token (c, tokp, c_ext, cblev, is_func)
1862 1761
1863 /* Detect GNU macros. */ 1762 /* Detect GNU macros. */
1864 if (definedef == dnone) 1763 if (definedef == dnone)
1865 if (strneq (tokp->p, "DEFUN", 5) /* Used in emacs */ 1764 if (strneq (str, "DEFUN", 5) /* Used in emacs */
1866#if FALSE 1765#if FALSE
1867 These are defined inside C functions, so currently they 1766 These are defined inside C functions, so currently they
1868 are not met anyway. 1767 are not met anyway.
1869 || strneq (tokp->p, "EXFUN", 5) /* Used in glibc */ 1768 || strneq (str, "EXFUN", 5) /* Used in glibc */
1870 || strneq (tokp->p, "DEFVAR_", 7) /* Used in emacs */ 1769 || strneq (str, "DEFVAR_", 7) /* Used in emacs */
1871#endif 1770#endif
1872 || strneq (tokp->p, "SYSCALL", 7) /* Used in glibc (mach) */ 1771 || strneq (str, "SYSCALL", 7) /* Used in glibc (mach) */
1873 || strneq (tokp->p, "ENTRY", 5) /* Used in glibc */ 1772 || strneq (str, "ENTRY", 5) /* Used in glibc */
1874 || strneq (tokp->p, "PSEUDO", 6)) /* Used in glibc */ 1773 || strneq (str, "PSEUDO", 6)) /* Used in glibc */
1875 1774
1876 { 1775 {
1877 next_token_is_func = TRUE; 1776 next_token_is_func = TRUE;
@@ -1910,6 +1809,16 @@ consider_token (c, tokp, c_ext, cblev, is_func)
1910 * struct/union/enum definitions in C syntax and adds them 1809 * struct/union/enum definitions in C syntax and adds them
1911 * to the list. 1810 * to the list.
1912 */ 1811 */
1812typedef struct
1813{
1814 char *str;
1815 logical named;
1816 int linelen;
1817 int lineno;
1818} TOKEN;
1819
1820#define current_lb_is_new (newndx == curndx)
1821#define switch_line_buffers() (curndx = 1 - curndx)
1913 1822
1914#define curlb (lbs[curndx].lb) 1823#define curlb (lbs[curndx].lb)
1915#define othlb (lbs[1-curndx].lb) 1824#define othlb (lbs[1-curndx].lb)
@@ -1918,18 +1827,9 @@ consider_token (c, tokp, c_ext, cblev, is_func)
1918#define othlinepos (lbs[1-curndx].linepos) 1827#define othlinepos (lbs[1-curndx].linepos)
1919#define newlinepos (lbs[newndx].linepos) 1828#define newlinepos (lbs[newndx].linepos)
1920 1829
1921/* Save and restore token state. This is used when preprocessor defines
1922 are handled, to avoid disturbing active function/typedef/struct states. */
1923#define TOKEN_SAVED_P (savetok.lineno > 0)
1924#define SAVE_TOKEN (savetok = tok, savetok.p = (char *) tokoff, \
1925 savetok.len = toklen, strcpy(savenameb, nameb))
1926#define RESTORE_TOKEN (tok = savetok, tokoff = (int) tok.p, \
1927 toklen = tok.len, strcpy(nameb, savenameb), \
1928 savetok.lineno = 0)
1929
1930#define CNL_SAVE_DEFINEDEF \ 1830#define CNL_SAVE_DEFINEDEF \
1931do { \ 1831do { \
1932 SET_FILEPOS (curlinepos, inf, charno); \ 1832 curlinepos = charno; \
1933 lineno++; \ 1833 lineno++; \
1934 charno += readline (&curlb, inf); \ 1834 charno += readline (&curlb, inf); \
1935 lp = curlb.buffer; \ 1835 lp = curlb.buffer; \
@@ -1940,15 +1840,18 @@ do { \
1940#define CNL \ 1840#define CNL \
1941do { \ 1841do { \
1942 CNL_SAVE_DEFINEDEF; \ 1842 CNL_SAVE_DEFINEDEF; \
1943 if (TOKEN_SAVED_P) \ 1843 if (token_saved) \
1944 RESTORE_TOKEN; \ 1844 { \
1845 tok = savetok; \
1846 token_saved = FALSE; \
1847 } \
1945 definedef = dnone; \ 1848 definedef = dnone; \
1946} while (0) 1849} while (0)
1947 1850
1948#define MAKE_TAG_FROM_NEW_LB(isfun) pfnote (nameb, isfun, tok.named, \ 1851#define make_tag_from_new_lb(isfun) pfnote (tok.str, isfun, tok.named, \
1949 newlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (newlinepos)) 1852 newlb.buffer, tok.linelen, tok.lineno, newlinepos)
1950#define MAKE_TAG_FROM_OTH_LB(isfun) pfnote (nameb, isfun, tok.named, \ 1853#define make_tag_from_oth_lb(isfun) pfnote (tok.str, isfun, tok.named, \
1951 othlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (othlinepos)) 1854 othlb.buffer, tok.linelen, tok.lineno, othlinepos)
1952 1855
1953void 1856void
1954C_entries (c_ext, inf) 1857C_entries (c_ext, inf)
@@ -1958,18 +1861,16 @@ C_entries (c_ext, inf)
1958 register char c; /* latest char read; '\0' for end of line */ 1861 register char c; /* latest char read; '\0' for end of line */
1959 register char *lp; /* pointer one beyond the character `c' */ 1862 register char *lp; /* pointer one beyond the character `c' */
1960 int curndx, newndx; /* indices for current and new lb */ 1863 int curndx, newndx; /* indices for current and new lb */
1961 TOKEN tok; /* latest token read for funcdef & structdef */ 1864 TOKEN tok; /* latest token read */
1962 char nameb[BUFSIZ]; /* latest token name for funcdef & structdef */ 1865 register int tokoff; /* offset in line of start of current token */
1963 register int tokoff; /* offset in line of start of latest token */ 1866 register int toklen; /* length of current token */
1964 register int toklen; /* length of latest token */
1965 int cblev; /* current curly brace level */ 1867 int cblev; /* current curly brace level */
1966 int parlev; /* current parenthesis level */ 1868 int parlev; /* current parenthesis level */
1967 logical incomm, inquote, inchar, quotednl, midtoken; 1869 logical incomm, inquote, inchar, quotednl, midtoken;
1968 logical cplpl; 1870 logical cplpl;
1969 TOKEN savetok; /* saved token during preprocessor handling */ 1871 logical token_saved; /* token saved */
1970 char savenameb[BUFSIZ]; /* ouch! */ 1872 TOKEN savetok; /* token saved during preprocessor handling */
1971 1873
1972 savetok.lineno = 0;
1973 curndx = newndx = 0; 1874 curndx = newndx = 0;
1974 lineno = 0; 1875 lineno = 0;
1975 charno = 0; 1876 charno = 0;
@@ -1977,7 +1878,7 @@ C_entries (c_ext, inf)
1977 *lp = 0; 1878 *lp = 0;
1978 1879
1979 definedef = dnone; funcdef = fnone; typdef = tnone; structdef = snone; 1880 definedef = dnone; funcdef = fnone; typdef = tnone; structdef = snone;
1980 next_token_is_func = yacc_rules = FALSE; 1881 next_token_is_func = yacc_rules = token_saved = FALSE;
1981 midtoken = inquote = inchar = incomm = quotednl = FALSE; 1882 midtoken = inquote = inchar = incomm = quotednl = FALSE;
1982 cblev = 0; 1883 cblev = 0;
1983 parlev = 0; 1884 parlev = 0;
@@ -2143,45 +2044,47 @@ C_entries (c_ext, inf)
2143 { 2044 {
2144 logical is_func = FALSE; 2045 logical is_func = FALSE;
2145 2046
2146 tok.lineno = lineno;
2147 tok.p = newlb.buffer + tokoff;
2148 tok.len = toklen;
2149 tok.named = FALSE;
2150 if (yacc_rules 2047 if (yacc_rules
2151 || consider_token (c, &tok, c_ext, cblev, &is_func)) 2048 || consider_token (newlb.buffer + tokoff, toklen,
2049 c, c_ext, cblev, &is_func))
2152 { 2050 {
2153 if (structdef == sinbody 2051 if (structdef == sinbody
2154 && definedef == dnone 2052 && definedef == dnone
2155 && is_func) 2053 && is_func)
2156 /* function defined in C++ class body */ 2054 /* function defined in C++ class body */
2157 { 2055 {
2158 sprintf (nameb, "%s::%.*s", 2056 char *cp = newlb.buffer + tokoff + toklen;
2159 ((structtag[0] == '\0') 2057 char c = *cp;
2160 ? "_anonymous_" : structtag), 2058 *cp = '\0';
2161 tok.len, tok.p); 2059 tok.str = concat (structtag, "::",
2060 newlb.buffer + tokoff);
2061 *cp = c;
2162 tok.named = TRUE; 2062 tok.named = TRUE;
2163 } 2063 }
2164 else 2064 else
2165 { 2065 {
2166 sprintf (nameb, "%.*s", tok.len, tok.p); 2066 tok.str = savenstr (newlb.buffer+tokoff, toklen);
2067 if (structdef == stagseen
2068 || typdef == tend
2069 || (is_func
2070 && definedef == dignorerest)) /* macro */
2071 tok.named = TRUE;
2072 else
2073 tok.named = FALSE;
2167 } 2074 }
2168 2075 tok.lineno = lineno;
2169 if (structdef == stagseen 2076 tok.linelen = tokoff + toklen + 1;
2170 || typdef == tend
2171 || (is_func
2172 && definedef == dignorerest)) /* macro */
2173 tok.named = TRUE;
2174 2077
2175 if (definedef == dnone 2078 if (definedef == dnone
2176 && (funcdef == ftagseen 2079 && (funcdef == ftagseen
2177 || structdef == stagseen 2080 || structdef == stagseen
2178 || typdef == tend)) 2081 || typdef == tend))
2179 { 2082 {
2180 if (newndx == curndx) 2083 if (current_lb_is_new)
2181 curndx = 1 - curndx; /* switch line buffers */ 2084 switch_line_buffers ();
2182 } 2085 }
2183 else 2086 else
2184 MAKE_TAG_FROM_NEW_LB (is_func); 2087 make_tag_from_new_lb (is_func);
2185 } 2088 }
2186 midtoken = FALSE; 2089 midtoken = FALSE;
2187 } 2090 }
@@ -2203,7 +2106,7 @@ C_entries (c_ext, inf)
2203 funcdef = finlist; 2106 funcdef = finlist;
2204 continue; 2107 continue;
2205 case flistseen: 2108 case flistseen:
2206 MAKE_TAG_FROM_OTH_LB (TRUE); 2109 make_tag_from_oth_lb (TRUE);
2207 funcdef = fignore; 2110 funcdef = fignore;
2208 break; 2111 break;
2209 case ftagseen: 2112 case ftagseen:
@@ -2220,7 +2123,8 @@ C_entries (c_ext, inf)
2220 if (c == 'd' && strneq (lp, "efine", 5) 2123 if (c == 'd' && strneq (lp, "efine", 5)
2221 && iswhite (*(lp + 5))) 2124 && iswhite (*(lp + 5)))
2222 { 2125 {
2223 SAVE_TOKEN; 2126 savetok = tok;
2127 token_saved = TRUE;
2224 definedef = ddefineseen; 2128 definedef = ddefineseen;
2225 lp += 6; 2129 lp += 6;
2226 } 2130 }
@@ -2254,7 +2158,7 @@ C_entries (c_ext, inf)
2254 case ftagseen: 2158 case ftagseen:
2255 if (yacc_rules) 2159 if (yacc_rules)
2256 { 2160 {
2257 MAKE_TAG_FROM_OTH_LB (FALSE); 2161 make_tag_from_oth_lb (FALSE);
2258 funcdef = fignore; 2162 funcdef = fignore;
2259 } 2163 }
2260 break; 2164 break;
@@ -2270,7 +2174,7 @@ C_entries (c_ext, inf)
2270 switch (typdef) 2174 switch (typdef)
2271 { 2175 {
2272 case tend: 2176 case tend:
2273 MAKE_TAG_FROM_OTH_LB (FALSE); 2177 make_tag_from_oth_lb (FALSE);
2274 /* FALLTHRU */ 2178 /* FALLTHRU */
2275 default: 2179 default:
2276 typdef = tnone; 2180 typdef = tnone;
@@ -2294,7 +2198,7 @@ C_entries (c_ext, inf)
2294 if (cblev == 0 && typdef == tend) 2198 if (cblev == 0 && typdef == tend)
2295 { 2199 {
2296 typdef = tignore; 2200 typdef = tignore;
2297 MAKE_TAG_FROM_OTH_LB (FALSE); 2201 make_tag_from_oth_lb (FALSE);
2298 break; 2202 break;
2299 } 2203 }
2300 if (funcdef != finlist && funcdef != fignore) 2204 if (funcdef != finlist && funcdef != fignore)
@@ -2318,7 +2222,7 @@ C_entries (c_ext, inf)
2318 if (*lp != '*') 2222 if (*lp != '*')
2319 { 2223 {
2320 typdef = tignore; 2224 typdef = tignore;
2321 MAKE_TAG_FROM_OTH_LB (FALSE); 2225 make_tag_from_oth_lb (FALSE);
2322 } 2226 }
2323 break; 2227 break;
2324 } /* switch (typdef) */ 2228 } /* switch (typdef) */
@@ -2347,7 +2251,7 @@ C_entries (c_ext, inf)
2347 if (cblev == 0 && typdef == tend) 2251 if (cblev == 0 && typdef == tend)
2348 { 2252 {
2349 typdef = tignore; 2253 typdef = tignore;
2350 MAKE_TAG_FROM_OTH_LB (FALSE); 2254 make_tag_from_oth_lb (FALSE);
2351 } 2255 }
2352 } 2256 }
2353 else if (parlev < 0) /* can happen due to ill-conceived #if's. */ 2257 else if (parlev < 0) /* can happen due to ill-conceived #if's. */
@@ -2361,19 +2265,19 @@ C_entries (c_ext, inf)
2361 switch (structdef) 2265 switch (structdef)
2362 { 2266 {
2363 case skeyseen: /* unnamed struct */ 2267 case skeyseen: /* unnamed struct */
2364 structtag[0] = '\0'; 2268 structtag = "_anonymous_";
2365 structdef = sinbody; 2269 structdef = sinbody;
2366 break; 2270 break;
2367 case stagseen: 2271 case stagseen:
2368 case scolonseen: /* named struct */ 2272 case scolonseen: /* named struct */
2369 structdef = sinbody; 2273 structdef = sinbody;
2370 MAKE_TAG_FROM_OTH_LB (FALSE); 2274 make_tag_from_oth_lb (FALSE);
2371 break; 2275 break;
2372 } 2276 }
2373 switch (funcdef) 2277 switch (funcdef)
2374 { 2278 {
2375 case flistseen: 2279 case flistseen:
2376 MAKE_TAG_FROM_OTH_LB (TRUE); 2280 make_tag_from_oth_lb (TRUE);
2377 /* FALLTHRU */ 2281 /* FALLTHRU */
2378 case fignore: 2282 case fignore:
2379 funcdef = fnone; 2283 funcdef = fnone;
@@ -2405,8 +2309,12 @@ C_entries (c_ext, inf)
2405 { 2309 {
2406 if (typdef == tinbody) 2310 if (typdef == tinbody)
2407 typdef = tend; 2311 typdef = tend;
2312#if FALSE /* too risky */
2313 if (structdef == sinbody)
2314 free (structtag);
2315#endif
2408 structdef = snone; 2316 structdef = snone;
2409 strcpy (structtag, "<error 2>"); 2317 structtag = "<error>";
2410 } 2318 }
2411 break; 2319 break;
2412 case '=': 2320 case '=':
@@ -2468,7 +2376,6 @@ Yacc_entries (inf)
2468/* Fortran parsing */ 2376/* Fortran parsing */
2469 2377
2470char *dbp; 2378char *dbp;
2471int pfcnt;
2472 2379
2473logical 2380logical
2474tail (cp) 2381tail (cp)
@@ -2513,8 +2420,6 @@ getit (inf)
2513 FILE *inf; 2420 FILE *inf;
2514{ 2421{
2515 register char *cp; 2422 register char *cp;
2516 char c;
2517 char nambuf[BUFSIZ];
2518 2423
2519 while (isspace (*dbp)) 2424 while (isspace (*dbp))
2520 dbp++; 2425 dbp++;
@@ -2539,13 +2444,8 @@ getit (inf)
2539 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$'))); 2444 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$')));
2540 cp++) 2445 cp++)
2541 continue; 2446 continue;
2542 c = *cp; 2447 pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE, lb.buffer,
2543 *cp = '\0';
2544 strcpy (nambuf, dbp);
2545 *cp = c;
2546 pfnote (nambuf, TRUE, FALSE, lb.buffer,
2547 cp - lb.buffer + 1, lineno, linecharno); 2448 cp - lb.buffer + 1, lineno, linecharno);
2548 pfcnt++;
2549} 2449}
2550 2450
2551void 2451void
@@ -2554,7 +2454,6 @@ Fortran_functions (inf)
2554{ 2454{
2555 lineno = 0; 2455 lineno = 0;
2556 charno = 0; 2456 charno = 0;
2557 pfcnt = 0;
2558 2457
2559 while (!feof (inf)) 2458 while (!feof (inf))
2560 { 2459 {
@@ -2639,13 +2538,10 @@ void
2639Asm_labels (inf) 2538Asm_labels (inf)
2640 FILE *inf; 2539 FILE *inf;
2641{ 2540{
2642 char nambuf[BUFSIZ];
2643 register char *cp; 2541 register char *cp;
2644 char c;
2645 2542
2646 lineno = 0; 2543 lineno = 0;
2647 charno = 0; 2544 charno = 0;
2648 pfcnt = 0;
2649 2545
2650 while (!feof (inf)) 2546 while (!feof (inf))
2651 { 2547 {
@@ -2665,13 +2561,8 @@ Asm_labels (inf)
2665 if (*cp == ':' || isspace (*cp)) 2561 if (*cp == ':' || isspace (*cp))
2666 { 2562 {
2667 /* Found end of label, so copy it and add it to the table. */ 2563 /* Found end of label, so copy it and add it to the table. */
2668 c = *cp; 2564 pfnote (savenstr (lb.buffer, cp-lb.buffer), TRUE, FALSE,
2669 *cp = '\0'; 2565 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2670 strcpy (nambuf, lb.buffer);
2671 *cp = c;
2672 pfnote (nambuf, TRUE, FALSE, lb.buffer,
2673 cp - lb.buffer + 1, lineno, linecharno);
2674 pfcnt++;
2675 } 2566 }
2676 } 2567 }
2677 } 2568 }
@@ -2701,7 +2592,7 @@ Pascal_functions (inf)
2701 long save_lcno; 2592 long save_lcno;
2702 int save_lineno; 2593 int save_lineno;
2703 char c, *cp; 2594 char c, *cp;
2704 char nambuf[BUFSIZ]; 2595 char *nambuf;
2705 2596
2706 logical /* each of these flags is TRUE iff: */ 2597 logical /* each of these flags is TRUE iff: */
2707 incomment, /* point is inside a comment */ 2598 incomment, /* point is inside a comment */
@@ -2731,16 +2622,16 @@ Pascal_functions (inf)
2731 while (!feof (inf)) 2622 while (!feof (inf))
2732 { 2623 {
2733 c = *dbp++; 2624 c = *dbp++;
2734 if (c == 0) /* if end of line */ 2625 if (c == '\0') /* if end of line */
2735 { 2626 {
2736 GET_NEW_LINE; 2627 GET_NEW_LINE;
2737 if (*dbp == 0) 2628 if (*dbp == '\0')
2738 continue; 2629 continue;
2739 if (!((found_tag && verify_tag) || 2630 if (!((found_tag && verify_tag) ||
2740 get_tagname)) 2631 get_tagname))
2741 c = *dbp++; /* only if don't need *dbp pointing */ 2632 c = *dbp++; /* only if don't need *dbp pointing */
2742 /* to the beginning of the name of */ 2633 /* to the beginning of the name of */
2743 /* the procedure or function */ 2634 /* the procedure or function */
2744 } 2635 }
2745 if (incomment) 2636 if (incomment)
2746 { 2637 {
@@ -2759,7 +2650,7 @@ Pascal_functions (inf)
2759 inquote = FALSE; 2650 inquote = FALSE;
2760 continue; 2651 continue;
2761 } 2652 }
2762 else 2653 else
2763 switch (c) 2654 switch (c)
2764 { 2655 {
2765 case '\'': 2656 case '\'':
@@ -2814,9 +2705,8 @@ Pascal_functions (inf)
2814 { 2705 {
2815 found_tag = FALSE; 2706 found_tag = FALSE;
2816 verify_tag = FALSE; 2707 verify_tag = FALSE;
2817 pfnote (nambuf, TRUE, FALSE, 2708 pfnote (nambuf, TRUE, FALSE, tline.buffer,
2818 tline.buffer, cp - tline.buffer + 1, 2709 cp - tline.buffer + 1, save_lineno, save_lcno);
2819 save_lineno, save_lcno);
2820 continue; 2710 continue;
2821 } 2711 }
2822 } 2712 }
@@ -2834,10 +2724,7 @@ Pascal_functions (inf)
2834 /* grab block name */ 2724 /* grab block name */
2835 for (cp = dbp + 1; *cp && (!endtoken (*cp)); cp++) 2725 for (cp = dbp + 1; *cp && (!endtoken (*cp)); cp++)
2836 continue; 2726 continue;
2837 c = cp[0]; 2727 nambuf = savenstr (dbp, cp-dbp);
2838 cp[0] = 0;
2839 strcpy (nambuf, dbp);
2840 cp[0] = c;
2841 dbp = cp; /* restore dbp to e-o-token */ 2728 dbp = cp; /* restore dbp to e-o-token */
2842 get_tagname = FALSE; 2729 get_tagname = FALSE;
2843 found_tag = TRUE; 2730 found_tag = TRUE;
@@ -2845,7 +2732,7 @@ Pascal_functions (inf)
2845 2732
2846 /* and proceed to check for "extern" */ 2733 /* and proceed to check for "extern" */
2847 } 2734 }
2848 if (!incomment && !inquote && !found_tag && !get_tagname) 2735 else if (!incomment && !inquote && !found_tag)
2849 { 2736 {
2850 /* check for proc/fn keywords */ 2737 /* check for proc/fn keywords */
2851 switch (c | ' ') 2738 switch (c | ' ')
@@ -2865,36 +2752,33 @@ Pascal_functions (inf)
2865 2752
2866/* 2753/*
2867 * lisp tag functions 2754 * lisp tag functions
2868 * just look for (def or (DEF 2755 * look for (def or (DEF, quote or QUOTE
2869 */ 2756 */
2870
2871int 2757int
2872L_isdef (tokp) 2758L_isdef (strp)
2873 register char *tokp; 2759 register char *strp;
2874{ 2760{
2875 return ((tokp[1] == 'd' || tokp[1] == 'D') 2761 return ((strp[1] == 'd' || strp[1] == 'D')
2876 && (tokp[2] == 'e' || tokp[2] == 'E') 2762 && (strp[2] == 'e' || strp[2] == 'E')
2877 && (tokp[3] == 'f' || tokp[3] == 'F')); 2763 && (strp[3] == 'f' || strp[3] == 'F'));
2878} 2764}
2879 2765
2880int 2766int
2881L_isquote (tokp) 2767L_isquote (strp)
2882 register char *tokp; 2768 register char *strp;
2883{ 2769{
2884 return ((*(++tokp) == 'q' || *tokp == 'Q') 2770 return ((*(++strp) == 'q' || *strp == 'Q')
2885 && (*(++tokp) == 'u' || *tokp == 'U') 2771 && (*(++strp) == 'u' || *strp == 'U')
2886 && (*(++tokp) == 'o' || *tokp == 'O') 2772 && (*(++strp) == 'o' || *strp == 'O')
2887 && (*(++tokp) == 't' || *tokp == 'T') 2773 && (*(++strp) == 't' || *strp == 'T')
2888 && (*(++tokp) == 'e' || *tokp == 'E') 2774 && (*(++strp) == 'e' || *strp == 'E')
2889 && isspace(*(++tokp))); 2775 && isspace(*(++strp)));
2890} 2776}
2891 2777
2892void 2778void
2893L_getit () 2779L_getit ()
2894{ 2780{
2895 register char *cp; 2781 register char *cp;
2896 char c;
2897 char nambuf[BUFSIZ];
2898 2782
2899 if (*dbp == '\'') /* Skip prefix quote */ 2783 if (*dbp == '\'') /* Skip prefix quote */
2900 dbp++; 2784 dbp++;
@@ -2904,18 +2788,15 @@ L_getit ()
2904 while (isspace(*dbp)) 2788 while (isspace(*dbp))
2905 dbp++; 2789 dbp++;
2906 } 2790 }
2907 for (cp = dbp /*+1*/; *cp && *cp != '(' && *cp != ' ' && *cp != ')'; cp++) 2791 for (cp = dbp /*+1*/;
2792 *cp && *cp != '(' && *cp != ' ' && *cp != ')';
2793 cp++)
2908 continue; 2794 continue;
2909 if (cp == dbp) 2795 if (cp == dbp)
2910 return; 2796 return;
2911 2797
2912 c = cp[0]; 2798 pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE, lb.buffer,
2913 cp[0] = 0;
2914 strcpy (nambuf, dbp);
2915 cp[0] = c;
2916 pfnote (nambuf, TRUE, FALSE, lb.buffer,
2917 cp - lb.buffer + 1, lineno, linecharno); 2799 cp - lb.buffer + 1, lineno, linecharno);
2918 pfcnt++;
2919} 2800}
2920 2801
2921void 2802void
@@ -2924,7 +2805,6 @@ Lisp_functions (inf)
2924{ 2805{
2925 lineno = 0; 2806 lineno = 0;
2926 charno = 0; 2807 charno = 0;
2927 pfcnt = 0;
2928 2808
2929 while (!feof (inf)) 2809 while (!feof (inf))
2930 { 2810 {
@@ -2985,7 +2865,6 @@ Scheme_functions (inf)
2985{ 2865{
2986 lineno = 0; 2866 lineno = 0;
2987 charno = 0; 2867 charno = 0;
2988 pfcnt = 0;
2989 2868
2990 while (!feof (inf)) 2869 while (!feof (inf))
2991 { 2870 {
@@ -3026,24 +2905,16 @@ void
3026get_scheme () 2905get_scheme ()
3027{ 2906{
3028 register char *cp; 2907 register char *cp;
3029 char c;
3030 char nambuf[BUFSIZ];
3031 2908
3032 if (*dbp == 0) 2909 if (*dbp == 0)
3033 return; 2910 return;
3034 /* Go till you get to white space or a syntactic break */ 2911 /* Go till you get to white space or a syntactic break */
3035 for (cp = dbp + 1; *cp && *cp != '(' && *cp != ')' && !isspace (*cp); cp++) 2912 for (cp = dbp + 1;
2913 *cp && *cp != '(' && *cp != ')' && !isspace (*cp);
2914 cp++)
3036 continue; 2915 continue;
3037 /* Null terminate the string there. */ 2916 pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE,
3038 c = cp[0]; 2917 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3039 cp[0] = 0;
3040 /* Copy the string */
3041 strcpy (nambuf, dbp);
3042 /* Unterminate the string */
3043 cp[0] = c;
3044 /* Announce the change */
3045 pfnote (nambuf, TRUE, FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3046 pfcnt++;
3047} 2918}
3048 2919
3049/* Find tags in TeX and LaTeX input files. */ 2920/* Find tags in TeX and LaTeX input files. */
@@ -3085,7 +2956,6 @@ TeX_functions (inf)
3085 2956
3086 lineno = 0; 2957 lineno = 0;
3087 charno = 0; 2958 charno = 0;
3088 pfcnt = 0;
3089 2959
3090 /* Select either \ or ! as escape character. */ 2960 /* Select either \ or ! as escape character. */
3091 TEX_mode (inf); 2961 TEX_mode (inf);
@@ -3216,7 +3086,6 @@ TEX_getit (name, len)
3216 int len; 3086 int len;
3217{ 3087{
3218 char *p = name + len; 3088 char *p = name + len;
3219 char nambuf[BUFSIZ];
3220 3089
3221 if (*name == 0) 3090 if (*name == 0)
3222 return; 3091 return;
@@ -3224,11 +3093,8 @@ TEX_getit (name, len)
3224 /* Let tag name extend to next group close (or end of line) */ 3093 /* Let tag name extend to next group close (or end of line) */
3225 while (*p && *p != TEX_clgrp) 3094 while (*p && *p != TEX_clgrp)
3226 p++; 3095 p++;
3227 strncpy (nambuf, name, p - name); 3096 pfnote (savenstr (name, p-name), TRUE, FALSE, lb.buffer,
3228 nambuf[p - name] = 0; 3097 strlen (lb.buffer), lineno, linecharno);
3229
3230 pfnote (nambuf, TRUE, FALSE, lb.buffer, strlen (lb.buffer), lineno, linecharno);
3231 pfcnt++;
3232} 3098}
3233 3099
3234/* If the text at CP matches one of the tag-defining TeX command names, 3100/* If the text at CP matches one of the tag-defining TeX command names,
@@ -3256,7 +3122,7 @@ void
3256prolog_getit (s) 3122prolog_getit (s)
3257 char *s; 3123 char *s;
3258{ 3124{
3259 char nambuf[BUFSIZ], *save_s, tmpc; 3125 char *save_s;
3260 int insquote, npar; 3126 int insquote, npar;
3261 3127
3262 save_s = s; 3128 save_s = s;
@@ -3264,21 +3130,21 @@ prolog_getit (s)
3264 npar = 0; 3130 npar = 0;
3265 while (1) 3131 while (1)
3266 { 3132 {
3267 if (*s == '\0') /* syntax error. */ 3133 if (s[0] == '\0') /* syntax error. */
3268 return; 3134 return;
3269 else if (insquote && *s == '\'' && *(s + 1) == '\'') 3135 else if (insquote && s[0] == '\'' && s[1] == '\'')
3270 s += 2; 3136 s += 2;
3271 else if (*s == '\'') 3137 else if (s[0] == '\'')
3272 { 3138 {
3273 insquote = !insquote; 3139 insquote = !insquote;
3274 s++; 3140 s++;
3275 } 3141 }
3276 else if (!insquote && *s == '(') 3142 else if (!insquote && s[0] == '(')
3277 { 3143 {
3278 npar++; 3144 npar++;
3279 s++; 3145 s++;
3280 } 3146 }
3281 else if (!insquote && *s == ')') 3147 else if (!insquote && s[0] == ')')
3282 { 3148 {
3283 npar--; 3149 npar--;
3284 s++; 3150 s++;
@@ -3287,7 +3153,8 @@ prolog_getit (s)
3287 else if (npar < 0) /* syntax error. */ 3153 else if (npar < 0) /* syntax error. */
3288 return; 3154 return;
3289 } 3155 }
3290 else if (!insquote && *s == '.' && (isspace (*(s + 1)) || *(s + 1) == '\0')) 3156 else if (!insquote && s[0] == '.'
3157 && (isspace (s[1]) || s[1] == '\0'))
3291 { /* fullstop. */ 3158 { /* fullstop. */
3292 if (npar != 0) /* syntax error. */ 3159 if (npar != 0) /* syntax error. */
3293 return; 3160 return;
@@ -3297,11 +3164,8 @@ prolog_getit (s)
3297 else 3164 else
3298 s++; 3165 s++;
3299 } 3166 }
3300 tmpc = *s; 3167 pfnote (savenstr (save_s, s-save_s), TRUE, FALSE,
3301 *s = '\0'; 3168 save_s, s-save_s, lineno, linecharno);
3302 strcpy (nambuf, save_s);
3303 *s = tmpc;
3304 pfnote (nambuf, TRUE, FALSE, save_s, strlen (nambuf), lineno, linecharno);
3305} 3169}
3306 3170
3307/* It is assumed that prolog predicate starts from column 0. */ 3171/* It is assumed that prolog predicate starts from column 0. */
@@ -3664,6 +3528,10 @@ just_read_file (inf)
3664} 3528}
3665 3529
3666 3530
3531/*
3532 * Return a pointer to a space of size strlen(cp)+1 allocated
3533 * with xnew where the string CP has been copied.
3534 */
3667char * 3535char *
3668savestr (cp) 3536savestr (cp)
3669 char *cp; 3537 char *cp;
@@ -3671,6 +3539,10 @@ savestr (cp)
3671 return savenstr (cp, strlen (cp)); 3539 return savenstr (cp, strlen (cp));
3672} 3540}
3673 3541
3542/*
3543 * Return a pointer to a space of size LEN+1 allocated with xnew where
3544 * the string CP has been copied for at most the first LEN characters.
3545 */
3674char * 3546char *
3675savenstr (cp, len) 3547savenstr (cp, len)
3676 char *cp; 3548 char *cp;