Mercurial > emacs
comparison lib-src/etags.c @ 10404:631f1dac6f7a
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.
author | Francesco Potortì <pot@gnu.org> |
---|---|
date | Thu, 12 Jan 1995 17:05:37 +0000 |
parents | fb23ac6e6199 |
children | 2266157d9bcc |
comparison
equal
deleted
inserted
replaced
10403:c0e27466fb3f | 10404:631f1dac6f7a |
---|---|
29 #endif | 29 #endif |
30 * | 30 * |
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 |
34 char pot_etags_version[] = "@(#) pot revision number is 11.14"; | 34 char 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> |
38 #include <sys/param.h> | 38 #include <sys/param.h> |
39 #endif /* MSDOS */ | 39 #endif /* MSDOS */ |
69 | 69 |
70 #ifdef ETAGS_REGEXPS | 70 #ifdef ETAGS_REGEXPS |
71 #include <regex.h> | 71 #include <regex.h> |
72 #endif /* ETAGS_REGEXPS */ | 72 #endif /* ETAGS_REGEXPS */ |
73 | 73 |
74 extern 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 |
78 tag tables and tags typedefs, #defines and struct/union/enum by default. */ | 79 tag tables and tags typedefs, #defines and struct/union/enum by default. */ |
79 #ifdef CTAGS | 80 #ifdef CTAGS |
90 #else | 91 #else |
91 #define GOOD 0 | 92 #define GOOD 0 |
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 */ | |
123 typedef 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 */ | |
132 typedef 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 | |
147 #define TRUE 1 | |
148 #define FALSE 0 | |
149 | 103 |
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 |
157 typedef int logical; | 116 typedef int logical; |
158 | 117 |
159 struct nd_st | 118 typedef 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 */ |
163 logical is_func; /* use pattern or line no */ | 122 logical is_func; /* use pattern or line no */ |
164 logical named; /* list name separately */ | 123 logical named; /* list name separately */ |
165 logical been_warned; /* set if noticed dup */ | 124 logical been_warned; /* set if noticed dup */ |
166 int lno; /* line number tag is on */ | 125 int lno; /* line number tag is on */ |
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 | 130 |
172 typedef struct nd_st NODE; | 131 extern char *getenv (); |
173 | |
174 /* boolean "functions" (see init) */ | |
175 logical _wht[0177], _etk[0177], _itk[0177], _btk[0177]; | |
176 | |
177 char *cwd; /* current working directory */ | |
178 char *tagfiledir; /* directory of tagfile */ | |
179 | 132 |
180 char *concat (); | 133 char *concat (); |
181 char *savenstr (), *savestr (); | 134 char *savenstr (), *savestr (); |
182 char *etags_strchr (), *etags_strrchr (); | 135 char *etags_strchr (), *etags_strrchr (); |
183 char *etags_getcwd (); | 136 char *etags_getcwd (); |
223 void add_regex (); | 176 void add_regex (); |
224 #endif | 177 #endif |
225 void add_node (); | 178 void add_node (); |
226 void error (); | 179 void error (); |
227 void fatal (), pfatal (); | 180 void fatal (), pfatal (); |
228 logical find_entries (); | 181 void find_entries (); |
229 void free_tree (); | 182 void free_tree (); |
230 void getit (); | 183 void getit (); |
231 void init (); | 184 void init (); |
232 void initbuffer (); | 185 void initbuffer (); |
233 void pfnote (); | 186 void pfnote (); |
234 void process_file (); | 187 void process_file (); |
235 void put_entries (); | 188 void put_entries (); |
236 void takeprec (); | 189 void takeprec (); |
237 | 190 |
191 | |
192 char searchar = '/'; /* use /.../ searches */ | |
193 | |
194 int lineno; /* line number of current line */ | |
195 long charno; /* current character number */ | |
196 | |
197 long linecharno; /* charno of start of line; not used by C, | |
198 but by every other language. */ | |
199 | |
200 char *curfile; /* current input file name */ | |
201 char *tagfile; /* output file */ | |
202 char *progname; /* name this program was invoked with */ | |
203 char *cwd; /* current working directory */ | |
204 char *tagfiledir; /* directory of tagfile */ | |
205 | |
206 FILE *tagf; /* ioptr for tags file */ | |
207 NODE *head; /* the head of the binary tree of tags */ | |
208 | |
238 /* | 209 /* |
239 * MACRO | 210 * A `struct linebuffer' is a structure which holds a line of text. |
240 * xnew -- allocate storage | 211 * `readline' reads a line from a stream into a linebuffer and works |
241 * | 212 * regardless of the length of the line. |
242 * SYNOPSIS | |
243 * Type *xnew (int n, Type); | |
244 */ | 213 */ |
245 #define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) | 214 struct linebuffer |
246 | 215 { |
247 /* | 216 long size; |
248 * Symbol table types. | 217 char *buffer; |
249 */ | |
250 enum sym_type | |
251 { | |
252 st_none, st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec | |
253 }; | 218 }; |
254 | 219 |
255 | 220 struct linebuffer lb; /* the current line */ |
256 | 221 struct |
257 typedef int LINENO; | 222 { |
258 | 223 long linepos; |
259 typedef struct | 224 struct linebuffer lb; /* used by C_entries instead of lb */ |
260 { | 225 } lbs[2]; |
261 char *p; | 226 |
262 int len; | 227 /* boolean "functions" (see init) */ |
263 LINENO lineno; | 228 logical _wht[0177], _etk[0177], _itk[0177], _btk[0177]; |
264 logical named; | 229 char |
265 } TOKEN; | |
266 | |
267 /* C extensions. | |
268 */ | |
269 #define C_PLPL 0x00001 /* C++ */ | |
270 #define C_STAR 0x00003 /* C* */ | |
271 #define YACC 0x10000 /* yacc file */ | |
272 | |
273 char searchar = '/'; /* use /.../ searches */ | |
274 | |
275 LINENO lineno; /* line number of current line */ | |
276 long charno; /* current character number */ | |
277 | |
278 long linecharno; /* charno of start of line; not used by C, but | |
279 * by every other language. | |
280 */ | |
281 | |
282 char *curfile, /* current input file name */ | |
283 *tagfile, /* output file */ | |
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 */ |
287 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~", | 233 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~", |
288 /* valid in-token chars */ | 234 /* valid in-token chars */ |
289 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; | 235 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; |
290 | 236 |
291 int append_to_tagfile; /* -a: append to tags */ | 237 logical 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. */ |
293 int typedefs; /* -t: create tags for typedefs */ | 239 logical typedefs; /* -t: create tags for typedefs */ |
294 int typedefs_and_cplusplus; /* -T: create tags for typedefs, level */ | 240 logical 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. */ |
297 int constantypedefs; /* -d: create tags for C #define and enum */ | 243 logical 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. */ |
300 int update; /* -u: update tags */ | 246 logical update; /* -u: update tags */ |
301 int vgrind_style; /* -v: create vgrind style index output */ | 247 logical vgrind_style; /* -v: create vgrind style index output */ |
302 int no_warnings; /* -w: suppress warnings */ | 248 logical no_warnings; /* -w: suppress warnings */ |
303 int cxref_style; /* -x: create cxref style output */ | 249 logical cxref_style; /* -x: create cxref style output */ |
304 int cplusplus; /* .[hc] means C++, not C */ | 250 logical cplusplus; /* .[hc] means C++, not C */ |
305 int noindentypedefs; /* -S: ignore indentation in C */ | 251 logical noindentypedefs; /* -S: ignore indentation in C */ |
306 | 252 #define permit_duplicates TRUE /* allow duplicate tags */ |
307 /* Name this program was invoked with. */ | |
308 char *progname; | |
309 | 253 |
310 struct option longopts[] = | 254 struct option longopts[] = |
311 { | 255 { |
312 { "append", no_argument, NULL, 'a' }, | 256 { "append", no_argument, NULL, 'a' }, |
313 { "backward-search", no_argument, NULL, 'B' }, | 257 { "backward-search", no_argument, NULL, 'B' }, |
329 { "update", no_argument, NULL, 'u' }, | 273 { "update", no_argument, NULL, 'u' }, |
330 { "version", no_argument, NULL, 'V' }, | 274 { "version", no_argument, NULL, 'V' }, |
331 { "vgrind", no_argument, NULL, 'v' }, | 275 { "vgrind", no_argument, NULL, 'v' }, |
332 { 0 } | 276 { 0 } |
333 }; | 277 }; |
334 | |
335 FILE *tagf; /* ioptr for tags file */ | |
336 NODE *head; /* the head of the binary tree of tags */ | |
337 logical 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 */ | |
344 struct linebuffer | |
345 { | |
346 long size; | |
347 char *buffer; | |
348 }; | |
349 | |
350 struct linebuffer lb; /* the current line */ | |
351 struct linebuffer filename_lb; /* used to read in filenames */ | |
352 struct | |
353 { | |
354 FILEPOS linepos; | |
355 struct linebuffer lb; /* used by C_entries instead of lb */ | |
356 } lbs[2]; | |
357 | 278 |
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. */ |
361 struct pattern | 282 struct pattern |
752 void | 673 void |
753 main (argc, argv) | 674 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 |
767 | 688 |
768 #ifdef DOS_NT | 689 #ifdef DOS_NT |
783 /* | 704 /* |
784 * If etags, always find typedefs and structure tags. Why not? | 705 * If etags, always find typedefs and structure tags. Why not? |
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 { |
792 int opt = getopt_long (argc, argv, | 713 int opt = getopt_long (argc, argv, |
793 "-aCdDf:l:o:r:RStTi:BuvxwVhH", longopts, 0); | 714 "-aCdDf:l:o:r:RStTi:BuvxwVhH", longopts, 0); |
810 ++file_count; | 731 ++file_count; |
811 break; | 732 break; |
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': |
828 if (tagfile) | 749 if (tagfile) |
829 { | 750 { |
854 argbuffer[current_arg].what = NULL; | 775 argbuffer[current_arg].what = NULL; |
855 ++current_arg; | 776 ++current_arg; |
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 (); |
863 break; | 784 break; |
864 case 'h': | 785 case 'h': |
865 case 'H': | 786 case 'H': |
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 */ |
877 case 'i': | 797 case 'i': |
878 included_files[nincluded_files++] = optarg; | 798 included_files[nincluded_files++] = optarg; |
881 /* Ctags options. */ | 801 /* Ctags options. */ |
882 case 'B': | 802 case 'B': |
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: |
899 fprintf (stderr, | 819 fprintf (stderr, |
900 "%s: -%c flag not recognised.\n", progname, opt); | 820 "%s: -%c flag not recognised.\n", progname, opt); |
987 and use them. */ | 907 and use them. */ |
988 if (streq (this_file, "-")) | 908 if (streq (this_file, "-")) |
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); |
997 } | 915 } |
998 } | 916 } |
1008 if (!CTAGS) | 926 if (!CTAGS) |
1009 { | 927 { |
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) |
1032 } | 957 fatal ("failed to execute shell command"); |
1033 append_to_tagfile++; | 958 } |
1034 } | 959 append_to_tagfile = TRUE; |
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 } |
1050 | 976 |
1051 | 977 |
1078 void | 1004 void |
1079 process_file (file) | 1005 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 { |
1086 fprintf (stderr, "Skipping %s: it is not a regular file.\n", file); | 1013 fprintf (stderr, "Skipping %s: it is not a regular file.\n", file); |
1087 return; | 1014 return; |
1089 if (streq (file, tagfile) && !streq (tagfile, "-")) | 1016 if (streq (file, tagfile) && !streq (tagfile, "-")) |
1090 { | 1017 { |
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"); |
1095 { | 1022 if (inf == NULL) |
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; |
1101 | 1033 |
1102 if (file[0] == '/') | 1034 if (file[0] == '/') |
1149 | 1081 |
1150 /* | 1082 /* |
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 */ |
1154 logical | 1086 void |
1155 find_entries (file) | 1087 find_entries (file, inf) |
1156 char *file; | 1088 char *file; |
1157 { | 1089 FILE *inf; |
1158 FILE *inf; | 1090 { |
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 |
1173 /* If user specified a language, use it. */ | 1099 /* If user specified a language, use it. */ |
1174 if (lang_func != NULL) | 1100 if (lang_func != NULL) |
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) |
1182 { | 1108 { |
1183 ++cp; | 1109 ++cp; |
1185 { | 1111 { |
1186 if (streq (cp, lang->extension)) | 1112 if (streq (cp, lang->extension)) |
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 } |
1194 | 1120 |
1195 /* Try Fortran. */ | 1121 /* Try Fortran. */ |
1198 | 1124 |
1199 /* No Fortran entries found. Try C. */ | 1125 /* No Fortran entries found. Try C. */ |
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. */ |
1207 /* Should take a TOKEN* instead!! */ | 1132 /* Should take a TOKEN* instead!! */ |
1208 void | 1133 void |
1209 pfnote (name, is_func, named, linestart, linelen, lno, cno) | 1134 pfnote (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; | 1145 |
1220 char tem[51]; | |
1221 char c; | |
1222 | |
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; |
1248 } | 1155 } |
1249 np->name = savestr (name); | 1156 else |
1157 { | |
1158 np->name = name; | |
1159 np->named = named; | |
1160 } | |
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. |
1256 Anyway, since emacs's are 1-base we espect etags.el to take care | 1166 Anyway, since emacs's are 1-base we espect etags.el to take care |
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 } |
1279 | 1175 |
1280 /* | 1176 /* |
1287 { | 1183 { |
1288 while (node) | 1184 while (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; |
1296 } | 1193 } |
1297 } | 1194 } |
1482 } | 1379 } |
1483 | 1380 |
1484 /* | 1381 /* |
1485 * The C symbol tables. | 1382 * The C symbol tables. |
1486 */ | 1383 */ |
1384 enum 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 |
1490 %[ | 1391 %[ |
1491 struct C_stab_entry { char *name; int c_ext; enum sym_type type; } | 1392 struct C_stab_entry { char *name; int c_ext; enum sym_type type; } |
1678 /* | 1579 /* |
1679 * When structdef is stagseen, scolonseen, or sinbody, structtag is the | 1580 * When structdef is stagseen, scolonseen, or sinbody, structtag is the |
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 */ |
1683 char structtag[BUFSIZ]; | 1584 char *structtag = "<uninited>"; |
1684 enum sym_type structtype; | 1585 enum sym_type structtype; |
1685 | 1586 |
1686 /* | 1587 /* |
1687 * Yet another little state machine to deal with preprocessor lines. | 1588 * Yet another little state machine to deal with preprocessor lines. |
1688 */ | 1589 */ |
1727 * typdef IN OUT | 1628 * typdef IN OUT |
1728 * next_token_is_func IN OUT | 1629 * next_token_is_func IN OUT |
1729 */ | 1630 */ |
1730 | 1631 |
1731 logical | 1632 logical |
1732 consider_token (c, tokp, c_ext, cblev, is_func) | 1633 consider_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. |
1743 */ | 1645 */ |
1744 switch (definedef) | 1646 switch (definedef) |
1838 } | 1740 } |
1839 return FALSE; | 1741 return FALSE; |
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 } |
1855 | 1754 |
1856 /* Avoid entering funcdef stuff if typdef is going on. */ | 1755 /* Avoid entering funcdef stuff if typdef is going on. */ |
1860 return FALSE; | 1759 return FALSE; |
1861 } | 1760 } |
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; |
1878 return FALSE; | 1777 return FALSE; |
1879 } | 1778 } |
1908 * C_entries () | 1807 * C_entries () |
1909 * This routine finds functions, typedefs, #define's and | 1808 * This routine finds functions, typedefs, #define's and |
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 */ |
1812 typedef 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) |
1916 #define newlb (lbs[newndx].lb) | 1825 #define newlb (lbs[newndx].lb) |
1917 #define curlinepos (lbs[curndx].linepos) | 1826 #define curlinepos (lbs[curndx].linepos) |
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 \ |
1931 do { \ | 1831 do { \ |
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; \ |
1936 quotednl = FALSE; \ | 1836 quotednl = FALSE; \ |
1937 newndx = curndx; \ | 1837 newndx = curndx; \ |
1938 } while (0) | 1838 } while (0) |
1939 | 1839 |
1940 #define CNL \ | 1840 #define CNL \ |
1941 do { \ | 1841 do { \ |
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 |
1953 void | 1856 void |
1954 C_entries (c_ext, inf) | 1857 C_entries (c_ext, inf) |
1955 int c_ext; /* extension of C */ | 1858 int c_ext; /* extension of C */ |
1956 FILE *inf; /* input file */ | 1859 FILE *inf; /* input file */ |
1957 { | 1860 { |
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; |
1976 lp = curlb.buffer; | 1877 lp = curlb.buffer; |
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; |
1984 cplpl = c_ext & C_PLPL; | 1885 cplpl = c_ext & C_PLPL; |
1985 | 1886 |
2141 } | 2042 } |
2142 else | 2043 else |
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 } |
2188 } /* if (endtoken (c)) */ | 2091 } /* if (endtoken (c)) */ |
2189 else if (intoken (c)) | 2092 else if (intoken (c)) |
2201 { | 2104 { |
2202 case fstartlist: | 2105 case fstartlist: |
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: |
2210 funcdef = fnone; | 2113 funcdef = fnone; |
2211 break; | 2114 break; |
2218 so we can avoid saving the token when not absolutely | 2121 so we can avoid saving the token when not absolutely |
2219 necessary. [This is a speed hack.] */ | 2122 necessary. [This is a speed hack.] */ |
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 } |
2227 else | 2131 else |
2228 definedef = dignorerest; | 2132 definedef = dignorerest; |
2252 switch (funcdef) | 2156 switch (funcdef) |
2253 { | 2157 { |
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; |
2261 case fstartlist: | 2165 case fstartlist: |
2262 funcdef = fnone; | 2166 funcdef = fnone; |
2268 break; | 2172 break; |
2269 if (cblev == 0) | 2173 if (cblev == 0) |
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; |
2277 } | 2181 } |
2278 if (funcdef != fignore) | 2182 if (funcdef != fignore) |
2292 if (definedef != dnone) | 2196 if (definedef != dnone) |
2293 break; | 2197 break; |
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) |
2301 funcdef = fnone; | 2205 funcdef = fnone; |
2302 if (structdef == stagseen) | 2206 if (structdef == stagseen) |
2316 This handles constructs like: | 2220 This handles constructs like: |
2317 typedef void OperatorFun (int fun); */ | 2221 typedef void OperatorFun (int fun); */ |
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) */ |
2325 break; | 2229 break; |
2326 case ftagseen: | 2230 case ftagseen: |
2345 break; | 2249 break; |
2346 } | 2250 } |
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. */ |
2354 parlev = 0; | 2258 parlev = 0; |
2355 break; | 2259 break; |
2359 if (typdef == ttypedseen) | 2263 if (typdef == ttypedseen) |
2360 typdef = tinbody; | 2264 typdef = tinbody; |
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; |
2380 break; | 2284 break; |
2381 case fnone: | 2285 case fnone: |
2403 cblev--; | 2307 cblev--; |
2404 if (cblev == 0) | 2308 if (cblev == 0) |
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 '=': |
2413 case '#': case '+': case '-': case '~': case '&': case '%': case '/': | 2321 case '#': case '+': case '-': case '~': case '&': case '%': case '/': |
2414 case '|': case '^': case '!': case '<': case '>': case '.': case '?': | 2322 case '|': case '^': case '!': case '<': case '>': case '.': case '?': |
2466 } | 2374 } |
2467 | 2375 |
2468 /* Fortran parsing */ | 2376 /* Fortran parsing */ |
2469 | 2377 |
2470 char *dbp; | 2378 char *dbp; |
2471 int pfcnt; | |
2472 | 2379 |
2473 logical | 2380 logical |
2474 tail (cp) | 2381 tail (cp) |
2475 char *cp; | 2382 char *cp; |
2476 { | 2383 { |
2511 void | 2418 void |
2512 getit (inf) | 2419 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++; |
2521 if (*dbp == '\0') | 2426 if (*dbp == '\0') |
2522 { | 2427 { |
2537 for (cp = dbp + 1; | 2442 for (cp = dbp + 1; |
2538 (*cp | 2443 (*cp |
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 |
2551 void | 2451 void |
2552 Fortran_functions (inf) | 2452 Fortran_functions (inf) |
2553 FILE *inf; | 2453 FILE *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 { |
2561 lineno++; | 2460 lineno++; |
2562 linecharno = charno; | 2461 linecharno = charno; |
2637 */ | 2536 */ |
2638 void | 2537 void |
2639 Asm_labels (inf) | 2538 Asm_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 { |
2652 lineno++; | 2548 lineno++; |
2653 linecharno = charno; | 2549 linecharno = charno; |
2663 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$') | 2559 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$') |
2664 cp++; | 2560 cp++; |
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 } |
2678 } | 2569 } |
2679 | 2570 |
2699 { | 2590 { |
2700 struct linebuffer tline; /* mostly copied from C_entries */ | 2591 struct linebuffer tline; /* mostly copied from C_entries */ |
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 */ |
2708 inquote, /* point is inside '..' string */ | 2599 inquote, /* point is inside '..' string */ |
2709 get_tagname, /* point is after PROCEDURE/FUNCTION */ | 2600 get_tagname, /* point is after PROCEDURE/FUNCTION */ |
2729 | 2620 |
2730 /* long main loop to get next char */ | 2621 /* long main loop to get next char */ |
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 { |
2747 if (c == '}') /* within { - } comments */ | 2638 if (c == '}') /* within { - } comments */ |
2748 incomment = FALSE; | 2639 incomment = FALSE; |
2757 { | 2648 { |
2758 if (c == '\'') | 2649 if (c == '\'') |
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 '\'': |
2766 inquote = TRUE; /* found first quote */ | 2657 inquote = TRUE; /* found first quote */ |
2767 continue; | 2658 continue; |
2812 } | 2703 } |
2813 if ((found_tag) && (verify_tag)) /* not external proc, so make tag */ | 2704 if ((found_tag) && (verify_tag)) /* not external proc, so make tag */ |
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 } |
2823 if (get_tagname) /* grab name of proc or fn */ | 2713 if (get_tagname) /* grab name of proc or fn */ |
2824 { | 2714 { |
2832 save_lcno = linecharno; | 2722 save_lcno = linecharno; |
2833 | 2723 |
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; |
2844 continue; | 2731 continue; |
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 | ' ') |
2852 { | 2739 { |
2853 case 'p': | 2740 case 'p': |
2863 } /* while not eof */ | 2750 } /* while not eof */ |
2864 } | 2751 } |
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 | |
2871 int | 2757 int |
2872 L_isdef (tokp) | 2758 L_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 |
2880 int | 2766 int |
2881 L_isquote (tokp) | 2767 L_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 |
2892 void | 2778 void |
2893 L_getit () | 2779 L_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++; |
2901 else if (*dbp == '(' && L_isquote (dbp)) /* Skip "(quote " */ | 2785 else if (*dbp == '(' && L_isquote (dbp)) /* Skip "(quote " */ |
2902 { | 2786 { |
2903 dbp += 7; | 2787 dbp += 7; |
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 |
2921 void | 2802 void |
2922 Lisp_functions (inf) | 2803 Lisp_functions (inf) |
2923 FILE *inf; | 2804 FILE *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 { |
2931 lineno++; | 2811 lineno++; |
2932 linecharno = charno; | 2812 linecharno = charno; |
2983 Scheme_functions (inf) | 2863 Scheme_functions (inf) |
2984 FILE *inf; | 2864 FILE *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 { |
2992 lineno++; | 2871 lineno++; |
2993 linecharno = charno; | 2872 linecharno = charno; |
3024 | 2903 |
3025 void | 2904 void |
3026 get_scheme () | 2905 get_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. */ |
3050 | 2921 |
3051 /* TEX_toktab is a table of TeX control sequences that define tags. | 2922 /* TEX_toktab is a table of TeX control sequences that define tags. |
3083 { | 2954 { |
3084 char *lasthit; | 2955 char *lasthit; |
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); |
3092 | 2962 |
3093 /* Initialize token table once from environment. */ | 2963 /* Initialize token table once from environment. */ |
3214 TEX_getit (name, len) | 3084 TEX_getit (name, len) |
3215 char *name; | 3085 char *name; |
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; |
3223 | 3092 |
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, |
3235 return the pointer to the first occurrence of that command in TEX_toktab. | 3101 return the pointer to the first occurrence of that command in TEX_toktab. |
3236 Otherwise return -1. | 3102 Otherwise return -1. |
3254 is gotten in compound term. */ | 3120 is gotten in compound term. */ |
3255 void | 3121 void |
3256 prolog_getit (s) | 3122 prolog_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; |
3263 insquote = FALSE; | 3129 insquote = FALSE; |
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++; |
3285 if (npar == 0) | 3151 if (npar == 0) |
3286 break; | 3152 break; |
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; |
3294 s++; | 3161 s++; |
3295 break; | 3162 break; |
3296 } | 3163 } |
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. */ |
3308 void | 3172 void |
3309 Prolog_functions (inf) | 3173 Prolog_functions (inf) |
3662 charno += readline (&lb, inf) + 1; | 3526 charno += readline (&lb, inf) + 1; |
3663 } | 3527 } |
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 */ | |
3667 char * | 3535 char * |
3668 savestr (cp) | 3536 savestr (cp) |
3669 char *cp; | 3537 char *cp; |
3670 { | 3538 { |
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 */ | |
3674 char * | 3546 char * |
3675 savenstr (cp, len) | 3547 savenstr (cp, len) |
3676 char *cp; | 3548 char *cp; |
3677 int len; | 3549 int len; |
3678 { | 3550 { |