148 lines
3.8 KiB
C
148 lines
3.8 KiB
C
/*
|
|
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
|
* Copyright (c) 1989-1992, Brian Berliner
|
|
*
|
|
* You may distribute under the terms of the GNU General Public License as
|
|
* specified in the README file that comes with the CVS 1.3 kit.
|
|
*/
|
|
|
|
#include "cvs.h"
|
|
|
|
#ifndef lint
|
|
static char rcsid[] = "@(#)parseinfo.c 1.16 92/04/10";
|
|
#endif
|
|
|
|
/*
|
|
* Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
|
|
* each line in the file that matches the REPOSITORY.
|
|
* Return 0 for success, -1 if there was not an INFOFILE, and >0 for failure.
|
|
*/
|
|
int
|
|
Parse_Info (infofile, repository, callproc, all)
|
|
char *infofile;
|
|
char *repository;
|
|
int (*callproc) ();
|
|
int all;
|
|
{
|
|
int err = 0;
|
|
FILE *fp_info;
|
|
char infopath[PATH_MAX];
|
|
char line[MAXLINELEN];
|
|
char *default_value = NULL;
|
|
int callback_done, line_number;
|
|
char *cp, *exp, *value, *srepos;
|
|
CONST char *regex_err;
|
|
|
|
if (CVSroot == NULL)
|
|
{
|
|
/* XXX - should be error maybe? */
|
|
error (0, 0, "CVSROOT variable not set");
|
|
return (1);
|
|
}
|
|
|
|
/* find the info file and open it */
|
|
(void) sprintf (infopath, "%s/%s/%s", CVSroot,
|
|
CVSROOTADM, infofile);
|
|
if ((fp_info = fopen (infopath, "r")) == NULL)
|
|
return (0); /* no file -> nothing special done */
|
|
|
|
/* strip off the CVSROOT if repository was absolute */
|
|
srepos = Short_Repository (repository);
|
|
|
|
/* search the info file for lines that match */
|
|
callback_done = line_number = 0;
|
|
while (fgets (line, sizeof (line), fp_info) != NULL)
|
|
{
|
|
line_number++;
|
|
|
|
/* skip lines starting with # */
|
|
if (line[0] == '#')
|
|
continue;
|
|
|
|
/* skip whitespace at beginning of line */
|
|
for (cp = line; *cp && isspace (*cp); cp++)
|
|
;
|
|
|
|
/* if *cp is null, the whole line was blank */
|
|
if (*cp == '\0')
|
|
continue;
|
|
|
|
/* the regular expression is everything up to the first space */
|
|
for (exp = cp; *cp && !isspace (*cp); cp++)
|
|
;
|
|
if (*cp != '\0')
|
|
*cp++ = '\0';
|
|
|
|
/* skip whitespace up to the start of the matching value */
|
|
while (*cp && isspace (*cp))
|
|
cp++;
|
|
|
|
/* no value to match with the regular expression is an error */
|
|
if (*cp == '\0')
|
|
{
|
|
error (0, 0, "syntax error at line %d file %s; ignored",
|
|
line_number, infofile);
|
|
continue;
|
|
}
|
|
value = cp;
|
|
|
|
/* strip the newline off the end of the value */
|
|
if ((cp = rindex (value, '\n')) != NULL)
|
|
*cp = '\0';
|
|
|
|
/*
|
|
* At this point, exp points to the regular expression, and value
|
|
* points to the value to call the callback routine with. Evaluate
|
|
* the regular expression against srepos and callback with the value
|
|
* if it matches.
|
|
*/
|
|
|
|
/* save the default value so we have it later if we need it */
|
|
if (strcmp (exp, "DEFAULT") == 0)
|
|
{
|
|
default_value = xstrdup (value);
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
* For a regular expression of "ALL", do the callback always We may
|
|
* execute lots of ALL callbacks in addition to one regular matching
|
|
* callback or default
|
|
*/
|
|
if (strcmp (exp, "ALL") == 0)
|
|
{
|
|
if (all)
|
|
err += callproc (repository, value);
|
|
else
|
|
error(0, 0, "Keyword `ALL' is ignored at line %d in %s file",
|
|
line_number, infofile);
|
|
continue;
|
|
}
|
|
|
|
/* see if the repository matched this regular expression */
|
|
if ((regex_err = re_comp (exp)) != NULL)
|
|
{
|
|
error (0, 0, "bad regular expression at line %d file %s: %s",
|
|
line_number, infofile, regex_err);
|
|
continue;
|
|
}
|
|
if (re_exec (srepos) == 0)
|
|
continue; /* no match */
|
|
|
|
/* it did, so do the callback and note that we did one */
|
|
err += callproc (repository, value);
|
|
callback_done = 1;
|
|
}
|
|
(void) fclose (fp_info);
|
|
|
|
/* if we fell through and didn't callback at all, do the default */
|
|
if (callback_done == 0 && default_value != NULL)
|
|
err += callproc (repository, default_value);
|
|
|
|
/* free up space if necessary */
|
|
if (default_value != NULL)
|
|
free (default_value);
|
|
|
|
return (err);
|
|
}
|