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

📄 ctags.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
					next = cpp_getc();				}				break;			  case '/':	/* start of a C++ comment */				do				{					ch = cpp_getc();				} while (ch != '\n' && ch != EOF);				break;			  default:	/* some other slash */				cpp_ungetc(ch);			}			token = DELETED;			break;		  case '(':			ch = cpp_getc();			if (ch == '*')			{				token = DELETED;			}			else			{				next = cpp_getc();				while (ch != '{' && ch != EOF && (ch != ')' || next != ';'))/*}*/				{					ch = next;					next = cpp_getc();				}				if (ch == '{')/*}*/				{					cpp_ungetc(ch);				}				else if (next == ';')				{					cpp_ungetc(next);				}				token = ARGS;			}			break;		  case '{':/*}*/			/* don't send the next characters to "refs" */			cpp_refsok = FALSE;			/* skip ahead to closing '}', or to embedded '{' */			do			{				ch = cpp_getc();			} while (ch != '{' && ch != '}' && ch != EOF);			/* if has embedded '{', then skip to '}' in column 1 */			if (ch == '{') /*}*/			{				ch = cpp_getc();				next = cpp_getc();				while (ch != EOF && (ch != '\n' || next != '}'))/*{*/				{					ch = next;					next = cpp_getc();				}			}			/* resume "refs" processing */			cpp_refsok = TRUE;			cpp_echo('}');			token = BODY;			break;		  case '[':			/* skip to matching ']' */			do			{				ch = cpp_getc();			} while (ch != ']' && ch != EOF);			token = DELETED;			break;		  case '=':		  	/* skip to next ';' */			do			{				ch = cpp_getc();				/* leave array initializers out of "refs" */				if (ch == '{')				{					cpp_refsok = FALSE;				}			} while (ch != ';' && ch != EOF);			/* resume echoing to "refs" */			if (!cpp_refsok)			{				cpp_refsok = TRUE;				cpp_echo('}');				cpp_echo(';');			}			token = SEMICOLON;			break;		  case EOF:			token = EOF;			break;		  default:			/* is this the start of a name/keyword? */			if (isalpha(ch) || ch == '_')			{				/* collect the whole word */				lex_name[0] = ch;				for (i = 1, ch = cpp_getc();				     i < BLKSIZE - 1 && (isalnum(ch) || ch == '_');				     i++, ch = cpp_getc())				{					lex_name[i] = ch;				}				lex_name[i] = '\0';				cpp_ungetc(ch);				/* is it a reserved word? */				if (!strcmp(lex_name, "typedef"))				{					token = TYPEDEF;					lex_seek = -1L;				}				else if (!strcmp(lex_name, "static")				      || !strcmp(lex_name, "private")				      || !strcmp(lex_name, "PRIVATE"))				{					token = STATIC;					lex_seek = -1L;				}				else if (!strcmp(lex_name, "extern")				      || !strcmp(lex_name, "EXTERN")				      || !strcmp(lex_name, "FORWARD"))				{					token = EXTERN;					lex_seek = -1L;				}				else				{					token = NAME;					lex_seek = file_seek;				}			}			else /* not part of a name/keyword */			{				token = DELETED;			}		} /* end switch(ch) */	} while (token == DELETED);	return token;}/* -------------------------------------------------------------------------- *//* This is the parser.  It locates tag candidates, and then decides whether to * generate a tag for them. *//* This function generates a tag for the object in lex_name, whose tag line is * located at a given seek offset. */void maketag(scope, seek)	int	scope;	/* 0 if global, or STATIC if static */	long	seek;	/* the seek offset of the line */{	/* output the tagname and filename fields */	if (scope == EXTERN)	{		/* whoa!  we should *never* output a tag for "extern" decl */		return;	}	else if (scope == STATIC)	{		fprintf(tags, "%s:%s\t%s\t", file_name, lex_name, file_name);	}	else	{		fprintf(tags, "%s\t%s\t", lex_name, file_name);	}	/* output the target line */	putc('/', tags);	putc('^', tags);	file_copyline(seek, tags);	putc('$', tags);	putc('/', tags);	putc('\n', tags);}/* This function parses a source file, adding any tags that it finds */void ctags(name)	char	*name;	/* the name of a source file to be checked */{	int	prev;	/* the previous token from the source file */	int	token;	/* the current token from the source file */	int	scope;	/* normally 0, but could be a TYPEDEF or STATIC token */	int	gotname;/* boolean: does lex_name contain a tag candidate? */	long	tagseek;/* start of line that contains lex_name */	/* open the file */	cpp_open(name);	/* reset */	scope = 0;	gotname = FALSE;	token = SEMICOLON;	/* parse until the end of the file */	while (prev = token, (token = lex_gettoken()) != EOF)	{		/* scope keyword? */		if (token == TYPEDEF || token == STATIC || token == EXTERN)		{			scope = token;			gotname = FALSE;			continue;		}		/* name of a possible tag candidate? */		if (token == NAME)		{			tagseek = file_seek;			gotname = TRUE;			continue;		}		/* if NAME BODY, without ARGS, then NAME is a struct tag */		if (gotname && token == BODY && prev != ARGS)		{			gotname = FALSE;						/* ignore if in typedef -- better name is coming soon */			if (scope == TYPEDEF)			{				continue;			}			/* generate a tag, if -t and maybe -s */			if (incl_types && (file_header || incl_static))			{				maketag(file_header ? 0 : STATIC, tagseek);			}		}		/* If NAME ARGS BODY, then NAME is a function */		if (gotname && prev == ARGS && token == BODY)		{			gotname = FALSE;						/* generate a tag, maybe checking -s */			if (scope != STATIC || incl_static)			{				maketag(scope, tagseek);			}		}		/* If NAME SEMICOLON or NAME COMMA, then NAME is var/typedef */		if (gotname && (token == SEMICOLON || token == COMMA))		{			gotname = FALSE;			/* generate a tag, if -v/-t and maybe -s */			if (scope == TYPEDEF && incl_types && (file_header || incl_static)			 || scope == STATIC && incl_vars && incl_static			 || incl_vars)			{				/* a TYPEDEF outside of a header is STATIC */				if (scope == TYPEDEF && !file_header)				{					maketag(STATIC, tagseek);				}				else /* use whatever scope was declared */				{					maketag(scope, tagseek);				}			}		}		/* reset after a semicolon or ARGS BODY pair */		if (token == SEMICOLON || (prev == ARGS && token == BODY))		{			scope = 0;			gotname = FALSE;		}	}	/* The source file will be automatically closed */}/* -------------------------------------------------------------------------- */void usage(){	fprintf(stderr, "usage: ctags [flags] filenames...\n");	fprintf(stderr, "\t-s  include static functions\n");	fprintf(stderr, "\t-t  include typedefs\n");	fprintf(stderr, "\t-v  include variable declarations\n");	fprintf(stderr, "\t-r  generate a \"refs\" file, too\n");	fprintf(stderr, "\t-a  append to \"tags\", instead of overwriting\n");	exit(2);}#if AMIGA# include "amiwild.c"#endif#if VMS# include "vmswild.c"#endifmain(argc, argv)	int	argc;	char	**argv;{	int	i, j;#if MSDOS || TOS	char	**wildexpand();	argv = wildexpand(&argc, argv);#endif	/* build the tables used by the ctype macros */	_ct_init("");	/* parse the option flags */	for (i = 1; i < argc && argv[i][0] == '-'; i++)	{		for (j = 1; argv[i][j]; j++)		{			switch (argv[i][j])			{			  case 's':	incl_static = TRUE;	break;			  case 't':	incl_types = TRUE;	break;			  case 'v':	incl_vars = TRUE;	break;			  case 'r':	make_refs = TRUE;	break;			  case 'a':	append_files = TRUE;	break;			  default:	usage();			}		}	}	/* There should always be at least one source file named in args */	if (i == argc)	{		usage();	}	/* open the "tags" and maybe "refs" files */	tags = fopen(TAGS, append_files ? "a" : "w");	if (!tags)	{		perror(TAGS);		exit(3);	}	if (make_refs)	{		refs = fopen(REFS, append_files ? "a" : "w");		if (!refs)		{			perror(REFS);			exit(4);		}	}	/* parse each source file */	for (; i < argc; i++)	{		ctags(argv[i]);	}	/* close "tags" and maybe "refs" */	fclose(tags);	if (make_refs)	{		fclose(refs);	}#ifdef SORT		/* This is a hack which will sort the tags list.   It should		 * on UNIX and OS-9.  You may have trouble with csh.   Note		 * that the tags list only has to be sorted if you intend to		 * use it with the real vi;  elvis permits unsorted tags.		 */# if OSK		system("qsort tags >-_tags; -nx; del tags; rename _tags tags");# else			system("sort tags >_tags$$; mv _tags$$ tags");# endif#endif	exit(0);	/*NOTREACHED*/}#if MSDOS || TOS# define WILDCARD_NO_MAIN# include "wildcard.c"#endif

⌨️ 快捷键说明

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