=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/less/tags.c,v retrieving revision 1.14 retrieving revision 1.15 diff -c -r1.14 -r1.15 *** src/usr.bin/less/tags.c 2015/11/07 18:07:44 1.14 --- src/usr.bin/less/tags.c 2015/11/08 08:53:49 1.15 *************** *** 29,61 **** TAG_INTR }; ! /* ! * Tag type ! */ ! enum { ! 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. ! * ! * 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 tag *tl_first; --- 29,41 ---- TAG_INTR }; ! static enum tag_result findctag(char *); ! static char *nextctag(void); ! static char *prevctag(void); ! static off_t ctagsearch(void); /* ! * The list of tags generated by the last findctag() call. */ struct taglist { struct tag *tl_first; *************** *** 123,170 **** } /* - * 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 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 findtag(char *tag) { - int type = gettagtype(); enum tag_result result; ! if (type == T_CTAGS) ! result = findctag(tag); ! else ! result = findgtag(tag, type); switch (result) { case TAG_FOUND: case TAG_INTR: --- 103,116 ---- } /* * Find tags in tag file. */ void findtag(char *tag) { enum tag_result result; ! result = findctag(tag); switch (result) { case TAG_FOUND: case TAG_INTR: *************** *** 188,198 **** tagsearch(void) { if (curtag == NULL) ! return (-1); /* No gtags loaded! */ if (curtag->tag_linenum != 0) ! return (gtagsearch()); ! else ! return (ctagsearch()); } /* --- 134,143 ---- tagsearch(void) { if (curtag == NULL) ! return (-1); /* No tags loaded! */ if (curtag->tag_linenum != 0) ! return (find_pos(curtag->tag_linenum)); ! return (ctagsearch()); } /* *************** *** 204,210 **** char *tagfile = NULL; while (n-- > 0) ! tagfile = nextgtag(); return (tagfile); } --- 149,155 ---- char *tagfile = NULL; while (n-- > 0) ! tagfile = nextctag(); return (tagfile); } *************** *** 217,223 **** char *tagfile = NULL; while (n-- > 0) ! tagfile = prevgtag(); return (tagfile); } --- 162,168 ---- char *tagfile = NULL; while (n-- > 0) ! tagfile = prevctag(); return (tagfile); } *************** *** 240,249 **** } /* - * ctags - */ - - /* * Find tags in the "tags" file. * Sets curtag to the first tag entry. */ --- 185,190 ---- *************** *** 435,568 **** 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 */ /* ! * Return the filename required for the next gtag in the queue that was setup ! * by findgtag(). The next call to gtagsearch() will try to position at the * appropriate tag. */ static char * ! nextgtag(void) { struct tag *tp; --- 376,390 ---- return (linepos); } static int circular = 0; /* 1: circular tag structure */ /* ! * Return the filename required for the next tag in the queue that was setup ! * by findctag(). The next call to ctagsearch() will try to position at the * appropriate tag. */ static char * ! nextctag(void) { struct tag *tp; *************** *** 585,596 **** } /* ! * Return the filename required for the previous gtag in the queue that was ! * setup by findgtat(). The next call to gtagsearch() will try to position * at the appropriate tag. */ static char * ! prevgtag(void) { struct tag *tp; --- 407,418 ---- } /* ! * Return the filename required for the previous ctag in the queue that was ! * setup by findctag(). The next call to ctagsearch() will try to position * at the appropriate tag. */ static char * ! prevctag(void) { struct tag *tp; *************** *** 610,703 **** curseq--; } 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] - * - * +------------------------------------------------ - * |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 - * - * [extended format] - * - * +---------------------------------------------------------- - * |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 - * - * 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); } --- 432,435 ----