home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / less_332.lzh / less_332 / tags.c < prev    next >
Text File  |  1998-03-03  |  6KB  |  248 lines

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