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