Add TO-DO list.
[bpt/emacs.git] / lib-src / etags.c
index 69d2910..5fe855b 100644 (file)
@@ -45,13 +45,11 @@ extern char *alloca ();
 
 extern char *malloc (), *realloc ();
 extern char *getenv ();
-extern char *index (), *rindex ();
 extern char *strcpy (), *strncpy ();
 extern int strcmp ();
 
-#ifdef hpux
-#define notdef
-#endif
+char *etags_index (), *etags_rindex ();
+char *savenstr ();
 
 /* Define the symbol ETAGS to make the program "etags",
  which makes emacs-style tag tables by default.
@@ -410,7 +408,7 @@ DEFINEST definedef;
  * for self-documentation only.
  */
 #define LEVEL_OK_FOR_FUNCDEF()                                 \
-       (level==0 || c_ext && level==1 && structdef==sinbody)
+       (level==0 || (c_ext && level==1 && structdef==sinbody))
 
 /*
  * next_token_is_func
@@ -872,7 +870,11 @@ process_file (file)
   struct stat stat_buf;
 
   stat (file, &stat_buf);
-  if (!(stat_buf.st_mode & S_IFREG) || !(stat_buf.st_mode & S_IFLNK))
+  if (!(stat_buf.st_mode & S_IFREG)
+#ifdef S_IFLNK
+      || !(stat_buf.st_mode & S_IFLNK)
+#endif
+      )
     {
       fprintf (stderr, "Skipping %s: it is not a regular file.\n", file);
       return;
@@ -885,7 +887,7 @@ process_file (file)
     }
   if (emacs_tags_format)
     {
-      char *cp = rindex (file, '/');
+      char *cp = etags_rindex (file, '/');
       if (cp)
        ++cp;
       else
@@ -904,7 +906,7 @@ process_file (file)
 
 /*
  * This routine sets up the boolean psuedo-functions which work
- * by seting boolean flags dependent upon the corresponding character
+ * by setting 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"
@@ -956,7 +958,7 @@ find_entries (file)
       return;
     }
   curfile = savestr (file);
-  cp = rindex (file, '.');
+  cp = etags_rindex (file, '.');
 
   header_file = (cp && (streq (cp + 1, "h")));
 
@@ -1032,11 +1034,17 @@ find_entries (file)
       PAS_funcs (inf);
       goto close_and_return;
     }
+  /* If .f or .for, assume it is fortran or nothing.  */
+  if (cp && (streq (cp + 1, "f") || streq (cp + 1, "for")))
+    {
+      PF_funcs (inf);
+      goto close_and_return;
+    }
   /* if not a .c or .h or .y file, try fortran */
-  else if (cp && ((cp[1] != 'c'
-                  && cp[1] != 'h'
-                  && cp[1] != 'y')
-                 || (cp[1] != 0 && cp[2] != 0)))
+  if (cp && ((cp[1] != 'c'
+             && cp[1] != 'h'
+             && cp[1] != 'y')
+            || (cp[1] != 0 && cp[2] != 0)))
     {
       if (PF_funcs (inf) != 0)
        goto close_and_return;
@@ -1099,9 +1107,9 @@ pfnote (name, is_func, rewritten, linestart, linelen, lno, cno)
   /* If ctags mode, change name "main" to M<thisfilename>. */
   if (!emacs_tags_format && !cxref_style && streq (name, "main"))
     {
-      fp = rindex (curfile, '/');
+      fp = etags_rindex (curfile, '/');
       name = concat ("M", fp == 0 ? curfile : fp + 1, "");
-      fp = rindex (name, '.');
+      fp = etags_rindex (name, '.');
       if (fp && fp[1] != '\0' && fp[2] == '\0')
        *fp = 0;
       rewritten = TRUE;
@@ -1283,7 +1291,7 @@ put_entries (node)
     fprintf (stdout, "%s %s %d\n",
             node->name, node->file, (node->lno + 63) / 64);
   else
-    fprintf (stdout, "%-16s%4d %-16s %s\n",
+    fprintf (stdout, "%-16s %3d %-16s %s\n",
             node->name, node->lno, node->file, node->pat);
 
   /* Output subentries that follow this one */
@@ -1405,6 +1413,7 @@ C_create_stabs ()
 
 #define CNL_SAVE_DEFINEDEF                                             \
 {                                                                      \
+  quotednl = FALSE;                                                    \
   prev_linepos = linepos;                                              \
   SET_FILEPOS (linepos, inf, charno);                                  \
   lineno++;                                                            \
@@ -1423,10 +1432,10 @@ C_entries (c_ext)
      int c_ext;                        /* extension of C? */
 {
   register int c;              /* latest char read; '\0' for end of line */
-  register int tokoff;         /* offset in line of beginning of latest token */
+  register int tokoff;         /* offset in line of start of latest token*/
   register int toklen;         /* length of latest token */
   register char *lp;           /* pointer one beyond the character `c' */
-  logical incomm, inquote, inchar, midtoken;
+  logical incomm, inquote, inchar, quotednl, midtoken;
   int level;                   /* current curly brace level */
   char tokb[BUFSIZ];
 
@@ -1436,7 +1445,7 @@ C_entries (c_ext)
   *lp = 0;
 
   definedef = dnone;
-  gotone = midtoken = inquote = inchar = incomm = FALSE;
+  gotone = midtoken = inquote = inchar = incomm = quotednl = FALSE;
   level = 0;
   tydef = none;
   next_token_is_func = 0;
@@ -1452,7 +1461,10 @@ C_entries (c_ext)
             '\0'; don't skip it, because it's the thing that tells us
             to read the next line.  */
          if (*lp == 0)
-           continue;
+           {
+             quotednl =TRUE;
+             continue;
+           }
          lp++;
          c = ' ';
        }
@@ -1468,7 +1480,8 @@ C_entries (c_ext)
        {
          if (c == '"')
            inquote = FALSE;
-         continue;
+         else if (c == '\\')
+           c = *lp++;
        }
       else if (inchar)
        {
@@ -1493,7 +1506,8 @@ C_entries (c_ext)
              }
            else if (c_ext && *lp == '/')
              {
-               c = 0;          /* C++ comment: skip rest of line */
+               c = 0;
+               break;
              }
            continue;
          case '#':
@@ -1510,7 +1524,8 @@ C_entries (c_ext)
            if (structdef == stagseen)
              structdef = scolonseen;
            break;
-           /* Not a struct definition when semicolon seen in non-sinbody context. */
+           /* Not a struct definition when semicolon seen
+              in non-sinbody context. */
          case ';':
            if (structdef != snone && structdef != sinbody)
              {
@@ -1617,7 +1632,7 @@ C_entries (c_ext)
                      lp = lp_tmp;
                      if (bingo)
                        {
-                         if (GET_CHARNO (tok.linestart) != GET_CHARNO (linepos)
+                         if (GET_CHARNO (tok.linestart) != GET_CHARNO(linepos)
                              && !tok_at_end_of_line)
                            {
                              /*
@@ -1629,7 +1644,8 @@ C_entries (c_ext)
                                tok.p = lb1.buffer + (tok.p - tok_linebuf);
                              tok_linebuf = lb1.buffer;
                            }
-                         if (structdef == sinbody && definedef == dnone && is_func)
+                         if (structdef == sinbody
+                             && definedef == dnone && is_func)
                            {   /* function defined in C++ class body */
                              sprintf (tokb, "%s::%.*s",
                                       structtag[0] == '\0' ? "_anonymous_"
@@ -1659,10 +1675,17 @@ C_entries (c_ext)
              midtoken = TRUE;
            }
        }
-      /* Detect end of line, after having handled the last token on the line.  */
+      /* Detect end of line, having handled the last token on the line.  */
       if (c == 0)
        {
-         CNL;
+         if (incomm || inquote || quotednl)
+           {
+             CNL_SAVE_DEFINEDEF;
+           }
+         else
+           {
+             CNL;
+           }
          gotone = FALSE;
        }
       if (c == ';' && tydef == end)    /* clean with typedefs */
@@ -1693,7 +1716,8 @@ C_entries (c_ext)
 logical
 consider_token (c, lpp, tokp, is_func, c_ext, level)
      reg char c;               /* IN: first char after the token */
-     char **lpp;               /* IN OUT: *lpp points to 2nd char after the token */
+     char **lpp;               /* IN OUT: *lpp points
+                                  to 2nd char after the token */
      reg TOKEN *tokp;          /* IN */
      logical *is_func;         /* OUT */
      int c_ext;                        /* IN */
@@ -1827,7 +1851,8 @@ consider_token (c, lpp, tokp, is_func, c_ext, level)
     {
     case st_C_struct:
     case st_C_enum:
-      if (tydef == begin || (typedefs_and_cplusplus && level == 0 && structdef == snone))
+      if (tydef == begin
+         || (typedefs_and_cplusplus && level == 0 && structdef == snone))
        {
          structdef = skeyseen;
          structkey = tokse;
@@ -1870,8 +1895,8 @@ consider_token (c, lpp, tokp, is_func, c_ext, level)
          structdef = snone;
          (void) strcpy (structtag, "<error 3>");
        }
-      /* Now what?  And how does/should this stuff interact with tydef?? */
-      /* Also maybe reset lp to *lpp for benefit of the function finding code. */
+      /* Now what?  And how does/should this stuff interact with tydef??  */
+      /* Also maybe reset lp to *lpp for sake of function-finding code.  */
     }
   if (tydef == begin)
     {
@@ -1886,7 +1911,10 @@ consider_token (c, lpp, tokp, is_func, c_ext, level)
   /* Detect GNUmacs's function-defining macros. */
   if (definedef == dnone)
     {
-      if (strneq (tokp->p, "DEF", 3))
+      if (strneq (tokp->p, "DEF", 3)
+         || strneq (tokp->p, "ENTRY", 5)
+         || strneq (tokp->p, "SYSCALL", 7)
+         || strneq (tokp->p, "PSEUDO", 6))
        {
          next_token_is_func = TRUE;
          goto badone;
@@ -2025,6 +2053,10 @@ PF_funcs (fi)
          if (tail ("subroutine"))
            getit ();
          continue;
+       case 'e':
+         if (tail ("entry"))
+           getit ();
+         continue;
        case 'p':
          if (tail ("program"))
            {
@@ -2084,7 +2116,10 @@ getit ()
 
   while (isspace (*dbp))
     dbp++;
-  if (*dbp == 0 || (!isalpha (*dbp)) && (*dbp != '_') && (*dbp != '$'))
+  if (*dbp == 0
+      || (!isalpha (*dbp)
+         && *dbp != '_'
+         && *dbp != '$'))
     return;
   for (cp = dbp + 1; *cp && (isalpha (*cp) || isdigit (*cp)
                             || (*cp == '_') || (*cp == '$')); cp++)
@@ -2532,34 +2567,25 @@ TEX_funcs (fi)
     TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
 
   while (!feof (fi))
-    {
+    {                          /* Scan each line in file */
       lineno++;
       linecharno = charno;
       charno += readline (&lb, fi);
       dbp = lb.buffer;
       lasthit = dbp;
+      while (dbp = etags_index (dbp, TEX_esc)) /* Look at each escape in line */
+       {
+         register int i;
 
-      while (!feof (fi))
-       {                       /* Scan each line in file */
-         lineno++;
-         linecharno = charno;
-         charno += readline (&lb, fi);
-         dbp = lb.buffer;
+         if (!*(++dbp))
+           break;
+         linecharno += dbp - lasthit;
          lasthit = dbp;
-         while (dbp = index (dbp, TEX_esc))    /* Look at each escape in line */
+         i = TEX_Token (lasthit);
+         if (0 <= i)
            {
-             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 */
-               }
+             TEX_getit (lasthit, TEX_toktab[i].len);
+             break;            /* We only save a line once */
            }
        }
     }
@@ -2612,7 +2638,6 @@ TEX_decode_env (evarname, defenv)
      char *defenv;
 {
   register char *env, *p;
-  extern char *savenstr (), *index ();
 
   struct TEX_tabent *tab;
   int size, i;
@@ -2626,15 +2651,16 @@ TEX_decode_env (evarname, defenv)
 
   /* Allocate a token table */
   for (size = 1, p = env; p;)
-    if ((p = index (p, ':')) && *(++p))
+    if ((p = etags_index (p, ':')) && *(++p))
       size++;
-  tab = xnew (size, struct TEX_tabent);
+  /* Add 1 to leave room for null terminator.  */
+  tab = xnew (size + 1, 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, ':');
+      p = etags_index (env, ':');
       if (!p)                  /* End of environment string. */
        p = env + strlen (env);
       if (p - env > 0)
@@ -2681,7 +2707,7 @@ TEX_getit (name, len)
 }
 
 /* If the text at CP matches one of the tag-defining TeX command names,
-   return the index of that command in TEX_toktab.
+   return the etags_index of that command in TEX_toktab.
    Otherwise return -1.  */
 
 /* Keep the capital `T' in `Token' for dumb truncating compilers
@@ -2804,7 +2830,7 @@ substr (sub, s)
      char *sub;
      char *s;
 {
-  while (*s && (s = index (s, *sub)))
+  while (*s && (s = etags_index (s, *sub)))
     if (prestr (sub, s))
       return (TRUE);
     else
@@ -2897,7 +2923,6 @@ savenstr (cp, len)
   return dp;
 }
 
-#ifdef notdef
 /*
  * Return the ptr in sp at which the character c last
  * appears; NULL if not found
@@ -2906,7 +2931,7 @@ savenstr (cp, len)
  */
 
 char *
-rindex (sp, c)
+etags_rindex (sp, c)
      register char *sp, c;
 {
   register char *r;
@@ -2920,6 +2945,7 @@ rindex (sp, c)
   return (r);
 }
 
+
 /*
  * Return the ptr in sp at which the character c first
  * appears; NULL if not found
@@ -2928,7 +2954,7 @@ rindex (sp, c)
  */
 
 char *
-index (sp, c)
+etags_index (sp, c)
      register char *sp, c;
 {
   do
@@ -2939,8 +2965,6 @@ index (sp, c)
   return (NULL);
 }
 
-#endif /* notdef */
-
 /* Print error message and exit.  */
 
 /* VARARGS1 */