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