Logo Search packages:      
Sourcecode: jless version File versions  Download package

tags.c

/*
 * Copyright (C) 1984-2000  Mark Nudelman
 *
 * You may distribute under the terms of either the GNU General Public
 * License or the Less License, as specified in the README file.
 *
 * For more information about less, or for information on how to 
 * contact the author, see the README file.
 */


#include "less.h"

#define     WHITESP(c)  ((c)==' ' || (c)=='\t')

#if TAGS

public char *tags = "tags";

static char *tagfile;
static char *tagpattern;
static int taglinenum;
static int tagendline;

extern int linenums;
extern int sigs;
extern int jump_sline;

/*
 * Find a tag in the "tags" file.
 * Sets "tagfile" to the name of the file containing the tag,
 * and "tagpattern" to the search pattern which should be used
 * to find the tag.
 */
      public void
findtag(tag)
      register char *tag;
{
      char *p;
      char *q;
      register FILE *f;
      register int taglen;
      int search_char;
      int err;
      char tline[TAGLINE_SIZE];

      p = unquote_file(tags);
      f = fopen(p, "r");
      free(p);
      if (f == NULL)
      {
            error("No tags file", NULL_PARG);
            tagfile = NULL;
            return;
      }

      taglen = strlen(tag);

      /*
       * Search the tags file for the desired tag.
       */
      while (fgets(tline, sizeof(tline), f) != NULL)
      {
            if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen]))
                  continue;

            /*
             * Found it.
             * The line contains the tag, the filename and the
             * location in the file, separated by white space.
             * The location is either a decimal line number, 
             * or a search pattern surrounded by a pair of delimiters.
             * Parse the line and extract these parts.
             */
            tagfile = tagpattern = NULL;
            taglinenum = 0;

            /*
             * Skip over the whitespace after the tag name.
             */
            p = skipsp(tline+taglen);
            if (*p == '\0')
                  /* File name is missing! */
                  continue;

            /*
             * Save the file name.
             * Skip over the whitespace after the file name.
             */
            tagfile = p;
            while (!WHITESP(*p) && *p != '\0')
                  p++;
            *p++ = '\0';
            p = skipsp(p);
            if (*p == '\0')
                  /* Pattern is missing! */
                  continue;
            tagfile = save(tagfile);

            /*
             * First see if it is a line number. 
             */
            taglinenum = getnum(&p, 0, &err);
            if (err)
            {
                  /*
                   * No, it must be a pattern.
                   * Delete the initial "^" (if present) and 
                   * the final "$" from the pattern.
                   * Delete any backslash in the pattern.
                   */
                  taglinenum = 0;
                  search_char = *p++;
                  if (*p == '^')
                        p++;
                  tagpattern = (char *) ecalloc(strlen(p)+1, sizeof(char));
                  q = tagpattern;
                  while (*p != search_char && *p != '\0')
                  {
                        if (*p == '\\')
                              p++;
                        *q++ = *p++;
                  }
                  tagendline = (q[-1] == '$');
                  if (tagendline)
                        q--;
                  *q = '\0';
            }

            fclose(f);
            return;
      }
      fclose(f);
      error("No such tag in tags file", NULL_PARG);
      tagfile = NULL;
}

      public int
edit_tagfile()
{
      int r;

      if (tagfile == NULL)
            return (1);
      r = edit(tagfile);
      free(tagfile);
      tagfile = NULL;
      return (r);
}

/*
 * Search for a tag.
 * This is a stripped-down version of search().
 * We don't use search() for several reasons:
 *   -      We don't want to blow away any search string we may have saved.
 *   -      The various regular-expression functions (from different systems:
 *    regcmp vs. re_comp) behave differently in the presence of 
 *    parentheses (which are almost always found in a tag).
 */
      public POSITION
tagsearch()
{
      POSITION pos, linepos;
      int linenum;
      int len;
      char *line;

      /*
       * If we have the line number of the tag instead of the pattern,
       * just use find_pos.
       */
      if (taglinenum)
            return (find_pos(taglinenum));

      pos = ch_zero();
      linenum = find_linenum(pos);

      for (;;)
      {
            /*
             * Get lines until we find a matching one or 
             * until we hit end-of-file.
             */
            if (ABORT_SIGS())
                  return (NULL_POSITION);

            /*
             * Read the next line, and save the 
             * starting position of that line in linepos.
             */
            linepos = pos;
            pos = forw_raw_line(pos, &line);
            if (linenum != 0)
                  linenum++;

            if (pos == NULL_POSITION)
            {
                  /*
                   * We hit EOF without a match.
                   */
                  error("Tag not found", NULL_PARG);
                  return (NULL_POSITION);
            }

            /*
             * If we're using line numbers, we might as well
             * remember the information we have now (the position
             * and line number of the current line).
             */
            if (linenums)
                  add_lnum(linenum, pos);

            /*
             * Test the line to see if we have a match.
             * Use strncmp because the pattern may be
             * truncated (in the tags file) if it is too long.
             * If tagendline is set, make sure we match all
             * the way to end of line (no extra chars after the match).
             */
            len = strlen(tagpattern);
            if (strncmp(tagpattern, line, len) == 0 &&
                (!tagendline || line[len] == '\0' || line[len] == '\r'))
                  break;
      }

      free(tagpattern);
      tagpattern = NULL;
      return (linepos);
}

#endif

Generated by  Doxygen 1.6.0   Back to index