>From: phk@flsco.fls.dk (Poul-Henning Kamp/P-HK)
[unix-history] / usr.bin / more / tags.c
CommitLineData
2ec5f51d
NW
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
36static char sccsid[] = "@(#)tags.c 5.5 (Berkeley) 6/1/90";
37#endif /* not lint */
38
39#include <sys/types.h>
40#include <stdio.h>
41#include <less.h>
42
43#define WHITESP(c) ((c)==' ' || (c)=='\t')
44
45char *tagfile;
46char *tagpattern;
47
48static char *tags = "tags";
49
50extern int linenums;
51extern int sigs;
52extern char *line;
53
54/*
55 * Find a tag in the "tags" file.
56 * Sets "tagfile" to the name of the file containing the tag,
57 * and "tagpattern" to the search pattern which should be used
58 * to find the tag.
59 */
60findtag(tag)
61 register char *tag;
62{
63 register char *p;
64 register FILE *f;
65 register int taglen;
66 int search_char;
67 static char tline[200];
68
69 if ((f = fopen(tags, "r")) == NULL)
70 {
71 error("No tags file");
72 tagfile = NULL;
73 return;
74 }
75
76 taglen = strlen(tag);
77
78 /*
79 * Search the tags file for the desired tag.
80 */
81 while (fgets(tline, sizeof(tline), f) != NULL)
82 {
83 if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen]))
84 continue;
85
86 /*
87 * Found it.
88 * The line contains the tag, the filename and the
89 * pattern, separated by white space.
90 * The pattern is surrounded by a pair of identical
91 * search characters.
92 * Parse the line and extract these parts.
93 */
94 tagfile = tagpattern = NULL;
95
96 /*
97 * Skip over the whitespace after the tag name.
98 */
99 for (p = tline; !WHITESP(*p) && *p != '\0'; p++)
100 continue;
101 while (WHITESP(*p))
102 p++;
103 if (*p == '\0')
104 /* File name is missing! */
105 continue;
106
107 /*
108 * Save the file name.
109 * Skip over the whitespace after the file name.
110 */
111 tagfile = p;
112 while (!WHITESP(*p) && *p != '\0')
113 p++;
114 *p++ = '\0';
115 while (WHITESP(*p))
116 p++;
117 if (*p == '\0')
118 /* Pattern is missing! */
119 continue;
120
121 /*
122 * Save the pattern.
123 * Skip to the end of the pattern.
124 * Delete the initial "^" and the final "$" from the pattern.
125 */
126 search_char = *p++;
127 if (*p == '^')
128 p++;
129 tagpattern = p;
130 while (*p != search_char && *p != '\0')
131 p++;
132 if (p[-1] == '$')
133 p--;
134 *p = '\0';
135
136 (void)fclose(f);
137 return;
138 }
139 (void)fclose(f);
140 error("No such tag in tags file");
141 tagfile = NULL;
142}
143
144/*
145 * Search for a tag.
146 * This is a stripped-down version of search().
147 * We don't use search() for several reasons:
148 * - We don't want to blow away any search string we may have saved.
149 * - The various regular-expression functions (from different systems:
150 * regcmp vs. re_comp) behave differently in the presence of
151 * parentheses (which are almost always found in a tag).
152 */
153tagsearch()
154{
155 off_t pos, linepos, forw_raw_line();
156 int linenum;
157
158 pos = (off_t)0;
159 linenum = find_linenum(pos);
160
161 for (;;)
162 {
163 /*
164 * Get lines until we find a matching one or
165 * until we hit end-of-file.
166 */
167 if (sigs)
168 return (1);
169
170 /*
171 * Read the next line, and save the
172 * starting position of that line in linepos.
173 */
174 linepos = pos;
175 pos = forw_raw_line(pos);
176 if (linenum != 0)
177 linenum++;
178
179 if (pos == NULL_POSITION)
180 {
181 /*
182 * We hit EOF without a match.
183 */
184 error("Tag not found");
185 return (1);
186 }
187
188 /*
189 * If we're using line numbers, we might as well
190 * remember the information we have now (the position
191 * and line number of the current line).
192 */
193 if (linenums)
194 add_lnum(linenum, pos);
195
196 /*
197 * Test the line to see if we have a match.
198 */
199 if (strcmp(tagpattern, line) == 0)
200 break;
201 }
202
203 jump_loc(linepos);
204 return (0);
205}