version 1.11, 2014/04/25 13:38:21 |
version 1.12, 2015/11/05 22:08:44 |
|
|
* |
* |
* For more information, see the README file. |
* For more information, see the README file. |
*/ |
*/ |
|
/* |
|
* Modified for use with illumos. |
|
* Copyright 2014 Garrett D'Amore <garrett@damore.org> |
|
*/ |
|
|
|
|
#include "less.h" |
#include "less.h" |
|
|
#define WHITESP(c) ((c)==' ' || (c)=='\t') |
#define WHITESP(c) ((c) == ' ' || (c) == '\t') |
|
|
#if TAGS |
char *tags = "tags"; |
|
|
public char *tags = "tags"; |
|
|
|
static int total; |
static int total; |
static int curseq; |
static int curseq; |
|
|
|
|
static enum tag_result findgtag(); |
static enum tag_result findgtag(); |
static char *nextgtag(); |
static char *nextgtag(); |
static char *prevgtag(); |
static char *prevgtag(); |
static POSITION ctagsearch(); |
static off_t ctagsearch(); |
static POSITION gtagsearch(); |
static off_t gtagsearch(); |
static int getentry(); |
static int getentry(); |
|
|
/* |
/* |
|
|
struct tag *tl_first; |
struct tag *tl_first; |
struct tag *tl_last; |
struct tag *tl_last; |
}; |
}; |
#define TAG_END ((struct tag *) &taglist) |
#define TAG_END ((struct tag *)&taglist) |
static struct taglist taglist = { TAG_END, TAG_END }; |
static struct taglist taglist = { TAG_END, TAG_END }; |
struct tag { |
struct tag { |
struct tag *next, *prev; /* List links */ |
struct tag *next, *prev; /* List links */ |
char *tag_file; /* Source file containing the tag */ |
char *tag_file; /* Source file containing the tag */ |
LINENUM tag_linenum; /* Appropriate line number in source file */ |
LINENUM tag_linenum; /* Appropriate line number in source file */ |
char *tag_pattern; /* Pattern used to find the tag */ |
char *tag_pattern; /* Pattern used to find the tag */ |
char tag_endline; /* True if the pattern includes '$' */ |
int tag_endline; /* True if the pattern includes '$' */ |
}; |
}; |
static struct tag *curtag; |
static struct tag *curtag; |
|
|
#define TAG_INS(tp) \ |
#define TAG_INS(tp) \ |
(tp)->next = TAG_END; \ |
(tp)->next = TAG_END; \ |
(tp)->prev = taglist.tl_last; \ |
(tp)->prev = taglist.tl_last; \ |
taglist.tl_last->next = (tp); \ |
taglist.tl_last->next = (tp); \ |
taglist.tl_last = (tp); |
taglist.tl_last = (tp); |
|
|
#define TAG_RM(tp) \ |
#define TAG_RM(tp) \ |
(tp)->next->prev = (tp)->prev; \ |
(tp)->next->prev = (tp)->prev; \ |
(tp)->prev->next = (tp)->next; |
(tp)->prev->next = (tp)->next; |
|
|
/* |
/* |
* Delete tag structures. |
* Delete tag structures. |
*/ |
*/ |
public void |
void |
cleantags() |
cleantags(void) |
{ |
{ |
register struct tag *tp; |
struct tag *tp; |
|
|
/* |
/* |
* Delete any existing tag list. |
* Delete any existing tag list. |
* {{ Ideally, we wouldn't do this until after we know that we |
* {{ Ideally, we wouldn't do this until after we know that we |
* can load some other tag information. }} |
* can load some other tag information. }} |
*/ |
*/ |
while ((tp = taglist.tl_first) != TAG_END) |
while ((tp = taglist.tl_first) != TAG_END) { |
{ |
|
TAG_RM(tp); |
TAG_RM(tp); |
free(tp); |
free(tp); |
} |
} |
|
|
/* |
/* |
* Create a new tag entry. |
* Create a new tag entry. |
*/ |
*/ |
static struct tag * |
static struct tag * |
maketagent(name, file, linenum, pattern, endline) |
maketagent(char *file, LINENUM linenum, char *pattern, int endline) |
char *name; |
|
char *file; |
|
LINENUM linenum; |
|
char *pattern; |
|
int endline; |
|
{ |
{ |
register struct tag *tp; |
struct tag *tp; |
|
|
tp = (struct tag *) ecalloc(sizeof(struct tag), 1); |
tp = ecalloc(sizeof (struct tag), 1); |
tp->tag_file = save(file); |
tp->tag_file = save(file); |
tp->tag_linenum = linenum; |
tp->tag_linenum = linenum; |
tp->tag_endline = endline; |
tp->tag_endline = endline; |
|
|
/* |
/* |
* Get tag mode. |
* Get tag mode. |
*/ |
*/ |
public int |
static int |
gettagtype() |
gettagtype(void) |
{ |
{ |
int f; |
int f; |
|
|
if (strcmp(tags, "GTAGS") == 0) |
if (strcmp(tags, "GTAGS") == 0) |
return T_GTAGS; |
return (T_GTAGS); |
if (strcmp(tags, "GRTAGS") == 0) |
if (strcmp(tags, "GRTAGS") == 0) |
return T_GRTAGS; |
return (T_GRTAGS); |
if (strcmp(tags, "GSYMS") == 0) |
if (strcmp(tags, "GSYMS") == 0) |
return T_GSYMS; |
return (T_GSYMS); |
if (strcmp(tags, "GPATH") == 0) |
if (strcmp(tags, "GPATH") == 0) |
return T_GPATH; |
return (T_GPATH); |
if (strcmp(tags, "-") == 0) |
if (strcmp(tags, "-") == 0) |
return T_CTAGS_X; |
return (T_CTAGS_X); |
f = open(tags, OPEN_READ); |
f = open(tags, OPEN_READ); |
if (f >= 0) |
if (f >= 0) { |
{ |
(void) close(f); |
close(f); |
return (T_CTAGS); |
return T_CTAGS; |
|
} |
} |
return T_GTAGS; |
return (T_GTAGS); |
} |
} |
|
|
/* |
/* |
|
|
* and "tagpattern" to the search pattern which should be used |
* and "tagpattern" to the search pattern which should be used |
* to find the tag. |
* to find the tag. |
*/ |
*/ |
public void |
void |
findtag(tag) |
findtag(char *tag) |
register char *tag; |
|
{ |
{ |
int type = gettagtype(); |
int type = gettagtype(); |
enum tag_result result; |
enum tag_result result; |
|
|
result = findctag(tag); |
result = findctag(tag); |
else |
else |
result = findgtag(tag, type); |
result = findgtag(tag, type); |
switch (result) |
switch (result) { |
{ |
|
case TAG_FOUND: |
case TAG_FOUND: |
case TAG_INTR: |
case TAG_INTR: |
break; |
break; |
|
|
/* |
/* |
* Search for a tag. |
* Search for a tag. |
*/ |
*/ |
public POSITION |
off_t |
tagsearch() |
tagsearch(void) |
{ |
{ |
if (curtag == NULL) |
if (curtag == NULL) |
return (NULL_POSITION); /* No gtags loaded! */ |
return (-1); /* No gtags loaded! */ |
if (curtag->tag_linenum != 0) |
if (curtag->tag_linenum != 0) |
return gtagsearch(); |
return (gtagsearch()); |
else |
else |
return ctagsearch(); |
return (ctagsearch()); |
} |
} |
|
|
/* |
/* |
* Go to the next tag. |
* Go to the next tag. |
*/ |
*/ |
public char * |
char * |
nexttag(n) |
nexttag(int n) |
int n; |
|
{ |
{ |
char *tagfile = (char *) NULL; |
char *tagfile = NULL; |
|
|
while (n-- > 0) |
while (n-- > 0) |
tagfile = nextgtag(); |
tagfile = nextgtag(); |
return tagfile; |
return (tagfile); |
} |
} |
|
|
/* |
/* |
* Go to the previous tag. |
* Go to the previous tag. |
*/ |
*/ |
public char * |
char * |
prevtag(n) |
prevtag(int n) |
int n; |
|
{ |
{ |
char *tagfile = (char *) NULL; |
char *tagfile = NULL; |
|
|
while (n-- > 0) |
while (n-- > 0) |
tagfile = prevgtag(); |
tagfile = prevgtag(); |
return tagfile; |
return (tagfile); |
} |
} |
|
|
/* |
/* |
* Return the total number of tags. |
* Return the total number of tags. |
*/ |
*/ |
public int |
int |
ntags() |
ntags(void) |
{ |
{ |
return total; |
return (total); |
} |
} |
|
|
/* |
/* |
* Return the sequence number of current tag. |
* Return the sequence number of current tag. |
*/ |
*/ |
public int |
int |
curr_tag() |
curr_tag(void) |
{ |
{ |
return curseq; |
return (curseq); |
} |
} |
|
|
/***************************************************************************** |
/* |
* ctags |
* 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. |
*/ |
*/ |
static enum tag_result |
static enum tag_result |
findctag(tag) |
findctag(char *tag) |
register char *tag; |
|
{ |
{ |
char *p; |
char *p; |
register FILE *f; |
FILE *f; |
register int taglen; |
int taglen; |
LINENUM taglinenum; |
LINENUM taglinenum; |
char *tagfile; |
char *tagfile; |
char *tagpattern; |
char *tagpattern; |
|
|
f = fopen(p, "r"); |
f = fopen(p, "r"); |
free(p); |
free(p); |
if (f == NULL) |
if (f == NULL) |
return TAG_NOFILE; |
return (TAG_NOFILE); |
|
|
cleantags(); |
cleantags(); |
total = 0; |
total = 0; |
|
|
/* |
/* |
* Search the tags file for the desired tag. |
* Search the tags file for the desired tag. |
*/ |
*/ |
while (fgets(tline, sizeof(tline), f) != NULL) |
while (fgets(tline, sizeof (tline), f) != NULL) { |
{ |
|
if (tline[0] == '!') |
if (tline[0] == '!') |
/* Skip header of extended format. */ |
/* Skip header of extended format. */ |
continue; |
continue; |
|
|
* Found it. |
* Found it. |
* The line contains the tag, the filename and the |
* The line contains the tag, the filename and the |
* location in the file, separated by white space. |
* location in the file, separated by white space. |
* The location is either a decimal line number, |
* The location is either a decimal line number, |
* or a search pattern surrounded by a pair of delimiters. |
* or a search pattern surrounded by a pair of delimiters. |
* Parse the line and extract these parts. |
* Parse the line and extract these parts. |
*/ |
*/ |
|
|
continue; |
continue; |
|
|
/* |
/* |
* First see if it is a line number. |
* First see if it is a line number. |
*/ |
*/ |
tagendline = 0; |
tagendline = 0; |
taglinenum = getnum(&p, 0, &err); |
taglinenum = getnum(&p, 0, &err); |
if (err) |
if (err) { |
{ |
|
/* |
/* |
* No, it must be a pattern. |
* No, it must be a pattern. |
* Delete the initial "^" (if present) and |
* Delete the initial "^" (if present) and |
* the final "$" from the pattern. |
* the final "$" from the pattern. |
* Delete any backslash in the pattern. |
* Delete any backslash in the pattern. |
*/ |
*/ |
|
|
if (*p == '^') |
if (*p == '^') |
p++; |
p++; |
tagpattern = p; |
tagpattern = p; |
while (*p != search_char && *p != '\0') |
while (*p != search_char && *p != '\0') { |
{ |
|
if (*p == '\\') |
if (*p == '\\') |
p++; |
p++; |
p++; |
p++; |
|
|
p--; |
p--; |
*p = '\0'; |
*p = '\0'; |
} |
} |
tp = maketagent(tag, tagfile, taglinenum, tagpattern, tagendline); |
tp = maketagent(tagfile, taglinenum, tagpattern, tagendline); |
TAG_INS(tp); |
TAG_INS(tp); |
total++; |
total++; |
} |
} |
fclose(f); |
fclose(f); |
if (total == 0) |
if (total == 0) |
return TAG_NOTAG; |
return (TAG_NOTAG); |
curtag = taglist.tl_first; |
curtag = taglist.tl_first; |
curseq = 1; |
curseq = 1; |
return TAG_FOUND; |
return (TAG_FOUND); |
} |
} |
|
|
/* |
/* |
* Edit current tagged file. |
* Edit current tagged file. |
*/ |
*/ |
public int |
int |
edit_tagfile() |
edit_tagfile(void) |
{ |
{ |
if (curtag == NULL) |
if (curtag == NULL) |
return (1); |
return (1); |
|
|
* We don't use search() for several reasons: |
* We don't use search() for several reasons: |
* - We don't want to blow away any search string we may have saved. |
* - We don't want to blow away any search string we may have saved. |
* - The various regular-expression functions (from different systems: |
* - The various regular-expression functions (from different systems: |
* regcmp vs. re_comp) behave differently in the presence of |
* regcmp vs. re_comp) behave differently in the presence of |
* parentheses (which are almost always found in a tag). |
* parentheses (which are almost always found in a tag). |
*/ |
*/ |
static POSITION |
static off_t |
ctagsearch() |
ctagsearch(void) |
{ |
{ |
POSITION pos, linepos; |
off_t pos, linepos; |
LINENUM linenum; |
LINENUM linenum; |
int len; |
int len; |
char *line; |
char *line; |
|
|
pos = ch_zero(); |
pos = ch_zero(); |
linenum = find_linenum(pos); |
linenum = find_linenum(pos); |
|
|
for (;;) |
for (;;) { |
{ |
|
/* |
/* |
* Get lines until we find a matching one or |
* Get lines until we find a matching one or |
* until we hit end-of-file. |
* until we hit end-of-file. |
*/ |
*/ |
if (ABORT_SIGS()) |
if (ABORT_SIGS()) |
return (NULL_POSITION); |
return (-1); |
|
|
/* |
/* |
* Read the next line, and save the |
* Read the next line, and save the |
* starting position of that line in linepos. |
* starting position of that line in linepos. |
*/ |
*/ |
linepos = pos; |
linepos = pos; |
|
|
if (linenum != 0) |
if (linenum != 0) |
linenum++; |
linenum++; |
|
|
if (pos == NULL_POSITION) |
if (pos == -1) { |
{ |
|
/* |
/* |
* We hit EOF without a match. |
* We hit EOF without a match. |
*/ |
*/ |
error("Tag not found", NULL_PARG); |
error("Tag not found", NULL_PARG); |
return (NULL_POSITION); |
return (-1); |
} |
} |
|
|
/* |
/* |
|
|
*/ |
*/ |
len = strlen(curtag->tag_pattern); |
len = strlen(curtag->tag_pattern); |
if (strncmp(curtag->tag_pattern, line, len) == 0 && |
if (strncmp(curtag->tag_pattern, line, len) == 0 && |
(!curtag->tag_endline || line[len] == '\0' || line[len] == '\r')) |
(!curtag->tag_endline || line[len] == '\0' || |
{ |
line[len] == '\r')) { |
curtag->tag_linenum = find_linenum(linepos); |
curtag->tag_linenum = find_linenum(linepos); |
break; |
break; |
} |
} |
|
|
return (linepos); |
return (linepos); |
} |
} |
|
|
/******************************************************************************* |
/* |
* gtags |
* gtags |
*/ |
*/ |
|
|
|
|
* for future use by gtagsearch(). |
* for future use by gtagsearch(). |
* Sets curtag to the first tag entry. |
* Sets curtag to the first tag entry. |
*/ |
*/ |
static enum tag_result |
static enum tag_result |
findgtag(tag, type) |
findgtag(char *tag, int type) |
char *tag; /* tag to load */ |
|
int type; /* tags type */ |
|
{ |
{ |
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); |
|
|
cleantags(); |
cleantags(); |
total = 0; |
total = 0; |
|
|
* If type == T_CTAGS_X then read ctags's -x format from stdin |
* If type == T_CTAGS_X then read ctags's -x format from stdin |
* else execute global(1) and read from it. |
* else execute global(1) and read from it. |
*/ |
*/ |
if (type == T_CTAGS_X) |
if (type == T_CTAGS_X) { |
{ |
|
fp = stdin; |
fp = stdin; |
/* Set tag default because we cannot read stdin again. */ |
/* Set tag default because we cannot read stdin again. */ |
tags = "tags"; |
tags = "tags"; |
} else |
} else { |
{ |
|
#if !HAVE_POPEN |
|
return TAG_NOFILE; |
|
#else |
|
char *command; |
char *command; |
char *flag; |
char *flag; |
char *qtag; |
char *qtag; |
char *cmd = lgetenv("LESSGLOBALTAGS"); |
char *cmd = lgetenv("LESSGLOBALTAGS"); |
|
|
if (cmd == NULL || *cmd == '\0') |
if (cmd == NULL || *cmd == '\0') |
return TAG_NOFILE; |
return (TAG_NOFILE); |
/* Get suitable flag value for global(1). */ |
/* Get suitable flag value for global(1). */ |
switch (type) |
switch (type) { |
{ |
|
case T_GTAGS: |
case T_GTAGS: |
flag = "" ; |
flag = ""; |
break; |
break; |
case T_GRTAGS: |
case T_GRTAGS: |
flag = "r"; |
flag = "r"; |
|
|
flag = "P"; |
flag = "P"; |
break; |
break; |
default: |
default: |
return TAG_NOTYPE; |
return (TAG_NOTYPE); |
} |
} |
|
|
/* Get our data from global(1). */ |
/* Get our data from global(1). */ |
qtag = shell_quote(tag); |
qtag = shell_quote(tag); |
if (qtag == NULL) |
if (qtag == NULL) |
qtag = tag; |
qtag = tag; |
len = strlen(cmd) + strlen(flag) + strlen(qtag) + 5; |
command = easprintf("%s -x%s %s", cmd, 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); |
free(command); |
#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; |
|
int len; |
|
|
if (sigs) |
if (sigs) { |
{ |
|
#if HAVE_POPEN |
|
if (fp != stdin) |
if (fp != stdin) |
pclose(fp); |
pclose(fp); |
#endif |
return (TAG_INTR); |
return TAG_INTR; |
|
} |
} |
len = strlen(buf); |
len = strlen(buf); |
if (len > 0 && buf[len-1] == '\n') |
if (len > 0 && buf[len-1] == '\n') { |
buf[len-1] = '\0'; |
buf[len-1] = '\0'; |
else |
} else { |
{ |
|
int c; |
int c; |
do { |
do { |
c = fgetc(fp); |
c = fgetc(fp); |
} while (c != '\n' && c != EOF); |
} while (c != '\n' && c != EOF); |
} |
} |
|
|
if (getentry(buf, &name, &file, &line)) |
if (getentry(buf, &name, &file, &line)) { |
{ |
|
/* |
/* |
* Couldn't parse this line for some reason. |
* Couldn't parse this line for some reason. |
* We'll just pretend it never happened. |
* We'll just pretend it never happened. |
|
|
} |
} |
|
|
/* Make new entry and add to list. */ |
/* Make new entry and add to list. */ |
tp = maketagent(name, file, (LINENUM) atoi(line), NULL, 0); |
tp = maketagent(file, (LINENUM) atoi(line), NULL, 0); |
TAG_INS(tp); |
TAG_INS(tp); |
total++; |
total++; |
} |
} |
if (fp != stdin) |
if (fp != stdin) { |
{ |
if (pclose(fp)) { |
if (pclose(fp)) |
|
{ |
|
curtag = NULL; |
curtag = NULL; |
total = curseq = 0; |
total = curseq = 0; |
return TAG_NOFILE; |
return (TAG_NOFILE); |
} |
} |
} |
} |
} |
} |
|
|
/* Check to see if we found anything. */ |
/* Check to see if we found anything. */ |
tp = taglist.tl_first; |
tp = taglist.tl_first; |
if (tp == TAG_END) |
if (tp == TAG_END) |
return TAG_NOTAG; |
return (TAG_NOTAG); |
curtag = tp; |
curtag = tp; |
curseq = 1; |
curseq = 1; |
return TAG_FOUND; |
return (TAG_FOUND); |
} |
} |
|
|
static int circular = 0; /* 1: circular tag structure */ |
static int circular = 0; /* 1: circular tag structure */ |
|
|
* by findgtag(). The next call to gtagsearch() will try to position at the |
* by findgtag(). The next call to gtagsearch() will try to position at the |
* appropriate tag. |
* appropriate tag. |
*/ |
*/ |
static char * |
static char * |
nextgtag() |
nextgtag(void) |
{ |
{ |
struct tag *tp; |
struct tag *tp; |
|
|
if (curtag == NULL) |
if (curtag == NULL) |
/* No tag loaded */ |
/* No tag loaded */ |
return NULL; |
return (NULL); |
|
|
tp = curtag->next; |
tp = curtag->next; |
if (tp == TAG_END) |
if (tp == TAG_END) { |
{ |
|
if (!circular) |
if (!circular) |
return NULL; |
return (NULL); |
/* Wrapped around to the head of the queue */ |
/* Wrapped around to the head of the queue */ |
curtag = taglist.tl_first; |
curtag = taglist.tl_first; |
curseq = 1; |
curseq = 1; |
} else |
} else { |
{ |
|
curtag = tp; |
curtag = tp; |
curseq++; |
curseq++; |
} |
} |
|
|
* setup by findgtat(). The next call to gtagsearch() will try to position |
* setup by findgtat(). The next call to gtagsearch() will try to position |
* at the appropriate tag. |
* at the appropriate tag. |
*/ |
*/ |
static char * |
static char * |
prevgtag() |
prevgtag(void) |
{ |
{ |
struct tag *tp; |
struct tag *tp; |
|
|
if (curtag == NULL) |
if (curtag == NULL) |
/* No tag loaded */ |
/* No tag loaded */ |
return NULL; |
return (NULL); |
|
|
tp = curtag->prev; |
tp = curtag->prev; |
if (tp == TAG_END) |
if (tp == TAG_END) { |
{ |
|
if (!circular) |
if (!circular) |
return NULL; |
return (NULL); |
/* Wrapped around to the tail of the queue */ |
/* Wrapped around to the tail of the queue */ |
curtag = taglist.tl_last; |
curtag = taglist.tl_last; |
curseq = total; |
curseq = total; |
} else |
} else { |
{ |
|
curtag = tp; |
curtag = tp; |
curseq--; |
curseq--; |
} |
} |
|
|
* using either findtag() or one of nextgtag() and prevgtag(). Returns -1 |
* using either findtag() or one of nextgtag() and prevgtag(). Returns -1 |
* if it was unable to position at the tag, 0 if successful. |
* if it was unable to position at the tag, 0 if successful. |
*/ |
*/ |
static POSITION |
static off_t |
gtagsearch() |
gtagsearch(void) |
{ |
{ |
if (curtag == NULL) |
if (curtag == NULL) |
return (NULL_POSITION); /* No gtags loaded! */ |
return (-1); /* No gtags loaded! */ |
return (find_pos(curtag->tag_linenum)); |
return (find_pos(curtag->tag_linenum)); |
} |
} |
|
|
|
|
* 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. |
*/ |
*/ |
static int |
static int |
getentry(buf, tag, file, line) |
getentry(char *buf, char **tag, char **file, char **line) |
char *buf; /* standard or extended ctags -x format data */ |
|
char **tag; /* name of the tag we actually found */ |
|
char **file; /* file in which to find this tag */ |
|
char **line; /* line number of file where this tag is found */ |
|
{ |
{ |
char *p = buf; |
char *p = buf; |
|
|
for (*tag = p; *p && !IS_SPACE(*p); p++) /* tag name */ |
for (*tag = p; *p && !isspace(*p); p++) /* tag name */ |
; |
; |
if (*p == 0) |
if (*p == 0) |
return (-1); |
return (-1); |
*p++ = 0; |
*p++ = 0; |
for ( ; *p && IS_SPACE(*p); p++) /* (skip blanks) */ |
for (; *p && isspace(*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 (!IS_DIGIT(*p)) |
if (!isdigit(*p)) { |
{ |
for (; *p && !isspace(*p); p++) /* (skip tag type) */ |
for ( ; *p && !IS_SPACE(*p); p++) /* (skip tag type) */ |
|
; |
; |
for (; *p && IS_SPACE(*p); p++) /* (skip blanks) */ |
for (; *p && isspace(*p); p++) /* (skip blanks) */ |
; |
; |
} |
} |
if (!IS_DIGIT(*p)) |
if (!isdigit(*p)) |
return (-1); |
return (-1); |
*line = p; /* line number */ |
*line = p; /* line number */ |
for (*line = p; *p && !IS_SPACE(*p); p++) |
for (*line = p; *p && !isspace(*p); p++) |
; |
; |
if (*p == 0) |
if (*p == 0) |
return (-1); |
return (-1); |
*p++ = 0; |
*p++ = 0; |
for ( ; *p && IS_SPACE(*p); p++) /* (skip blanks) */ |
for (; *p && isspace(*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 && !IS_SPACE(*p); p++) |
for (*file = p; *p && !isspace(*p); p++) |
; |
; |
if (*p == 0) |
if (*p == 0) |
return (-1); |
return (-1); |
|
|
return (0); |
return (0); |
return (-1); |
return (-1); |
} |
} |
|
|
#endif |
|