mirror of https://github.com/GnoConsortium/gno.git
Initial commit of ctags utility
This commit is contained in:
parent
3e68d4bd15
commit
bb09eed7f6
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)C.c 8.4 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ctags.h"
|
||||
|
||||
static int func_entry __P((void));
|
||||
static void hash_entry __P((void));
|
||||
static void skip_string __P((int));
|
||||
static int str_entry __P((int));
|
||||
|
||||
/*
|
||||
* c_entries --
|
||||
* read .c and .h files and call appropriate routines
|
||||
*/
|
||||
void
|
||||
c_entries(void)
|
||||
{
|
||||
int c; /* current character */
|
||||
int level; /* brace level */
|
||||
int token; /* if reading a token */
|
||||
int t_def; /* if reading a typedef */
|
||||
int t_level; /* typedef's brace level */
|
||||
char *sp; /* buffer pointer */
|
||||
static char tok[MAXTOKEN]; /* token buffer */
|
||||
|
||||
lineftell = ftell(inf);
|
||||
#ifdef __ORCAC203__
|
||||
sp = tok; token = NO; t_def = NO; t_level = -1; level = 0; lineno = 1;
|
||||
#else
|
||||
sp = tok; token = t_def = NO; t_level = -1; level = 0; lineno = 1;
|
||||
#endif
|
||||
while (GETC(!=, EOF)) {
|
||||
switch (c) {
|
||||
/*
|
||||
* Here's where it DOESN'T handle: {
|
||||
* foo(a)
|
||||
* {
|
||||
* #ifdef notdef
|
||||
* }
|
||||
* #endif
|
||||
* if (a)
|
||||
* puts("hello, world");
|
||||
* }
|
||||
*/
|
||||
case '{':
|
||||
++level;
|
||||
goto endtok;
|
||||
case '}':
|
||||
/*
|
||||
* if level goes below zero, try and fix
|
||||
* it, even though we've already messed up
|
||||
*/
|
||||
if (--level < 0)
|
||||
level = 0;
|
||||
goto endtok;
|
||||
|
||||
case '\n':
|
||||
SETLINE;
|
||||
/*
|
||||
* the above 3 cases are similar in that they
|
||||
* are special characters that also end tokens.
|
||||
*/
|
||||
endtok: if (sp > tok) {
|
||||
*sp = EOS;
|
||||
token = YES;
|
||||
sp = tok;
|
||||
}
|
||||
else
|
||||
token = NO;
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We ignore quoted strings and character constants
|
||||
* completely.
|
||||
*/
|
||||
case '"':
|
||||
case '\'':
|
||||
(void)skip_string(c);
|
||||
break;
|
||||
|
||||
/*
|
||||
* comments can be fun; note the state is unchanged after
|
||||
* return, in case we found:
|
||||
* "foo() XX comment XX { int bar; }"
|
||||
*/
|
||||
case '/':
|
||||
if (GETC(==, '*')) {
|
||||
skip_comment();
|
||||
continue;
|
||||
}
|
||||
(void)ungetc(c, inf);
|
||||
c = '/';
|
||||
goto storec;
|
||||
|
||||
/* hash marks flag #define's. */
|
||||
case '#':
|
||||
if (sp == tok) {
|
||||
hash_entry();
|
||||
break;
|
||||
}
|
||||
goto storec;
|
||||
|
||||
/*
|
||||
* if we have a current token, parenthesis on
|
||||
* level zero indicates a function.
|
||||
*/
|
||||
case '(':
|
||||
if (!level && token) {
|
||||
int curline;
|
||||
|
||||
if (sp != tok)
|
||||
*sp = EOS;
|
||||
/*
|
||||
* grab the line immediately, we may
|
||||
* already be wrong, for example,
|
||||
* foo\n
|
||||
* (arg1,
|
||||
*/
|
||||
getline();
|
||||
curline = lineno;
|
||||
if (func_entry()) {
|
||||
++level;
|
||||
pfnote(tok, curline);
|
||||
}
|
||||
break;
|
||||
}
|
||||
goto storec;
|
||||
|
||||
/*
|
||||
* semi-colons indicate the end of a typedef; if we find a
|
||||
* typedef we search for the next semi-colon of the same
|
||||
* level as the typedef. Ignoring "structs", they are
|
||||
* tricky, since you can find:
|
||||
*
|
||||
* "typedef long time_t;"
|
||||
* "typedef unsigned int u_int;"
|
||||
* "typedef unsigned int u_int [10];"
|
||||
*
|
||||
* If looking at a typedef, we save a copy of the last token
|
||||
* found. Then, when we find the ';' we take the current
|
||||
* token if it starts with a valid token name, else we take
|
||||
* the one we saved. There's probably some reasonable
|
||||
* alternative to this...
|
||||
*/
|
||||
case ';':
|
||||
if (t_def && level == t_level) {
|
||||
t_def = NO;
|
||||
getline();
|
||||
if (sp != tok)
|
||||
*sp = EOS;
|
||||
pfnote(tok, lineno);
|
||||
break;
|
||||
}
|
||||
goto storec;
|
||||
|
||||
/*
|
||||
* store characters until one that can't be part of a token
|
||||
* comes along; check the current token against certain
|
||||
* reserved words.
|
||||
*/
|
||||
default:
|
||||
storec: if (!intoken(c)) {
|
||||
if (sp == tok)
|
||||
break;
|
||||
*sp = EOS;
|
||||
if (tflag) {
|
||||
/* no typedefs inside typedefs */
|
||||
if (!t_def &&
|
||||
!memcmp(tok, "typedef",8)) {
|
||||
t_def = YES;
|
||||
t_level = level;
|
||||
break;
|
||||
}
|
||||
/* catch "typedef struct" */
|
||||
if ((!t_def || t_level < level)
|
||||
&& (!memcmp(tok, "struct", 7)
|
||||
|| !memcmp(tok, "union", 6)
|
||||
|| !memcmp(tok, "enum", 5))) {
|
||||
/*
|
||||
* get line immediately;
|
||||
* may change before '{'
|
||||
*/
|
||||
getline();
|
||||
if (str_entry(c))
|
||||
++level;
|
||||
break;
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
sp = tok;
|
||||
}
|
||||
else if (sp != tok || begtoken(c)) {
|
||||
*sp++ = c;
|
||||
token = YES;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
sp = tok;
|
||||
token = NO;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* func_entry --
|
||||
* handle a function reference
|
||||
*/
|
||||
static int
|
||||
func_entry(void)
|
||||
{
|
||||
int c; /* current character */
|
||||
int level = 0; /* for matching '()' */
|
||||
|
||||
/*
|
||||
* Find the end of the assumed function declaration.
|
||||
* Note that ANSI C functions can have type definitions so keep
|
||||
* track of the parentheses nesting level.
|
||||
*/
|
||||
while (GETC(!=, EOF)) {
|
||||
switch (c) {
|
||||
case '\'':
|
||||
case '"':
|
||||
/* skip strings and character constants */
|
||||
skip_string(c);
|
||||
break;
|
||||
case '/':
|
||||
/* skip comments */
|
||||
if (GETC(==, '*'))
|
||||
skip_comment();
|
||||
break;
|
||||
case '(':
|
||||
level++;
|
||||
break;
|
||||
case ')':
|
||||
if (level == 0)
|
||||
goto fnd;
|
||||
level--;
|
||||
break;
|
||||
case '\n':
|
||||
SETLINE;
|
||||
}
|
||||
}
|
||||
return (NO);
|
||||
fnd:
|
||||
/*
|
||||
* we assume that the character after a function's right paren
|
||||
* is a token character if it's a function and a non-token
|
||||
* character if it's a declaration. Comments don't count...
|
||||
*/
|
||||
for (;;) {
|
||||
while (GETC(!=, EOF) && iswhite(c))
|
||||
if (c == '\n')
|
||||
SETLINE;
|
||||
if (intoken(c) || c == '{')
|
||||
break;
|
||||
if (c == '/' && GETC(==, '*'))
|
||||
skip_comment();
|
||||
else { /* don't ever "read" '/' */
|
||||
(void)ungetc(c, inf);
|
||||
return (NO);
|
||||
}
|
||||
}
|
||||
if (c != '{')
|
||||
(void)skip_key('{');
|
||||
return (YES);
|
||||
}
|
||||
|
||||
/*
|
||||
* hash_entry --
|
||||
* handle a line starting with a '#'
|
||||
*/
|
||||
static void
|
||||
hash_entry(void)
|
||||
{
|
||||
int c; /* character read */
|
||||
int curline; /* line started on */
|
||||
char *sp; /* buffer pointer */
|
||||
static char tok[MAXTOKEN]; /* storage buffer */
|
||||
|
||||
curline = lineno;
|
||||
for (sp = tok;;) { /* get next token */
|
||||
if (GETC(==, EOF))
|
||||
return;
|
||||
if (iswhite(c))
|
||||
break;
|
||||
*sp++ = c;
|
||||
}
|
||||
*sp = EOS;
|
||||
if (memcmp(tok, "define", 6)) /* only interested in #define's */
|
||||
goto skip;
|
||||
for (;;) { /* this doesn't handle "#define \n" */
|
||||
if (GETC(==, EOF))
|
||||
return;
|
||||
if (!iswhite(c))
|
||||
break;
|
||||
}
|
||||
for (sp = tok;;) { /* get next token */
|
||||
*sp++ = c;
|
||||
if (GETC(==, EOF))
|
||||
return;
|
||||
/*
|
||||
* this is where it DOESN'T handle
|
||||
* "#define \n"
|
||||
*/
|
||||
if (!intoken(c))
|
||||
break;
|
||||
}
|
||||
*sp = EOS;
|
||||
if (dflag || c == '(') { /* only want macros */
|
||||
getline();
|
||||
pfnote(tok, curline);
|
||||
}
|
||||
skip: if (c == '\n') { /* get rid of rest of define */
|
||||
SETLINE
|
||||
if (*(sp - 1) != '\\')
|
||||
return;
|
||||
}
|
||||
(void)skip_key('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* str_entry --
|
||||
* handle a struct, union or enum entry
|
||||
*/
|
||||
static int
|
||||
str_entry(int c)
|
||||
{
|
||||
int curline; /* line started on */
|
||||
char *sp; /* buffer pointer */
|
||||
static char tok[LINE_MAX]; /* storage buffer */
|
||||
|
||||
curline = lineno;
|
||||
while (iswhite(c))
|
||||
if (GETC(==, EOF))
|
||||
return (NO);
|
||||
if (c == '{') /* it was "struct {" */
|
||||
return (YES);
|
||||
for (sp = tok;;) { /* get next token */
|
||||
*sp++ = c;
|
||||
if (GETC(==, EOF))
|
||||
return (NO);
|
||||
if (!intoken(c))
|
||||
break;
|
||||
}
|
||||
switch (c) {
|
||||
case '{': /* it was "struct foo{" */
|
||||
--sp;
|
||||
break;
|
||||
case '\n': /* it was "struct foo\n" */
|
||||
SETLINE;
|
||||
/*FALLTHROUGH*/
|
||||
default: /* probably "struct foo " */
|
||||
while (GETC(!=, EOF))
|
||||
if (!iswhite(c))
|
||||
break;
|
||||
if (c != '{') {
|
||||
(void)ungetc(c, inf);
|
||||
return (NO);
|
||||
}
|
||||
}
|
||||
*sp = EOS;
|
||||
pfnote(tok, curline);
|
||||
return (YES);
|
||||
}
|
||||
|
||||
/*
|
||||
* skip_comment --
|
||||
* skip over comment
|
||||
*/
|
||||
void
|
||||
skip_comment(void)
|
||||
{
|
||||
int c; /* character read */
|
||||
int star; /* '*' flag */
|
||||
|
||||
for (star = 0; GETC(!=, EOF);)
|
||||
switch(c) {
|
||||
/* comments don't nest, nor can they be escaped. */
|
||||
case '*':
|
||||
star = YES;
|
||||
break;
|
||||
case '/':
|
||||
if (star)
|
||||
return;
|
||||
break;
|
||||
case '\n':
|
||||
SETLINE;
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
star = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* skip_string --
|
||||
* skip to the end of a string or character constant.
|
||||
*/
|
||||
void
|
||||
skip_string(int key)
|
||||
{
|
||||
int c,
|
||||
skip;
|
||||
|
||||
for (skip = NO; GETC(!=, EOF); )
|
||||
switch (c) {
|
||||
case '\\': /* a backslash escapes anything */
|
||||
skip = !skip; /* we toggle in case it's "\\" */
|
||||
break;
|
||||
case '\n':
|
||||
SETLINE;
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
if (c == key && !skip)
|
||||
return;
|
||||
skip = NO;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* skip_key --
|
||||
* skip to next char "key"
|
||||
*/
|
||||
int
|
||||
skip_key(int key)
|
||||
{
|
||||
int c,
|
||||
skip,
|
||||
retval;
|
||||
|
||||
#ifdef __ORCAC203__
|
||||
for (skip = NO, retval = NO; GETC(!=, EOF);)
|
||||
#else
|
||||
for (skip = retval = NO; GETC(!=, EOF);)
|
||||
#endif
|
||||
switch(c) {
|
||||
case '\\': /* a backslash escapes anything */
|
||||
skip = !skip; /* we toggle in case it's "\\" */
|
||||
break;
|
||||
case ';': /* special case for yacc; if one */
|
||||
case '|': /* of these chars occurs, we may */
|
||||
retval = YES; /* have moved out of the rule */
|
||||
break; /* not used by C */
|
||||
case '\'':
|
||||
case '"':
|
||||
/* skip strings and character constants */
|
||||
skip_string(c);
|
||||
break;
|
||||
case '/':
|
||||
/* skip comments */
|
||||
if (GETC(==, '*')) {
|
||||
skip_comment();
|
||||
break;
|
||||
}
|
||||
(void)ungetc(c, inf);
|
||||
c = '/';
|
||||
goto norm;
|
||||
case '\n':
|
||||
SETLINE;
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
norm:
|
||||
if (c == key && !skip)
|
||||
return (retval);
|
||||
skip = NO;
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
# $Id: Makefile,v 1.1 1998/01/24 07:58:57 taubert Exp $
|
||||
|
||||
PROG= ctags
|
||||
SRCS= ctags.c C.c fortran.c lisp.c print.c tree.c yacc.c
|
||||
STACK= 2048
|
||||
|
||||
.INCLUDE: /src/gno/prog.mk
|
|
@ -0,0 +1,214 @@
|
|||
.\" Copyright (c) 1987, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)ctags.1 8.1 (Berkeley) 6/6/93
|
||||
.\"
|
||||
.Dd June 6, 1993
|
||||
.Dt CTAGS 1
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm ctags
|
||||
.Nd create a tags file
|
||||
.Sh SYNOPSIS
|
||||
.Nm ctags
|
||||
.Op Fl BFadtuwvx
|
||||
.Op Fl f Ar tagsfile
|
||||
.Ar name ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm Ctags
|
||||
makes a tags file for
|
||||
.Xr ex 1
|
||||
from the specified C,
|
||||
Pascal, Fortran,
|
||||
.Tn YACC ,
|
||||
lex, and lisp sources.
|
||||
A tags file gives the locations of specified objects in a group of files.
|
||||
Each line of the tags file contains the object name, the file in which it
|
||||
is defined, and a search pattern for the object definition, separated by
|
||||
white-space.
|
||||
Using the
|
||||
.Ar tags
|
||||
file,
|
||||
.Xr ex 1
|
||||
can quickly locate these object definitions.
|
||||
Depending upon the options provided to
|
||||
.Nm ctags ,
|
||||
objects will consist of subroutines, typedefs, defines, structs,
|
||||
enums and unions.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl B
|
||||
use backward searching patterns
|
||||
.Pq Li ?...? .
|
||||
.It Fl F
|
||||
use forward searching patterns
|
||||
.Pq Li /.../
|
||||
(the default).
|
||||
.It Fl a
|
||||
append to
|
||||
.Ar tags
|
||||
file.
|
||||
.It Fl d
|
||||
create tags for
|
||||
.Li #defines
|
||||
that don't take arguments;
|
||||
.Li #defines
|
||||
that take arguments are tagged automatically.
|
||||
.It Fl f
|
||||
Places the tag descriptions in a file called
|
||||
.Ar tagsfile .
|
||||
The default behaviour is to place them in a file called
|
||||
.Ar tags .
|
||||
.It Fl t
|
||||
create tags for typedefs, structs, unions, and enums.
|
||||
.It Fl u
|
||||
update the specified files in the
|
||||
.Ar tags
|
||||
file, that is, all
|
||||
references to them are deleted, and the new values are appended to the
|
||||
file. (Beware: this option is implemented in a way which is rather
|
||||
slow; it is usually faster to simply rebuild the
|
||||
.Ar tags
|
||||
file.)
|
||||
.It Fl v
|
||||
An index of the form expected by
|
||||
.Xr vgrind 1
|
||||
is produced on the standard output. This listing
|
||||
contains the object name, file name, and page number (assuming 64
|
||||
line pages). Since the output will be sorted into lexicographic order,
|
||||
it may be desired to run the output through
|
||||
.Xr sort 1 .
|
||||
Sample use:
|
||||
.Bd -literal -offset indent
|
||||
ctags \-v files \&| sort \-f > index
|
||||
vgrind \-x index
|
||||
.Ed
|
||||
.It Fl w
|
||||
suppress warning diagnostics.
|
||||
.It Fl x
|
||||
.Nm ctags
|
||||
produces a list of object
|
||||
names, the line number and file name on which each is defined, as well
|
||||
as the text of that line and prints this on the standard output. This
|
||||
is a simple index which can be printed out as an off-line readable
|
||||
function index.
|
||||
.El
|
||||
.Pp
|
||||
Files whose names end in
|
||||
.Nm \&.c
|
||||
or
|
||||
.Nm \&.h
|
||||
are assumed to be C
|
||||
source files and are searched for C style routine and macro definitions.
|
||||
Files whose names end in
|
||||
.Nm \&.y
|
||||
are assumed to be
|
||||
.Tn YACC
|
||||
source files.
|
||||
Files whose names end in
|
||||
.Nm \&.l
|
||||
are assumed to be lisp files if their
|
||||
first non-blank character is `;', `(', or `[',
|
||||
otherwise, they are
|
||||
treated as lex files. Other files are first examined to see if they
|
||||
contain any Pascal or Fortran routine definitions, and, if not, are
|
||||
searched for C style definitions.
|
||||
.Pp
|
||||
The tag
|
||||
.Li main
|
||||
is treated specially in C programs. The tag formed
|
||||
is created by prepending
|
||||
.Ar M
|
||||
to the name of the file, with the
|
||||
trailing
|
||||
.Nm \&.c
|
||||
and any leading pathname components removed. This
|
||||
makes use of
|
||||
.Nm ctags
|
||||
practical in directories with more than one
|
||||
program.
|
||||
.Pp
|
||||
Yacc and lex files each have a special tag.
|
||||
.Ar Yyparse
|
||||
is the start
|
||||
of the second section of the yacc file, and
|
||||
.Ar yylex
|
||||
is the start of
|
||||
the second section of the lex file.
|
||||
.Sh FILES
|
||||
.Bl -tag -width tags -compact
|
||||
.It Pa tags
|
||||
default output tags file
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
.Nm Ctags
|
||||
exits with a value of 1 if an error occurred, 0 otherwise.
|
||||
Duplicate objects are not considered errors.
|
||||
.Sh SEE ALSO
|
||||
.Xr ex 1 ,
|
||||
.Xr vi 1
|
||||
.Sh BUGS
|
||||
Recognition of
|
||||
.Nm functions ,
|
||||
.Nm subroutines
|
||||
and
|
||||
.Nm procedures
|
||||
for
|
||||
.Tn FORTRAN
|
||||
and Pascal is done is a very simpleminded way. No attempt
|
||||
is made to deal with block structure; if you have two Pascal procedures
|
||||
in different blocks with the same name you lose.
|
||||
.Nm Ctags
|
||||
doesn't
|
||||
understand about Pascal types.
|
||||
.Pp
|
||||
The method of deciding whether to look for C, Pascal or
|
||||
.Tn FORTRAN
|
||||
functions is a hack.
|
||||
.Pp
|
||||
.Nm Ctags
|
||||
relies on the input being well formed, and any syntactical
|
||||
errors will completely confuse it. It also finds some legal syntax
|
||||
confusing; for example, since it doesn't understand
|
||||
.Li #ifdef Ns 's
|
||||
(incidentally, that's a feature, not a bug), any code with unbalanced
|
||||
braces inside
|
||||
.Li #ifdef Ns 's
|
||||
will cause it to become somewhat disoriented.
|
||||
In a similar fashion, multiple line changes within a definition will
|
||||
cause it to enter the last line of the object, rather than the first, as
|
||||
the searching pattern. The last line of multiple line
|
||||
.Li typedef Ns 's
|
||||
will similarly be noted.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 3.0 .
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1987, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ctags.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <err.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ctags.h"
|
||||
|
||||
/*
|
||||
* ctags: create a tags file
|
||||
*/
|
||||
|
||||
NODE *head; /* head of the sorted binary tree */
|
||||
|
||||
/* boolean "func" (see init()) */
|
||||
bool _wht[256], _etk[256], _itk[256], _btk[256], _gd[256];
|
||||
|
||||
FILE *inf; /* ioptr for current input file */
|
||||
FILE *outf; /* ioptr for tags file */
|
||||
|
||||
long lineftell; /* ftell after getc( inf ) == '\n' */
|
||||
|
||||
int lineno; /* line number of current line */
|
||||
int dflag; /* -d: non-macro defines */
|
||||
int tflag; /* -t: create tags for typedefs */
|
||||
int vflag; /* -v: vgrind style index output */
|
||||
int wflag; /* -w: suppress warnings */
|
||||
int xflag; /* -x: cxref style output */
|
||||
|
||||
char *curfile; /* current input file name */
|
||||
char searchar = '/'; /* use /.../ searches by default */
|
||||
char lbuf[LINE_MAX];
|
||||
|
||||
void init __P((void));
|
||||
void find_entries __P((char *));
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
static char *outfile = "tags"; /* output file */
|
||||
int aflag; /* -a: append to tags */
|
||||
int uflag; /* -u: update tags */
|
||||
int exit_val; /* exit value */
|
||||
int step; /* step through args */
|
||||
int ch; /* getopts char */
|
||||
static char cmd[100]; /* too ugly to explain */
|
||||
|
||||
#ifdef __ORCAC203__
|
||||
aflag = NO; uflag = NO;
|
||||
#else
|
||||
aflag = uflag = NO;
|
||||
#endif
|
||||
while ((ch = getopt(argc, argv, "BFadf:tuwvx")) != EOF)
|
||||
switch(ch) {
|
||||
case 'B':
|
||||
searchar = '?';
|
||||
break;
|
||||
case 'F':
|
||||
searchar = '/';
|
||||
break;
|
||||
case 'a':
|
||||
aflag++;
|
||||
break;
|
||||
case 'd':
|
||||
dflag++;
|
||||
break;
|
||||
case 'f':
|
||||
outfile = optarg;
|
||||
break;
|
||||
case 't':
|
||||
tflag++;
|
||||
break;
|
||||
case 'u':
|
||||
uflag++;
|
||||
break;
|
||||
case 'w':
|
||||
wflag++;
|
||||
break;
|
||||
case 'v':
|
||||
vflag++;
|
||||
case 'x':
|
||||
xflag++;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
if (!argc) {
|
||||
usage: (void)fprintf(stderr,
|
||||
"usage: ctags [-BFadtuwvx] [-f tagsfile] file ...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
#ifdef __ORCAC203__
|
||||
for (exit_val = 0, step = 0; step < argc; ++step)
|
||||
#else
|
||||
for (exit_val = step = 0; step < argc; ++step)
|
||||
#endif
|
||||
if (!(inf = fopen(argv[step], "r"))) {
|
||||
warn("%s", argv[step]);
|
||||
exit_val = 1;
|
||||
}
|
||||
else {
|
||||
curfile = argv[step];
|
||||
find_entries(argv[step]);
|
||||
(void)fclose(inf);
|
||||
}
|
||||
|
||||
if (head)
|
||||
if (xflag)
|
||||
put_entries(head);
|
||||
else {
|
||||
if (uflag) {
|
||||
for (step = 0; step < argc; step++) {
|
||||
(void)sprintf(cmd,
|
||||
"mv %s OTAGS; fgrep -v '\t%s\t' OTAGS >%s; rm OTAGS",
|
||||
outfile, argv[step],
|
||||
outfile);
|
||||
system(cmd);
|
||||
}
|
||||
++aflag;
|
||||
}
|
||||
if (!(outf = fopen(outfile, aflag ? "a" : "w")))
|
||||
err(exit_val, "%s", outfile);
|
||||
put_entries(head);
|
||||
(void)fclose(outf);
|
||||
if (uflag) {
|
||||
(void)sprintf(cmd, "sort -o %s %s",
|
||||
outfile, outfile);
|
||||
system(cmd);
|
||||
}
|
||||
}
|
||||
exit(exit_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* init --
|
||||
* this routine sets up the boolean psuedo-functions which work by
|
||||
* setting boolean flags dependent upon the corresponding character.
|
||||
* Every char which is NOT in that string is false with respect to
|
||||
* the pseudo-function. Therefore, all of the array "_wht" is NO
|
||||
* by default and then the elements subscripted by the chars in
|
||||
* CWHITE are set to YES. Thus, "_wht" of a char is YES if it is in
|
||||
* the string CWHITE, else NO.
|
||||
*/
|
||||
void
|
||||
init(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char *sp;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
#ifdef __ORCAC203__
|
||||
_wht[i] = NO; _etk[i] = NO; _itk[i] = NO; _btk[i] = NO;
|
||||
#else
|
||||
_wht[i] = _etk[i] = _itk[i] = _btk[i] = NO;
|
||||
#endif
|
||||
_gd[i] = YES;
|
||||
}
|
||||
#define CWHITE " \f\t\n"
|
||||
for (sp = CWHITE; *sp; sp++) /* white space chars */
|
||||
_wht[*sp] = YES;
|
||||
#define CTOKEN " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?"
|
||||
for (sp = CTOKEN; *sp; sp++) /* token ending chars */
|
||||
_etk[*sp] = YES;
|
||||
#define CINTOK "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
for (sp = CINTOK; *sp; sp++) /* valid in-token chars */
|
||||
_itk[*sp] = YES;
|
||||
#define CBEGIN "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
|
||||
for (sp = CBEGIN; *sp; sp++) /* token starting chars */
|
||||
_btk[*sp] = YES;
|
||||
#define CNOTGD ",;"
|
||||
for (sp = CNOTGD; *sp; sp++) /* invalid after-function chars */
|
||||
_gd[*sp] = NO;
|
||||
}
|
||||
|
||||
/*
|
||||
* find_entries --
|
||||
* this routine opens the specified file and calls the function
|
||||
* which searches the file.
|
||||
*/
|
||||
void
|
||||
find_entries(char *file)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
lineno = 0; /* should be 1 ?? KB */
|
||||
if (cp = strrchr(file, '.')) {
|
||||
if (cp[1] == 'l' && !cp[2]) {
|
||||
int c;
|
||||
|
||||
for (;;) {
|
||||
if (GETC(==, EOF))
|
||||
return;
|
||||
if (!iswhite(c)) {
|
||||
rewind(inf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#define LISPCHR ";(["
|
||||
/* lisp */ if (strchr(LISPCHR, c)) {
|
||||
l_entries();
|
||||
return;
|
||||
}
|
||||
/* lex */ else {
|
||||
/*
|
||||
* we search all 3 parts of a lex file
|
||||
* for C references. This may be wrong.
|
||||
*/
|
||||
toss_yysec();
|
||||
(void)strcpy(lbuf, "%%$");
|
||||
pfnote("yylex", lineno);
|
||||
rewind(inf);
|
||||
}
|
||||
}
|
||||
/* yacc */ else if (cp[1] == 'y' && !cp[2]) {
|
||||
/*
|
||||
* we search only the 3rd part of a yacc file
|
||||
* for C references. This may be wrong.
|
||||
*/
|
||||
toss_yysec();
|
||||
(void)strcpy(lbuf, "%%$");
|
||||
pfnote("yyparse", lineno);
|
||||
y_entries();
|
||||
}
|
||||
/* fortran */ else if ((cp[1] != 'c' && cp[1] != 'h') && !cp[2]) {
|
||||
if (PF_funcs())
|
||||
return;
|
||||
rewind(inf);
|
||||
}
|
||||
}
|
||||
/* C */ c_entries();
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
Name: ctags
|
||||
Version: 1.0 (October 1997)
|
||||
Shell: GNO
|
||||
Author: Derek Taubert (from FreeBSD 2.1.0 code)
|
||||
Contact: taubert@geeks.org
|
||||
Where: /usr/bin
|
||||
FTP: ground.isca.uiowa.edu apple2.caltech.edu trenco.myrias.com
|
||||
|
||||
Generate tag file for Emacs, vi.
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ctags.h 8.3 (Berkeley) 4/2/94
|
||||
*/
|
||||
|
||||
#define bool char
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
#define EOS '\0'
|
||||
|
||||
#define ENDLINE 50 /* max length of pattern */
|
||||
#define MAXTOKEN 250 /* max size of single token */
|
||||
|
||||
#define SETLINE {++lineno;lineftell = ftell(inf);}
|
||||
#define GETC(op,exp) ((c = getc(inf)) op (int)exp)
|
||||
|
||||
#define iswhite(arg) (_wht[(unsigned)arg]) /* T if char is white */
|
||||
#define begtoken(arg) (_btk[(unsigned)arg]) /* T if char can start token */
|
||||
#define intoken(arg) (_itk[(unsigned)arg]) /* T if char can be in token */
|
||||
#define endtoken(arg) (_etk[(unsigned)arg]) /* T if char ends tokens */
|
||||
#define isgood(arg) (_gd[(unsigned)arg]) /* T if char can be after ')' */
|
||||
|
||||
typedef struct nd_st { /* sorting structure */
|
||||
struct nd_st *left,
|
||||
*right; /* left and right sons */
|
||||
char *entry, /* function or type name */
|
||||
*file, /* file name */
|
||||
*pat; /* search pattern */
|
||||
int lno; /* for -x option */
|
||||
bool been_warned; /* set if noticed dup */
|
||||
} NODE;
|
||||
|
||||
extern char *curfile; /* current input file name */
|
||||
extern NODE *head; /* head of the sorted binary tree */
|
||||
extern FILE *inf; /* ioptr for current input file */
|
||||
extern FILE *outf; /* ioptr for current output file */
|
||||
extern long lineftell; /* ftell after getc( inf ) == '\n' */
|
||||
extern int lineno; /* line number of current line */
|
||||
extern int dflag; /* -d: non-macro defines */
|
||||
extern int tflag; /* -t: create tags for typedefs */
|
||||
extern int vflag; /* -v: vgrind style index output */
|
||||
extern int wflag; /* -w: suppress warnings */
|
||||
extern int xflag; /* -x: cxref style output */
|
||||
extern bool _wht[], _etk[], _itk[], _btk[], _gd[];
|
||||
extern char lbuf[LINE_MAX];
|
||||
extern char *lbp;
|
||||
extern char searchar; /* ex search character */
|
||||
|
||||
extern int cicmp __P((char *));
|
||||
extern void getline __P((void));
|
||||
extern void pfnote __P((char *, int));
|
||||
extern int skip_key __P((int));
|
||||
extern void put_entries __P((NODE *));
|
||||
extern void toss_yysec __P((void));
|
||||
extern void l_entries __P((void));
|
||||
extern void y_entries __P((void));
|
||||
extern int PF_funcs __P((void));
|
||||
extern void c_entries __P((void));
|
||||
extern void skip_comment __P((void));
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Resources for ctags version and comment
|
||||
*
|
||||
* $Id: ctags.rez,v 1.1 1998/01/24 07:59:02 taubert Exp $
|
||||
*/
|
||||
#define PROG "ctags"
|
||||
#define DESC "Generate tag file for Emacs, vi."
|
||||
|
||||
#include "Types.rez"
|
||||
|
||||
/*
|
||||
* Version
|
||||
*/
|
||||
resource rVersion (1, purgeable3) {
|
||||
{ 1, 0, 0, /* Version 1.0.0 */
|
||||
release, /* development|alpha|beta|final|release */
|
||||
0 }, /* non-final release number */
|
||||
verUS, /* Country */
|
||||
PROG, /* Program name */
|
||||
DESC " Released with GNO/ME."
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Comment
|
||||
*/
|
||||
resource rComment (1, purgeable3) {
|
||||
PROG " v1.0 (October 1997)\n"
|
||||
"GNO utility: " DESC "\n"
|
||||
"Ported from FreeBSD 2.1.0 code by Derek Taubert."
|
||||
};
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)fortran.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ctags.h"
|
||||
|
||||
static void takeprec __P((void));
|
||||
|
||||
char *lbp; /* line buffer pointer */
|
||||
|
||||
int
|
||||
PF_funcs(void)
|
||||
{
|
||||
bool pfcnt; /* pascal/fortran functions found */
|
||||
char *cp;
|
||||
static char tok[MAXTOKEN];
|
||||
|
||||
for (pfcnt = NO;;) {
|
||||
lineftell = ftell(inf);
|
||||
if (!fgets(lbuf, sizeof(lbuf), inf))
|
||||
return (pfcnt);
|
||||
++lineno;
|
||||
lbp = lbuf;
|
||||
if (*lbp == '%') /* Ratfor escape to fortran */
|
||||
++lbp;
|
||||
for (; isspace(*lbp); ++lbp)
|
||||
continue;
|
||||
if (!*lbp)
|
||||
continue;
|
||||
switch (*lbp | ' ') { /* convert to lower-case */
|
||||
case 'c':
|
||||
if (cicmp("complex") || cicmp("character"))
|
||||
takeprec();
|
||||
break;
|
||||
case 'd':
|
||||
if (cicmp("double")) {
|
||||
for (; isspace(*lbp); ++lbp)
|
||||
continue;
|
||||
if (!*lbp)
|
||||
continue;
|
||||
if (cicmp("precision"))
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
if (cicmp("integer"))
|
||||
takeprec();
|
||||
break;
|
||||
case 'l':
|
||||
if (cicmp("logical"))
|
||||
takeprec();
|
||||
break;
|
||||
case 'r':
|
||||
if (cicmp("real"))
|
||||
takeprec();
|
||||
break;
|
||||
}
|
||||
for (; isspace(*lbp); ++lbp)
|
||||
continue;
|
||||
if (!*lbp)
|
||||
continue;
|
||||
switch (*lbp | ' ') {
|
||||
case 'f':
|
||||
if (cicmp("function"))
|
||||
break;
|
||||
continue;
|
||||
case 'p':
|
||||
if (cicmp("program") || cicmp("procedure"))
|
||||
break;
|
||||
continue;
|
||||
case 's':
|
||||
if (cicmp("subroutine"))
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
for (; isspace(*lbp); ++lbp)
|
||||
continue;
|
||||
if (!*lbp)
|
||||
continue;
|
||||
for (cp = lbp + 1; *cp && intoken(*cp); ++cp)
|
||||
continue;
|
||||
if (cp = lbp + 1)
|
||||
continue;
|
||||
*cp = EOS;
|
||||
(void)strcpy(tok, lbp);
|
||||
getline(); /* process line for ex(1) */
|
||||
pfnote(tok, lineno);
|
||||
pfcnt = YES;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* cicmp --
|
||||
* do case-independent strcmp
|
||||
*/
|
||||
int
|
||||
cicmp(char *cp)
|
||||
{
|
||||
int len;
|
||||
char *bp;
|
||||
|
||||
for (len = 0, bp = lbp; *cp && (*cp &~ ' ') == (*bp++ &~ ' ');
|
||||
++cp, ++len)
|
||||
continue;
|
||||
if (!*cp) {
|
||||
lbp += len;
|
||||
return (YES);
|
||||
}
|
||||
return (NO);
|
||||
}
|
||||
|
||||
static void
|
||||
takeprec(void)
|
||||
{
|
||||
for (; isspace(*lbp); ++lbp)
|
||||
continue;
|
||||
if (*lbp == '*') {
|
||||
for (++lbp; isspace(*lbp); ++lbp)
|
||||
continue;
|
||||
if (!isdigit(*lbp))
|
||||
--lbp; /* force failure */
|
||||
else
|
||||
while (isdigit(*++lbp))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)lisp.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ctags.h"
|
||||
|
||||
/*
|
||||
* lisp tag functions
|
||||
* just look for (def or (DEF
|
||||
*/
|
||||
void
|
||||
l_entries(void)
|
||||
{
|
||||
int special;
|
||||
char *cp;
|
||||
char savedc;
|
||||
static char tok[MAXTOKEN];
|
||||
|
||||
for (;;) {
|
||||
lineftell = ftell(inf);
|
||||
if (!fgets(lbuf, sizeof(lbuf), inf))
|
||||
return;
|
||||
++lineno;
|
||||
lbp = lbuf;
|
||||
if (!cicmp("(def"))
|
||||
continue;
|
||||
special = NO;
|
||||
switch(*lbp | ' ') {
|
||||
case 'm':
|
||||
if (cicmp("method"))
|
||||
special = YES;
|
||||
break;
|
||||
case 'w':
|
||||
if (cicmp("wrapper") || cicmp("whopper"))
|
||||
special = YES;
|
||||
}
|
||||
for (; !isspace(*lbp); ++lbp)
|
||||
continue;
|
||||
for (; isspace(*lbp); ++lbp)
|
||||
continue;
|
||||
for (cp = lbp; *cp && *cp != '\n'; ++cp)
|
||||
continue;
|
||||
*cp = EOS;
|
||||
if (special) {
|
||||
if (!(cp = strchr(lbp, ')')))
|
||||
continue;
|
||||
for (; cp >= lbp && *cp != ':'; --cp)
|
||||
continue;
|
||||
if (cp < lbp)
|
||||
continue;
|
||||
lbp = cp;
|
||||
for (; *cp && *cp != ')' && *cp != ' '; ++cp)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
for (cp = lbp + 1;
|
||||
*cp && *cp != '(' && *cp != ' '; ++cp)
|
||||
continue;
|
||||
savedc = *cp;
|
||||
*cp = EOS;
|
||||
(void)strcpy(tok, lbp);
|
||||
*cp = savedc;
|
||||
getline();
|
||||
pfnote(tok, lineno);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)print.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __GNO__
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "ctags.h"
|
||||
|
||||
/*
|
||||
* getline --
|
||||
* get the line the token of interest occurred on,
|
||||
* prepare it for printing.
|
||||
*/
|
||||
void
|
||||
getline(void)
|
||||
{
|
||||
long saveftell;
|
||||
int c;
|
||||
int cnt;
|
||||
char *cp;
|
||||
|
||||
saveftell = ftell(inf);
|
||||
(void)fseek(inf, lineftell, L_SET);
|
||||
if (xflag)
|
||||
for (cp = lbuf; GETC(!=, '\n'); *cp++ = c)
|
||||
continue;
|
||||
/*
|
||||
* do all processing here, so we don't step through the
|
||||
* line more than once; means you don't call this routine
|
||||
* unless you're sure you've got a keeper.
|
||||
*/
|
||||
else for (cnt = 0, cp = lbuf; GETC(!=, EOF) && cnt < ENDLINE; ++cnt) {
|
||||
if (c == '\\') { /* backslashes */
|
||||
if (cnt > ENDLINE - 2)
|
||||
break;
|
||||
*cp++ = '\\'; *cp++ = '\\';
|
||||
++cnt;
|
||||
}
|
||||
#ifdef __GNO__
|
||||
else if (c == '*' || c == '[' || c == ']' ||
|
||||
c == '.' || c == '^' || c == '$' ||
|
||||
c == (int)searchar) /* search character */
|
||||
#else
|
||||
else if (c == (int)searchar) /* search character */
|
||||
#endif
|
||||
{
|
||||
if (cnt > ENDLINE - 2)
|
||||
break;
|
||||
*cp++ = '\\'; *cp++ = c;
|
||||
++cnt;
|
||||
}
|
||||
else if (c == '\n') { /* end of keep */
|
||||
*cp++ = '$'; /* can find whole line */
|
||||
break;
|
||||
}
|
||||
else
|
||||
*cp++ = c;
|
||||
}
|
||||
*cp = EOS;
|
||||
(void)fseek(inf, saveftell, L_SET);
|
||||
}
|
||||
|
||||
/*
|
||||
* put_entries --
|
||||
* write out the tags
|
||||
*/
|
||||
void
|
||||
put_entries(NODE *node)
|
||||
{
|
||||
if (node->left)
|
||||
put_entries(node->left);
|
||||
if (vflag)
|
||||
printf("%s %s %d\n",
|
||||
node->entry, node->file, (node->lno + 63) / 64);
|
||||
else if (xflag)
|
||||
printf("%-16s%4d %-16s %s\n",
|
||||
node->entry, node->lno, node->file, node->pat);
|
||||
else
|
||||
fprintf(outf, "%s\t%s\t%c^%s%c\n",
|
||||
node->entry, node->file, searchar, node->pat, searchar);
|
||||
if (node->right)
|
||||
put_entries(node->right);
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
CBEGIN ctags.c /^#define CBEGIN "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefg/
|
||||
CINTOK ctags.c /^#define CINTOK "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefg/
|
||||
CNOTGD ctags.c /^#define CNOTGD ",;"$/
|
||||
CTOKEN ctags.c /^#define CTOKEN " \\t\\n\\"'#()\[\]{}=-+%\*\/&|\^~!/
|
||||
CWHITE ctags.c /^#define CWHITE " \\f\\t\\n"$/
|
||||
ENDLINE ctags.h /^#define ENDLINE 50 \/\* max length of pattern \*/
|
||||
EOS ctags.h /^#define EOS '\\0'$/
|
||||
GETC ctags.h /^#define GETC(op,exp) ((c = getc(inf)) op (int)exp)/
|
||||
LISPCHR ctags.c /^#define LISPCHR ";(\["$/
|
||||
MAXTOKEN ctags.h /^#define MAXTOKEN 250 \/\* max size of single toke/
|
||||
Mctags ctags.c /^main(int argc, char \*\*argv)$/
|
||||
NO ctags.h /^#define NO 0$/
|
||||
NODE ctags.h /^} NODE;$/
|
||||
PF_funcs fortran.c /^PF_funcs(void)$/
|
||||
SETLINE ctags.h /^#define SETLINE {++lineno;lineftell = ftell(inf);/
|
||||
YES ctags.h /^#define YES 1$/
|
||||
add_node tree.c /^add_node(NODE \*node, NODE \*cur_node)$/
|
||||
begtoken ctags.h /^#define begtoken(arg) (_btk\[(unsigned)arg\]) \/\*/
|
||||
bool ctags.h /^#define bool char$/
|
||||
c_entries C.c /^c_entries(void)$/
|
||||
cicmp fortran.c /^cicmp(char \*cp)$/
|
||||
endtoken ctags.h /^#define endtoken(arg) (_etk\[(unsigned)arg\]) \/\*/
|
||||
find_entries ctags.c /^find_entries(char \*file)$/
|
||||
free_tree tree.c /^free_tree(NODE \*node)$/
|
||||
func_entry C.c /^func_entry(void)$/
|
||||
getline print.c /^getline(void)$/
|
||||
hash_entry C.c /^hash_entry(void)$/
|
||||
init ctags.c /^init(void)$/
|
||||
intoken ctags.h /^#define intoken(arg) (_itk\[(unsigned)arg\]) \/\* /
|
||||
isgood ctags.h /^#define isgood(arg) (_gd\[(unsigned)arg\]) \/\* T /
|
||||
iswhite ctags.h /^#define iswhite(arg) (_wht\[(unsigned)arg\]) \/\* /
|
||||
l_entries lisp.c /^l_entries(void)$/
|
||||
pfnote tree.c /^pfnote(char \*name, int ln)$/
|
||||
put_entries print.c /^put_entries(NODE \*node)$/
|
||||
skip_comment C.c /^skip_comment(void)$/
|
||||
skip_key C.c /^skip_key(int key)$/
|
||||
skip_string C.c /^skip_string(int key)$/
|
||||
str_entry C.c /^str_entry(int c)$/
|
||||
takeprec fortran.c /^takeprec(void)$/
|
||||
toss_yysec yacc.c /^toss_yysec(void)$/
|
||||
y_entries yacc.c /^y_entries(void)$/
|
|
@ -0,0 +1,67 @@
|
|||
int bar = (1 + 5);
|
||||
|
||||
FOO("here is a #define test: ) {");
|
||||
char sysent[20];
|
||||
int nsysent = sizeof (sysent) / sizeof (sysent[0]);
|
||||
/*
|
||||
* now is the time for a comment.
|
||||
* four lines in length...
|
||||
*/struct struct_xtra{int list;};r4(x,y){};typedef struct{int bar;}struct_xxe;
|
||||
#define FOO BAR
|
||||
struct struct_three {
|
||||
int list;
|
||||
};
|
||||
#define SINGLE
|
||||
int BAD();
|
||||
enum color {red, green, gold, brown};
|
||||
char qq[] = " quote(one,two) {int bar;} ";
|
||||
typedef struct {
|
||||
int bar;
|
||||
struct struct_two {
|
||||
int foo;
|
||||
union union_3 {
|
||||
struct struct_three entry;
|
||||
char size[25];
|
||||
};
|
||||
struct last {
|
||||
struct struct_three xentry;
|
||||
char list[34];
|
||||
};
|
||||
};
|
||||
} struct_one;
|
||||
#define TWOLINE ((MAXLIST + FUTURE + 15) \
|
||||
/ (time_to_live ? 3 : 4))
|
||||
#if (defined(BAR))
|
||||
int bar;
|
||||
#endif
|
||||
#define MULTIPLE {\
|
||||
multiple(one,two); \
|
||||
lineno++; \
|
||||
callroute(one,two); \
|
||||
}
|
||||
#if defined(BAR)
|
||||
int bar;
|
||||
#endif
|
||||
union union_one {
|
||||
struct struct_three s3;
|
||||
char foo[25];
|
||||
};
|
||||
#define XYZ(A,B) (A + B / 2) * (3 - 26 + l_lineno)
|
||||
routine1(one,two) /* comments here are fun... */
|
||||
struct {
|
||||
int entry;
|
||||
char bar[34];
|
||||
} *one;
|
||||
char two[10];
|
||||
{
|
||||
typedef unsigned char u_char;
|
||||
register struct buf *bp;
|
||||
five(one,two);
|
||||
}
|
||||
routine2 (one,two) { puts("hello\n"); }
|
||||
routine3
|
||||
(one,
|
||||
two) { puts("world\n"); }
|
||||
routine4(int one, char (*two)(void)) /* test ANSI arguments */
|
||||
{
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)tree.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <err.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ctags.h"
|
||||
|
||||
static void add_node __P((NODE *, NODE *));
|
||||
static void free_tree __P((NODE *));
|
||||
|
||||
/*
|
||||
* pfnote --
|
||||
* enter a new node in the tree
|
||||
*/
|
||||
void
|
||||
pfnote(char *name, int ln)
|
||||
{
|
||||
NODE *np;
|
||||
char *fp;
|
||||
static char nbuf[MAXTOKEN];
|
||||
|
||||
/*NOSTRICT*/
|
||||
if (!(np = (NODE *)malloc(sizeof(NODE)))) {
|
||||
warnx("too many entries to sort");
|
||||
put_entries(head);
|
||||
free_tree(head);
|
||||
/*NOSTRICT*/
|
||||
#ifdef __ORCAC203__
|
||||
np = (NODE *)malloc(sizeof(NODE));
|
||||
if (!(head = np))
|
||||
#else
|
||||
if (!(head = np = (NODE *)malloc(sizeof(NODE))))
|
||||
#endif
|
||||
err(1, "out of space");
|
||||
}
|
||||
if (!xflag && !strcmp(name, "main")) {
|
||||
if (!(fp = strrchr(curfile, '/')))
|
||||
fp = curfile;
|
||||
else
|
||||
++fp;
|
||||
(void)sprintf(nbuf, "M%s", fp);
|
||||
fp = strrchr(nbuf, '.');
|
||||
if (fp && !fp[2])
|
||||
*fp = EOS;
|
||||
name = nbuf;
|
||||
}
|
||||
if (!(np->entry = strdup(name)))
|
||||
err(1, NULL);
|
||||
np->file = curfile;
|
||||
np->lno = ln;
|
||||
#ifdef __ORCAC203__
|
||||
np->left = 0; np->right = 0;
|
||||
#else
|
||||
np->left = np->right = 0;
|
||||
#endif
|
||||
if (!(np->pat = strdup(lbuf)))
|
||||
err(1, NULL);
|
||||
if (!head)
|
||||
head = np;
|
||||
else
|
||||
add_node(np, head);
|
||||
}
|
||||
|
||||
static void
|
||||
add_node(NODE *node, NODE *cur_node)
|
||||
{
|
||||
int dif;
|
||||
|
||||
dif = strcmp(node->entry, cur_node->entry);
|
||||
if (!dif) {
|
||||
if (node->file == cur_node->file) {
|
||||
if (!wflag)
|
||||
fprintf(stderr, "Duplicate entry in file %s, line %d: %s\nSecond entry ignored\n", node->file, lineno, node->entry);
|
||||
return;
|
||||
}
|
||||
if (!cur_node->been_warned)
|
||||
if (!wflag)
|
||||
fprintf(stderr, "Duplicate entry in files %s and %s: %s (Warning only)\n", node->file, cur_node->file, node->entry);
|
||||
cur_node->been_warned = YES;
|
||||
}
|
||||
else if (dif < 0)
|
||||
if (cur_node->left)
|
||||
add_node(node, cur_node->left);
|
||||
else
|
||||
cur_node->left = node;
|
||||
else if (cur_node->right)
|
||||
add_node(node, cur_node->right);
|
||||
else
|
||||
cur_node->right = node;
|
||||
}
|
||||
|
||||
static void
|
||||
free_tree(NODE *node)
|
||||
{
|
||||
while (node) {
|
||||
if (node->right)
|
||||
free_tree(node->right);
|
||||
free(node);
|
||||
node = node->left;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)yacc.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ctags.h"
|
||||
|
||||
/*
|
||||
* y_entries:
|
||||
* find the yacc tags and put them in.
|
||||
*/
|
||||
void
|
||||
y_entries(void)
|
||||
{
|
||||
int c;
|
||||
char *sp;
|
||||
bool in_rule;
|
||||
static char tok[MAXTOKEN];
|
||||
|
||||
in_rule = NO;
|
||||
|
||||
while (GETC(!=, EOF))
|
||||
switch (c) {
|
||||
case '\n':
|
||||
SETLINE;
|
||||
/* FALLTHROUGH */
|
||||
case ' ':
|
||||
case '\f':
|
||||
case '\r':
|
||||
case '\t':
|
||||
break;
|
||||
case '{':
|
||||
if (skip_key('}'))
|
||||
in_rule = NO;
|
||||
break;
|
||||
case '\'':
|
||||
case '"':
|
||||
if (skip_key(c))
|
||||
in_rule = NO;
|
||||
break;
|
||||
case '%':
|
||||
if (GETC(==, '%'))
|
||||
return;
|
||||
(void)ungetc(c, inf);
|
||||
break;
|
||||
case '/':
|
||||
if (GETC(==, '*'))
|
||||
skip_comment();
|
||||
else
|
||||
(void)ungetc(c, inf);
|
||||
break;
|
||||
case '|':
|
||||
case ';':
|
||||
in_rule = NO;
|
||||
break;
|
||||
default:
|
||||
if (in_rule || !isalpha(c) && c != '.' && c != '_')
|
||||
break;
|
||||
sp = tok;
|
||||
*sp++ = c;
|
||||
while (GETC(!=, EOF) && (intoken(c) || c == '.'))
|
||||
*sp++ = c;
|
||||
*sp = EOS;
|
||||
getline(); /* may change before ':' */
|
||||
while (iswhite(c)) {
|
||||
if (c == '\n')
|
||||
SETLINE;
|
||||
if (GETC(==, EOF))
|
||||
return;
|
||||
}
|
||||
if (c == ':') {
|
||||
pfnote(tok, lineno);
|
||||
in_rule = YES;
|
||||
}
|
||||
else
|
||||
(void)ungetc(c, inf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* toss_yysec --
|
||||
* throw away lines up to the next "\n%%\n"
|
||||
*/
|
||||
void
|
||||
toss_yysec(void)
|
||||
{
|
||||
int c; /* read character */
|
||||
int state;
|
||||
|
||||
/*
|
||||
* state == 0 : waiting
|
||||
* state == 1 : received a newline
|
||||
* state == 2 : received first %
|
||||
* state == 3 : recieved second %
|
||||
*/
|
||||
lineftell = ftell(inf);
|
||||
for (state = 0; GETC(!=, EOF);)
|
||||
switch (c) {
|
||||
case '\n':
|
||||
++lineno;
|
||||
lineftell = ftell(inf);
|
||||
if (state == 3) /* done! */
|
||||
return;
|
||||
state = 1; /* start over */
|
||||
break;
|
||||
case '%':
|
||||
if (state) /* if 1 or 2 */
|
||||
++state; /* goto 3 */
|
||||
break;
|
||||
default:
|
||||
state = 0; /* reset */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue