386BSD 0.1 development
[unix-history] / usr / othersrc / public / cvs-1.3 / src / parseinfo.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);
}