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