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

Diff for /src/usr.bin/less/tags.c between version 1.14 and 1.15

version 1.14, 2015/11/07 18:07:44 version 1.15, 2015/11/08 08:53:49
Line 29 
Line 29 
         TAG_INTR          TAG_INTR
 };  };
   
 /*  static enum tag_result findctag(char *);
  * Tag type  static char *nextctag(void);
  */  static char *prevctag(void);
 enum {  static off_t ctagsearch(void);
         T_CTAGS,        /* 'tags': standard and extended format (ctags) */  
         T_CTAGS_X,      /* stdin: cross reference format (ctags) */  
         T_GTAGS,        /* 'GTAGS': function defenition (global) */  
         T_GRTAGS,       /* 'GRTAGS': function reference (global) */  
         T_GSYMS,        /* 'GSYMS': other symbols (global) */  
         T_GPATH         /* 'GPATH': path name (global) */  
 };  
   
 static enum tag_result findctag();  
 static enum tag_result findgtag();  
 static char *nextgtag();  
 static char *prevgtag();  
 static off_t ctagsearch();  
 static off_t gtagsearch();  
 static int getentry();  
   
 /*  /*
  * The list of tags generated by the last findgtag() call.   * The list of tags generated by the last findctag() call.
  *  
  * Use either pattern or line number.  
  * findgtag() always uses line number, so pattern is always NULL.  
  * findctag() uses either pattern (in which case line number is 0),  
  * or line number (in which case pattern is NULL).  
  */   */
 struct taglist {  struct taglist {
         struct tag *tl_first;          struct tag *tl_first;
Line 123 
Line 103 
 }  }
   
 /*  /*
  * Get tag mode.  
  */  
 static int  
 gettagtype(void)  
 {  
         int f;  
   
         if (strcmp(tags, "GTAGS") == 0)  
                 return (T_GTAGS);  
         if (strcmp(tags, "GRTAGS") == 0)  
                 return (T_GRTAGS);  
         if (strcmp(tags, "GSYMS") == 0)  
                 return (T_GSYMS);  
         if (strcmp(tags, "GPATH") == 0)  
                 return (T_GPATH);  
         if (strcmp(tags, "-") == 0)  
                 return (T_CTAGS_X);  
         f = open(tags, OPEN_READ);  
         if (f >= 0) {  
                 (void) close(f);  
                 return (T_CTAGS);  
         }  
         return (T_GTAGS);  
 }  
   
 /*  
  * Find tags in tag file.   * Find tags in tag file.
  * Find a tag in the "tags" file.  
  * Sets "tag_file" to the name of the file containing the tag,  
  * and "tagpattern" to the search pattern which should be used  
  * to find the tag.  
  */   */
 void  void
 findtag(char *tag)  findtag(char *tag)
 {  {
         int type = gettagtype();  
         enum tag_result result;          enum tag_result result;
   
         if (type == T_CTAGS)          result = findctag(tag);
                 result = findctag(tag);  
         else  
                 result = findgtag(tag, type);  
         switch (result) {          switch (result) {
         case TAG_FOUND:          case TAG_FOUND:
         case TAG_INTR:          case TAG_INTR:
Line 188 
Line 134 
 tagsearch(void)  tagsearch(void)
 {  {
         if (curtag == NULL)          if (curtag == NULL)
                 return (-1);  /* No gtags loaded! */                  return (-1);   /* No tags loaded! */
         if (curtag->tag_linenum != 0)          if (curtag->tag_linenum != 0)
                 return (gtagsearch());                  return (find_pos(curtag->tag_linenum));
         else          return (ctagsearch());
                 return (ctagsearch());  
 }  }
   
 /*  /*
Line 204 
Line 149 
         char *tagfile = NULL;          char *tagfile = NULL;
   
         while (n-- > 0)          while (n-- > 0)
                 tagfile = nextgtag();                  tagfile = nextctag();
         return (tagfile);          return (tagfile);
 }  }
   
Line 217 
Line 162 
         char *tagfile = NULL;          char *tagfile = NULL;
   
         while (n-- > 0)          while (n-- > 0)
                 tagfile = prevgtag();                  tagfile = prevctag();
         return (tagfile);          return (tagfile);
 }  }
   
Line 240 
Line 185 
 }  }
   
 /*  /*
  * ctags  
  */  
   
 /*  
  * Find tags in the "tags" file.   * Find tags in the "tags" file.
  * Sets curtag to the first tag entry.   * Sets curtag to the first tag entry.
  */   */
Line 435 
Line 376 
         return (linepos);          return (linepos);
 }  }
   
 /*  
  * gtags  
  */  
   
 /*  
  * Find tags in the GLOBAL's tag file.  
  * The findgtag() will try and load information about the requested tag.  
  * It does this by calling "global -x tag" and storing the parsed output  
  * for future use by gtagsearch().  
  * Sets curtag to the first tag entry.  
  */  
 static enum tag_result  
 findgtag(char *tag, int type)  
 {  
         char buf[256];  
         FILE *fp;  
         struct tag *tp;  
   
         if (type != T_CTAGS_X && tag == NULL)  
                 return (TAG_NOFILE);  
   
         cleantags();  
         total = 0;  
   
         /*  
          * If type == T_CTAGS_X then read ctags's -x format from stdin  
          * else execute global(1) and read from it.  
          */  
         if (type == T_CTAGS_X) {  
                 fp = stdin;  
                 /* Set tag default because we cannot read stdin again. */  
                 tags = "tags";  
         } else {  
                 char *command;  
                 char *flag;  
                 char *qtag;  
                 char *cmd = lgetenv("LESSGLOBALTAGS");  
   
                 if (cmd == NULL || *cmd == '\0')  
                         return (TAG_NOFILE);  
                 /* Get suitable flag value for global(1). */  
                 switch (type) {  
                 case T_GTAGS:  
                         flag = "";  
                         break;  
                 case T_GRTAGS:  
                         flag = "r";  
                         break;  
                 case T_GSYMS:  
                         flag = "s";  
                         break;  
                 case T_GPATH:  
                         flag = "P";  
                         break;  
                 default:  
                         return (TAG_NOTYPE);  
                 }  
   
                 /* Get our data from global(1). */  
                 qtag = shell_quote(tag);  
                 if (qtag == NULL)  
                         qtag = tag;  
                 command = easprintf("%s -x%s %s", cmd, flag, qtag);  
                 if (qtag != tag)  
                         free(qtag);  
                 fp = popen(command, "r");  
                 free(command);  
         }  
         if (fp != NULL) {  
                 while (fgets(buf, sizeof (buf), fp)) {  
                         char *name, *file, *line;  
                         int len;  
   
                         if (sigs) {  
                                 if (fp != stdin)  
                                         pclose(fp);  
                                 return (TAG_INTR);  
                         }  
                         len = strlen(buf);  
                         if (len > 0 && buf[len-1] == '\n') {  
                                 buf[len-1] = '\0';  
                         } else {  
                                 int c;  
                                 do {  
                                         c = fgetc(fp);  
                                 } while (c != '\n' && c != EOF);  
                         }  
   
                         if (getentry(buf, &name, &file, &line)) {  
                                 /*  
                                  * Couldn't parse this line for some reason.  
                                  * We'll just pretend it never happened.  
                                  */  
                                 break;  
                         }  
   
                         /* Make new entry and add to list. */  
                         tp = maketagent(file, (LINENUM) atoi(line), NULL, 0);  
                         TAG_INS(tp);  
                         total++;  
                 }  
                 if (fp != stdin) {  
                         if (pclose(fp)) {  
                                 curtag = NULL;  
                                 total = curseq = 0;  
                                 return (TAG_NOFILE);  
                         }  
                 }  
         }  
   
         /* Check to see if we found anything. */  
         tp = taglist.tl_first;  
         if (tp == TAG_END)  
                 return (TAG_NOTAG);  
         curtag = tp;  
         curseq = 1;  
         return (TAG_FOUND);  
 }  
   
 static int circular = 0;        /* 1: circular tag structure */  static int circular = 0;        /* 1: circular tag structure */
   
 /*  /*
  * Return the filename required for the next gtag in the queue that was setup   * Return the filename required for the next tag in the queue that was setup
  * by findgtag().  The next call to gtagsearch() will try to position at the   * by findctag().  The next call to ctagsearch() will try to position at the
  * appropriate tag.   * appropriate tag.
  */   */
 static char *  static char *
 nextgtag(void)  nextctag(void)
 {  {
         struct tag *tp;          struct tag *tp;
   
Line 585 
Line 407 
 }  }
   
 /*  /*
  * Return the filename required for the previous gtag in the queue that was   * Return the filename required for the previous ctag in the queue that was
  * setup by findgtat().  The next call to gtagsearch() will try to position   * setup by findctag().  The next call to ctagsearch() will try to position
  * at the appropriate tag.   * at the appropriate tag.
  */   */
 static char *  static char *
 prevgtag(void)  prevctag(void)
 {  {
         struct tag *tp;          struct tag *tp;
   
Line 610 
Line 432 
                 curseq--;                  curseq--;
         }          }
         return (curtag->tag_file);          return (curtag->tag_file);
 }  
   
 /*  
  * Position the current file at at what is hopefully the tag that was chosen  
  * using either findtag() or one of nextgtag() and prevgtag().  Returns -1  
  * if it was unable to position at the tag, 0 if successful.  
  */  
 static off_t  
 gtagsearch(void)  
 {  
         if (curtag == NULL)  
                 return (-1);  /* No gtags loaded! */  
         return (find_pos(curtag->tag_linenum));  
 }  
   
 /*  
  * The getentry() parses both standard and extended ctags -x format.  
  *  
  * [standard format]  
  * <tag>   <lineno>  <file>         <image>  
  * +------------------------------------------------  
  * |main     30      main.c         main(argc, argv)  
  * |func     21      subr.c         func(arg)  
  *  
  * The following commands write this format.  
  *      o Traditinal Ctags with -x option  
  *      o Global with -x option  
  *              See <http://www.gnu.org/software/global/global.html>  
  *  
  * [extended format]  
  * <tag>   <type>  <lineno>   <file>        <image>  
  * +----------------------------------------------------------  
  * |main     function 30      main.c         main(argc, argv)  
  * |func     function 21      subr.c         func(arg)  
  *  
  * The following commands write this format.  
  *      o Exuberant Ctags with -x option  
  *              See <http://ctags.sourceforge.net>  
  *  
  * Returns 0 on success, -1 on error.  
  * The tag, file, and line will each be NUL-terminated pointers  
  * into buf.  
  */  
 static int  
 getentry(char *buf, char **tag, char **file, char **line)  
 {  
         char *p = buf;  
   
         for (*tag = p; *p && !isspace(*p); p++)         /* tag name */  
                 ;  
         if (*p == 0)  
                 return (-1);  
         *p++ = 0;  
         for (; *p && isspace(*p); p++)                  /* (skip blanks) */  
                 ;  
         if (*p == 0)  
                 return (-1);  
         /*  
          * If the second part begin with other than digit,  
          * it is assumed tag type. Skip it.  
          */  
         if (!isdigit(*p)) {  
                 for (; *p && !isspace(*p); p++)         /* (skip tag type) */  
                         ;  
                 for (; *p && isspace(*p); p++)          /* (skip blanks) */  
                         ;  
         }  
         if (!isdigit(*p))  
                 return (-1);  
         *line = p;                                      /* line number */  
         for (*line = p;  *p && !isspace(*p);  p++)  
                 ;  
         if (*p == 0)  
                 return (-1);  
         *p++ = 0;  
         for (; *p && isspace(*p); p++)          /* (skip blanks) */  
                 ;  
         if (*p == 0)  
                 return (-1);  
         *file = p;                                      /* file name */  
         for (*file = p;  *p && !isspace(*p);  p++)  
                 ;  
         if (*p == 0)  
                 return (-1);  
         *p = 0;  
   
         /* value check */  
         if (strlen(*tag) && strlen(*line) && strlen(*file) && atoi(*line) > 0)  
                 return (0);  
         return (-1);  
 }  }

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15