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