home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 036 / less232.zip / TAGS.C < prev    next >
C/C++ Source or Header  |  1994-08-26  |  5KB  |  215 lines

  1. /*
  2.  * Copyright (c) 1984,1985,1989,1994  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.     register FILE *f;
  56.     register int taglen;
  57.     int search_char;
  58.     int err;
  59.     static char tline[200];
  60.  
  61.     if ((f = fopen(tags, "r")) == NULL)
  62.     {
  63.         error("No tags file", NULL_PARG);
  64.         tagfile = NULL;
  65.         return;
  66.     }
  67.  
  68.     taglen = strlen(tag);
  69.  
  70.     /*
  71.      * Search the tags file for the desired tag.
  72.      */
  73.     while (fgets(tline, sizeof(tline), f) != NULL)
  74.     {
  75.         if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen]))
  76.             continue;
  77.  
  78.         /*
  79.          * Found it.
  80.          * The line contains the tag, the filename and the
  81.          * location in the file, separated by white space.
  82.          * The location is either a decimal line number, 
  83.          * or a search pattern surrounded by a pair of delimiters.
  84.          * Parse the line and extract these parts.
  85.          */
  86.         tagfile = tagpattern = NULL;
  87.         taglinenum = 0;
  88.  
  89.         /*
  90.          * Skip over the whitespace after the tag name.
  91.          */
  92.         p = skipsp(tline+taglen);
  93.         if (*p == '\0')
  94.             /* File name is missing! */
  95.             continue;
  96.  
  97.         /*
  98.          * Save the file name.
  99.          * Skip over the whitespace after the file name.
  100.          */
  101.         tagfile = p;
  102.         while (!WHITESP(*p) && *p != '\0')
  103.             p++;
  104.         *p++ = '\0';
  105.         p = skipsp(p);
  106.         if (*p == '\0')
  107.             /* Pattern is missing! */
  108.             continue;
  109.  
  110.         /*
  111.          * First see if it is a line number. 
  112.          */
  113.         taglinenum = getnum(&p, 0, &err);
  114.         if (err)
  115.         {
  116.             /*
  117.              * No, it must be a pattern.
  118.              * Delete the initial "^" (if present) and 
  119.              * the final "$" from the pattern.
  120.              */
  121.             taglinenum = 0;
  122.             search_char = *p++;
  123.             if (*p == '^')
  124.                 p++;
  125.             tagpattern = p;
  126.             while (*p != search_char && *p != '\0')
  127.                 p++;
  128.             if (p[-1] == '$')
  129.                 p--;
  130.             *p = '\0';
  131.         }
  132.  
  133.         fclose(f);
  134.         return;
  135.     }
  136.     fclose(f);
  137.     error("No such tag in tags file", NULL_PARG);
  138.     tagfile = NULL;
  139. }
  140.  
  141. /*
  142.  * Search for a tag.
  143.  * This is a stripped-down version of search().
  144.  * We don't use search() for several reasons:
  145.  *   -    We don't want to blow away any search string we may have saved.
  146.  *   -    The various regular-expression functions (from different systems:
  147.  *    regcmp vs. re_comp) behave differently in the presence of 
  148.  *    parentheses (which are almost always found in a tag).
  149.  */
  150.     public POSITION
  151. tagsearch()
  152. {
  153.     POSITION pos, linepos;
  154.     int linenum;
  155.     char *line;
  156.  
  157.     /*
  158.      * If we have the line number of the tag instead of the pattern,
  159.      * just use find_pos.
  160.      */
  161.     if (taglinenum)
  162.         return (find_pos(taglinenum));
  163.  
  164.     pos = ch_zero();
  165.     linenum = find_linenum(pos);
  166.  
  167.     for (;;)
  168.     {
  169.         /*
  170.          * Get lines until we find a matching one or 
  171.          * until we hit end-of-file.
  172.          */
  173.         if (ABORT_SIGS())
  174.             return (NULL_POSITION);
  175.  
  176.         /*
  177.          * Read the next line, and save the 
  178.          * starting position of that line in linepos.
  179.          */
  180.         linepos = pos;
  181.         pos = forw_raw_line(pos, &line);
  182.         if (linenum != 0)
  183.             linenum++;
  184.  
  185.         if (pos == NULL_POSITION)
  186.         {
  187.             /*
  188.              * We hit EOF without a match.
  189.              */
  190.             error("Tag not found", NULL_PARG);
  191.             return (NULL_POSITION);
  192.         }
  193.  
  194.         /*
  195.          * If we're using line numbers, we might as well
  196.          * remember the information we have now (the position
  197.          * and line number of the current line).
  198.          */
  199.         if (linenums)
  200.             add_lnum(linenum, pos);
  201.  
  202.         /*
  203.          * Test the line to see if we have a match.
  204.          * Use strncmp because the pattern may be
  205.          * truncated (in the tags file) if it is too long.
  206.          */
  207.         if (strncmp(tagpattern, line, strlen(tagpattern)) == 0)
  208.             break;
  209.     }
  210.  
  211.     return (linepos);
  212. }
  213.  
  214. #endif
  215.