mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-30 13:44:55 +00:00
Grok gtags too.
This commit is contained in:
parent
e6923505ee
commit
ac8ab44cf6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=47684
|
@ -38,7 +38,7 @@ static char sccsid[] = "@(#)command.c 8.1 (Berkeley) 6/6/93";
|
|||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
"$Id: command.c,v 1.11 1999/05/30 18:06:52 hoek Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -364,6 +364,7 @@ commands()
|
|||
register int action;
|
||||
static int default_hscroll = 1;
|
||||
static int saved_horiz_off = NO_HORIZ_OFF;
|
||||
extern char *tagfile;
|
||||
|
||||
last_mca = 0;
|
||||
scroll = (sc_height + 1) / 2;
|
||||
|
@ -569,6 +570,24 @@ again: if (sigs)
|
|||
start_mca(A_TAGFILE, "Tag: ");
|
||||
c = getcc();
|
||||
goto again;
|
||||
case A_NEXTTAG:
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
nexttag(number);
|
||||
if (tagfile == NULL)
|
||||
break;
|
||||
if (edit(tagfile))
|
||||
(void)tagsearch();
|
||||
break;
|
||||
case A_PREVTAG:
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
prevtag(number);
|
||||
if (tagfile == NULL)
|
||||
break;
|
||||
if (edit(tagfile))
|
||||
(void)tagsearch();
|
||||
break;
|
||||
case A_FILE_LIST: /* show list of file names */
|
||||
CMD_EXEC;
|
||||
showlist();
|
||||
|
|
|
@ -38,7 +38,7 @@ static char sccsid[] = "@(#)decode.c 8.1 (Berkeley) 6/6/93";
|
|||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
"$Id: decode.c,v 1.2 1999/05/30 18:06:53 hoek Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
|
@ -133,6 +133,8 @@ static char cmdtable[] = {
|
|||
'q',0, A_QUIT,
|
||||
':','q',0, A_QUIT,
|
||||
':','t',0, A_TAGFILE,
|
||||
'T',0, A_PREVTAG,
|
||||
't',0, A_NEXTTAG,
|
||||
':', 'a', 0, A_FILE_LIST,
|
||||
'Z','Z',0, A_QUIT,
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
*
|
||||
* @(#)less.h 8.1 (Berkeley) 6/6/93
|
||||
*
|
||||
* $Id$
|
||||
* $Id: less.h,v 1.3 1999/05/30 18:06:55 hoek Exp $
|
||||
*/
|
||||
|
||||
#define NULL_POSITION ((off_t)(-1))
|
||||
|
@ -90,3 +90,5 @@
|
|||
#define A_L_COL 28
|
||||
#define A_R_COL 29
|
||||
#define A_HOME 30
|
||||
#define A_NEXTTAG 31
|
||||
#define A_PREVTAG 32
|
||||
|
|
|
@ -45,7 +45,7 @@ static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/7/93";
|
|||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
"$Id: main.c,v 1.11 1999/05/30 18:06:56 hoek Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
|
@ -82,7 +82,8 @@ extern int tagoption;
|
|||
/*
|
||||
* Edit a new file.
|
||||
* Filename "-" means standard input.
|
||||
* No filename means the "current" file, from the command line.
|
||||
* No filename means the "current" file, from the command line. If called
|
||||
* with the same filename in succession, filename will be closed and reopened.
|
||||
*/
|
||||
edit(filename)
|
||||
register char *filename;
|
||||
|
|
|
@ -245,6 +245,10 @@ Examine the previous file.
|
|||
If a number N is specified, the N-th previous file is examined.
|
||||
.It Ic \&:t
|
||||
Go to supplied tag.
|
||||
.It Ic t
|
||||
Go forward in tag queue [gtags only].
|
||||
.It Ic T
|
||||
Go backward in tag queue [gtags only].
|
||||
.It Ic v
|
||||
Invokes an editor to edit the current file being viewed.
|
||||
The editor is taken from the environment variable
|
||||
|
@ -286,6 +290,8 @@ Specifies terminal type, used by more to get the terminal
|
|||
characteristics necessary to manipulate the screen.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr gtags 1 ,
|
||||
.Xr global 1 ,
|
||||
.Xr ctags 1 ,
|
||||
.Xr vi 1
|
||||
.Sh BUGS
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
:n, N * Examine the next file.
|
||||
:p, P * Examine the previous file.
|
||||
:t [tag] Examine the tag.
|
||||
t, T Move forward or backward N tags in the gtags queue.
|
||||
v Run an editor on the current file.
|
||||
|
||||
=, ^G Print current file name and stats.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright (c) 1988 Mark Nudleman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* Portions copyright (c) 1996, 1997, 1998 Shigio Yamaguchi.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -36,43 +37,158 @@
|
|||
static char sccsid[] = "@(#)tags.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <less.h>
|
||||
|
||||
#include "less.h"
|
||||
|
||||
#define WHITESP(c) ((c)==' ' || (c)=='\t')
|
||||
|
||||
char *tagfile;
|
||||
char *tagpattern;
|
||||
|
||||
static char *tags = "tags";
|
||||
|
||||
extern int linenums;
|
||||
extern int sigs;
|
||||
extern char *line;
|
||||
char *tagfile; /* Name of source file containing current tag */
|
||||
|
||||
static enum { CTAGS, GTAGS } tagstyle = GTAGS;
|
||||
static char *findctag(), *findgtag(), *nextgtag(), *prevgtag();
|
||||
static ctagsearch(), gtagsearch();
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* Load information about the tag. The global variable tagfile will point to
|
||||
* the file that contains the tag, or will be NULL if information could not be
|
||||
* found (in which case an error message will have been printed). After
|
||||
* loading the file named by tagfile, tagsearch() should be called to
|
||||
* set the current position to the tag.
|
||||
*/
|
||||
findtag(tag)
|
||||
register char *tag;
|
||||
char *tag; /* The tag to load */
|
||||
{
|
||||
/*
|
||||
* Try using gtags or ctags first, as indicated by tagstyle. If
|
||||
* that fails, try the other. Someday there may even be a way to
|
||||
* assert a certain tagstyle...
|
||||
*/
|
||||
switch(tagstyle) {
|
||||
case CTAGS:
|
||||
tagfile = findctag(tag);
|
||||
if (!tagfile && (tagfile = findgtag(tag))) tagstyle = GTAGS;
|
||||
if (tagfile) return;
|
||||
break;
|
||||
case GTAGS:
|
||||
/* Would be nice to print the number of tag references
|
||||
* we found (for nexttag() and prevtag()) in a (not-)error()
|
||||
* message. */
|
||||
tagfile = findgtag(tag);
|
||||
if (!tagfile && (tagfile = findctag(tag))) tagstyle = CTAGS;
|
||||
if (tagfile) return;
|
||||
break;
|
||||
}
|
||||
|
||||
error("could not find relevent tag information");
|
||||
}
|
||||
|
||||
/*
|
||||
* Load information about the next number'th tag, if the last findtag() call
|
||||
* found multiple tag references. The global variable tagfile will point to the
|
||||
* file that contains the tag, or will be NULL if information could not be
|
||||
* found (in which case an error message will have been printed). After
|
||||
* loading the file named by tagfile, tagsearch() should be called to set
|
||||
* the current position to the tag.
|
||||
*/
|
||||
nexttag(number)
|
||||
int number; /* How many tags to go forward by */
|
||||
{
|
||||
if (number < 0) number = -number; /* positive only, please */
|
||||
|
||||
switch(tagstyle) {
|
||||
case CTAGS:
|
||||
break;
|
||||
case GTAGS:
|
||||
while (number--) tagfile = nextgtag();
|
||||
break;
|
||||
}
|
||||
if (!tagfile)
|
||||
error("no next tag");
|
||||
}
|
||||
|
||||
/*
|
||||
* The antithesis to nexttag().
|
||||
*/
|
||||
prevtag(number)
|
||||
int number; /* How many tags to go backwards by */
|
||||
{
|
||||
if (number < 0) number = -number; /* positive only, please */
|
||||
|
||||
switch(tagstyle) {
|
||||
case CTAGS:
|
||||
break;
|
||||
case GTAGS:
|
||||
while (number--) tagfile = prevgtag();
|
||||
break;
|
||||
}
|
||||
if (!tagfile)
|
||||
error("no previous tag");
|
||||
}
|
||||
|
||||
/*
|
||||
* Try and position the currently loaded file at the last tag that was
|
||||
* succesfully passed to findtag() or chosen with nexttag() and prevtag().
|
||||
* An error message will be printed if unsuccessful.
|
||||
*/
|
||||
tagsearch()
|
||||
{
|
||||
switch(tagstyle) {
|
||||
case CTAGS:
|
||||
if (ctagsearch())
|
||||
error("could not locate ctag");
|
||||
return;
|
||||
case GTAGS:
|
||||
if (gtagsearch())
|
||||
error("could not locate gtag");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* ctags
|
||||
*
|
||||
*/
|
||||
|
||||
extern int linenums;
|
||||
extern char *line;
|
||||
|
||||
static char *ctagpattern;
|
||||
|
||||
/*
|
||||
* Find specified tag in the ctags(1)-format tag file ctagfile. Returns
|
||||
* pointer to a static buffer holding the name of the file containing
|
||||
* the tag. Returns NULL on failure. The next call to ctagsearch() will
|
||||
* position the currently loaded file at the tag.
|
||||
*/
|
||||
static char *
|
||||
findctag(tag)
|
||||
register char *tag; /* tag to search for */
|
||||
{
|
||||
register char *p;
|
||||
register FILE *f;
|
||||
register int taglen;
|
||||
int search_char;
|
||||
static char tline[200];
|
||||
static char tline[200]; /* XXX should be dynamic */
|
||||
const char *ctagfile = "tags";
|
||||
char *retr;
|
||||
|
||||
if ((f = fopen(tags, "r")) == NULL)
|
||||
{
|
||||
error("No tags file");
|
||||
tagfile = NULL;
|
||||
return;
|
||||
}
|
||||
if ((f = fopen(ctagfile, "r")) == NULL)
|
||||
return (NULL);
|
||||
|
||||
taglen = strlen(tag);
|
||||
|
||||
|
@ -81,6 +197,9 @@ findtag(tag)
|
|||
*/
|
||||
while (fgets(tline, sizeof(tline), f) != NULL)
|
||||
{
|
||||
if (sigs)
|
||||
break; /* abandon */
|
||||
|
||||
if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen]))
|
||||
continue;
|
||||
|
||||
|
@ -92,10 +211,9 @@ findtag(tag)
|
|||
* search characters.
|
||||
* Parse the line and extract these parts.
|
||||
*/
|
||||
tagfile = tagpattern = NULL;
|
||||
|
||||
/*
|
||||
* Skip over the whitespace after the tag name.
|
||||
* Skip over the tag and the whitespace after the tag name.
|
||||
*/
|
||||
for (p = tline; !WHITESP(*p) && *p != '\0'; p++)
|
||||
continue;
|
||||
|
@ -107,9 +225,9 @@ findtag(tag)
|
|||
|
||||
/*
|
||||
* Save the file name.
|
||||
* Skip over the whitespace after the file name.
|
||||
* Skip over the filename and whitespace after the file name.
|
||||
*/
|
||||
tagfile = p;
|
||||
retr = p;
|
||||
while (!WHITESP(*p) && *p != '\0')
|
||||
p++;
|
||||
*p++ = '\0';
|
||||
|
@ -127,7 +245,7 @@ findtag(tag)
|
|||
search_char = *p++;
|
||||
if (*p == '^')
|
||||
p++;
|
||||
tagpattern = p;
|
||||
ctagpattern = p; /* cock ctagsearch() */
|
||||
while (*p != search_char && *p != '\0')
|
||||
p++;
|
||||
if (p[-1] == '$')
|
||||
|
@ -135,23 +253,26 @@ findtag(tag)
|
|||
*p = '\0';
|
||||
|
||||
(void)fclose(f);
|
||||
return;
|
||||
return (retr);
|
||||
}
|
||||
(void)fclose(f);
|
||||
error("No such tag in tags file");
|
||||
tagfile = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for a tag.
|
||||
* Locate the tag that was loaded by findctag().
|
||||
* 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).
|
||||
*
|
||||
* Returns -1 if it was unable to position at the requested pattern,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
tagsearch()
|
||||
static
|
||||
ctagsearch()
|
||||
{
|
||||
off_t pos, linepos, forw_raw_line();
|
||||
int linenum;
|
||||
|
@ -166,7 +287,7 @@ tagsearch()
|
|||
* until we hit end-of-file.
|
||||
*/
|
||||
if (sigs)
|
||||
return (1);
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Read the next line, and save the
|
||||
|
@ -178,13 +299,7 @@ tagsearch()
|
|||
linenum++;
|
||||
|
||||
if (pos == NULL_POSITION)
|
||||
{
|
||||
/*
|
||||
* We hit EOF without a match.
|
||||
*/
|
||||
error("Tag not found");
|
||||
return (1);
|
||||
}
|
||||
return (-1); /* Tag not found. */
|
||||
|
||||
/*
|
||||
* If we're using line numbers, we might as well
|
||||
|
@ -197,10 +312,247 @@ tagsearch()
|
|||
/*
|
||||
* Test the line to see if we have a match.
|
||||
*/
|
||||
if (strcmp(tagpattern, line) == 0)
|
||||
if (strcmp(ctagpattern, line) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
jump_loc(linepos);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* gtags
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The findgtag() and getentry() functions are stolen, more or less, from the
|
||||
* patches to nvi-1.79 included in Shigio Yamaguchi's global-3.42 distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The queue of tags generated by the last findgtag() call.
|
||||
*/
|
||||
static CIRCLEQ_HEAD(gtag_q, gtag) gtag_q;
|
||||
struct gtag {
|
||||
CIRCLEQ_ENTRY(gtag) ptrs;
|
||||
char *file; /* source file containing the tag */
|
||||
int line; /* appropriate line number of source file */
|
||||
};
|
||||
static struct gtag *curgtag;
|
||||
static getentry();
|
||||
|
||||
/*
|
||||
* The findgtag() will try and load information about the requested tag.
|
||||
* It does this by calling "global -x tag; global -xr tag;" and storing the
|
||||
* parsed output for future use by gtagsearch_f() and gtagsearch_b(). A
|
||||
* pointer to a static buffer containing the name of the source file will
|
||||
* be returned, or NULL on failure. The first filename printed by global is
|
||||
* returned (hopefully the function definition) and the other filenames may
|
||||
* be accessed by nextgtag() and prevgtag().
|
||||
*/
|
||||
static char *
|
||||
findgtag(tag)
|
||||
char *tag; /* tag to load */
|
||||
{
|
||||
struct gtag *gtag_p1, *gtag_p2;
|
||||
char command[512];
|
||||
char buf[256];
|
||||
FILE *fp;
|
||||
|
||||
if (!tag) return (NULL); /* Sanity check */
|
||||
|
||||
/* Clear any existing tag circle queue */
|
||||
/* XXX Ideally, we wouldn't do this until after we know that we
|
||||
* can load some other tag information. */
|
||||
curgtag = NULL;
|
||||
gtag_p1 = gtag_q.cqh_first;
|
||||
if (gtag_p1) while (gtag_p1 != (void *)>ag_q) {
|
||||
gtag_p2 = gtag_p1->ptrs.cqe_next;
|
||||
free(gtag_p1);
|
||||
gtag_p1 = gtag_p2;
|
||||
}
|
||||
|
||||
/* Allocate and initialize the tag queue structure. */
|
||||
CIRCLEQ_INIT(>ag_q);
|
||||
|
||||
/* Get our data from global(1) */
|
||||
snprintf(command, sizeof(command),
|
||||
"(global -x '%s'; global -xr '%s') 2>/dev/null", tag, tag);
|
||||
if (fp = popen(command, "r")) {
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
char *name, *file, *line;
|
||||
|
||||
if (sigs) {
|
||||
pclose(fp);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* chop(buf) */
|
||||
if (buf[strlen(buf) - 1] == '\n')
|
||||
buf[strlen(buf) - 1] = 0;
|
||||
else
|
||||
while (fgetc(fp) != '\n')
|
||||
;
|
||||
|
||||
if (getentry(buf, &name, &file, &line)) {
|
||||
/*
|
||||
* Couldn't parse this line for some reason.
|
||||
* We'll just pretend it never happened.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add to queue */
|
||||
gtag_p1 = malloc(sizeof(struct gtag));
|
||||
if (!gtag_p1) {
|
||||
pclose(fp);
|
||||
error("malloc() failed");
|
||||
return (NULL);
|
||||
}
|
||||
gtag_p1->file = file;
|
||||
gtag_p1->file = malloc(strlen(file));
|
||||
if (!gtag_p1->file) {
|
||||
pclose(fp);
|
||||
error("malloc() failed");
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(gtag_p1->file, file);
|
||||
gtag_p1->line = atoi(line);
|
||||
CIRCLEQ_INSERT_TAIL(>ag_q, gtag_p1, ptrs);
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
|
||||
/* Check to see if we found anything. */
|
||||
if (gtag_q.cqh_first == (void *)>ag_q)
|
||||
return (NULL); /* Nope! */
|
||||
|
||||
curgtag = gtag_q.cqh_first;
|
||||
return (curgtag->file);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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()
|
||||
{
|
||||
if (!curgtag) {
|
||||
/* No tag stack loaded */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
curgtag = curgtag->ptrs.cqe_next;
|
||||
if (curgtag == (void *)>ag_q) {
|
||||
/* Wrapped around to the head of the queue */
|
||||
curgtag = ((struct gtag_q *)curgtag)->cqh_first;
|
||||
}
|
||||
|
||||
return (curgtag->file);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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()
|
||||
{
|
||||
if (!curgtag) {
|
||||
/* No tag stack loaded */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
curgtag = curgtag->ptrs.cqe_prev;
|
||||
if (curgtag == (void *)>ag_q) {
|
||||
/* Wrapped around to the head of the queue */
|
||||
curgtag = ((struct gtag_q *)curgtag)->cqh_last;
|
||||
}
|
||||
|
||||
return (curgtag->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 succesful.
|
||||
*/
|
||||
static
|
||||
gtagsearch()
|
||||
{
|
||||
if (!curgtag)
|
||||
return (-1); /* No gtags loaded! */
|
||||
|
||||
jump_back(curgtag->line);
|
||||
|
||||
/*
|
||||
* XXX We'll assume we were successful --- jump_back() will call error()
|
||||
* if it fails, so the user will receive some kind of notification.
|
||||
* Eventually, jump_back() should do its work silently and let us
|
||||
* perform the error notification, eventually allowing our caller
|
||||
* (presumably tagsearch()) to go error("Could not locate tag.");
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The getentry() parses output from the global(1) command. The output
|
||||
* must be in the format described below. Returns 0 on success, -1 on
|
||||
* error. The tag, file, and line will each be NUL-terminated pointers
|
||||
* into buf.
|
||||
*
|
||||
* gtags temporary file format.
|
||||
* <tag> <lineno> <file> <image>
|
||||
*
|
||||
* sample.
|
||||
* +------------------------------------------------
|
||||
* |main 30 main.c main(argc, argv)
|
||||
* |func 21 subr.c func(arg)
|
||||
*/
|
||||
static
|
||||
getentry(buf, tag, file, line)
|
||||
char *buf; /* output from global -x */
|
||||
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;
|
||||
|
||||
for (*tag = p; *p && !isspace(*p); p++) /* tag name */
|
||||
;
|
||||
if (*p == 0)
|
||||
goto err;
|
||||
*p++ = 0;
|
||||
for (; *p && isspace(*p); p++) /* (skip blanks) */
|
||||
;
|
||||
if (*p == 0)
|
||||
goto err;
|
||||
*line = p; /* line no */
|
||||
for (*line = p; *p && !isspace(*p); p++)
|
||||
;
|
||||
if (*p == 0)
|
||||
goto err;
|
||||
*p++ = 0;
|
||||
for (; *p && isspace(*p); p++) /* (skip blanks) */
|
||||
;
|
||||
if (*p == 0)
|
||||
goto err;
|
||||
*file = p; /* file name */
|
||||
for (*file = p; *p && !isspace(*p); p++)
|
||||
;
|
||||
if (*p == 0)
|
||||
goto err;
|
||||
*p = 0;
|
||||
|
||||
/* value check */
|
||||
if (strlen(*tag) && strlen(*line) && strlen(*file) && atoi(*line) > 0)
|
||||
return (0); /* OK */
|
||||
err:
|
||||
return (-1); /* ERROR */
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue