xref: /original-bsd/usr.bin/more/tags.c (revision de0f5fa5)
1 /*
2  * Copyright (c) 1988 Mark Nudleman
3  * Copyright (c) 1988, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * %sccs.include.redist.c%
7  */
8 
9 #ifndef lint
10 static char sccsid[] = "@(#)tags.c	8.1 (Berkeley) 06/06/93";
11 #endif /* not lint */
12 
13 #include <sys/types.h>
14 #include <stdio.h>
15 #include <less.h>
16 
17 #define	WHITESP(c)	((c)==' ' || (c)=='\t')
18 
19 char *tagfile;
20 char *tagpattern;
21 
22 static char *tags = "tags";
23 
24 extern int linenums;
25 extern int sigs;
26 extern char *line;
27 
28 /*
29  * Find a tag in the "tags" file.
30  * Sets "tagfile" to the name of the file containing the tag,
31  * and "tagpattern" to the search pattern which should be used
32  * to find the tag.
33  */
34 findtag(tag)
35 	register char *tag;
36 {
37 	register char *p;
38 	register FILE *f;
39 	register int taglen;
40 	int search_char;
41 	static char tline[200];
42 
43 	if ((f = fopen(tags, "r")) == NULL)
44 	{
45 		error("No tags file");
46 		tagfile = NULL;
47 		return;
48 	}
49 
50 	taglen = strlen(tag);
51 
52 	/*
53 	 * Search the tags file for the desired tag.
54 	 */
55 	while (fgets(tline, sizeof(tline), f) != NULL)
56 	{
57 		if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen]))
58 			continue;
59 
60 		/*
61 		 * Found it.
62 		 * The line contains the tag, the filename and the
63 		 * pattern, separated by white space.
64 		 * The pattern is surrounded by a pair of identical
65 		 * search characters.
66 		 * Parse the line and extract these parts.
67 		 */
68 		tagfile = tagpattern = NULL;
69 
70 		/*
71 		 * Skip over the whitespace after the tag name.
72 		 */
73 		for (p = tline;  !WHITESP(*p) && *p != '\0';  p++)
74 			continue;
75 		while (WHITESP(*p))
76 			p++;
77 		if (*p == '\0')
78 			/* File name is missing! */
79 			continue;
80 
81 		/*
82 		 * Save the file name.
83 		 * Skip over the whitespace after the file name.
84 		 */
85 		tagfile = p;
86 		while (!WHITESP(*p) && *p != '\0')
87 			p++;
88 		*p++ = '\0';
89 		while (WHITESP(*p))
90 			p++;
91 		if (*p == '\0')
92 			/* Pattern is missing! */
93 			continue;
94 
95 		/*
96 		 * Save the pattern.
97 		 * Skip to the end of the pattern.
98 		 * Delete the initial "^" and the final "$" from the pattern.
99 		 */
100 		search_char = *p++;
101 		if (*p == '^')
102 			p++;
103 		tagpattern = p;
104 		while (*p != search_char && *p != '\0')
105 			p++;
106 		if (p[-1] == '$')
107 			p--;
108 		*p = '\0';
109 
110 		(void)fclose(f);
111 		return;
112 	}
113 	(void)fclose(f);
114 	error("No such tag in tags file");
115 	tagfile = NULL;
116 }
117 
118 /*
119  * Search for a tag.
120  * This is a stripped-down version of search().
121  * We don't use search() for several reasons:
122  *   -	We don't want to blow away any search string we may have saved.
123  *   -	The various regular-expression functions (from different systems:
124  *	regcmp vs. re_comp) behave differently in the presence of
125  *	parentheses (which are almost always found in a tag).
126  */
127 tagsearch()
128 {
129 	off_t pos, linepos, forw_raw_line();
130 	int linenum;
131 
132 	pos = (off_t)0;
133 	linenum = find_linenum(pos);
134 
135 	for (;;)
136 	{
137 		/*
138 		 * Get lines until we find a matching one or
139 		 * until we hit end-of-file.
140 		 */
141 		if (sigs)
142 			return (1);
143 
144 		/*
145 		 * Read the next line, and save the
146 		 * starting position of that line in linepos.
147 		 */
148 		linepos = pos;
149 		pos = forw_raw_line(pos);
150 		if (linenum != 0)
151 			linenum++;
152 
153 		if (pos == NULL_POSITION)
154 		{
155 			/*
156 			 * We hit EOF without a match.
157 			 */
158 			error("Tag not found");
159 			return (1);
160 		}
161 
162 		/*
163 		 * If we're using line numbers, we might as well
164 		 * remember the information we have now (the position
165 		 * and line number of the current line).
166 		 */
167 		if (linenums)
168 			add_lnum(linenum, pos);
169 
170 		/*
171 		 * Test the line to see if we have a match.
172 		 */
173 		if (strcmp(tagpattern, line) == 0)
174 			break;
175 	}
176 
177 	jump_loc(linepos);
178 	return (0);
179 }
180