⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 etags.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Tags file maker to go with GNUmacs   Copyright (C) 1984, 1987, 1988 Free Software Foundation, Inc. and Ken Arnold    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 1, or (at your option)    any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.In other words, you are welcome to use, share and improve this program.You are forbidden to forbid anyone else to use, share and improvewhat 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#define	TRUE	(1)#define	FALSE	(0)#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;#if 0  /* VMS now provides the `system' function.  */#ifdef VMS#include <descrip.h>voidsystem (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 */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'		 && string_numeric_p (cp + 1))             || (cp[-1] == 'M' && cp[-2] == 'C' && cp[-3] == 'S'		 && string_numeric_p (cp + 1))))    {      Scheme_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);}/* Nonzero if string STR is composed of digits.  */intstring_numeric_p (str)     char *str;{  while (*str)    {      if (*str < '0' || *str > '9')	return 0;    }  return 1;}/* 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -