home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / RCS_SRC.ZIP / RCSKEEP.C < prev    next >
C/C++ Source or Header  |  1991-01-15  |  10KB  |  310 lines

  1. /*
  2.  *                     RCS keyword extraction
  3.  */
  4. #ifndef lint
  5. static char rcsid[]= "$Id: rcskeep.c,v 4.6 89/05/01 15:12:56 narten Exp $ Purdue CS";
  6. #endif
  7. /*****************************************************************************
  8.  *                       main routine: getoldkeys()
  9.  *                       Testprogram: define KEEPTEST
  10.  *****************************************************************************
  11.  */
  12.  
  13. /* Copyright (C) 1982, 1988, 1989 Walter Tichy
  14.    Distributed under license by the Free Software Foundation, Inc.
  15.  
  16. This file is part of RCS.
  17.  
  18. RCS is free software; you can redistribute it and/or modify
  19. it under the terms of the GNU General Public License as published by
  20. the Free Software Foundation; either version 1, or (at your option)
  21. any later version.
  22.  
  23. RCS is distributed in the hope that it will be useful,
  24. but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26. GNU General Public License for more details.
  27.  
  28. You should have received a copy of the GNU General Public License
  29. along with RCS; see the file COPYING.  If not, write to
  30. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  31.  
  32. Report problems and direct all questions to:
  33.  
  34.     rcs-bugs@cs.purdue.edu
  35.  
  36. */
  37.  
  38.  
  39.  
  40. /* $Log:    rcskeep.c,v $
  41.  * Revision 4.6  89/05/01  15:12:56  narten
  42.  * changed copyright header to reflect current distribution rules
  43.  * 
  44.  * Revision 4.5  88/11/08  12:01:05  narten
  45.  * changes from  eggert@sm.unisys.com (Paul Eggert)
  46.  * 
  47.  * Revision 4.5  88/08/09  19:13:03  eggert
  48.  * Remove lint and speed up by making FILE *fp local, not global.
  49.  * 
  50.  * Revision 4.4  87/12/18  11:44:21  narten
  51.  * more lint cleanups (Guy Harris)
  52.  * 
  53.  * Revision 4.3  87/10/18  10:35:50  narten
  54.  * Updating version numbers. Changes relative to 1.1 actually relative
  55.  * to 4.1
  56.  * 
  57.  * Revision 1.3  87/09/24  14:00:00  narten
  58.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  59.  * warnings)
  60.  * 
  61.  * Revision 1.2  87/03/27  14:22:29  jenkins
  62.  * Port to suns
  63.  * 
  64.  * Revision 1.1  84/01/23  14:50:30  kcs
  65.  * Initial revision
  66.  * 
  67.  * Revision 4.1  83/05/10  16:26:44  wft
  68.  * Added new markers Id and RCSfile; extraction added.
  69.  * Marker matching with trymatch().
  70.  * 
  71.  * Revision 3.2  82/12/24  12:08:26  wft
  72.  * added missing #endif.
  73.  *
  74.  * Revision 3.1  82/12/04  13:22:41  wft
  75.  * Initial revision.
  76.  *
  77.  */
  78.  
  79. /*
  80. #define KEEPTEST
  81. /* Testprogram; prints out the keyword values found. */
  82.  
  83. #include  "rcsbase.h"
  84. extern char * checkid();
  85. extern FILE * fopen();
  86. static int getval();
  87. extern enum markers trymatch();
  88.  
  89. #define IDLENGTH 30
  90. char prevauthor[IDLENGTH];
  91. char prevdate[datelength];
  92. char prevRCS[NCPFN];
  93. char prevrev[revlength];
  94. char prevsource[NCPPN];
  95. char prevstate [IDLENGTH];
  96. char prevlocker[IDLENGTH];
  97. char dummy[IDLENGTH];
  98.  
  99. getoldkeys(fname)
  100. char * fname;
  101. /* Function: Tries to read keyword values for author, date,
  102.  * revision number, RCS file, (both with and without path),
  103.  * state, and workfilename out of the file fname.
  104.  * The results are placed into
  105.  * prevauthor, prevdate, prevRCS, prevrev, prevsource, prevstate.
  106.  * Aborts immediately if it finds an error and returns false.
  107.  * If it returns true, it doesn't mean that any of the
  108.  * values were found; instead, check to see whether the corresponding arrays
  109.  * contain the empty string.
  110.  */
  111. {
  112.     register FILE *fp;
  113.     register int c;
  114.     char keyword[keylength+2];
  115.     register char * tp;
  116.     enum markers mresult;
  117.  
  118.     /* initialize to empty */
  119.     prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0';
  120.  
  121.     if ( (fp = fopen(fname, "r") ) == NULL ) {
  122.        error("Can't open %s\n", fname);
  123.        return false;
  124.     }
  125.     while( (c=getc(fp)) != EOF) {
  126.         if ( c==KDELIM) {
  127.             /* try to get keyword */
  128.             tp = keyword;
  129.         while( (c=getc(fp))!=EOF && (tp< keyword+keylength) && (c!='\n')
  130.            && (c!=KDELIM) && (c!=VDELIM))
  131.           *tp++ = c;
  132.  
  133.             if (c==KDELIM) {VOID ungetc(c,fp);continue;}
  134.             if (c!=VDELIM) continue;
  135.         *tp++ = c;
  136.             *tp='\0';
  137.             while ((c=getc(fp))==' '||c=='\t'); /* skip blanks */
  138.             VOID ungetc(c,fp); /* needed for getval */
  139.  
  140.         switch (mresult=trymatch(keyword,true)) {
  141.             case Author:
  142.         if (getval(fp,prevauthor,IDLENGTH,true))
  143.                     if (!checkid(prevauthor, '\0')) goto errexit;
  144.                 break;
  145.             case Date:
  146.         if (!getprevdate(fp,true)) goto errexit;
  147.                 break;
  148.             case Header:
  149.             case Id:
  150.         if (mresult==Header) {
  151.             if (!getval(fp,prevsource,NCPPN,true)) break; /*unexpanded*/
  152.         } else {
  153.             if (!getval(fp,prevRCS,NCPFN,true))    break; /*unexpanded*/
  154.         }
  155.         if (!getval(fp,prevrev,revlength,false)) goto errexit;
  156.         if (!checknum(prevrev,-1)) {
  157.             error("Bad revision number");
  158.             goto errexit;
  159.         }
  160.         if (!getprevdate(fp,false)) goto errexit;
  161.         if (!getval(fp,prevauthor,IDLENGTH,false)) goto errexit;
  162.         if (!checkid(prevauthor, '\0')) goto errexit;
  163.         if (!getval(fp,prevstate,IDLENGTH,false)) goto errexit;
  164.         if (!checkid(prevstate, '\0')) goto errexit;
  165.         VOID getval(fp, dummy, IDLENGTH, true);    /* optional locker*/
  166.         VOID getval(fp, prevlocker,IDLENGTH,true); /* optional locker*/
  167.                 break;
  168.             case Locker:
  169.                 VOID getval(fp,prevlocker,IDLENGTH,true);
  170.         if (!checkid(prevlocker, '\0')) goto errexit;
  171.                 break;
  172.             case Log:
  173.         VOID getval(fp,prevRCS,NCPPN,true);
  174.                 break;
  175.             case RCSfile:
  176.                 VOID getval(fp,prevRCS,NCPFN,true);
  177.                 break;
  178.             case Revision:
  179.                 if (getval(fp,prevrev,revlength,true))
  180.                     if (!checknum(prevrev,-1)) {
  181.                         error("Bad revision number");
  182.                         goto errexit;
  183.                     }
  184.                 break;
  185.             case Source:
  186.                 VOID getval(fp,prevsource,NCPPN,true);
  187.                 break;
  188.             case State:
  189.                 if (getval(fp,prevstate,IDLENGTH,true))
  190.                     if (!checkid(prevstate, '\0')) goto errexit;
  191.                 break;
  192.             default:
  193.                continue;
  194.             }
  195.             if (getc(fp)!=KDELIM)
  196.                 warn("Closing %c missing on keyword",KDELIM);
  197.             if (prevauthor[0]!='\0'&&prevrev[0]!='\0'&&prevstate[0]!='\0'&&
  198.                 prevdate[0]!='\0' &&
  199.          ((prevsource[0]!='\0')||(prevRCS[0]!='\0'))){
  200.                 /* done; prevlocker is irrelevant */
  201.                 break;
  202.            }
  203.         }
  204.     }
  205.     VOID fclose(fp);
  206.     return true;
  207.  
  208. errexit:
  209.     prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0';
  210.     VOID fclose(fp); return false;
  211. }
  212.  
  213.  
  214. static int getval(fp,target,maxchars,optional)
  215. register FILE *fp;
  216. char * target; int maxchars, optional;
  217. /* Function: Places a keyword value into target, but not more
  218.  * than maxchars characters. Prints an error if optional==false
  219.  * and there is no keyword. Returns true if one is found, false otherwise.
  220.  */
  221. {   register char * tp;
  222.     register int c;
  223.  
  224.     tp=target;
  225.     c=getc(fp);
  226.     if (c==KDELIM) {
  227.         if (!optional)
  228.             error("Missing keyword value");
  229.         VOID ungetc(c,fp);
  230.         return false;
  231.     } else {
  232.         while (!(c==' '||c=='\n'||c=='\t'||c==KDELIM||c==EOF)) {
  233.             if (tp-target>=maxchars-1) {
  234.                 error("keyword value too long");
  235.                 return false;
  236.             } else {
  237.                 *tp++ =c;
  238.                 c=getc(fp);
  239.             }
  240.         }
  241.         *tp= '\0';
  242. #       ifdef KEEPTEST
  243.         VOID printf("getval: %s\n",target);
  244. #       endif
  245.         while(c==' '||c=='\t') c=getc(fp); /* skip trailing blanks */
  246.     }
  247.     VOID ungetc(c,fp);
  248.     return true;
  249. }
  250.  
  251.  
  252. int getprevdate(fp,optional)
  253. FILE *fp;
  254. int optional;
  255. /* Function: reads a date prevdate; checks format
  256.  * If there is not date and optional==false, an error is printed.
  257.  * Returns false on error, true otherwise.
  258.  */
  259. {   char prevday[10];
  260.     char prevtime[10];
  261.  
  262.     prevday[0]=prevtime[0]='\0';
  263.     if (!getval(fp,prevday,9,optional)) return optional;
  264.     if (!getval(fp,prevtime,9,false)) return false;
  265.     /*process date */
  266.     prevday[2]=prevday[5]=prevday[8]=prevtime[2]=prevtime[5]='.';
  267.     prevday[9]='\0';
  268.     VOID strcpy(prevdate,prevday);
  269.     VOID strcat(prevdate,prevtime);
  270.     if (!checknum(prevdate,5)) {
  271.             error("Bad date: %s",prevdate);
  272.             prevdate[0]='\0';
  273.             return false;
  274.     }
  275.     return true;
  276. }
  277.  
  278. int checknum(sp,fields)
  279. register char * sp; int fields;
  280. {    register int dotcount;
  281.      if (sp==nil||*sp=='\0') return true;
  282.      dotcount=0;
  283.      while(*sp) {
  284.         if (*sp=='.') dotcount++;
  285.         elsif (ctab[*sp]!=DIGIT) return false;
  286.         sp++;
  287.      }
  288.      if (fields >= 0 && dotcount!=fields) return false;
  289.      return true;
  290. }
  291.  
  292.  
  293.  
  294. #ifdef KEEPTEST
  295. char * RCSfilename, * workfilename;
  296.  
  297. main(argc, argv)
  298. int  argc; char  *argv[];
  299. {
  300.     cmdid="keeptest";
  301.         while (*(++argv)) {
  302.                 if (getoldkeys(*argv))
  303.                 VOID printf("%s:  revision: %s, date: %s, author: %s, state: %s\n",
  304.                         *argv, prevrev, prevdate, prevauthor,prevstate);
  305.         VOID printf("Source: %s, RCSfile: %s\n",prevsource,prevRCS);
  306.     }
  307.     exit(0);
  308. }
  309. #endif
  310.