[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.2

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