[BACK]Return to tags.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Annotation of src/usr.bin/less/tags.c, Revision 1.1.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