version 1.8, 2010/07/02 22:43:38 |
version 1.9, 2011/09/16 18:12:09 |
|
|
/* |
/* |
* Copyright (C) 1984-2002 Mark Nudelman |
* Copyright (C) 1984-2011 Mark Nudelman |
* |
* |
* You may distribute under the terms of either the GNU General Public |
* You may distribute under the terms of either the GNU General Public |
* License or the Less License, as specified in the README file. |
* License or the Less License, as specified in the README file. |
|
|
* |
* |
* Use either pattern or line number. |
* Use either pattern or line number. |
* findgtag() always uses line number, so pattern is always NULL. |
* findgtag() always uses line number, so pattern is always NULL. |
* findctag() usually either pattern (in which case line number is 0), |
* findctag() uses either pattern (in which case line number is 0), |
* or line number (in which case pattern is NULL). |
* or line number (in which case pattern is NULL). |
*/ |
*/ |
struct taglist { |
struct taglist { |
|
|
static struct tag *curtag; |
static struct tag *curtag; |
|
|
#define TAG_INS(tp) \ |
#define TAG_INS(tp) \ |
(tp)->next = taglist.tl_first; \ |
(tp)->next = TAG_END; \ |
(tp)->prev = TAG_END; \ |
(tp)->prev = taglist.tl_last; \ |
taglist.tl_first->prev = (tp); \ |
taglist.tl_last->next = (tp); \ |
taglist.tl_first = (tp); |
taglist.tl_last = (tp); |
|
|
#define TAG_RM(tp) \ |
#define TAG_RM(tp) \ |
(tp)->next->prev = (tp)->prev; \ |
(tp)->next->prev = (tp)->prev; \ |
|
|
* starting position of that line in linepos. |
* starting position of that line in linepos. |
*/ |
*/ |
linepos = pos; |
linepos = pos; |
pos = forw_raw_line(pos, &line); |
pos = forw_raw_line(pos, &line, (int *)NULL); |
if (linenum != 0) |
if (linenum != 0) |
linenum++; |
linenum++; |
|
|
|
|
char buf[256]; |
char buf[256]; |
FILE *fp; |
FILE *fp; |
struct tag *tp; |
struct tag *tp; |
|
size_t len; |
|
|
if (type != T_CTAGS_X && tag == NULL) |
if (type != T_CTAGS_X && tag == NULL) |
return TAG_NOFILE; |
return TAG_NOFILE; |
|
|
#if !HAVE_POPEN |
#if !HAVE_POPEN |
return TAG_NOFILE; |
return TAG_NOFILE; |
#else |
#else |
char command[512]; |
char *command; |
char *flag; |
char *flag; |
char *qtag; |
char *qtag; |
char *cmd = lgetenv("LESSGLOBALTAGS"); |
char *cmd = lgetenv("LESSGLOBALTAGS"); |
|
|
qtag = shell_quote(tag); |
qtag = shell_quote(tag); |
if (qtag == NULL) |
if (qtag == NULL) |
qtag = tag; |
qtag = tag; |
snprintf(command, sizeof(command), "%s -x%s %s", cmd, |
len = strlen(cmd) + strlen(flag) + strlen(qtag) + 5; |
flag, qtag); |
command = (char *) ecalloc(len, sizeof(char)); |
|
snprintf(command, len, "%s -x%s %s", cmd, flag, qtag); |
if (qtag != tag) |
if (qtag != tag) |
free(qtag); |
free(qtag); |
fp = popen(command, "r"); |
fp = popen(command, "r"); |
|
free(command); |
#endif |
#endif |
} |
} |
if (fp != NULL) |
if (fp != NULL) |
|
|
while (fgets(buf, sizeof(buf), fp)) |
while (fgets(buf, sizeof(buf), fp)) |
{ |
{ |
char *name, *file, *line; |
char *name, *file, *line; |
size_t len; |
|
|
|
if (sigs) |
if (sigs) |
{ |
{ |
|
|
#endif |
#endif |
return TAG_INTR; |
return TAG_INTR; |
} |
} |
if ((len = strlen(buf)) && buf[len - 1] == '\n') |
len = strlen(buf); |
buf[len - 1] = 0; |
if (len > 0 && buf[len-1] == '\n') |
|
buf[len-1] = '\0'; |
else |
else |
{ |
{ |
int c; |
int c; |
|
|
* The tag, file, and line will each be NUL-terminated pointers |
* The tag, file, and line will each be NUL-terminated pointers |
* into buf. |
* into buf. |
*/ |
*/ |
|
|
#ifndef isspace |
|
#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == '\f') |
|
#endif |
|
#ifndef isdigit |
|
#define isdigit(c) ((c) >= '0' && (c <= '9')) |
|
#endif |
|
|
|
static int |
static int |
getentry(buf, tag, file, line) |
getentry(buf, tag, file, line) |
char *buf; /* standard or extended ctags -x format data */ |
char *buf; /* standard or extended ctags -x format data */ |
|
|
{ |
{ |
char *p = buf; |
char *p = buf; |
|
|
for (*tag = p; *p && !isspace(*p); p++) /* tag name */ |
for (*tag = p; *p && !IS_SPACE(*p); p++) /* tag name */ |
; |
; |
if (*p == 0) |
if (*p == 0) |
return (-1); |
return (-1); |
*p++ = 0; |
*p++ = 0; |
for ( ; isspace(*p); p++) /* (skip blanks) */ |
for ( ; *p && IS_SPACE(*p); p++) /* (skip blanks) */ |
; |
; |
if (*p == 0) |
if (*p == 0) |
return (-1); |
return (-1); |
|
|
* If the second part begin with other than digit, |
* If the second part begin with other than digit, |
* it is assumed tag type. Skip it. |
* it is assumed tag type. Skip it. |
*/ |
*/ |
if (!isdigit(*p)) |
if (!IS_DIGIT(*p)) |
{ |
{ |
for ( ; *p && !isspace(*p); p++) /* (skip tag type) */ |
for ( ; *p && !IS_SPACE(*p); p++) /* (skip tag type) */ |
; |
; |
for (; isspace(*p); p++) /* (skip blanks) */ |
for (; *p && IS_SPACE(*p); p++) /* (skip blanks) */ |
; |
; |
} |
} |
if (!isdigit(*p)) |
if (!IS_DIGIT(*p)) |
return (-1); |
return (-1); |
*line = p; /* line number */ |
*line = p; /* line number */ |
for (*line = p; *p && !isspace(*p); p++) |
for (*line = p; *p && !IS_SPACE(*p); p++) |
; |
; |
if (*p == 0) |
if (*p == 0) |
return (-1); |
return (-1); |
*p++ = 0; |
*p++ = 0; |
for ( ; isspace(*p); p++) /* (skip blanks) */ |
for ( ; *p && IS_SPACE(*p); p++) /* (skip blanks) */ |
; |
; |
if (*p == 0) |
if (*p == 0) |
return (-1); |
return (-1); |
*file = p; /* file name */ |
*file = p; /* file name */ |
for (*file = p; *p && !isspace(*p); p++) |
for (*file = p; *p && !IS_SPACE(*p); p++) |
; |
; |
if (*p == 0) |
if (*p == 0) |
return (-1); |
return (-1); |