[project @ 1996-07-25 20:43:49 by partain]
[ghc-hetmet.git] / glafp-utils / etags / etags.c
diff --git a/glafp-utils/etags/etags.c b/glafp-utils/etags/etags.c
deleted file mode 100644 (file)
index b24592d..0000000
+++ /dev/null
@@ -1,1762 +0,0 @@
-/* Tags file maker to go with GNUmacs
-   Copyright (C) 1984, 1987, 1988 Free Software Foundation, Inc. and Ken Arnold
-
-                          NO WARRANTY
-
-  BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
-NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
-WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
-RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
-WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
-AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
-DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
-CORRECTION.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
-STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
-WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
-LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
-OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
-DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
-A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
-PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
-
-               GENERAL PUBLIC LICENSE TO COPY
-
-  1. You may copy and distribute verbatim copies of this source file
-as you receive it, in any medium, provided that you conspicuously
-and appropriately publish on each copy a valid copyright notice
-"Copyright (C) 1986 Free Software Foundation"; and include
-following the copyright notice a verbatim copy of the above disclaimer
-of warranty and of this License.
-
-  2. You may modify your copy or copies of this source file or
-any portion of it, and copy and distribute such modifications under
-the terms of Paragraph 1 above, provided that you also do the following:
-
-    a) cause the modified files to carry prominent notices stating
-    that you changed the files and the date of any change; and
-
-    b) cause the whole of any work that you distribute or publish,
-    that in whole or in part contains or is a derivative of this
-    program or any part thereof, to be licensed at no charge to all
-    third parties on terms identical to those contained in this
-    License Agreement (except that you may choose to grant more extensive
-    warranty protection to some or all third parties, at your option).
-
-    c) You may charge a distribution fee for the physical act of
-    transferring a copy, and you may at your option offer warranty
-    protection in exchange for a fee.
-
-Mere aggregation of another unrelated program with this program (or its
-derivative) on a volume of a storage or distribution medium does not bring
-the other program under the scope of these terms.
-
-  3. You may copy and distribute this program (or a portion or derivative
-of it, under Paragraph 2) in object code or executable form under the terms
-of Paragraphs 1 and 2 above provided that you also do one of the following:
-
-    a) accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of
-    Paragraphs 1 and 2 above; or,
-
-    b) accompany it with a written offer, valid for at least three
-    years, to give any third party free (except for a nominal
-    shipping charge) a complete machine-readable copy of the
-    corresponding source code, to be distributed under the terms of
-    Paragraphs 1 and 2 above; or,
-
-    c) accompany it with the information you received as to where the
-    corresponding source code may be obtained.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form alone.)
-
-For an executable file, complete source code means all the source code for
-all modules it contains; but, as a special exception, it need not include
-source code for modules which are standard libraries that accompany the
-operating system on which the executable file runs.
-
-  4. You may not copy, sublicense, distribute or transfer this program
-except as expressly provided under this License Agreement.  Any attempt
-otherwise to copy, sublicense, distribute or transfer this program is void and
-your rights to use the program under this License agreement shall be
-automatically terminated.  However, parties who have received computer
-software programs from you with this License Agreement will not have
-their licenses terminated so long as such parties remain in full compliance.
-
-In other words, you are welcome to use, share and improve this program.
-You are forbidden to forbid anyone else to use, share and improve
-what you give them.   Help stamp out software-hoarding!  */
-
-#include <stdio.h>
-#include <ctype.h>
-
-/* Define the symbol ETAGS to make the program "etags",
- which makes emacs-style tag tables by default.
- Define CTAGS to make the program "ctags" compatible with the usual one.
- Define neither one to get behavior that depends
- on the name with which the program is invoked
- (but we don't normally compile it that way).  */
-
-/* On VMS, CTAGS is not useful, so always do ETAGS.  */
-#ifdef VMS
-#ifndef ETAGS
-#define ETAGS
-#endif
-#endif
-
-/* Exit codes for success and failure.  */
-
-#ifdef VMS
-#define        GOOD    (1)
-#define BAD    (0)
-#else
-#define        GOOD    (0)
-#define        BAD     (1)
-#endif
-
-#define        reg     register
-#define        logical char
-
-#ifndef TRUE
-#define        TRUE    (1)
-#endif
-
-#ifndef FALSE
-#define        FALSE   (0)
-#endif
-
-#define        iswhite(arg)    (_wht[arg])     /* T if char is white           */
-#define        begtoken(arg)   (_btk[arg])     /* T if char can start token    */
-#define        intoken(arg)    (_itk[arg])     /* T if char can be in token    */
-#define        endtoken(arg)   (_etk[arg])     /* T if char ends tokens        */
-#define        isgood(arg)     (_gd[arg])      /* T if char can be after ')'   */
-
-#define        max(I1,I2)      (I1 > I2 ? I1 : I2)
-
-/* cause token checking for typedef, struct, union, enum to distinguish
-   keywords from identifier-prefixes (e.g. struct vs struct_tag).  */
-#define istoken(s, tok, len) (!strncmp(s,tok,len) && endtoken(*((s)+(len))))
-
-struct nd_st {                 /* sorting structure                    */
-       char    *name;                  /* function or type name        */
-       char    *file;                  /* file name                    */
-       logical f;                      /* use pattern or line no       */
-       int     lno;                    /* line number tag is on        */
-       long    cno;                    /* character number line starts on */
-       char    *pat;                   /* search pattern               */
-       logical been_warned;            /* set if noticed dup           */
-       struct  nd_st   *left,*right;   /* left and right sons          */
-};
-
-long   ftell();
-typedef        struct  nd_st   NODE;
-
-int number; /* tokens found so far on line starting with # (including #) */
-logical gotone,                                /* found a func already on line */
-                                       /* boolean "func" (see init)    */
-       _wht[0177],_etk[0177],_itk[0177],_btk[0177],_gd[0177];
-
-       /* typedefs are recognized using a simple finite automata,
-        * tydef is its state variable.
-        */
-typedef enum {none, begin, tag_ok, middle, end } TYST;
-
-TYST tydef = none;
-
-char   searchar = '/';                 /* use /.../ searches           */
-
-int    lineno;                 /* line number of current line */
-long   charno;                 /* current character number */
-long   linecharno;             /* character number of start of line */
-
-char    *curfile,              /* current input file name              */
-       *outfile= 0,            /* output file                          */
-       *white  = " \f\t\n",    /* white chars                          */
-       *endtk  = " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?",
-                               /* token ending chars                   */
-       *begtk  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$",
-                               /* token starting chars                 */
-       *intk   = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789",
-                               /* valid in-token chars                 */
-       *notgd  = ",;";         /* non-valid after-function chars       */
-
-int    file_num = 0;           /* current file number                  */
-int    aflag = 0;              /* -a: append to tags */
-int    tflag = 0;              /* -t: create tags for typedefs */
-int    uflag = 0;              /* -u: update tags */
-int    wflag = 0;              /* -w: suppress warnings */
-int    vflag = 0;              /* -v: create vgrind style index output */
-int    xflag = 0;              /* -x: create cxref style output */
-int    eflag = 0;              /* -e: emacs style output */
-
-/* Name this program was invoked with.  */
-char *progname;
-
-FILE   *inf,                   /* ioptr for current input file         */
-       *outf;                  /* ioptr for tags file                  */
-
-NODE   *head;                  /* the head of the sorted binary tree   */
-
-char *savestr();
-char *savenstr ();
-char *rindex();
-char *index();
-char *concat ();
-void initbuffer ();
-long readline ();
-
-/* A `struct linebuffer' is a structure which holds a line of text.
- `readline' reads a line from a stream into a linebuffer
- and works regardless of the length of the line.  */
-
-struct linebuffer
-  {
-    long size;
-    char *buffer;
-  };
-
-struct linebuffer lb, lb1;
-\f
-#if 0  /* VMS now provides the `system' function.  */
-#ifdef VMS
-
-#include <descrip.h>
-
-void
-system (buf)
-     char *buf;
-{
-  struct dsc$descriptor_s command =
-    {
-      strlen(buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf
-    };
-
-  LIB$SPAWN(&command);
-}
-#endif /* VMS */
-#endif /* 0 */
-\f
-main(ac,av)
-     int       ac;
-     char      *av[];
-{
-  char cmd[100];
-  int i;
-  int fflag = 0;
-  char *this_file;
-#ifdef VMS
-  char got_err;
-
-  extern char *gfnames();
-  extern char *massage_name();
-#endif
-
-  progname = av[0];
-
-#ifdef ETAGS
-  eflag = 1;
-#else
-#ifdef CTAGS
-  eflag = 0;
-#else
-  {
-    char *subname = rindex (progname, '/');
-    if (subname++ == NULL)
-      subname = progname;
-    eflag = ! strcmp(subname, "ctags");
-  }
-#endif
-#endif
-
-  while (ac > 1 && av[1][0] == '-')
-    {
-      for (i=1; av[1][i]; i++)
-       {
-         switch(av[1][i])
-           {
-#ifndef VMS  /* These options are useful only with ctags,
-               and VMS can't input them, so just omit them.  */
-           case 'B':
-             searchar='?';
-             eflag = 0;
-             break;
-           case 'F':
-             searchar='/';
-             eflag = 0;
-             break;
-#endif
-           case 'a':
-             aflag++;
-             break;
-           case 'e':
-             eflag++;
-             break;
-           case 'f':
-             if (fflag > 0)
-               {
-                 fprintf(stderr,
-                         "%s: -f flag may only be given once\n", progname);
-                 goto usage;
-               }
-             fflag++, ac--; av++;
-             if (ac <= 1 || av[1][0] == '\0')
-               {
-                 fprintf(stderr,
-                         "%s: -f flag must be followed by a filename\n",
-                         progname);
-                 goto usage;
-               }
-             outfile = av[1];
-             goto end_loop;
-           case 't':
-             tflag++;
-             break;
-#ifndef VMS
-           case 'u':
-             uflag++;
-             eflag = 0;
-             break;
-#endif
-           case 'w':
-             wflag++;
-             break;
-           case 'v':
-             vflag++;
-             xflag++;
-             eflag = 0;
-             break;
-           case 'x':
-             xflag++;
-             eflag = 0;
-             break;
-           default:
-             goto usage;
-           }
-       }
-    end_loop: ;
-      ac--; av++;
-    }
-
-  if (ac <= 1)
-    {
-    usage:
-#ifdef VMS
-      fprintf (stderr, "Usage: %s [-aetwvx] [-f outfile] file ...\n", progname);
-#else
-      fprintf (stderr, "Usage: %s [-BFaetuwvx] [-f outfile] file ...\n", progname);
-#endif
-      exit(BAD);
-    }
-
-  if (outfile == 0)
-    {
-      outfile = eflag ? "TAGS" : "tags";
-    }
-
-  init();                      /* set up boolean "functions"           */
-
-  initbuffer (&lb);
-  initbuffer (&lb1);
-  /*
-   * loop through files finding functions
-   */
-  if (eflag)
-    {
-      outf = fopen (outfile, aflag ? "a" : "w");
-      if (!outf)
-       {
-         fprintf (stderr, "%s: ", progname);
-         perror (outfile);
-         exit (BAD);
-       }
-    }
-
-  file_num = 1;
-#ifdef VMS
-  for (ac--, av++;
-       (this_file = gfnames (&ac, &av, &got_err)) != NULL; file_num++)
-    {
-      if (got_err)
-       {
-         error("Can't find file %s\n", this_file);
-         ac--, av++;
-       }
-      else
-       {
-         this_file = massage_name (this_file);
-#else     
-  for (; file_num < ac; file_num++)
-    {
-      this_file = av[file_num];
-      if (1)
-       {
-#endif
-         find_entries (this_file);
-         if (eflag)
-           {
-             fprintf (outf, "\f\n%s,%d\n",
-                      this_file, total_size_of_entries (head));
-             put_entries (head);
-             free_tree (head);
-             head = NULL;
-           }
-       }
-    }
-
-  if (eflag)
-    {
-      fclose (outf);
-      exit (GOOD);
-    }
-
-  if (xflag)
-    {
-      put_entries(head);
-      exit(GOOD);
-    }
-  if (uflag)
-    {
-      for (i=1; i<ac; i++)
-       {
-         sprintf(cmd,
-                 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
-                 outfile, av[i], outfile);
-         system(cmd);
-       }
-      aflag++;
-    }
-  outf = fopen(outfile, aflag ? "a" : "w");
-  if (outf == NULL)
-    {
-      fprintf (stderr, "%s: ", outfile);
-      perror(outfile);
-      exit(BAD);
-    }
-  put_entries(head);
-  fclose(outf);
-#ifndef VMS
-  if (uflag)
-    {
-      sprintf(cmd, "sort %s -o %s", outfile, outfile);
-      system(cmd);
-    }
-#endif
-  exit(GOOD);
-}
-
-/*
- * This routine sets up the boolean psuedo-functions which work
- * by seting boolean flags dependent upon the corresponding character
- * Every char which is NOT in that string is not a white char.  Therefore,
- * all of the array "_wht" is set to FALSE, and then the elements
- * subscripted by the chars in "white" are set to TRUE.  Thus "_wht"
- * of a char is TRUE if it is the string "white", else FALSE.
- */
-init()
-{
-
-  reg char *sp;
-  reg int i;
-
-  for (i = 0; i < 0177; i++)
-    {
-      _wht[i] = _etk[i] = _itk[i] = _btk[i] = FALSE;
-      _gd[i] = TRUE;
-    }
-  for (sp = white; *sp; sp++)
-    _wht[*sp] = TRUE;
-  for (sp = endtk; *sp; sp++)
-    _etk[*sp] = TRUE;
-  for (sp = intk; *sp; sp++)
-    _itk[*sp] = TRUE;
-  for (sp = begtk; *sp; sp++)
-    _btk[*sp] = TRUE;
-  for (sp = notgd; *sp; sp++)
-    _gd[*sp] = FALSE;
-  _wht[0] = _wht['\n'];
-  _etk[0] = _etk['\n'];
-  _btk[0] = _btk['\n'];
-  _itk[0] = _itk['\n'];
-  _gd[0] = _gd['\n'];
-}
-
-/*
- * This routine opens the specified file and calls the function
- * which finds the function and type definitions.
- */
-find_entries (file)
-     char *file;
-{
-  char *cp;
-
-  if ((inf=fopen(file,"r")) == NULL)
-    {
-      fprintf (stderr, "%s: ", progname);
-      perror(file);
-      return;
-    }
-  curfile = savestr(file);
-  cp = rindex(file, '.');
-  /* .tex, .aux or .bbl implies LaTeX source code */
-  if (cp && (!strcmp (cp + 1, "tex") || !strcmp (cp + 1, "aux")
-            || !strcmp (cp + 1, "bbl")))
-    {
-      TEX_funcs(inf);
-      fclose(inf);
-      return;
-    }
-  /* .l or .el or .lisp (or .cl or .clisp or ...) implies lisp source code */
-  if (cp && (!strcmp (cp + 1, "l") ||
-            !strcmp (cp + 1, "el") ||
-            !strcmp (cp + 1, "lsp") ||
-            !strcmp (cp + 1, "lisp") ||
-            !strcmp (cp + 1, "cl") ||
-            !strcmp (cp + 1, "clisp")))
-    {
-      L_funcs(inf);
-      fclose(inf);
-      return;
-    }
-  /* .scm or .sm or .scheme implies scheme source code */
-  if (cp && (!strcmp (cp + 1, "sm")
-            || !strcmp (cp + 1, "scm")
-            || !strcmp (cp + 1, "scheme")
-            || !strcmp (cp + 1, "t")
-            || !strcmp (cp + 1, "sch")
-            || !strcmp (cp + 1, "SM")
-            || !strcmp (cp + 1, "SCM")
-             /* The `SCM' or `scm' prefix with a version number */
-             || (cp[-1] == 'm' && cp[-2] == 'c' && cp[-3] == 's')
-             || (cp[-1] == 'M' && cp[-2] == 'C' && cp[-3] == 'S')))
-    {
-      Scheme_funcs(inf);
-      fclose(inf);
-      return;
-    }
-  /* .M implies Mcode source code */
-  if (cp && !strcmp (cp + 1, "M"))
-    {
-      Mcode_funcs(inf);
-      fclose(inf);
-      return;
-    }
-
-  /* if not a .c or .h or .y file, try fortran */
-  if (cp && (cp[1] != 'c' && cp[1] != 'h' && cp[1] != 'y')
-      && cp[2] == '\0')
-    {
-      if (PF_funcs(inf) != 0)
-       {
-         fclose(inf);
-         return;
-       }
-      rewind(inf);     /* no fortran tags found, try C */
-    }
-  C_entries();
-  fclose(inf);
-}
-\f
-/* Record a tag on the current line.
-  name is the tag name,
-  f is nonzero to use a pattern, zero to use line number instead. */
-
-pfnote (name, f, linestart, linelen, lno, cno)
-     char *name;
-     logical f;                        /* f == TRUE when function */
-     char *linestart;
-     int linelen;
-     int lno;
-     long cno;
-{
-  register char *fp;
-  register NODE *np;
-  char *altname;
-  char tem[51];
-
-  if ((np = (NODE *) malloc (sizeof (NODE))) == NULL)
-    {
-      fprintf(stderr, "%s: too many entries to sort\n", progname);
-      put_entries(head);
-      free_tree(head);
-      head = NULL;
-      np = (NODE *) xmalloc(sizeof (NODE));
-    }
-  /* Change name "main" to M<thisfilename>. */
-  if (!eflag && !xflag && !strcmp(name, "main"))
-    {
-      fp = rindex(curfile, '/');
-      if (fp == 0)
-       fp = curfile;
-      else
-       fp++;
-      altname = concat ("M", fp, "");
-      fp = rindex(altname, '.');
-      if (fp && fp[2] == 0)
-       *fp = 0;
-      name = altname;
-    }
-  np->name = savestr(name);
-  np->file = curfile;
-  np->f = f;
-  np->lno = lno;
-  np->cno = cno;
-  np->left = np->right = 0;
-  if (eflag)
-    {
-      linestart[linelen] = 0;
-    }
-  else if (xflag == 0)
-    {
-      sprintf (tem, strlen (linestart) < 50 ? "%s$" : "%.50s", linestart);
-      linestart = tem;
-    }
-  np->pat = savestr (linestart);
-  if (head == NULL)
-    head = np;
-  else
-    add_node(np, head);
-}
-
-free_tree(node)
-     NODE *node;
-{
-  while (node)
-    {
-      free_tree(node->right);
-      free(node);
-      node = node->left;
-    }
-}
-
-add_node(node, cur_node)
-     NODE *node,*cur_node;
-{
-  register int dif;
-
-  dif = strcmp(node->name, cur_node->name);
-
-  /* If this tag name matches an existing one, then
-     unless -e was given, do not add the node, but maybe print a warning */
-  if (!eflag && !dif)
-    {
-      if (node->file == cur_node->file)
-       {
-         if (!wflag)
-           {
-             fprintf(stderr,"%s: Duplicate entry in file %s, line %d: %s\n",
-                     progname, node->file,lineno,node->name);
-             fprintf(stderr,"Second entry ignored\n");
-           }
-         return;
-       }
-      if (!cur_node->been_warned)
-       if (!wflag)
-         fprintf(stderr,"%s: Duplicate entry in files %s and %s: %s (Warning only)\n",
-                 progname, node->file, cur_node->file, node->name);
-      cur_node->been_warned = TRUE;
-      return;
-    } 
-
-  /* Actually add the node */
-  if (dif < 0) 
-    {
-      if (cur_node->left != NULL)
-       add_node(node,cur_node->left);
-      else
-       cur_node->left = node;
-      return;
-    }
-  if (cur_node->right != NULL)
-    add_node(node,cur_node->right);
-  else
-    cur_node->right = node;
-}
-\f
-put_entries(node)
-     reg NODE *node;
-{
-  reg char *sp;
-
-  if (node == NULL)
-    return;
-
-  /* Output subentries that precede this one */
-  put_entries (node->left);
-
-  /* Output this entry */
-
-  if (eflag)
-    {
-      fprintf (outf, "%s%c%d,%d\n",
-              node->pat, 0177, node->lno, node->cno);
-    }
-  else if (!xflag)
-    {
-      fprintf (outf, "%s\t%s\t",
-              node->name, node->file);
-
-      if (node->f)
-       {               /* a function */
-         putc (searchar, outf);
-         putc ('^', outf);
-
-         for (sp = node->pat; *sp; sp++)
-           {
-             if (*sp == '\\' || *sp == searchar)
-               putc ('\\', outf);
-             putc (*sp, outf);
-           }
-         putc (searchar, outf);
-       }
-      else
-       {               /* a typedef; text pattern inadequate */
-         fprintf (outf, "%d", node->lno);
-       }
-      putc ('\n', outf);
-    }
-  else if (vflag)
-    fprintf (stdout, "%s %s %d\n",
-            node->name, node->file, (node->lno+63)/64);
-  else
-    fprintf (stdout, "%-16s%4d %-16s %s\n",
-            node->name, node->lno, node->file, node->pat);
-
-  /* Output subentries that follow this one */
-  put_entries (node->right);
-}
-
-/* Return total number of characters that put_entries will output for
- the nodes in the subtree of the specified node.
- Works only if eflag is set, but called only in that case.  */
-
-total_size_of_entries(node)
-     reg NODE *node;
-{
-  reg int total = 0;
-  reg long num;
-
-  if (node == NULL)
-    return 0;
-
-  /* Count subentries that precede this one */
-  total = total_size_of_entries (node->left);
-
-  /* Count subentries that follow this one */
-  total += total_size_of_entries (node->right);
-
-  /* Count this entry */
-
-  total += strlen (node->pat) + 3;
-
-  num = node->lno;
-  while (num)
-    {
-      total++;
-      num /= 10;
-    }
-
-  num = node->cno;
-  if (!num) total++;
-  while (num)
-    {
-      total++;
-      num /= 10;
-    }
-  return total;
-}
-\f
-/*
- * This routine finds functions and typedefs in C syntax and adds them
- * to the list.
- */
-#ifdef VMS
-long vmslinecharno;
-#define VMS_SET_LINECHARNO     (vmslinecharno = ftell(inf))
-#else
-#define VMS_SET_LINECHARNO
-#endif
-
-#define CNL_SAVE_NUMBER \
-{ \
-  VMS_SET_LINECHARNO; \
-  linecharno = charno; lineno++; \
-  charno += 1 + readline (&lb, inf); \
-  lp = lb.buffer; \
-}
-
-#define CNL \
-{ \
-  CNL_SAVE_NUMBER; \
-  number = 0; \
-}
-
-C_entries ()
-{
-  register int c;
-  register char *token, *tp, *lp;
-  logical incomm, inquote, inchar, midtoken;
-  int level;
-  char tok[BUFSIZ];
-
-  lineno = 0;
-  charno = 0;
-  lp = lb.buffer;
-  *lp = 0;
-
-  number = 0;
-  gotone = midtoken = inquote = inchar = incomm = FALSE;
-  level = 0;
-
-  while (!feof (inf))
-    {
-      c = *lp++;
-      if (c == 0)
-       {
-         CNL;
-         gotone = FALSE;
-       }
-      if (c == '\\')
-       {
-         c = *lp++;
-         if (c == 0)
-           CNL_SAVE_NUMBER;
-         c = ' ';
-       } 
-      else if (incomm)
-       {
-         if (c == '*')
-           {
-             while ((c = *lp++) == '*')
-               continue;
-             if (c == 0)
-               CNL;
-             if (c == '/')
-               incomm = FALSE;
-           }
-       }
-      else if (inquote)
-       {
-         /*
-         * Too dumb to know about \" not being magic, but
-         * they usually occur in pairs anyway.
-         */
-         if (c == '"')
-           inquote = FALSE;
-         continue;
-       }
-      else if (inchar)
-       {
-         if (c == '\'')
-           inchar = FALSE;
-         continue;
-       }
-      else switch (c)
-       {
-       case '"':
-         inquote = TRUE;
-         continue;
-       case '\'':
-         inchar = TRUE;
-         continue;
-       case '/':
-         if (*lp == '*')
-           {
-             lp++;
-             incomm = TRUE;
-           }
-         continue;
-       case '#':
-         if (lp == lb.buffer + 1)
-           number = 1;
-         continue;
-       case '{':
-         if (tydef == tag_ok)
-           {
-             tydef=middle;
-           }
-         level++;
-         continue;
-       case '}':
-         if (lp == lb.buffer + 1)
-           level = 0;  /* reset */
-         else
-           level--;
-         if (!level && tydef==middle)
-           {
-             tydef=end;
-           }
-         continue;
-       }
-      if (!level && !inquote && !incomm && gotone == FALSE)
-       {
-         if (midtoken)
-           {
-             if (endtoken(c))
-               {
-                 int f;
-                 char *buf = lb.buffer;
-                 int endpos = lp - lb.buffer;
-                 char *lp1 = lp;
-                 int line = lineno;
-                 long linestart = linecharno;
-#ifdef VMS
-                 long vmslinestart = vmslinecharno;
-#endif
-                 int tem = consider_token (&lp1, token, &f, level);
-                 lp = lp1;
-                 if (tem)
-                   {
-                     if (linestart != linecharno)
-                       {
-#ifdef VMS
-                         getline (vmslinestart);
-#else
-                         getline (linestart);
-#endif
-                         strncpy (tok, token + (lb1.buffer - buf),
-                                  tp-token+1);
-                         tok[tp-token+1] = 0;
-                         pfnote(tok, f, lb1.buffer, endpos, line, linestart);
-                       }
-                     else
-                       {
-                         strncpy (tok, token, tp-token+1);
-                         tok[tp-token+1] = 0;
-                         pfnote(tok, f, lb.buffer, endpos, line, linestart);
-                       }
-                     gotone = f;       /* function */
-                   }
-                 midtoken = FALSE;
-                 token = lp - 1;
-               }
-             else if (intoken(c))
-               tp++;
-           }
-         else if (begtoken(c))
-           {
-             token = tp = lp - 1;
-             midtoken = TRUE;
-           }
-       }
-      if (c == ';'  &&  tydef==end)    /* clean with typedefs */
-       tydef=none;
-    }
-}
-
-/*
- * This routine  checks to see if the current token is
- * at the start of a function, or corresponds to a typedef
- * It updates the input line * so that the '(' will be
- * in it when it returns.
- */
-consider_token (lpp, token, f, level)
-     char **lpp, *token;
-     int *f, level;
-{
-  reg char *lp = *lpp;
-  reg char c;
-  static logical next_token_is_func;
-  logical firsttok;    /* T if have seen first token in ()'s */
-  int bad, win;
-
-  *f = 1;                      /* a function */
-  c = lp[-1];
-  bad = FALSE;
-  if (!number)
-    {          /* space is not allowed in macro defs   */
-      while (iswhite(c))
-       {
-         c = *lp++;
-         if (c == 0)
-           {
-             if (feof (inf))
-               break;
-             CNL;
-           }
-       }
-    }
-  else
-    {
-      /* the following tries to make it so that a #define a b(c)       */
-      /* doesn't count as a define of b.                               */
-
-      number++;
-      if (number >= 4  || (number==2 && strncmp (token, "define", 6)==0))
-       {
-         /* Force the next symbol to be recognised, even if it is #define a b(c)! */
-         if(number == 2) next_token_is_func = 1;
-         else
-           gotone = TRUE;
-       badone:
-         bad = TRUE;
-         goto ret;
-       }
-    }
-  /* check for the typedef cases               */
-  if (tflag && istoken(token, "typedef", 7))
-    {
-      tydef=begin;
-      goto badone;
-    }
-  if (tydef==begin && (istoken(token, "struct", 6) ||
-                      istoken(token, "union", 5) || istoken(token, "enum", 4)))
-  {
-    tydef=tag_ok;      
-    goto badone;
-  }
-  if (tydef==tag_ok)
-    {
-      tydef=middle;
-      goto badone;
-    }
-  if (tydef==begin)            /* e.g. typedef ->int<- */
-    {
-      tydef=end;
-      goto badone;
-    }
-  if (tydef==middle && level == 0) /* e.g. typedef struct tag ->struct_t<- */
-    {
-      tydef=end;
-    }
-  if (tydef==end)
-    {
-      *f = 0;
-      win = 1;
-      goto ret;
-    }
-  /* Detect GNUmacs's function-defining macros. */
-  if (!number && !strncmp (token, "DEF", 3))
-        
-    {
-      next_token_is_func = 1;
-      goto badone;
-    }
-  if (next_token_is_func)
-    {
-      next_token_is_func = 0;
-      win = 1;
-      goto ret;
-    }
-  if (c != '(')
-    goto badone;
-  firsttok = FALSE;
-  while ((c = *lp++) != ')')
-    {
-      if (c == 0)
-       {
-         if (feof (inf))
-           break;
-         CNL;
-       }
-      /*
-       * This line used to confuse ctags:
-       *       int     (*oldhup)();
-       * This fixes it. A nonwhite char before the first
-       * token, other than a / (in case of a comment in there)
-       * makes this not a declaration.
-       */
-      if (begtoken(c) || c=='/') firsttok++;
-      else if (!iswhite(c) && !firsttok) goto badone;
-    }
-  while (iswhite (c = *lp++))
-    {
-      if (c == 0)
-       {
-         if (feof (inf))
-           break;
-         CNL;
-       }
-    }
-  win = isgood (c);
-ret:
-  *lpp = lp - 1;
-  return !bad && win;
-}
-
-getline (atchar)
-     long atchar;
-{
-  long saveftell = ftell (inf);
-
-  fseek (inf, atchar, 0);
-  readline (&lb1, inf);
-  fseek (inf, saveftell, 0);
-}
-\f
-/* Fortran parsing */
-
-char   *dbp;
-int    pfcnt;
-
-PF_funcs(fi)
-     FILE *fi;
-{
-  lineno = 0;
-  charno = 0;
-  pfcnt = 0;
-
-  while (!feof (fi))
-    {
-      lineno++;
-      linecharno = charno;
-      charno += readline (&lb, fi) + 1;
-      dbp = lb.buffer;
-      if (*dbp == '%') dbp++ ; /* Ratfor escape to fortran */
-      while (isspace(*dbp))
-       dbp++;
-      if (*dbp == 0)
-       continue;
-      switch (*dbp |' ')
-       {
-       case 'i':
-         if (tail("integer"))
-           takeprec();
-         break;
-       case 'r':
-         if (tail("real"))
-           takeprec();
-         break;
-       case 'l':
-         if (tail("logical"))
-           takeprec();
-         break;
-       case 'c':
-         if (tail("complex") || tail("character"))
-           takeprec();
-         break;
-       case 'd':
-         if (tail("double"))
-           {
-             while (isspace(*dbp))
-               dbp++;
-             if (*dbp == 0)
-               continue;
-             if (tail("precision"))
-               break;
-             continue;
-           }
-         break;
-       }
-      while (isspace(*dbp))
-       dbp++;
-      if (*dbp == 0)
-       continue;
-      switch (*dbp|' ')
-       {
-       case 'f':
-         if (tail("function"))
-           getit();
-         continue;
-       case 's':
-         if (tail("subroutine"))
-           getit();
-         continue;
-       case 'p':
-         if (tail("program"))
-           {
-             getit();
-             continue;
-           }
-         if (tail("procedure"))
-           getit();
-         continue;
-       }
-    }
-  return (pfcnt);
-}
-
-tail(cp)
-     char *cp;
-{
-  register int len = 0;
-
-  while (*cp && (*cp&~' ') == ((*(dbp+len))&~' '))
-    cp++, len++;
-  if (*cp == 0)
-    {
-      dbp += len;
-      return (1);
-    }
-  return (0);
-}
-
-takeprec()
-{
-  while (isspace(*dbp))
-    dbp++;
-  if (*dbp != '*')
-    return;
-  dbp++;
-  while (isspace(*dbp))
-    dbp++;
-  if (!isdigit(*dbp))
-    {
-      --dbp;           /* force failure */
-      return;
-    }
-  do
-    dbp++;
-  while (isdigit(*dbp));
-}
-
-getit()
-{
-  register char *cp;
-  char c;
-  char nambuf[BUFSIZ];
-
-  while (isspace(*dbp))
-    dbp++;
-  if (*dbp == 0 || !isalpha(*dbp))
-    return;
-  for (cp = dbp+1; *cp && (isalpha(*cp) || isdigit(*cp)); cp++)
-    continue;
-  c = cp[0];
-  cp[0] = 0;
-  strcpy(nambuf, dbp);
-  cp[0] = c;
-  pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
-  pfcnt++;
-}
-\f
-/*
- * lisp tag functions
- * just look for (def or (DEF
- */
-
-L_funcs (fi)
-     FILE *fi;
-{
-  lineno = 0;
-  charno = 0;
-  pfcnt = 0;
-
-  while (!feof (fi))
-    {
-      lineno++;
-      linecharno = charno;
-      charno += readline (&lb, fi) + 1;
-      dbp = lb.buffer;
-      if (dbp[0] == '(' && 
-         (dbp[1] == 'D' || dbp[1] == 'd') &&
-           (dbp[2] == 'E' || dbp[2] == 'e') &&
-             (dbp[3] == 'F' || dbp[3] == 'f'))
-       {
-         while (!isspace(*dbp)) dbp++;
-         while (isspace(*dbp)) dbp++;
-         L_getit();
-       }
-    }
-}
-
-L_getit()
-{
-  register char *cp;
-  char c;
-  char nambuf[BUFSIZ];
-
-  if (*dbp == 0) return;
-  for (cp = dbp+1; *cp && *cp != '(' && *cp != ' '; cp++)
-    continue;
-  c = cp[0];
-  cp[0] = 0;
-  strcpy(nambuf, dbp);
-  cp[0] = c;
-  pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
-  pfcnt++;
-}
-\f
-/*
- * Scheme tag functions
- * look for (def... xyzzy
- * look for (def... (xyzzy
- * look for (def ... ((...(xyzzy ....
- * look for (set! xyzzy
- */
-
-static get_scheme ();
-Scheme_funcs (fi)
-     FILE *fi;
-{
-  lineno = 0;
-  charno = 0;
-  pfcnt = 0;
-
-  while (!feof (fi))
-    {
-      lineno++;
-      linecharno = charno;
-      charno += readline (&lb, fi) + 1;
-      dbp = lb.buffer;
-      if (dbp[0] == '(' && 
-         (dbp[1] == 'D' || dbp[1] == 'd') &&
-           (dbp[2] == 'E' || dbp[2] == 'e') &&
-             (dbp[3] == 'F' || dbp[3] == 'f'))
-       {
-         while (!isspace(*dbp)) dbp++;
-          /* Skip over open parens and white space */
-          while (*dbp && (isspace(*dbp) || *dbp == '(')) dbp++;
-         get_scheme ();
-       }
-      if (dbp[0] == '(' && 
-         (dbp[1] == 'S' || dbp[1] == 's') &&
-           (dbp[2] == 'E' || dbp[2] == 'e') &&
-             (dbp[3] == 'T' || dbp[3] == 't') &&
-                (dbp[4] == '!' || dbp[4] == '!') &&
-                  (isspace(dbp[5])))
-       {
-         while (!isspace(*dbp)) dbp++;
-          /* Skip over white space */
-          while (isspace(*dbp)) dbp++;
-         get_scheme ();
-       }
-    }
-}
-
-static
-get_scheme()
-{
-  register char *cp;
-  char c;
-  char nambuf[BUFSIZ];
-
-  if (*dbp == 0) return;
-  /* Go till you get to white space or a syntactic break */
-  for (cp = dbp+1; *cp && *cp != '(' && *cp != ')' && !isspace(*cp); cp++)
-    continue;
-  /* Null terminate the string there. */
-  c = cp[0];
-  cp[0] = 0;
-  /* Copy the string */
-  strcpy(nambuf, dbp);
-  /* Unterminate the string */
-  cp[0] = c;
-  /* Announce the change */
-  pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
-  pfcnt++;
-}
-static get_mcode ();
-Mcode_funcs (fi)
-     FILE *fi;
-{
-  lineno = 0;
-  charno = 0;
-  pfcnt = 0;
-
-  while (!feof (fi))
-    {
-      lineno++;
-      linecharno = charno;
-      charno += readline (&lb, fi) + 1;
-      dbp = lb.buffer;
-
-      while (*dbp != 0)
-       {
-         /* Skip over white space */
-         while (isspace(*dbp)) dbp++;
-         get_mcode();
-       }
-    }
-}
-
-static
-get_mcode()
-{
-  register char *cp;
-  char c;
-  char nambuf[BUFSIZ];
-
-  if (*dbp == 0) return;
-  /* Go till you get to white space or a syntactic break */
-  for (cp = dbp; *cp && *cp != ':' && *cp != ';' && !isspace(*cp); cp++)
-    continue;
-
-  if(*cp == ':')
-    {
-      /* Null terminate the string there. */
-      c = cp[0];
-      cp[0] = 0;
-      /* Copy the string */
-      strcpy(nambuf, dbp);
-      /* Unterminate the string */
-      cp[0] = c;
-      /* Announce the change */
-      pfnote(nambuf, TRUE, lb.buffer, strlen(lb.buffer), lineno, linecharno);
-      pfcnt++;
-      *dbp = 0;
-    }
-  if (*cp == ';')
-    *dbp = 0;
-  else
-    dbp = cp;
-}
-\f
-/* Find tags in TeX and LaTeX input files.  */
-
-/* TEX_toktab is a table of TeX control sequences that define tags.
-   Each TEX_tabent records one such control sequence.  */
-
-struct TEX_tabent
-{
-  char *name;
-  int len;
-};
-
-struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
-
-/* Default set of control sequences to put into TEX_toktab.
-   The value of environment var TEXTAGS is prepended to this.  */
-
-static char *TEX_defenv =
-  ":chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
-
-struct TEX_tabent *TEX_decode_env (); 
-
-static char TEX_esc = '\\';
-static char TEX_opgrp = '{';
-static char TEX_clgrp = '}';
-
-/*
- * TeX/LaTeX scanning loop.
- */
-
-TEX_funcs (fi)
-    FILE *fi;
-{
-  char *lasthit;
-
-  lineno = 0;
-  charno = 0;
-  pfcnt = 0;
-
-  /* Select either \ or ! as escape character.  */
-  TEX_mode (fi);
-
-  /* Initialize token table once from environment. */
-  if (!TEX_toktab)
-    TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
-
-  while (!feof (fi))
-    {
-      lineno++;
-      linecharno = charno;
-      charno += readline (&lb, fi) + 1;
-      dbp = lb.buffer;
-      lasthit = dbp;
-
-      while (!feof (fi))
-       {       /* Scan each line in file */
-         lineno++;
-         linecharno = charno;
-         charno += readline (&lb, fi) + 1;
-         dbp = lb.buffer;
-         lasthit = dbp;
-         while (dbp = index (dbp, TEX_esc)) /* Look at each escape in line */
-           {
-             register int i;
-
-             if (! *(++dbp))
-               break;
-             linecharno += dbp - lasthit;
-             lasthit = dbp;
-             i = TEX_Token (lasthit);
-             if (0 <= i)
-               {
-                 TEX_getit (lasthit, TEX_toktab[i].len);
-                 break;                /* We only save a line once */
-               }
-           }
-       }
-    }
-}
-
-#define TEX_LESC '\\'
-#define TEX_SESC '!'
-
-/* Figure out whether TeX's escapechar is '\\' or '!' and set grouping */
-/* chars accordingly. */
-
-TEX_mode (f)
-     FILE *f;
-{
-  int c;
-
-  while ((c = getc (f)) != EOF)
-    if (c == TEX_LESC || c == TEX_SESC)
-      break;
-
-  if (c == TEX_LESC)
-    {
-      TEX_esc = TEX_LESC;
-      TEX_opgrp = '{';
-      TEX_clgrp = '}';
-    } 
-  else
-    {
-      TEX_esc = TEX_SESC;
-      TEX_opgrp = '<';
-      TEX_clgrp = '>';
-    }
-  rewind (f);
-}
-
-/* Read environment and prepend it to the default string. */
-/* Build token table. */
-
-struct TEX_tabent *
-TEX_decode_env (evarname, defenv)
-     char *evarname;
-     char *defenv;
-{
-  register char *env, *p;
-  extern char *savenstr (), *index ();
-
-  struct TEX_tabent *tab;
-  int size, i;
-
-  /* Append deafult string to environment. */
-  env = (char *) getenv (evarname);
-  if (!env)
-    env = defenv;
-  else
-    env = concat (env, defenv, "");
-
-  /* Allocate a token table */
-  for (size = 1, p=env; p;)
-    if ((p = index (p, ':')) && *(++p))
-      size++;
-  tab = (struct TEX_tabent *) xmalloc (size * sizeof (struct TEX_tabent));
-
-  /* Unpack environment string into token table. Be careful about */
-  /* zero-length strings (leading ':', "::" and trailing ':') */
-  for (i = 0; *env;)
-    {
-      p = index (env, ':');
-      if (!p)                  /* End of environment string. */
-       p = env + strlen (env);
-      if (p - env > 0)
-       {       /* Only non-zero strings. */
-         tab[i].name = savenstr (env, p - env);
-         tab[i].len = strlen (tab[i].name);
-         i++;
-       }
-      if (*p)
-       env = p + 1;
-      else
-       {
-         tab[i].name = NULL;   /* Mark end of table. */
-         tab[i].len = 0;
-         break;
-       }
-    }
-  return tab;
-}
-
-/* Record a tag defined by a TeX command of length LEN and starting at NAME.
-   The name being defined actually starts at (NAME + LEN + 1).
-   But we seem to include the TeX command in the tag name.  */
-
-TEX_getit (name, len)
-    char *name;
-    int len;
-{
-  char *p = name + len;
-  char nambuf[BUFSIZ];
-
-  if (*name == 0) return;
-
-  /* Let tag name extend to next group close (or end of line) */
-  while (*p && *p != TEX_clgrp)
-    p++;
-  strncpy (nambuf, name, p - name);
-  nambuf[p - name] = 0;
-
-  pfnote (nambuf, TRUE, lb.buffer, strlen (lb.buffer), lineno, linecharno);
-  pfcnt++;
-}
-
-/* If the text at CP matches one of the tag-defining TeX command names,
-   return the index of that command in TEX_toktab.
-   Otherwise return -1.  */
-
-/* Keep the capital `T' in `Token' for dumb truncating compilers
-   (this distinguishes it from `TEX_toktab' */
-TEX_Token (cp)
-    char *cp;
-{
-  int i;
-
-  for (i = 0; TEX_toktab[i].len > 0; i++)
-    if (strncmp (TEX_toktab[i].name, cp, TEX_toktab[i].len) == 0)
-      return i;
-  return -1;
-}
-\f
-/* Initialize a linebuffer for use */
-
-void
-initbuffer (linebuffer)
-     struct linebuffer *linebuffer;
-{
-  linebuffer->size = 200;
-  linebuffer->buffer = (char *) xmalloc (200);
-}
-
-/* Read a line of text from `stream' into `linebuffer'.
- Return the length of the line.  */
-
-long
-readline (linebuffer, stream)
-     struct linebuffer *linebuffer;
-     register FILE *stream;
-{
-  char *buffer = linebuffer->buffer;
-  register char *p = linebuffer->buffer;
-  register char *pend = p + linebuffer->size;
-
-  while (1)
-    {
-      int c = getc (stream);
-      if (p == pend)
-       {
-         linebuffer->size *= 2;
-         buffer = (char *) xrealloc (buffer, linebuffer->size);
-         p += buffer - linebuffer->buffer;
-         pend = buffer + linebuffer->size;
-         linebuffer->buffer = buffer;
-       }
-      if (c < 0 || c == '\n')
-       {
-         *p = 0;
-         break;
-       }
-      *p++ = c;
-    }
-
-  return p - buffer;
-}
-\f
-char *
-savestr(cp)
-     char *cp;
-{
-  return savenstr (cp, strlen (cp));
-}
-
-char *
-savenstr(cp, len)
-    char *cp;
-    int len;
-{
-  register char *dp;
-
-  dp = (char *) xmalloc (len + 1);
-  strncpy (dp, cp, len);
-  dp[len] = '\0';
-  return dp;
-}
-
-/*
- * Return the ptr in sp at which the character c last
- * appears; NULL if not found
- *
- * Identical to v7 rindex, included for portability.
- */
-
-char *
-rindex(sp, c)
-     register char *sp, c;
-{
-  register char *r;
-
-  r = NULL;
-  do
-    {
-      if (*sp == c)
-       r = sp;
-    } while (*sp++);
-  return(r);
-}
-
-/*
- * Return the ptr in sp at which the character c first
- * appears; NULL if not found
- *
- * Identical to v7 index, included for portability.
- */
-
-char *
-index(sp, c)
-     register char *sp, c;
-{
-  do
-    {
-      if (*sp == c)
-       return (sp);
-    } while (*sp++);
-  return (NULL);
-}
-
-/* Print error message and exit.  */
-
-fatal (s1, s2)
-     char *s1, *s2;
-{
-  error (s1, s2);
-  exit (BAD);
-}
-
-/* Print error message.  `s1' is printf control string, `s2' is arg for it. */
-
-error (s1, s2)
-     char *s1, *s2;
-{
-  fprintf (stderr, "%s: ", progname);
-  fprintf (stderr, s1, s2);
-  fprintf (stderr, "\n");
-}
-
-/* Return a newly-allocated string whose contents concatenate those of s1, s2, s3.  */
-
-char *
-concat (s1, s2, s3)
-     char *s1, *s2, *s3;
-{
-  int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
-  char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
-
-  strcpy (result, s1);
-  strcpy (result + len1, s2);
-  strcpy (result + len1 + len2, s3);
-  *(result + len1 + len2 + len3) = 0;
-
-  return result;
-}
-
-/* Like malloc but get fatal error if memory is exhausted.  */
-
-int
-xmalloc (size)
-     int size;
-{
-  int result = malloc (size);
-  if (!result)
-    fatal ("virtual memory exhausted", 0);
-  return result;
-}
-
-int
-xrealloc (ptr, size)
-     char *ptr;
-     int size;
-{
-  int result = realloc (ptr, size);
-  if (!result)
-    fatal ("virtual memory exhausted");
-  return result;
-}