Annotation of src/usr.bin/more/tags.c, Revision 1.1.1.1
1.1 deraadt 1: /*
2: * Copyright (c) 1988 Mark Nudleman
3: * Copyright (c) 1988 Regents of the University of California.
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
16: * This product includes software developed by the University of
17: * California, Berkeley and its contributors.
18: * 4. Neither the name of the University nor the names of its contributors
19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: */
34:
35: #ifndef lint
36: /* from: static char sccsid[] = "@(#)tags.c 5.5 (Berkeley) 6/1/90"; */
37: static char *rcsid = "$Id: tags.c,v 1.3 1994/12/24 17:17:14 cgd Exp $";
38: #endif /* not lint */
39:
40: #include <sys/types.h>
41: #include <stdio.h>
42: #include <string.h>
43: #include <less.h>
44:
45: #define WHITESP(c) ((c)==' ' || (c)=='\t')
46:
47: char *tagfile;
48: char *tagpattern;
49:
50: static char *tags = "tags";
51:
52: extern int linenums;
53: extern int sigs;
54: extern char *line;
55:
56: /*
57: * Find a tag in the "tags" file.
58: * Sets "tagfile" to the name of the file containing the tag,
59: * and "tagpattern" to the search pattern which should be used
60: * to find the tag.
61: */
62: findtag(tag)
63: register char *tag;
64: {
65: register char *p;
66: register FILE *f;
67: register int taglen;
68: int search_char;
69: static char tline[200];
70:
71: if ((f = fopen(tags, "r")) == NULL)
72: {
73: error("No tags file");
74: tagfile = NULL;
75: return;
76: }
77:
78: taglen = strlen(tag);
79:
80: /*
81: * Search the tags file for the desired tag.
82: */
83: while (fgets(tline, sizeof(tline), f) != NULL)
84: {
85: if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen]))
86: continue;
87:
88: /*
89: * Found it.
90: * The line contains the tag, the filename and the
91: * pattern, separated by white space.
92: * The pattern is surrounded by a pair of identical
93: * search characters.
94: * Parse the line and extract these parts.
95: */
96: tagfile = tagpattern = NULL;
97:
98: /*
99: * Skip over the whitespace after the tag name.
100: */
101: for (p = tline; !WHITESP(*p) && *p != '\0'; p++)
102: continue;
103: while (WHITESP(*p))
104: p++;
105: if (*p == '\0')
106: /* File name is missing! */
107: continue;
108:
109: /*
110: * Save the file name.
111: * Skip over the whitespace after the file name.
112: */
113: tagfile = p;
114: while (!WHITESP(*p) && *p != '\0')
115: p++;
116: *p++ = '\0';
117: while (WHITESP(*p))
118: p++;
119: if (*p == '\0')
120: /* Pattern is missing! */
121: continue;
122:
123: /*
124: * Save the pattern.
125: * Skip to the end of the pattern.
126: * Delete the initial "^" and the final "$" from the pattern.
127: */
128: search_char = *p++;
129: if (*p == '^')
130: p++;
131: tagpattern = p;
132: while (*p != search_char && *p != '\0')
133: p++;
134: if (p[-1] == '$')
135: p--;
136: *p = '\0';
137:
138: (void)fclose(f);
139: return;
140: }
141: (void)fclose(f);
142: error("No such tag in tags file");
143: tagfile = NULL;
144: }
145:
146: /*
147: * Search for a tag.
148: * This is a stripped-down version of search().
149: * We don't use search() for several reasons:
150: * - We don't want to blow away any search string we may have saved.
151: * - The various regular-expression functions (from different systems:
152: * regcmp vs. re_comp) behave differently in the presence of
153: * parentheses (which are almost always found in a tag).
154: */
155: tagsearch()
156: {
157: off_t pos, linepos, forw_raw_line();
158: int linenum;
159:
160: pos = (off_t)0;
161: linenum = find_linenum(pos);
162:
163: for (;;)
164: {
165: /*
166: * Get lines until we find a matching one or
167: * until we hit end-of-file.
168: */
169: if (sigs)
170: return (1);
171:
172: /*
173: * Read the next line, and save the
174: * starting position of that line in linepos.
175: */
176: linepos = pos;
177: pos = forw_raw_line(pos);
178: if (linenum != 0)
179: linenum++;
180:
181: if (pos == NULL_POSITION)
182: {
183: /*
184: * We hit EOF without a match.
185: */
186: error("Tag not found");
187: return (1);
188: }
189:
190: /*
191: * If we're using line numbers, we might as well
192: * remember the information we have now (the position
193: * and line number of the current line).
194: */
195: if (linenums)
196: add_lnum(linenum, pos);
197:
198: /*
199: * Test the line to see if we have a match.
200: */
201: if (strcmp(tagpattern, line) == 0)
202: break;
203: }
204:
205: jump_loc(linepos);
206: return (0);
207: }