home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / src / parseinfo.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  163 lines

  1. /*
  2.  * Copyright (c) 1992, Brian Berliner and Jeff Polk
  3.  * Copyright (c) 1989-1992, Brian Berliner
  4.  * 
  5.  * You may distribute under the terms of the GNU General Public License as
  6.  * specified in the README file that comes with the CVS 1.4 kit.
  7.  */
  8.  
  9. #include "cvs.h"
  10.  
  11. /*
  12.  * Parse the INFOFILE file for the specified REPOSITORY.  Invoke CALLPROC for
  13.  * the first line in the file that matches the REPOSITORY, or if ALL != 0, any lines
  14.  * matching "ALL", or if no lines match, the last line matching "DEFAULT".
  15.  *
  16.  * Return 0 for success, -1 if there was not an INFOFILE, and >0 for failure.
  17.  */
  18. int
  19. Parse_Info (infofile, repository, callproc, all)
  20.     char *infofile;
  21.     char *repository;
  22.     CALLPROC callproc;
  23.     int all;
  24. {
  25.     int err = 0;
  26.     FILE *fp_info;
  27.     char infopath[PATH_MAX];
  28.     char line[MAXLINELEN];
  29.     char *default_value = NULL;
  30.     char *expanded_value= NULL;
  31.     int callback_done, line_number;
  32.     char *cp, *exp, *value, *srepos;
  33.     const char *regex_err;
  34.  
  35.     if (CVSroot_original == NULL)
  36.     {
  37.     /* XXX - should be error maybe? */
  38.     error (0, 0, "CVSROOT variable not set");
  39.     return (1);
  40.     }
  41.  
  42.     /* find the info file and open it */
  43.     (void) sprintf (infopath, "%s/%s/%s", CVSroot_directory,
  44.             CVSROOTADM, infofile);
  45.     if ((fp_info = CVS_FOPEN (infopath, "r")) == NULL)
  46.     return (0);            /* no file -> nothing special done */
  47.  
  48.     /* strip off the CVSROOT if repository was absolute */
  49.     srepos = Short_Repository (repository);
  50.  
  51.     if (trace)
  52.     (void) fprintf (stderr, "-> ParseInfo(%s, %s, %s)\n",
  53.             infopath, srepos, all ? "ALL" : "not ALL");
  54.  
  55.     /* search the info file for lines that match */
  56.     callback_done = line_number = 0;
  57.     while (fgets (line, sizeof (line), fp_info) != NULL)
  58.     {
  59.     line_number++;
  60.  
  61.     /* skip lines starting with # */
  62.     if (line[0] == '#')
  63.         continue;
  64.  
  65.     /* skip whitespace at beginning of line */
  66.     for (cp = line; *cp && isspace (*cp); cp++)
  67.         ;
  68.  
  69.     /* if *cp is null, the whole line was blank */
  70.     if (*cp == '\0')
  71.         continue;
  72.  
  73.     /* the regular expression is everything up to the first space */
  74.     for (exp = cp; *cp && !isspace (*cp); cp++)
  75.         ;
  76.     if (*cp != '\0')
  77.         *cp++ = '\0';
  78.  
  79.     /* skip whitespace up to the start of the matching value */
  80.     while (*cp && isspace (*cp))
  81.         cp++;
  82.  
  83.     /* no value to match with the regular expression is an error */
  84.     if (*cp == '\0')
  85.     {
  86.         error (0, 0, "syntax error at line %d file %s; ignored",
  87.            line_number, infofile);
  88.         continue;
  89.     }
  90.     value = cp;
  91.  
  92.     /* strip the newline off the end of the value */
  93.     if ((cp = strrchr (value, '\n')) != NULL)
  94.         *cp = '\0';
  95.  
  96.     expanded_value = expand_path (value, infofile, line_number);
  97.     if (!expanded_value)
  98.     {
  99.         continue;
  100.     }
  101.  
  102.     /*
  103.      * At this point, exp points to the regular expression, and value
  104.      * points to the value to call the callback routine with.  Evaluate
  105.      * the regular expression against srepos and callback with the value
  106.      * if it matches.
  107.      */
  108.  
  109.     /* save the default value so we have it later if we need it */
  110.     if (strcmp (exp, "DEFAULT") == 0)
  111.     {
  112.         default_value = xstrdup (expanded_value);
  113.         continue;
  114.     }
  115.  
  116.     /*
  117.      * For a regular expression of "ALL", do the callback always We may
  118.      * execute lots of ALL callbacks in addition to *one* regular matching
  119.      * callback or default
  120.      */
  121.     if (strcmp (exp, "ALL") == 0)
  122.     {
  123.         if (all)
  124.         err += callproc (repository, expanded_value);
  125.         else
  126.         error(0, 0, "Keyword `ALL' is ignored at line %d in %s file",
  127.               line_number, infofile);
  128.         continue;
  129.     }
  130.  
  131.     if (callback_done)
  132.         /* only first matching, plus "ALL"'s */
  133.         continue;
  134.  
  135.     /* see if the repository matched this regular expression */
  136.     if ((regex_err = re_comp (exp)) != NULL)
  137.     {
  138.         error (0, 0, "bad regular expression at line %d file %s: %s",
  139.            line_number, infofile, regex_err);
  140.         continue;
  141.     }
  142.     if (re_exec (srepos) == 0)
  143.         continue;                /* no match */
  144.  
  145.     /* it did, so do the callback and note that we did one */
  146.     err += callproc (repository, expanded_value);
  147.     callback_done = 1;
  148.     }
  149.     (void) fclose (fp_info);
  150.  
  151.     /* if we fell through and didn't callback at all, do the default */
  152.     if (callback_done == 0 && default_value != NULL)
  153.     err += callproc (repository, default_value);
  154.  
  155.     /* free up space if necessary */
  156.     if (default_value != NULL)
  157.     free (default_value);
  158.     if (expanded_value != NULL)
  159.     free (expanded_value);
  160.  
  161.     return (err);
  162. }
  163.