eustags.c
Go to the documentation of this file.
1 /* Tags file maker to go with GNUmacs
2  Copyright (C) 1984, 1987, 1988 Free Software Foundation, Inc. and Ken Arnold
3 
4  NO WARRANTY
5 
6  BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
7 NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
8 WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
9 RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
10 WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
11 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
12 FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
13 AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
14 DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
15 CORRECTION.
16 
17  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
18 STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
19 WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
20 LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
21 OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
22 USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
23 DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
24 A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
25 PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
26 DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
27 
28  GENERAL PUBLIC LICENSE TO COPY
29 
30  1. You may copy and distribute verbatim copies of this source file
31 as you receive it, in any medium, provided that you conspicuously
32 and appropriately publish on each copy a valid copyright notice
33 "Copyright (C) 1986 Free Software Foundation"; and include
34 following the copyright notice a verbatim copy of the above disclaimer
35 of warranty and of this License.
36 
37  2. You may modify your copy or copies of this source file or
38 any portion of it, and copy and distribute such modifications under
39 the terms of Paragraph 1 above, provided that you also do the following:
40 
41  a) cause the modified files to carry prominent notices stating
42  that you changed the files and the date of any change; and
43 
44  b) cause the whole of any work that you distribute or publish,
45  that in whole or in part contains or is a derivative of this
46  program or any part thereof, to be licensed at no charge to all
47  third parties on terms identical to those contained in this
48  License Agreement (except that you may choose to grant more extensive
49  warranty protection to some or all third parties, at your option).
50 
51  c) You may charge a distribution fee for the physical act of
52  transferring a copy, and you may at your option offer warranty
53  protection in exchange for a fee.
54 
55 Mere aggregation of another unrelated program with this program (or its
56 derivative) on a volume of a storage or distribution medium does not bring
57 the other program under the scope of these terms.
58 
59  3. You may copy and distribute this program (or a portion or derivative
60 of it, under Paragraph 2) in object code or executable form under the terms
61 of Paragraphs 1 and 2 above provided that you also do one of the following:
62 
63  a) accompany it with the complete corresponding machine-readable
64  source code, which must be distributed under the terms of
65  Paragraphs 1 and 2 above; or,
66 
67  b) accompany it with a written offer, valid for at least three
68  years, to give any third party free (except for a nominal
69  shipping charge) a complete machine-readable copy of the
70  corresponding source code, to be distributed under the terms of
71  Paragraphs 1 and 2 above; or,
72 
73  c) accompany it with the information you received as to where the
74  corresponding source code may be obtained. (This alternative is
75  allowed only for noncommercial distribution and only if you
76  received the program in object code or executable form alone.)
77 
78 For an executable file, complete source code means all the source code for
79 all modules it contains; but, as a special exception, it need not include
80 source code for modules which are standard libraries that accompany the
81 operating system on which the executable file runs.
82 
83  4. You may not copy, sublicense, distribute or transfer this program
84 except as expressly provided under this License Agreement. Any attempt
85 otherwise to copy, sublicense, distribute or transfer this program is void and
86 your rights to use the program under this License agreement shall be
87 automatically terminated. However, parties who have received computer
88 software programs from you with this License Agreement will not have
89 their licenses terminated so long as such parties remain in full compliance.
90 
91 In other words, you are welcome to use, share and improve this program.
92 You are forbidden to forbid anyone else to use, share and improve
93 what you give them. Help stamp out software-hoarding! */
94 
95 #include <stdio.h>
96 #include <ctype.h>
97 
98 /* Define the symbol ETAGS to make the program "etags",
99  which makes emacs-style tag tables by default.
100  Define CTAGS to make the program "ctags" compatible with the usual one.
101  Define neither one to get behavior that depends
102  on the name with which the program is invoked
103  (but we don't normally compile it that way). */
104 
105 /* On VMS, CTAGS is not useful, so always do ETAGS. */
106 #ifdef VMS
107 #ifndef ETAGS
108 #define ETAGS
109 #endif
110 #endif
111 
112 /* Exit codes for success and failure. */
113 
114 #ifdef VMS
115 #define GOOD (1)
116 #define BAD (0)
117 #else
118 #define GOOD (0)
119 #define BAD (1)
120 #endif
121 
122 #define reg register
123 #define logical char
124 
125 #define TRUE (1)
126 #define FALSE (0)
127 
128 #define iswhite(arg) (_wht[arg]) /* T if char is white */
129 #define begtoken(arg) (_btk[arg]) /* T if char can start token */
130 #define intoken(arg) (_itk[arg]) /* T if char can be in token */
131 #define endtoken(arg) (_etk[arg]) /* T if char ends tokens */
132 #define isgood(arg) (_gd[arg]) /* T if char can be after ')' */
133 
134 #define max(I1,I2) (I1 > I2 ? I1 : I2)
135 
136 /* cause token checking for typedef, struct, union, enum to distinguish
137  keywords from identifier-prefixes (e.g. struct vs struct_tag). */
138 #define istoken(s, tok, len) (!strncmp(s,tok,len) && endtoken(*((s)+(len))))
139 
140 struct nd_st { /* sorting structure */
141  char *name; /* function or type name */
142  char *file; /* file name */
143  logical f; /* use pattern or line no */
144  int lno; /* line number tag is on */
145  long cno; /* character number line starts on */
146  char *pat; /* search pattern */
147  logical been_warned; /* set if noticed dup */
148  struct nd_st *left,*right; /* left and right sons */
149 };
150 
151 long ftell();
152 typedef struct nd_st NODE;
153 
154 int number; /* tokens found so far on line starting with # (including #) */
155 logical gotone, /* found a func already on line */
156  /* boolean "func" (see init) */
157  _wht[0177],_etk[0177],_itk[0177],_btk[0177],_gd[0177];
158 
159  /* typedefs are recognized using a simple finite automata,
160  * tydef is its state variable.
161  */
162 typedef enum {none, begin, tag_ok, middle, end } TYST;
163 
165 
166 char searchar = '/'; /* use /.../ searches */
167 
168 int lineno; /* line number of current line */
169 long charno; /* current character number */
170 long linecharno; /* character number of start of line */
171 
172 char *curfile, /* current input file name */
173  *outfile= 0, /* output file */
174  *white = " \f\t\n", /* white chars */
175  *endtk = " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?",
176  /* token ending chars */
177  *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$",
178  /* token starting chars */
179  *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789",
180  /* valid in-token chars */
181  *notgd = ",;"; /* non-valid after-function chars */
182 
183 int file_num = 0; /* current file number */
184 int aflag = 0; /* -a: append to tags */
185 int tflag = 0; /* -t: create tags for typedefs */
186 int uflag = 0; /* -u: update tags */
187 int wflag = 0; /* -w: suppress warnings */
188 int vflag = 0; /* -v: create vgrind style index output */
189 int xflag = 0; /* -x: create cxref style output */
190 int eflag = 0; /* -e: emacs style output */
191 
192 /* Name this program was invoked with. */
193 char *progname;
194 
195 FILE *inf, /* ioptr for current input file */
196  *outf; /* ioptr for tags file */
197 
198 NODE *head; /* the head of the sorted binary tree */
199 
200 char *savestr();
201 char *savenstr ();
202 // char *rindex();
203 //char *index();
204 char *concat ();
205 void initbuffer ();
206 long readline ();
207 
208 /* A `struct linebuffer' is a structure which holds a line of text.
209  `readline' reads a line from a stream into a linebuffer
210  and works regardless of the length of the line. */
211 
213  {
214  long size;
215  char *buffer;
216  };
217 
218 struct linebuffer lb, lb1;
219 
220 #if 0 /* VMS now provides the `system' function. */
221 #ifdef VMS
222 
223 #include <descrip.h>
224 
225 void
226 system (buf)
227  char *buf;
228 {
229  struct dsc$descriptor_s command =
230  {
231  strlen(buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf
232  };
233 
234  LIB$SPAWN(&command);
235 }
236 #endif /* VMS */
237 #endif /* 0 */
238 
239 main(ac,av)
240  int ac;
241  char *av[];
242 {
243  char cmd[100];
244  int i;
245  int fflag = 0;
246  char *this_file;
247 #ifdef VMS
248  char got_err;
249 
250  extern char *gfnames();
251  extern char *massage_name();
252 #endif
253 
254  progname = av[0];
255 
256 #ifdef ETAGS
257  eflag = 1;
258 #else
259 #ifdef CTAGS
260  eflag = 0;
261 #else
262  {
263  char *subname = rindex (progname, '/');
264  if (subname++ == NULL)
265  subname = progname;
266  eflag = ! strcmp(subname, "ctags");
267  }
268 #endif
269 #endif
270 
271  while (ac > 1 && av[1][0] == '-')
272  {
273  for (i=1; av[1][i]; i++)
274  {
275  switch(av[1][i])
276  {
277 #ifndef VMS /* These options are useful only with ctags,
278  and VMS can't input them, so just omit them. */
279  case 'B':
280  searchar='?';
281  eflag = 0;
282  break;
283  case 'F':
284  searchar='/';
285  eflag = 0;
286  break;
287 #endif
288  case 'a':
289  aflag++;
290  break;
291  case 'e':
292  eflag++;
293  break;
294  case 'f':
295  if (fflag > 0)
296  {
297  fprintf(stderr,
298  "%s: -f flag may only be given once\n", progname);
299  goto usage;
300  }
301  fflag++, ac--; av++;
302  if (ac <= 1 || av[1][0] == '\0')
303  {
304  fprintf(stderr,
305  "%s: -f flag must be followed by a filename\n",
306  progname);
307  goto usage;
308  }
309  outfile = av[1];
310  goto end_loop;
311  case 't':
312  tflag++;
313  break;
314 #ifndef VMS
315  case 'u':
316  uflag++;
317  eflag = 0;
318  break;
319 #endif
320  case 'w':
321  wflag++;
322  break;
323  case 'v':
324  vflag++;
325  xflag++;
326  eflag = 0;
327  break;
328  case 'x':
329  xflag++;
330  eflag = 0;
331  break;
332  default:
333  goto usage;
334  }
335  }
336  end_loop: ;
337  ac--; av++;
338  }
339 
340  if (ac <= 1)
341  {
342  usage:
343 #ifdef VMS
344  fprintf (stderr, "Usage: %s [-aetwvx] [-f outfile] file ...\n", progname);
345 #else
346  fprintf (stderr, "Usage: %s [-BFaetuwvx] [-f outfile] file ...\n", progname);
347 #endif
348  exit(BAD);
349  }
350 
351  if (outfile == 0)
352  {
353  outfile = eflag ? "TAGS" : "tags";
354  }
355 
356  init(); /* set up boolean "functions" */
357 
358  initbuffer (&lb);
359  initbuffer (&lb1);
360  /*
361  * loop through files finding functions
362  */
363  if (eflag)
364  {
365  outf = fopen (outfile, aflag ? "a" : "w");
366  if (!outf)
367  {
368  fprintf (stderr, "%s: ", progname);
369  perror (outfile);
370  exit (BAD);
371  }
372  }
373 
374  file_num = 1;
375 #ifdef VMS
376  for (ac--, av++;
377  (this_file = gfnames (&ac, &av, &got_err)) != NULL; file_num++)
378  {
379  if (got_err)
380  {
381  error("Can't find file %s\n", this_file);
382  ac--, av++;
383  }
384  else
385  {
386  this_file = massage_name (this_file);
387 #else
388  for (; file_num < ac; file_num++)
389  {
390  this_file = av[file_num];
391  if (1)
392  {
393 #endif
394  find_entries (this_file);
395  if (eflag)
396  {
397  fprintf (outf, "\f\n%s,%d\n",
398  this_file, total_size_of_entries (head));
399  put_entries (head);
400  free_tree (head);
401  head = NULL;
402  }
403  }
404  }
405 
406  if (eflag)
407  {
408  fclose (outf);
409  exit (GOOD);
410  }
411 
412  if (xflag)
413  {
414  put_entries(head);
415  exit(GOOD);
416  }
417  if (uflag)
418  {
419  for (i=1; i<ac; i++)
420  {
421  sprintf(cmd,
422  "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
423  outfile, av[i], outfile);
424  system(cmd);
425  }
426  aflag++;
427  }
428  outf = fopen(outfile, aflag ? "a" : "w");
429  if (outf == NULL)
430  {
431  fprintf (stderr, "%s: ", outfile);
432  perror(outfile);
433  exit(BAD);
434  }
435  put_entries(head);
436  fclose(outf);
437 #ifndef VMS
438  if (uflag)
439  {
440  sprintf(cmd, "sort %s -o %s", outfile, outfile);
441  system(cmd);
442  }
443 #endif
444  exit(GOOD);
445 }
446 
447 /*
448  * This routine sets up the boolean psuedo-functions which work
449  * by seting boolean flags dependent upon the corresponding character
450  * Every char which is NOT in that string is not a white char. Therefore,
451  * all of the array "_wht" is set to FALSE, and then the elements
452  * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
453  * of a char is TRUE if it is the string "white", else FALSE.
454  */
456 {
457 
458  reg char *sp;
459  reg int i;
460 
461  for (i = 0; i < 0177; i++)
462  {
463  _wht[i] = _etk[i] = _itk[i] = _btk[i] = FALSE;
464  _gd[i] = TRUE;
465  }
466  for (sp = white; *sp; sp++)
467  _wht[*sp] = TRUE;
468  for (sp = endtk; *sp; sp++)
469  _etk[*sp] = TRUE;
470  for (sp = intk; *sp; sp++)
471  _itk[*sp] = TRUE;
472  for (sp = begtk; *sp; sp++)
473  _btk[*sp] = TRUE;
474  for (sp = notgd; *sp; sp++)
475  _gd[*sp] = FALSE;
476  _wht[0] = _wht['\n'];
477  _etk[0] = _etk['\n'];
478  _btk[0] = _btk['\n'];
479  _itk[0] = _itk['\n'];
480  _gd[0] = _gd['\n'];
481 }
482 
483 /*
484  * This routine opens the specified file and calls the function
485  * which finds the function and type definitions.
486  */
488  char *file;
489 {
490  char *cp;
491 
492  if ((inf=fopen(file,"r")) == NULL)
493  {
494  fprintf (stderr, "%s: ", progname);
495  perror(file);
496  return;
497  }
498  curfile = savestr(file);
499  cp = rindex(file, '.');
500  /* .tex, .aux or .bbl implies LaTeX source code */
501  if (cp && (!strcmp (cp + 1, "tex") || !strcmp (cp + 1, "aux")
502  || !strcmp (cp + 1, "bbl")))
503  {
504  TEX_funcs(inf);
505  fclose(inf);
506  return;
507  }
508  /* .l or .el or .lisp (or .cl or .clisp or ...) implies lisp source code */
509  if (cp && (!strcmp (cp + 1, "l") ||
510  !strcmp (cp + 1, "el") ||
511  !strcmp (cp + 1, "lsp") ||
512  !strcmp (cp + 1, "lisp") ||
513  !strcmp (cp + 1, "cl") ||
514  !strcmp (cp + 1, "clisp")))
515  {
516  L_funcs(inf);
517  fclose(inf);
518  return;
519  }
520  /* .scm or .sm or .scheme implies scheme source code */
521  if (cp && (!strcmp (cp + 1, "sm")
522  || !strcmp (cp + 1, "scm")
523  || !strcmp (cp + 1, "scheme")
524  || !strcmp (cp + 1, "t")
525  || !strcmp (cp + 1, "sch")
526  || !strcmp (cp + 1, "SM")
527  || !strcmp (cp + 1, "SCM")
528  /* The `SCM' or `scm' prefix with a version number */
529  || (cp[-1] == 'm' && cp[-2] == 'c' && cp[-3] == 's')
530  || (cp[-1] == 'M' && cp[-2] == 'C' && cp[-3] == 'S')))
531  {
532  Scheme_funcs(inf);
533  fclose(inf);
534  return;
535  }
536  /* if not a .c or .h or .y file, try fortran */
537  if (cp && (cp[1] != 'c' && cp[1] != 'h' && cp[1] != 'y')
538  && cp[2] == '\0')
539  {
540  if (PF_funcs(inf) != 0)
541  {
542  fclose(inf);
543  return;
544  }
545  rewind(inf); /* no fortran tags found, try C */
546  }
547  C_entries();
548  fclose(inf);
549 }
550 
551 /* Record a tag on the current line.
552  name is the tag name,
553  f is nonzero to use a pattern, zero to use line number instead. */
554 
555 pfnote (name, f, linestart, linelen, lno, cno)
556  char *name;
557  logical f; /* f == TRUE when function */
558  char *linestart;
559  int linelen;
560  int lno;
561  long cno;
562 {
563  register char *fp;
564  register NODE *np;
565  char *altname;
566  char tem[51];
567 
568  if ((np = (NODE *) malloc (sizeof (NODE))) == NULL)
569  {
570  fprintf(stderr, "%s: too many entries to sort\n", progname);
571  put_entries(head);
572  free_tree(head);
573  head = NULL;
574  np = (NODE *) xmalloc(sizeof (NODE));
575  }
576  /* Change name "main" to M<thisfilename>. */
577  if (!eflag && !xflag && !strcmp(name, "main"))
578  {
579  fp = rindex(curfile, '/');
580  if (fp == 0)
581  fp = curfile;
582  else
583  fp++;
584  altname = concat ("M", fp, "");
585  fp = rindex(altname, '.');
586  if (fp && fp[2] == 0)
587  *fp = 0;
588  name = altname;
589  }
590  np->name = savestr(name);
591  np->file = curfile;
592  np->f = f;
593  np->lno = lno;
594  np->cno = cno;
595  np->left = np->right = 0;
596  if (eflag)
597  {
598  linestart[linelen] = 0;
599  }
600  else if (xflag == 0)
601  {
602  sprintf (tem, strlen (linestart) < 50 ? "%s$" : "%.50s", linestart);
603  linestart = tem;
604  }
605  np->pat = savestr (linestart);
606  if (head == NULL)
607  head = np;
608  else
609  add_node(np, head);
610 }
611 
613  NODE *node;
614 {
615  while (node)
616  {
617  free_tree(node->right);
618  free(node);
619  node = node->left;
620  }
621 }
622 
623 add_node(node, cur_node)
624  NODE *node,*cur_node;
625 {
626  register int dif;
627 
628  dif = strcmp(node->name, cur_node->name);
629 
630  /* If this tag name matches an existing one, then
631  unless -e was given, do not add the node, but maybe print a warning */
632  if (!eflag && !dif)
633  {
634  if (node->file == cur_node->file)
635  {
636  if (!wflag)
637  {
638  fprintf(stderr,"%s: Duplicate entry in file %s, line %d: %s\n",
639  progname, node->file,lineno,node->name);
640  fprintf(stderr,"Second entry ignored\n");
641  }
642  return;
643  }
644  if (!cur_node->been_warned)
645  if (!wflag)
646  fprintf(stderr,"%s: Duplicate entry in files %s and %s: %s (Warning only)\n",
647  progname, node->file, cur_node->file, node->name);
648  cur_node->been_warned = TRUE;
649  return;
650  }
651 
652  /* Actually add the node */
653  if (dif < 0)
654  {
655  if (cur_node->left != NULL)
656  add_node(node,cur_node->left);
657  else
658  cur_node->left = node;
659  return;
660  }
661  if (cur_node->right != NULL)
662  add_node(node,cur_node->right);
663  else
664  cur_node->right = node;
665 }
666 
668  reg NODE *node;
669 {
670  reg char *sp;
671 
672  if (node == NULL)
673  return;
674 
675  /* Output subentries that precede this one */
676  put_entries (node->left);
677 
678  /* Output this entry */
679 
680  if (eflag)
681  {
682  fprintf (outf, "%s%c%d,%d\n",
683  node->pat, 0177, node->lno, node->cno);
684  }
685  else if (!xflag)
686  {
687  fprintf (outf, "%s\t%s\t",
688  node->name, node->file);
689 
690  if (node->f)
691  { /* a function */
692  putc (searchar, outf);
693  putc ('^', outf);
694 
695  for (sp = node->pat; *sp; sp++)
696  {
697  if (*sp == '\\' || *sp == searchar)
698  putc ('\\', outf);
699  putc (*sp, outf);
700  }
701  putc (searchar, outf);
702  }
703  else
704  { /* a typedef; text pattern inadequate */
705  fprintf (outf, "%d", node->lno);
706  }
707  putc ('\n', outf);
708  }
709  else if (vflag)
710  fprintf (stdout, "%s %s %d\n",
711  node->name, node->file, (node->lno+63)/64);
712  else
713  fprintf (stdout, "%-16s%4d %-16s %s\n",
714  node->name, node->lno, node->file, node->pat);
715 
716  /* Output subentries that follow this one */
717  put_entries (node->right);
718 }
719 
720 /* Return total number of characters that put_entries will output for
721  the nodes in the subtree of the specified node.
722  Works only if eflag is set, but called only in that case. */
723 
725  reg NODE *node;
726 {
727  reg int total = 0;
728  reg long num;
729 
730  if (node == NULL)
731  return 0;
732 
733  /* Count subentries that precede this one */
734  total = total_size_of_entries (node->left);
735 
736  /* Count subentries that follow this one */
737  total += total_size_of_entries (node->right);
738 
739  /* Count this entry */
740 
741  total += strlen (node->pat) + 3;
742 
743  num = node->lno;
744  while (num)
745  {
746  total++;
747  num /= 10;
748  }
749 
750  num = node->cno;
751  if (!num) total++;
752  while (num)
753  {
754  total++;
755  num /= 10;
756  }
757  return total;
758 }
759 
760 /*
761  * This routine finds functions and typedefs in C syntax and adds them
762  * to the list.
763  */
764 #ifdef VMS
765 long vmslinecharno;
766 #define VMS_SET_LINECHARNO (vmslinecharno = ftell(inf))
767 #else
768 #define VMS_SET_LINECHARNO
769 #endif
770 
771 #define CNL_SAVE_NUMBER \
772 { \
773  VMS_SET_LINECHARNO; \
774  linecharno = charno; lineno++; \
775  charno += 1 + readline (&lb, inf); \
776  lp = lb.buffer; \
777 }
778 
779 #define CNL \
780 { \
781  CNL_SAVE_NUMBER; \
782  number = 0; \
783 }
784 
786 {
787  register int c;
788  register char *token, *tp, *lp;
789  logical incomm, inquote, inchar, midtoken;
790  int level;
791  char tok[BUFSIZ];
792 
793  lineno = 0;
794  charno = 0;
795  lp = lb.buffer;
796  *lp = 0;
797 
798  number = 0;
799  gotone = midtoken = inquote = inchar = incomm = FALSE;
800  level = 0;
801 
802  while (!feof (inf))
803  {
804  c = *lp++;
805  if (c == 0)
806  {
807  CNL;
808  gotone = FALSE;
809  }
810  if (c == '\\')
811  {
812  c = *lp++;
813  if (c == 0)
815  c = ' ';
816  }
817  else if (incomm)
818  {
819  if (c == '*')
820  {
821  while ((c = *lp++) == '*')
822  continue;
823  if (c == 0)
824  CNL;
825  if (c == '/')
826  incomm = FALSE;
827  }
828  }
829  else if (inquote)
830  {
831  /*
832  * Too dumb to know about \" not being magic, but
833  * they usually occur in pairs anyway.
834  */
835  if (c == '"')
836  inquote = FALSE;
837  continue;
838  }
839  else if (inchar)
840  {
841  if (c == '\'')
842  inchar = FALSE;
843  continue;
844  }
845  else switch (c)
846  {
847  case '"':
848  inquote = TRUE;
849  continue;
850  case '\'':
851  inchar = TRUE;
852  continue;
853  case '/':
854  if (*lp == '*')
855  {
856  lp++;
857  incomm = TRUE;
858  }
859  continue;
860  case '#':
861  if (lp == lb.buffer + 1)
862  number = 1;
863  continue;
864  case '{':
865  if (tydef == tag_ok)
866  {
867  tydef=middle;
868  }
869  level++;
870  continue;
871  case '}':
872  if (lp == lb.buffer + 1)
873  level = 0; /* reset */
874  else
875  level--;
876  if (!level && tydef==middle)
877  {
878  tydef=end;
879  }
880  continue;
881  }
882  if (!level && !inquote && !incomm && gotone == FALSE)
883  {
884  if (midtoken)
885  {
886  if (endtoken(c))
887  {
888  int f;
889  char *buf = lb.buffer;
890  int endpos = lp - lb.buffer;
891  char *lp1 = lp;
892  int line = lineno;
893  long linestart = linecharno;
894 #ifdef VMS
895  long vmslinestart = vmslinecharno;
896 #endif
897  int tem = consider_token (&lp1, token, &f, level);
898  lp = lp1;
899  if (tem)
900  {
901  if (linestart != linecharno)
902  {
903 #ifdef VMS
904  getline (vmslinestart);
905 #else
906  getline (linestart);
907 #endif
908  strncpy (tok, token + (lb1.buffer - buf),
909  tp-token+1);
910  tok[tp-token+1] = 0;
911  pfnote(tok, f, lb1.buffer, endpos, line, linestart);
912  }
913  else
914  {
915  strncpy (tok, token, tp-token+1);
916  tok[tp-token+1] = 0;
917  pfnote(tok, f, lb.buffer, endpos, line, linestart);
918  }
919  gotone = f; /* function */
920  }
921  midtoken = FALSE;
922  token = lp - 1;
923  }
924  else if (intoken(c))
925  tp++;
926  }
927  else if (begtoken(c))
928  {
929  token = tp = lp - 1;
930  midtoken = TRUE;
931  }
932  }
933  if (c == ';' && tydef==end) /* clean with typedefs */
934  tydef=none;
935  }
936 }
937 
938 /*
939  * This routine checks to see if the current token is
940  * at the start of a function, or corresponds to a typedef
941  * It updates the input line * so that the '(' will be
942  * in it when it returns.
943  */
944 consider_token (lpp, token, f, level)
945  char **lpp, *token;
946  int *f, level;
947 {
948  reg char *lp = *lpp;
949  reg char c;
950  static logical next_token_is_func;
951  logical firsttok; /* T if have seen first token in ()'s */
952  int bad, win;
953 
954  *f = 1; /* a function */
955  c = lp[-1];
956  bad = FALSE;
957  if (!number)
958  { /* space is not allowed in macro defs */
959  while (iswhite(c))
960  {
961  c = *lp++;
962  if (c == 0)
963  {
964  if (feof (inf))
965  break;
966  CNL;
967  }
968  }
969  /* the following tries to make it so that a #define a b(c) */
970  /* doesn't count as a define of b. */
971  }
972  else
973  {
974  number++;
975  if (number >= 4 || (number==2 && strncmp (token, "define", 6)))
976  {
977  gotone = TRUE;
978  badone:
979  bad = TRUE;
980  goto ret;
981  }
982  }
983  /* check for the typedef cases */
984  if (tflag && istoken(token, "typedef", 7))
985  {
986  tydef=begin;
987  goto badone;
988  }
989  if (tydef==begin && (istoken(token, "struct", 6) ||
990  istoken(token, "union", 5) || istoken(token, "enum", 4)))
991  {
992  tydef=tag_ok;
993  goto badone;
994  }
995  if (tydef==tag_ok)
996  {
997  tydef=middle;
998  goto badone;
999  }
1000  if (tydef==begin) /* e.g. typedef ->int<- */
1001  {
1002  tydef=end;
1003  goto badone;
1004  }
1005  if (tydef==middle && level == 0) /* e.g. typedef struct tag ->struct_t<- */
1006  {
1007  tydef=end;
1008  }
1009  if (tydef==end)
1010  {
1011  *f = 0;
1012  win = 1;
1013  goto ret;
1014  }
1015  /* Detect GNUmacs's function-defining macros. */
1016  if (!number && !strncmp (token, "DEF", 3))
1017 
1018  {
1019  next_token_is_func = 1;
1020  goto badone;
1021  }
1022  if (next_token_is_func)
1023  {
1024  next_token_is_func = 0;
1025  win = 1;
1026  goto ret;
1027  }
1028  if (c != '(')
1029  goto badone;
1030  firsttok = FALSE;
1031  while ((c = *lp++) != ')')
1032  {
1033  if (c == 0)
1034  {
1035  if (feof (inf))
1036  break;
1037  CNL;
1038  }
1039  /*
1040  * This line used to confuse ctags:
1041  * int (*oldhup)();
1042  * This fixes it. A nonwhite char before the first
1043  * token, other than a / (in case of a comment in there)
1044  * makes this not a declaration.
1045  */
1046  if (begtoken(c) || c=='/') firsttok++;
1047  else if (!iswhite(c) && !firsttok) goto badone;
1048  }
1049  while (iswhite (c = *lp++))
1050  {
1051  if (c == 0)
1052  {
1053  if (feof (inf))
1054  break;
1055  CNL;
1056  }
1057  }
1058  win = isgood (c);
1059 ret:
1060  *lpp = lp - 1;
1061  return !bad && win;
1062 }
1063 
1064 getline (atchar)
1065  long atchar;
1066 {
1067  long saveftell = ftell (inf);
1068 
1069  fseek (inf, atchar, 0);
1070  readline (&lb1, inf);
1071  fseek (inf, saveftell, 0);
1072 }
1073 
1074 /* Fortran parsing */
1075 
1076 char *dbp;
1077 int pfcnt;
1078 
1080  FILE *fi;
1081 {
1082  lineno = 0;
1083  charno = 0;
1084  pfcnt = 0;
1085 
1086  while (!feof (fi))
1087  {
1088  lineno++;
1089  linecharno = charno;
1090  charno += readline (&lb, fi) + 1;
1091  dbp = lb.buffer;
1092  if (*dbp == '%') dbp++ ; /* Ratfor escape to fortran */
1093  while (isspace(*dbp))
1094  dbp++;
1095  if (*dbp == 0)
1096  continue;
1097  switch (*dbp |' ')
1098  {
1099  case 'i':
1100  if (tail("integer"))
1101  takeprec();
1102  break;
1103  case 'r':
1104  if (tail("real"))
1105  takeprec();
1106  break;
1107  case 'l':
1108  if (tail("logical"))
1109  takeprec();
1110  break;
1111  case 'c':
1112  if (tail("complex") || tail("character"))
1113  takeprec();
1114  break;
1115  case 'd':
1116  if (tail("double"))
1117  {
1118  while (isspace(*dbp))
1119  dbp++;
1120  if (*dbp == 0)
1121  continue;
1122  if (tail("precision"))
1123  break;
1124  continue;
1125  }
1126  break;
1127  }
1128  while (isspace(*dbp))
1129  dbp++;
1130  if (*dbp == 0)
1131  continue;
1132  switch (*dbp|' ')
1133  {
1134  case 'f':
1135  if (tail("function"))
1136  getit();
1137  continue;
1138  case 's':
1139  if (tail("subroutine"))
1140  getit();
1141  continue;
1142  case 'p':
1143  if (tail("program"))
1144  {
1145  getit();
1146  continue;
1147  }
1148  if (tail("procedure"))
1149  getit();
1150  continue;
1151  }
1152  }
1153  return (pfcnt);
1154 }
1155 
1156 tail(cp)
1157  char *cp;
1158 {
1159  register int len = 0;
1160 
1161  while (*cp && (*cp&~' ') == ((*(dbp+len))&~' '))
1162  cp++, len++;
1163  if (*cp == 0)
1164  {
1165  dbp += len;
1166  return (1);
1167  }
1168  return (0);
1169 }
1170 
1172 {
1173  while (isspace(*dbp))
1174  dbp++;
1175  if (*dbp != '*')
1176  return;
1177  dbp++;
1178  while (isspace(*dbp))
1179  dbp++;
1180  if (!isdigit(*dbp))
1181  {
1182  --dbp; /* force failure */
1183  return;
1184  }
1185  do
1186  dbp++;
1187  while (isdigit(*dbp));
1188 }
1189 
1191 {
1192  register char *cp;
1193  char c;
1194  char nambuf[BUFSIZ];
1195 
1196  while (isspace(*dbp))
1197  dbp++;
1198  if (*dbp == 0 || !isalpha(*dbp))
1199  return;
1200  for (cp = dbp+1; *cp && (isalpha(*cp) || isdigit(*cp)); cp++)
1201  continue;
1202  c = cp[0];
1203  cp[0] = 0;
1204  strcpy(nambuf, dbp);
1205  cp[0] = c;
1206  pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
1207  pfcnt++;
1208 }
1209 
1210 /*
1211  * lisp tag functions
1212  * just look for (def or (DEF
1213  */
1214 
1216  FILE *fi;
1217 {
1218  lineno = 0;
1219  charno = 0;
1220  pfcnt = 0;
1221 
1222  while (!feof (fi))
1223  {
1224  lineno++;
1225  linecharno = charno;
1226  charno += readline (&lb, fi) + 1;
1227  dbp = lb.buffer;
1228  while (isspace(*dbp)) dbp++;
1229  if (dbp[0] == '(' &&
1230  (dbp[1] == 'D' || dbp[1] == 'd') &&
1231  (dbp[2] == 'E' || dbp[2] == 'e') &&
1232  (dbp[3] == 'F' || dbp[3] == 'f'))
1233  {
1234  while (!isspace(*dbp)) dbp++;
1235  while (isspace(*dbp)) dbp++;
1236  L_getit();
1237  }
1238  if (dbp[0] == '(' &&
1239  (dbp[1] == ':'))
1240  {
1241  while (!isspace(*dbp)) dbp++;
1242  while (isspace(*dbp)) dbp++;
1243  L_getit();
1244  }
1245 
1246  }
1247 }
1248 
1250 {
1251  register char *cp;
1252  char c;
1253  char nambuf[BUFSIZ];
1254 
1255  if (*dbp == 0) return;
1256  for (cp = dbp+1; *cp && *cp != '(' && *cp != ' '; cp++)
1257  continue;
1258  c = cp[0];
1259  cp[0] = 0;
1260  strcpy(nambuf, dbp);
1261  cp[0] = c;
1262  pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
1263  pfcnt++;
1264 }
1265 
1266 /*
1267  * Scheme tag functions
1268  * look for (def... xyzzy
1269  * look for (def... (xyzzy
1270  * look for (def ... ((...(xyzzy ....
1271  * look for (set! xyzzy
1272  */
1273 
1274 static get_scheme ();
1276  FILE *fi;
1277 {
1278  lineno = 0;
1279  charno = 0;
1280  pfcnt = 0;
1281 
1282  while (!feof (fi))
1283  {
1284  lineno++;
1285  linecharno = charno;
1286  charno += readline (&lb, fi) + 1;
1287  dbp = lb.buffer;
1288  if (dbp[0] == '(' &&
1289  (dbp[1] == 'D' || dbp[1] == 'd') &&
1290  (dbp[2] == 'E' || dbp[2] == 'e') &&
1291  (dbp[3] == 'F' || dbp[3] == 'f'))
1292  {
1293  while (!isspace(*dbp)) dbp++;
1294  /* Skip over open parens and white space */
1295  while (*dbp && (isspace(*dbp) || *dbp == '(')) dbp++;
1296  get_scheme ();
1297  }
1298  if (dbp[0] == '(' &&
1299  (dbp[1] == 'S' || dbp[1] == 's') &&
1300  (dbp[2] == 'E' || dbp[2] == 'e') &&
1301  (dbp[3] == 'T' || dbp[3] == 't') &&
1302  (dbp[4] == '!' || dbp[4] == '!') &&
1303  (isspace(dbp[5])))
1304  {
1305  while (!isspace(*dbp)) dbp++;
1306  /* Skip over white space */
1307  while (isspace(*dbp)) dbp++;
1308  get_scheme ();
1309  }
1310  }
1311 }
1312 
1313 static
1315 {
1316  register char *cp;
1317  char c;
1318  char nambuf[BUFSIZ];
1319 
1320  if (*dbp == 0) return;
1321  /* Go till you get to white space or a syntactic break */
1322  for (cp = dbp+1; *cp && *cp != '(' && *cp != ')' && !isspace(*cp); cp++)
1323  continue;
1324  /* Null terminate the string there. */
1325  c = cp[0];
1326  cp[0] = 0;
1327  /* Copy the string */
1328  strcpy(nambuf, dbp);
1329  /* Unterminate the string */
1330  cp[0] = c;
1331  /* Announce the change */
1332  pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
1333  pfcnt++;
1334 }
1335 
1336 /* Find tags in TeX and LaTeX input files. */
1337 
1338 /* TEX_toktab is a table of TeX control sequences that define tags.
1339  Each TEX_tabent records one such control sequence. */
1340 
1342 {
1343  char *name;
1344  int len;
1345 };
1346 
1347 struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
1348 
1349 /* Default set of control sequences to put into TEX_toktab.
1350  The value of environment var TEXTAGS is prepended to this. */
1351 
1352 static char *TEX_defenv =
1353  ":chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
1354 
1355 struct TEX_tabent *TEX_decode_env ();
1356 
1357 static char TEX_esc = '\\';
1358 static char TEX_opgrp = '{';
1359 static char TEX_clgrp = '}';
1360 
1361 /*
1362  * TeX/LaTeX scanning loop.
1363  */
1364 
1366  FILE *fi;
1367 {
1368  char *lasthit;
1369 
1370  lineno = 0;
1371  charno = 0;
1372  pfcnt = 0;
1373 
1374  /* Select either \ or ! as escape character. */
1375  TEX_mode (fi);
1376 
1377  /* Initialize token table once from environment. */
1378  if (!TEX_toktab)
1379  TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
1380 
1381  while (!feof (fi))
1382  {
1383  lineno++;
1384  linecharno = charno;
1385  charno += readline (&lb, fi) + 1;
1386  dbp = lb.buffer;
1387  lasthit = dbp;
1388 
1389  while (!feof (fi))
1390  { /* Scan each line in file */
1391  lineno++;
1392  linecharno = charno;
1393  charno += readline (&lb, fi) + 1;
1394  dbp = lb.buffer;
1395  lasthit = dbp;
1396  while (dbp = index (dbp, TEX_esc)) /* Look at each escape in line */
1397  {
1398  register int i;
1399 
1400  if (! *(++dbp))
1401  break;
1402  linecharno += dbp - lasthit;
1403  lasthit = dbp;
1404  i = TEX_Token (lasthit);
1405  if (0 <= i)
1406  {
1407  TEX_getit (lasthit, TEX_toktab[i].len);
1408  break; /* We only save a line once */
1409  }
1410  }
1411  }
1412  }
1413 }
1414 
1415 #define TEX_LESC '\\'
1416 #define TEX_SESC '!'
1417 
1418 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping */
1419 /* chars accordingly. */
1420 
1422  FILE *f;
1423 {
1424  int c;
1425 
1426  while ((c = getc (f)) != EOF)
1427  if (c == TEX_LESC || c == TEX_SESC)
1428  break;
1429 
1430  if (c == TEX_LESC)
1431  {
1432  TEX_esc = TEX_LESC;
1433  TEX_opgrp = '{';
1434  TEX_clgrp = '}';
1435  }
1436  else
1437  {
1438  TEX_esc = TEX_SESC;
1439  TEX_opgrp = '<';
1440  TEX_clgrp = '>';
1441  }
1442  rewind (f);
1443 }
1444 
1445 /* Read environment and prepend it to the default string. */
1446 /* Build token table. */
1447 
1448 struct TEX_tabent *
1449 TEX_decode_env (evarname, defenv)
1450  char *evarname;
1451  char *defenv;
1452 {
1453  register char *env, *p;
1454  extern char *savenstr (), *index ();
1455 
1456  struct TEX_tabent *tab;
1457  int size, i;
1458 
1459  /* Append deafult string to environment. */
1460  env = (char *) getenv (evarname);
1461  if (!env)
1462  env = defenv;
1463  else
1464  env = concat (env, defenv, "");
1465 
1466  /* Allocate a token table */
1467  for (size = 1, p=env; p;)
1468  if ((p = index (p, ':')) && *(++p))
1469  size++;
1470  tab = (struct TEX_tabent *) xmalloc (size * sizeof (struct TEX_tabent));
1471 
1472  /* Unpack environment string into token table. Be careful about */
1473  /* zero-length strings (leading ':', "::" and trailing ':') */
1474  for (i = 0; *env;)
1475  {
1476  p = index (env, ':');
1477  if (!p) /* End of environment string. */
1478  p = env + strlen (env);
1479  if (p - env > 0)
1480  { /* Only non-zero strings. */
1481  tab[i].name = savenstr (env, p - env);
1482  tab[i].len = strlen (tab[i].name);
1483  i++;
1484  }
1485  if (*p)
1486  env = p + 1;
1487  else
1488  {
1489  tab[i].name = NULL; /* Mark end of table. */
1490  tab[i].len = 0;
1491  break;
1492  }
1493  }
1494  return tab;
1495 }
1496 
1497 /* Record a tag defined by a TeX command of length LEN and starting at NAME.
1498  The name being defined actually starts at (NAME + LEN + 1).
1499  But we seem to include the TeX command in the tag name. */
1500 
1502  char *name;
1503  int len;
1504 {
1505  char *p = name + len;
1506  char nambuf[BUFSIZ];
1507 
1508  if (*name == 0) return;
1509 
1510  /* Let tag name extend to next group close (or end of line) */
1511  while (*p && *p != TEX_clgrp)
1512  p++;
1513  strncpy (nambuf, name, p - name);
1514  nambuf[p - name] = 0;
1515 
1516  pfnote (nambuf, TRUE, lb.buffer, strlen (lb.buffer), lineno, linecharno);
1517  pfcnt++;
1518 }
1519 
1520 /* If the text at CP matches one of the tag-defining TeX command names,
1521  return the index of that command in TEX_toktab.
1522  Otherwise return -1. */
1523 
1524 /* Keep the capital `T' in `Token' for dumb truncating compilers
1525  (this distinguishes it from `TEX_toktab' */
1527  char *cp;
1528 {
1529  int i;
1530 
1531  for (i = 0; TEX_toktab[i].len > 0; i++)
1532  if (strncmp (TEX_toktab[i].name, cp, TEX_toktab[i].len) == 0)
1533  return i;
1534  return -1;
1535 }
1536 
1537 /* Initialize a linebuffer for use */
1538 
1539 void
1541  struct linebuffer *linebuffer;
1542 {
1543  linebuffer->size = 200;
1544  linebuffer->buffer = (char *) xmalloc (200);
1545 }
1546 
1547 /* Read a line of text from `stream' into `linebuffer'.
1548  Return the length of the line. */
1549 
1550 long
1552  struct linebuffer *linebuffer;
1553  register FILE *stream;
1554 {
1555  char *buffer = linebuffer->buffer;
1556  register char *p = linebuffer->buffer;
1557  register char *pend = p + linebuffer->size;
1558 
1559  while (1)
1560  {
1561  int c = getc (stream);
1562  if (p == pend)
1563  {
1564  linebuffer->size *= 2;
1565  buffer = (char *) xrealloc (buffer, linebuffer->size);
1566  p += buffer - linebuffer->buffer;
1567  pend = buffer + linebuffer->size;
1568  linebuffer->buffer = buffer;
1569  }
1570  if (c < 0 || c == '\n')
1571  {
1572  *p = 0;
1573  break;
1574  }
1575  *p++ = c;
1576  }
1577 
1578  return p - buffer;
1579 }
1580 
1581 char *
1583  char *cp;
1584 {
1585  return savenstr (cp, strlen (cp));
1586 }
1587 
1588 char *
1590  char *cp;
1591  int len;
1592 {
1593  register char *dp;
1594 
1595  dp = (char *) xmalloc (len + 1);
1596  strncpy (dp, cp, len);
1597  dp[len] = '\0';
1598  return dp;
1599 }
1600 
1601 /*
1602  * Return the ptr in sp at which the character c last
1603  * appears; NULL if not found
1604  *
1605  * Identical to v7 rindex, included for portability.
1606  */
1607 
1608 char *
1609 rindex(sp, c)
1610  char *sp, c;
1611 {
1612  char *r;
1613 
1614  r = NULL;
1615  do
1616  {
1617  if (*sp == c)
1618  r = sp;
1619  } while (*sp++);
1620  return(r);
1621 }
1622 
1623 /*
1624  * Return the ptr in sp at which the character c first
1625  * appears; NULL if not found
1626  *
1627  * Identical to v7 index, included for portability.
1628  */
1629 
1630 char *
1631 index(sp, c)
1632  register char *sp, c;
1633 {
1634  do
1635  {
1636  if (*sp == c)
1637  return (sp);
1638  } while (*sp++);
1639  return (NULL);
1640 }
1641 
1642 /* Print error message and exit. */
1643 
1644 fatal (s1, s2)
1645  char *s1, *s2;
1646 {
1647  error (s1, s2);
1648  exit (BAD);
1649 }
1650 
1651 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
1652 
1653 error (s1, s2)
1654  char *s1, *s2;
1655 {
1656  fprintf (stderr, "%s: ", progname);
1657  fprintf (stderr, s1, s2);
1658  fprintf (stderr, "\n");
1659 }
1660 
1661 /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
1662 
1663 char *
1664 concat (s1, s2, s3)
1665  char *s1, *s2, *s3;
1666 {
1667  int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
1668  char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
1669 
1670  strcpy (result, s1);
1671  strcpy (result + len1, s2);
1672  strcpy (result + len1 + len2, s3);
1673  *(result + len1 + len2 + len3) = 0;
1674 
1675  return result;
1676 }
1677 
1678 /* Like malloc but get fatal error if memory is exhausted. */
1679 
1680 int
1681 xmalloc (size)
1682  int size;
1683 {
1684  int result = malloc (size);
1685  if (!result)
1686  fatal ("virtual memory exhausted", 0);
1687  return result;
1688 }
1689 
1690 int
1691 xrealloc (ptr, size)
1692  char *ptr;
1693  int size;
1694 {
1695  int result = realloc (ptr, size);
1696  if (!result)
1697  fatal ("virtual memory exhausted");
1698  return result;
1699 }
char * rindex(char *sp, char c)
Definition: eustags.c:1609
#define CNL_SAVE_NUMBER
Definition: eustags.c:771
static char buf[CHAR_SIZE]
int vflag
Definition: eustags.c:188
struct linebuffer lb lb1
Definition: eustags.c:218
free_tree(NODE *node)
Definition: eustags.c:612
char * white
Definition: eustags.c:174
int wflag
Definition: eustags.c:187
long readline()
int xflag
Definition: eustags.c:189
char * concat()
long size
Definition: eustags.c:214
error(char *s1, char *s2)
Definition: eustags.c:1653
logical gotone
Definition: eustags.c:155
fatal(char *s1, char *s2)
Definition: eustags.c:1644
int xrealloc(char *ptr, int size)
Definition: eustags.c:1691
pfnote(char *name, logical f, char *linestart, int linelen, int lno, long cno)
Definition: eustags.c:555
char * curfile
Definition: eustags.c:172
logical f
Definition: eustags.c:143
logical _wht[0177]
Definition: eustags.c:155
Definition: eustags.c:162
getline(long atchar)
Definition: eustags.c:1064
#define TRUE
Definition: eustags.c:125
total_size_of_entries(reg NODE *node)
Definition: eustags.c:724
TYST tydef
Definition: eustags.c:164
char * file
Definition: eustags.c:142
long linecharno
Definition: eustags.c:170
int aflag
Definition: eustags.c:184
#define TEX_SESC
Definition: eustags.c:1416
long cno
Definition: eustags.c:145
init()
Definition: eustags.c:455
long charno
Definition: eustags.c:169
#define iswhite(arg)
Definition: eustags.c:128
L_getit()
Definition: eustags.c:1249
logical _etk[0177]
Definition: eustags.c:155
#define istoken(s, tok, len)
Definition: eustags.c:138
int pfcnt
Definition: eustags.c:1077
static char * TEX_defenv
Definition: eustags.c:1352
#define begtoken(arg)
Definition: eustags.c:129
char * savenstr()
struct nd_st * left
Definition: eustags.c:148
getit()
Definition: eustags.c:1190
Definition: eustags.c:162
struct nd_st * right
Definition: eustags.c:148
put_entries(reg NODE *node)
Definition: eustags.c:667
NODE * head
Definition: eustags.c:198
Definition: eustags.c:140
TEX_mode(FILE *f)
Definition: eustags.c:1421
static char TEX_esc
Definition: eustags.c:1357
char * endtk
Definition: eustags.c:175
char * name
Definition: eustags.c:1343
char * buffer
Definition: eustags.c:215
Scheme_funcs(FILE *fi)
Definition: eustags.c:1275
Definition: arith.h:33
#define intoken(arg)
Definition: eustags.c:130
logical _btk[0177]
Definition: eustags.c:155
int number
Definition: eustags.c:154
logical _itk[0177]
Definition: eustags.c:155
#define reg
Definition: eustags.c:122
static void usage(void)
Definition: scube.c:195
TYST
Definition: eustags.c:162
struct TEX_tabent * TEX_toktab
Definition: eustags.c:1347
char searchar
Definition: eustags.c:166
static char TEX_clgrp
Definition: eustags.c:1359
char * dbp
Definition: eustags.c:1076
takeprec()
Definition: eustags.c:1171
int uflag
Definition: eustags.c:186
pointer buffer
Definition: eus.h:274
char * savestr()
TEX_funcs(FILE *fi)
Definition: eustags.c:1365
Definition: eustags.c:162
PF_funcs(FILE *fi)
Definition: eustags.c:1079
L_funcs(FILE *fi)
Definition: eustags.c:1215
#define CNL
Definition: eustags.c:779
static get_scheme()
Definition: eustags.c:1314
Definition: eus.h:271
struct TEX_tabent * TEX_decode_env()
main(int ac, av)
Definition: eustags.c:239
consider_token(char **lpp, char *token, int *f, int level)
Definition: eustags.c:944
int eflag
Definition: eustags.c:190
int file_num
Definition: eustags.c:183
FILE * outf
Definition: eustags.c:195
int lineno
Definition: eustags.c:168
#define isgood(arg)
Definition: eustags.c:132
int xmalloc(int size)
Definition: eustags.c:1681
char * begtk
Definition: eustags.c:177
tail(char *cp)
Definition: eustags.c:1156
char * outfile
Definition: eustags.c:173
char * name
Definition: eustags.c:141
char * index(char *sp, char c)
Definition: eustags.c:1631
#define TEX_LESC
Definition: eustags.c:1415
add_node(NODE *node, NODE *cur_node)
Definition: eustags.c:623
char * intk
Definition: eustags.c:179
#define GOOD
Definition: eustags.c:118
#define NULL
Definition: transargv.c:8
find_entries(char *file)
Definition: eustags.c:487
FILE * inf
Definition: eustags.c:195
logical _gd[0177]
Definition: eustags.c:155
int lno
Definition: eustags.c:144
char * notgd
Definition: eustags.c:181
void initbuffer()
#define FALSE
Definition: eustags.c:126
char * progname
Definition: eustags.c:193
char * pat
Definition: eustags.c:146
#define logical
Definition: eustags.c:123
C_entries()
Definition: eustags.c:785
TEX_getit(char *name, int len)
Definition: eustags.c:1501
logical been_warned
Definition: eustags.c:147
long ftell()
#define endtoken(arg)
Definition: eustags.c:131
static char TEX_opgrp
Definition: eustags.c:1358
TEX_Token(char *cp)
Definition: eustags.c:1526
#define BAD
Definition: eustags.c:119
int tflag
Definition: eustags.c:185


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Jun 6 2019 20:00:44