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

📄 ref.c

📁 操作系统源代码
💻 C
字号:
/* ref2.c *//* This is a totally rewritten version of ref.  This version looks for the * desired function name in the "tags" file, and then reads the header out * from the source file.  There is no longer any need for a "refs" file. * * Usage:	ref [-a] [-t] [-f file] [-c class] tag * Options:	-t	   output tag info, not the description *		-f file	   default filename for static functions *		-c class   default class names for class functions */#include <stdio.h>#include "config.h"extern char	*getenv();extern char	*fgets();/* This is the default path that is searched for tags */#if OSK# define DEFTAGPATH ".:/dd/defs:/dd/defs/sys:/dd/usr/src/lib:../lib:/dd/usr/lib"#else# if ANY_UNIX#  define DEFTAGPATH ".:/usr/include:/usr/include/sys:/usr/src/lib:../lib:/usr/local/lib"# else#  if MSDOS || TOS#   define DEFTAGPATH ".;C:\\include;C:\\include\\sys;C:\\lib;..\\lib"#   define SEP ';'#  else#   if AMIGA#    define DEFTAGPATH ".;Include:;Include:sys"#    define SEP ';'#   else /* any other OS */#    define DEFTAGPATH "."#   endif#  endif# endif#endif#ifndef SEP# define SEP ':'#endif/* These variables reflect the command-line options given by the user. */int	taginfo;	/* boolean: give only the tag info? (not header?) */char	*def_file;	/* default filename for static functions */char	*def_class;	/* default classname for class members */int	colons;		/* #colons in tag: 0=normal, 1=static, 2=member *//* This function checks for a tag in the "tags" file of given directory. * If the tag is found, then it returns a pointer to a static buffer which * contains the filename, a tab character, and a linespec for finding the * the tag.  If the tag is not found in the "tags" file, or if the "tags" * file cannot be opened or doesn't exist, then this function returns NULL. */char *cktagdir(tag, dir)	char	*tag;	/* name of the tag to look for */	char	*dir;	/* name of the directory to check */{	char	buf[BLKSIZE];	static char found[BLKSIZE];	FILE	*tfile;	int	len;#if AMIGA	if (dir[strlen(dir) - 1] == COLON)	    sprintf(buf, "%s%s", dir, TAGS);   /* no slash after colon. */	else#endif	/* construct the name of the "tags" file in this directory */	sprintf(buf, "%s%c%s", dir, SLASH, TAGS);	/* Try to open the tags file.  Return NULL if can't open */#if AMIGA	if (buf[0] == '.' && buf[1] == SLASH)	    tfile = fopen(&buf[2], "r");	else#endif	tfile = fopen(buf, "r");	if (!tfile)	{		return (char *)0;	}	/* compute the length of the tagname once */	len = strlen(tag);	/* read lines until we get the one for this tag */	found[0] = '\0';	while (fgets(buf, sizeof buf, tfile))	{		/* is this the one we want? */		if (!strncmp(buf, tag, len) && buf[len] == '\t')		{			/* we've found a match -- remember it */			strcpy(found, buf);			/* if there is no default file, or this match is in			 * the default file, then we've definitely found the			 * one we want.  Break out of the loop now.			 */			if (!def_file || !strncmp(&buf[len + 1], def_file, strlen(def_file)))			{				break;			}		}	}	/* we're through reading */	fclose(tfile);	/* if there's anything in found[], use it */	if (found[0])	{		return &found[len + 1];	}	/* else we didn't find it */	return (char *)0;}/* This function reads a single textline from a binary file.  It returns * the number of bytes read, or 0 at EOF. */int getline(buf, limit, fp)	char	*buf;	/* buffer to read into */	int	limit;	/* maximum characters to read */	FILE	*fp;	/* binary stream to read from */{	int	bytes;	/* number of bytes read so far */	int	ch;	/* single character from file */	for (bytes = 0, ch = 0; ch != '\n' && --limit > 0 && (ch = getc(fp)) != EOF; bytes++)	{#if MSDOS || TOS		/* since this is a binary file, we'll need to manually strip CR's */		if (ch == '\r')		{			continue;		}#endif		*buf++ = ch;	}	*buf = '\0';	return bytes;}/* This function reads a source file, looking for a given tag.  If it finds * the tag, then it displays it and returns TRUE.  Otherwise it returns FALSE. * To display the tag, it attempts to output any introductory comment, the * tag line itself, and any arguments.  Arguments are assumed to immediately * follow the tag line, and start with whitespace.  Comments are assumed to * start with lines that begin with "/*", "//", "(*", or "--", and end at the * tag line or at a blank line. */int lookup(dir, entry)	char	*dir;	/* name of the directory that contains the source */	char	*entry;	/* source filename, <Tab>, linespec */{	char	buf[BLKSIZE];	/* pathname of sourcefile */	long	lnum;		/* line number */	long	here;		/* seek position where current line began */	long	comment;	/* seek position of introductory comment, or -1L */	FILE	*sfile;		/* used for reading the source file */	int	len;		/* length of string */	char	*ptr;	/* construct the pathname of the source file */	strcpy(buf, dir);	ptr = buf + strlen(buf);#if AMIGA	if (ptr[-1] != COLON)#endif	*ptr++ = SLASH;	while (*entry != '\t')	{		*ptr++ = *entry++;	}	*ptr = '\0';	entry++;	/* searching for string or number? */	if (*entry >= '0' && *entry <= '9')	{		/* given a specific line number */		lnum = atol(entry);		entry = (char *)0;	}	else	{		/* given a string -- strip off "/^" and "$/\n" */		entry += 2;		len = strlen(entry) - 2;		if (entry[len - 1] == '$')		{			entry[len - 1] = '\n';		}		lnum = 0L;	}	/* Open the file.  Note that we open the file in binary mode even	 * though we know it is a text file, because ftell() and fseek()	 * don't work on text files.	 */#if MSDOS || TOS	sfile = fopen(buf, "rb");#else# if AMIGA	if (buf[0] == '.' && buf[1] == SLASH)	    sfile = fopen(&buf[2], "r");	else# endif	sfile = fopen(buf, "r");#endif	if (!sfile)	{		/* can't open the real source file.  Try "refs" instead */#if AMIGA		if (dir[strlen(dir) - 1] == COLON)			sprintf(buf, "%srefs", dir);		else#endif		sprintf(buf, "%s%crefs", dir, SLASH);#if MSDOS || TOS		sfile = fopen(buf, "rb");#else# if AMIGA		if (buf[0] == '.' && buf[1] == SLASH)		    sfile = fopen(&buf[2], "r");		else# endif		sfile = fopen(buf, "r");#endif		if (!sfile)		{			/* failed! */			return 0;		}	}	/* search the file */	for (comment = -1L; here = ftell(sfile), getline(buf, BLKSIZE, sfile) > 0; )	{		/* Is this the start/end of a comment? */		if (comment == -1L)		{			/* starting a comment? */			if (buf[0] == '/' && buf[1] == '*'			 || buf[0] == '/' && buf[1] == '/'			 || buf[0] == '(' && buf[1] == '*'			 || buf[0] == '-' && buf[1] == '-')			{				comment = here;			}		}		else		{			/* ending a comment? */			if (buf[0] == '\n' || buf[0] == '#')			{				comment = -1L;			}		}		/* is this the tag line? */		if (--lnum == 0L || (entry && !strncmp(buf, entry, len)))		{			/* if there were introductory comments, show them */			if (comment != -1L)			{				fseek(sfile, comment, 0);				while (comment != here)				{					getline(buf, BLKSIZE, sfile);					fputs(buf, stdout);					comment = ftell(sfile);				}				/* re-fetch the tag line */				fgets(buf, BLKSIZE, sfile);			}			/* show the tag line */			fputs(buf, stdout);			/* show any argument lines */			while (getline(buf, BLKSIZE, sfile) > 0			    && buf[0] != '#'			    && strchr(buf, '{') == (char *)0)			{				fputs(buf, stdout);			}			/* Done!  Close the file, and return TRUE */			fclose(sfile);			return 1;		}	}	/* not found -- return FALSE */	return 0;}/* This function searches through the entire search path for a given tag. * If it finds the tag, then it displays the info and returns TRUE; * otherwise it returns FALSE. */int find(tag)	char	*tag;	/* the tag to look up */{	char	*tagpath;	char	dir[80];	char	*ptr;	int	len;	if (colons == 1)	{		/* looking for static function -- only look in current dir */		tagpath = ".";	}	else	{		/* get the tagpath from the environment.  Default to DEFTAGPATH */		tagpath = getenv("TAGPATH");		if (!tagpath)		{			tagpath = DEFTAGPATH;		}	}	/* for each entry in the path... */	while (*tagpath)	{		/* Copy the entry into the dir[] buffer */		for (ptr = dir; *tagpath && *tagpath != SEP; tagpath++)		{			*ptr++ = *tagpath;		}		if (*tagpath == SEP)		{			tagpath++;		}		/* if the entry ended with "/tags", then strip that off */		len = strlen(TAGS);		if (&dir[len] < ptr && ptr[-len - 1] == SLASH && !strncmp(&ptr[-len], TAGS, len))		{			ptr -= len + 1;		}		/* if the entry is now an empty string, then assume "." */		if (ptr == dir)		{			*ptr++ = '.';		}		*ptr = '\0';		/* look for the tag in this path.  If found, then display it		 * and exit.		 */		ptr = cktagdir(tag, dir);		if (ptr)		{			/* just supposed to display tag info? */			if (taginfo)			{				/* then do only that! */				if (strcmp(dir, "."))				{					printf("%s%c%s", dir, SLASH, ptr);				}				else				{					/* avoid leading "./" if possible */					fputs(ptr, stdout);				}				return 1;			}			else			{				/* else look up the declaration of the thing */				return lookup(dir, ptr);			}		}	}	/* if we get here, then the tag wasn't found anywhere */	return 0;}void usage(){	fputs("usage: ref [-a] [-t] [-c class] [-f file] tag\n", stderr);	fputs("   -a        function's args may be flush against left margin\n", stderr);	fputs("   -t        output tag info, instead of the function header\n", stderr);	fputs("   -f File   tag might be a static function in File\n", stderr);	fputs("   -c Class  tag might be a member of class Class\n", stderr);	exit(2);}int countcolons(str)	char	*str;{	while (*str != ':' && *str)	{		str++;	}	if (str[0] != ':')	{		return 0;	}	else if (str[1] != ':')	{		return 1;	}	return 2;}int main(argc, argv)	int	argc;	char	**argv;{	char	def_tag[100];	/* used to build tag name with default file/class */	int	i;	/* parse flags */	for (i = 1; i < argc && argv[i][0] == '-'; i++)	{		switch (argv[i][1])		{		  case 't':			taginfo = 1;			break;		  case 'f':			if (argv[i][2])			{				def_file = &argv[i][2];			}			else if (++i < argc)			{				def_file = argv[i];			}			else			{				usage();			}			break;		  case 'c':			if (argv[i][2])			{				def_class = &argv[i][2];			}			else if (++i < argc)			{				def_class = argv[i];			}			else			{				usage();			}			break;		  default:			usage();		}	}	/* if no tag was given, complain */	if (i + 1 != argc)	{		usage();	}	/* does the tag have an explicit class or file? */	colons = countcolons(argv[i]);	/* if not, then maybe try some defaults */	if (colons == 0)	{		/* try a static function in the file first */		if (def_file)		{			sprintf(def_tag, "%s:%s", def_file, argv[i]);			colons = 1;			if (find(def_tag))			{				exit(0);			}		}		/* try a member function for a class */		if (def_class)		{			sprintf(def_tag, "%s::%s", def_class, argv[i]);			colons = 2;			if (find(def_tag))			{				exit(0);			}		}		/* oh, well */		colons = 0;	}	/* find the tag */	if (find(argv[i]))	{		exit(0);	}	exit(1);	/*NOTREACHED*/}

⌨️ 快捷键说明

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