* Ed Pelegri-Llopart added C typedefs.
* Gnu Emacs TAGS format and modifications by RMS?
* Sam Kendall added C++.
+ *
+ * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 9.7
*/
#ifdef HAVE_CONFIG_H
-#include "../src/config.h"
+#include <../src/config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
+#if !defined (S_ISREG) && defined (S_IFREG)
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
#include "getopt.h"
extern char *malloc (), *realloc ();
char *name; /* function or type name */
char *file; /* file name */
logical is_func; /* use pattern or line no */
- logical rewritten; /* list name separately */
+ logical named; /* list name separately */
logical been_warned; /* set if noticed dup */
int lno; /* line number tag is on */
long cno; /* character number line starts on */
char *savestr ();
char *xmalloc ();
char *xrealloc ();
-int L_isdef ();
+int L_isdef (), L_isquote ();
int PF_funcs ();
int total_size_of_entries ();
logical consider_token ();
char *p;
int len;
LINENO lineno;
- logical rewritten;
+ logical named;
} TOKEN;
/* C extensions.
#ifdef ETAGS
printf ("ETAGS ");
#endif
- printf ("for Emacs version 19.0.\n");
+ printf ("for Emacs version 19.\n");
exit (0);
}
{
struct stat stat_buf;
- stat (file, &stat_buf);
- if (!(stat_buf.st_mode & S_IFREG)
-#ifdef S_IFLNK
- || !(stat_buf.st_mode & S_IFLNK)
-#endif
- )
+ if (stat (file, &stat_buf) || !S_ISREG (stat_buf.st_mode))
{
fprintf (stderr, "Skipping %s: it is not a regular file.\n", file);
return;
fprintf (stderr, "Skipping inclusion of %s in self.\n", file);
return;
}
- if (emacs_tags_format)
- {
- char *cp = etags_rindex (file, '/');
- if (cp)
- ++cp;
- else
- cp = file;
- }
find_entries (file);
if (emacs_tags_format)
{
- fprintf (outf, "\f\n%s,%d\n",
- file, total_size_of_entries (head));
+ fprintf (outf, "\f\n%s,%d\n", file, total_size_of_entries (head));
put_entries (head);
free_tree (head);
head = NULL;
/* Record a tag. */
/* Should take a TOKEN* instead!! */
void
-pfnote (name, is_func, rewritten, linestart, linelen, lno, cno)
+pfnote (name, is_func, named, linestart, linelen, lno, cno)
char *name; /* tag name */
logical is_func; /* function or type name? */
- logical rewritten; /* tag different from text of definition? */
+ logical named; /* tag different from text of definition? */
char *linestart;
int linelen;
int lno;
fp = etags_rindex (name, '.');
if (fp && fp[1] != '\0' && fp[2] == '\0')
*fp = 0;
- rewritten = TRUE;
+ named = TRUE;
}
np->name = savestr (name);
np->file = curfile;
np->is_func = is_func;
- np->rewritten = rewritten;
+ np->named = named;
np->lno = lno;
/* UNCOMMENT THE +1 HERE: */
np->cno = cno /* + 1 */ ; /* our char numbers are 0-base; emacs's are 1-base */
if (emacs_tags_format)
{
- if (node->rewritten)
+ if (node->named)
{
fprintf (outf, "%s\177%s\001%d,%d\n",
- node->name, node->pat, node->lno, node->cno);
+ node->pat, node->name,
+ node->lno, node->cno);
}
else
{
fprintf (outf, "%s\177%d,%d\n",
- node->pat, node->lno, node->cno);
+ node->pat,
+ node->lno, node->cno);
}
}
else if (!cxref_style)
/* Count this entry */
total += strlen (node->pat) + 1;
total += number_len ((long) node->lno) + 1 + number_len (node->cno) + 1;
- if (node->rewritten)
+ if (node->named)
total += 1 + strlen (node->name); /* \001name */
}
}
\f
/*
- * etags.c 4.2 1993/03/22 12:13:40 pot Exp
* C functions are recognized using a simple finite automaton.
* funcdef is its state variable.
*/
typedef enum
{
- fnone, ftagseen, finlist, flistseen
+ fnone, /* nothing seen */
+ ftagseen, /* function-like tag seen */
+ finlist, /* in parameter list */
+ flistseen, /* after parameter list */
+ fignore, /* before open brace */
} FUNCST;
FUNCST funcdef;
*/
typedef enum
{
- tnone, ttypedseen, tinbody, tend
+ tnone, /* nothing seen */
+ ttypedseen, /* typedef keyword seen */
+ tinbody, /* inside typedef body */
+ tend, /* just before typedef tag */
} TYPEDST;
TYPEDST typdef;
skeyseen, /* struct-like keyword seen */
stagseen, /* struct-like tag seen */
scolonseen, /* colon seen after struct-like tag */
- sinbody /* in struct body: recognize member func defs*/
+ sinbody, /* in struct body: recognize member func defs*/
} STRUCTST;
STRUCTST structdef;
/*
dnone, /* nothing seen */
dsharpseen, /* '#' seen as first char on line */
ddefineseen, /* '#' and 'define' seen */
- dignorerest /* ignore rest of line */
+ dignorerest, /* ignore rest of line */
} DEFINEST;
DEFINEST definedef;
definedef = dnone; \
} while (FALSE)
-#define MAKE_TAG_FROM_NEW_LB(isfun) pfnote (tokb, isfun, tok.rewritten, \
+#define MAKE_TAG_FROM_NEW_LB(isfun) pfnote (nameb, isfun, tok.named, \
newlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (newlinepos))
-#define MAKE_TAG_FROM_OTH_LB(isfun) pfnote (tokb, isfun, tok.rewritten, \
+#define MAKE_TAG_FROM_OTH_LB(isfun) pfnote (nameb, isfun, tok.named, \
othlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (othlinepos))
void
register char *lp; /* pointer one beyond the character `c' */
int curndx, newndx; /* indices for current and new lb */
TOKEN tok; /* latest token read for funcdef & structdef */
- char tokb[BUFSIZ]; /* latest token name for funcdef & structdef */
+ char nameb[BUFSIZ]; /* latest token name for funcdef & structdef */
register int tokoff; /* offset in line of start of latest token */
register int toklen; /* length of latest token */
int cblev; /* current curly brace level */
}
else
{
- logical is_func;
+ logical is_func = FALSE;
tok.lineno = lineno;
tok.p = newlb.buffer + tokoff;
tok.len = toklen;
- tok.rewritten = FALSE;
+ tok.named = FALSE;
if (yacc_rules
|| consider_token (c, lp, &tok,
c_ext, cblev, &is_func))
{
if (structdef == sinbody
- && definedef == dnone && is_func)
- { /* function defined in C++ class body */
- sprintf (tokb, "%s::%.*s",
+ && definedef == dnone
+ && is_func)
+ /* function defined in C++ class body */
+ {
+ tok.named = TRUE;
+ sprintf (nameb, "%s::%.*s",
((structtag[0] == '\0')
? "_anonymous_" : structtag),
tok.len, tok.p);
- tok.rewritten = TRUE;
}
else
{
- sprintf (tokb, "%.*s", tok.len, tok.p);
+ sprintf (nameb, "%.*s", tok.len, tok.p);
}
+ if (structdef == stagseen
+ || typdef == tend)
+ tok.named = TRUE;
+
if (funcdef == ftagseen
|| structdef == stagseen
|| typdef == tend)
{
case flistseen:
MAKE_TAG_FROM_OTH_LB (TRUE);
- /* FALLTHRU */
+ funcdef = fignore;
+ break;
case ftagseen:
funcdef = fnone;
break;
else if (yacc_rules && funcdef == ftagseen)
{
MAKE_TAG_FROM_OTH_LB (FALSE);
- funcdef == fnone;
+ funcdef = fignore;
}
break;
case ';':
typdef = tnone;
MAKE_TAG_FROM_OTH_LB (FALSE);
}
- funcdef = fnone;
+ if (funcdef != fignore)
+ funcdef = fnone;
/* FALLTHRU */
case ',':
/* FALLTHRU */
case '[':
- if (funcdef != finlist)
+ if (funcdef != finlist && funcdef != fignore)
funcdef = fnone;
if (structdef == stagseen)
structdef = snone;
MAKE_TAG_FROM_OTH_LB (FALSE);
break;
}
+ switch (funcdef)
+ {
+ case flistseen:
+ MAKE_TAG_FROM_OTH_LB (TRUE);
+ /* FALLTHRU */
+ case fignore:
+ funcdef = fnone;
+ }
cblev++;
- /* FALLTHRU */
+ break;
case '*':
if (funcdef == flistseen)
{
MAKE_TAG_FROM_OTH_LB (TRUE);
- funcdef = fnone;
+ funcdef = fignore;
}
break;
case '}':
int cblev; /* IN: curly brace level */
logical *is_func; /* OUT */
{
- logical firsttok; /* TRUE if have seen first token in ()'s */
Stab_entry *tokse = stab_find (get_C_stab (c_ext), tokp->p, tokp->len);
enum sym_type toktype = stab_type (tokse);
- *is_func = FALSE; /* not a function */
-
/*
* Advance the definedef state machine.
*/
if (next_token_is_func)
{
next_token_is_func = FALSE;
- *is_func = TRUE;
+ funcdef = fnone;
+ *is_func = TRUE; /* to force search string in ctags */
return (TRUE);
}
funcdef = fnone; /* should be useless */
return (FALSE);
default:
- funcdef = ftagseen;
- *is_func = TRUE;
- return (TRUE);
+ if (funcdef == fnone)
+ {
+ funcdef = ftagseen;
+ *is_func = TRUE;
+ return (TRUE);
+ }
}
+
+ return (FALSE);
}
\f
/* Fortran parsing */
else
{
/* Check for (foo::defmumble name-defined ... */
- while (*dbp && *dbp != ':' && !isspace (*dbp)
- && *dbp != '(' && *dbp != ')')
+ do
dbp++;
+ while (*dbp && !isspace (*dbp)
+ && *dbp != ':' && *dbp != '(' && *dbp != ')');
if (*dbp == ':')
{
- while (*dbp == ':')
+ do
dbp++;
+ while (*dbp == ':');
- if (L_isdef (dbp))
+ if (L_isdef (dbp - 1))
{
while (!isspace (*dbp))
dbp++;
int
L_isdef (dbp)
- char *dbp;
+ register char *dbp;
{
- return ((dbp[1] == 'D' || dbp[1] == 'd') &&
- (dbp[2] == 'E' || dbp[2] == 'e') &&
- (dbp[3] == 'F' || dbp[3] == 'f'));
+ return ((dbp[1] == 'd' || dbp[1] == 'D')
+ && (dbp[2] == 'e' || dbp[2] == 'E')
+ && (dbp[3] == 'f' || dbp[3] == 'F'));
+}
+
+int
+L_isquote (dbp)
+ register char *dbp;
+{
+ return ((*(++dbp) == 'q' || *dbp == 'Q')
+ && (*(++dbp) == 'u' || *dbp == 'U')
+ && (*(++dbp) == 'o' || *dbp == 'O')
+ && (*(++dbp) == 't' || *dbp == 'T')
+ && (*(++dbp) == 'e' || *dbp == 'E')
+ && isspace(*(++dbp)));
}
void
char c;
char nambuf[BUFSIZ];
- if (*dbp == 0)
- return;
- for (cp = dbp + 1; *cp && *cp != '(' && *cp != ' '; cp++)
+ if (*dbp == '\'') /* Skip prefix quote */
+ dbp++;
+ else if (*dbp == '(' && L_isquote (dbp)) /* Skip "(quote " */
+ {
+ dbp += 7;
+ while (isspace(*dbp))
+ dbp++;
+ }
+ for (cp = dbp /*+1*/; *cp && *cp != '(' && *cp != ' ' && *cp != ')'; cp++)
continue;
+ if (cp == dbp)
+ return;
+
c = cp[0];
cp[0] = 0;
(void) strcpy (nambuf, dbp);
*s = '\0';
strcpy (nambuf, save_s);
*s = tmpc;
- pfnote (nambuf, TRUE, save_s, strlen (nambuf), lineno, linecharno);
+ pfnote (nambuf, TRUE, FALSE, save_s, strlen (nambuf), lineno, linecharno);
}
/* It is assumed that prolog predicate starts from column 0. */