home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / comm / tcp / amitcp / src / devtools / rcsrev / rcsrev.c next >
Encoding:
C/C++ Source or Header  |  1994-03-07  |  9.2 KB  |  350 lines

  1. /****** utilities/rcsrev *****************************************************
  2.  
  3.     NAME  
  4.         RCSRev - Convert a RCS ID into #?_rev.? Files
  5.  
  6.     VERSION
  7.         $Id: rcsrev.c,v 2.3 1994/03/08 00:36:12 ppessi Exp $      
  8.  
  9.     TEMPLATE       
  10.         RCSREV NAME/A SOURCE/A POSTFIX ASM=ASMINCLUDE/S DATE/K
  11.  
  12.     FUNCTION
  13.         RCSRev is intended to generate a BumbRev-compatible revision
  14.         include files from RCS ID. 
  15.  
  16.         The arguments are used as follows:
  17.  
  18.         NAME/A       - name for program (generate file NAME_rev.h).
  19.         SOURCE/A     - source file name
  20.         PREFIX/K     - optional prefix to program name (eg. AmiTCP/IP_)
  21.         POSTFIX/K    - optional string postfixed to revision string
  22.         ASMINCLUDE/S - create also an assembler include file (generate file
  23.                        NAME_rev.i).
  24.  
  25.         DATE/K       - specify the date format used.  The date formats
  26.                        available are as follows:
  27.             CURRENT   - use current date (default) 
  28.             RCS       - use date from RCS ID
  29.             SASC      - use preprocessor macro __AMIGADATE__
  30.             DICE      - use preprocessor macro __COMMODORE_DATE__
  31.  
  32.     NOTES
  33.         The macro DATE is not defined in the revision file with SASC or
  34.         COMMODORE date formats.  The macro VSTRING is not defined in
  35.         revision file with the SASC format.  (See sources and macro
  36.         FIXED_AMIGADATE).
  37.  
  38.         The SASC or DICE formats can not be used with the ASMINCLUDE option.
  39.  
  40.     BUGS
  41.         RCSRev doesn't recognize other RCS ident string except Id.
  42.  
  43.         Maximum allowed line length is fixed.
  44.  
  45.     AUTHOR
  46.         ppessi <Pekka.Pessi@hut.fi>
  47.  
  48.     COPYRIGHT 
  49.         Copyright © 1993 AmiTCP/IP Group, <AmiTCP-group@hut.fi>, 
  50.         Helsinki University of Technology, Finland.
  51.  
  52. *****************************************************************************
  53. *
  54. */
  55.  
  56. #include <proto/dos.h>
  57.  
  58. #include <clib/exec_protos.h>
  59. extern struct ExecBase* SysBase;
  60. #include <pragmas/exec_sysbase_pragmas.h>
  61. #include <exec/memory.h>
  62.  
  63. #include <dos/dos.h>
  64.  
  65. #include <string.h>
  66. #include <stdlib.h>
  67.  
  68. #ifndef MAXLINELENGTH 
  69. #define MAXLINELENGTH 1024
  70. #endif
  71.  
  72. #ifndef MAXPATHLEN 
  73. #define MAXPATHLEN 1024
  74. #endif
  75.  
  76. #ifndef BOOTSTRAP
  77. #include "rcsrev_rev.h"
  78.  
  79. static const char version[] = VERSTAG;
  80. #endif
  81.  
  82. static const char copyright[] =
  83.   "Copyright © 1994 Pekka Pessi\n";
  84.  
  85. static char *strsep(register char **stringp, register const char *delim);
  86.  
  87. LONG rcsrev(void)
  88. {
  89.   LONG retval = 128;
  90.   struct ExecBase *SysBase = *(struct ExecBase**)4;
  91.   struct DosLibrary *DOSBase = (struct DosLibrary *)
  92.     OpenLibrary("dos.library", 37L);
  93.   STRPTR buffer = AllocVec(MAXLINELENGTH + 1, MEMF_PUBLIC);
  94.   STRPTR fnbuf = AllocVec(MAXPATHLEN + 1, MEMF_PUBLIC);
  95.   
  96.   if (DOSBase && buffer) {
  97.     const char *template = 
  98.       "Name/A,Source/A,Prefix/K,Postfix/K,ASM=ASMINCLUDE/S,DATE/K";
  99.     struct {
  100.       UBYTE *a_name;
  101.       UBYTE *a_file;
  102.       UBYTE *a_prefix;
  103.       UBYTE *a_postfix;
  104.       LONG   a_ifile;
  105.       UBYTE *a_date;
  106.     } args[1] = { 0 };
  107.     struct RDArgs *rdargs = NULL;
  108.     UBYTE date[LEN_DATSTRING];
  109.     struct DateTime dt[1];
  110.     UBYTE *year, *month, *day;
  111.  
  112.     retval = RETURN_ERROR;
  113.  
  114.     /* Get current date */
  115.     bzero(dt, sizeof(*dt));
  116.     dt->dat_Format = FORMAT_CDN;
  117.     dt->dat_StrDate = date;
  118.     (void)DateStamp(&dt->dat_Stamp);
  119.     (void)DateToStr(dt);
  120.  
  121.     day = date; month = date + 3; year = date + 6;
  122.     date[2] = '\0';
  123.     date[5] = '\0';
  124.  
  125.     if (rdargs = ReadArgs((UBYTE *)template, (LONG *)args, NULL)) {
  126.       enum { 
  127.     err_e = -1, current_e = 0, rcs_e, sasc_e, dice_e,
  128.       } datefmt = current_e;
  129.       BPTR infile; 
  130.       LONG line = 0;
  131.  
  132.       buffer[MAXLINELENGTH] = '\0';
  133.  
  134.       /* Get the date format to be used */
  135.       if (args->a_date) {
  136.     datefmt = FindArg("CURRENT,RCS,SASC,DICE", args->a_date);
  137.     if (args->a_ifile && (datefmt == sasc_e || datefmt == dice_e))
  138.       datefmt = err_e;
  139.       }
  140.  
  141.       if (datefmt != err_e && (infile = Open(args->a_file, MODE_OLDFILE))) { 
  142.     while (FGets(infile, buffer, MAXLINELENGTH)) {
  143.       UBYTE *s = buffer;
  144.       line++;
  145.  
  146.       while (s = strchr(s, '$')) {
  147.         /*
  148.          * RCS Id consists of
  149.          * "¤Id: file,v major.minor mm/dd/yy time author state [locker] ¤"
  150.          */
  151.         if (strncmp("$" "Id: ", s, 5) == 0) {
  152.           /*
  153.            * Probably parsing should be done with sscanf()
  154.            */
  155.           UBYTE *sp = s + 5;
  156.           UBYTE *path = strsep(&sp, " ");
  157.           UBYTE *ver = strsep(&sp, ".");
  158.           UBYTE *rev = strsep(&sp, " ");
  159.           UBYTE *rcs_year = strsep(&sp, "/");
  160.           UBYTE *rcs_month = strsep(&sp, "/");
  161.           UBYTE *rcs_day = strsep(&sp, " ");
  162.           UBYTE *rcs_time = strsep(&sp, " ");
  163.           UBYTE *datemacro =
  164.         datefmt == sasc_e ? (UBYTE *)"__AMIGADATE__" :
  165.           (datefmt == dice_e ? (UBYTE *)"__COMMODORE_DATE__" : 
  166.            (UBYTE *)NULL);
  167.           UBYTE *postfix = args->a_postfix ? args->a_postfix : (UBYTE *)"";
  168.  
  169.           if (path && ver && rev && 
  170.           rcs_year && rcs_month && rcs_day && rcs_time) {
  171.         BPTR hfile = 0;
  172.  
  173.         if (datefmt == rcs_e) {
  174.           year  = rcs_year;
  175.           month = rcs_month;
  176.           day   = rcs_day;
  177.         }
  178.  
  179.         if (strlen(year) == 4)
  180.           year += 2;
  181.         if (month[0] == '0')
  182.           month++;
  183.         if (day[0] == '0')
  184.           day++;
  185.  
  186.         strncpy(fnbuf, args->a_name, MAXPATHLEN);
  187.         strncat(fnbuf, "_rev.h", MAXPATHLEN);
  188.  
  189.         if (hfile = Open(fnbuf, MODE_NEWFILE)) {
  190.           FPrintf(hfile, "#define\tVERSION\t\t%s\n", ver);
  191.           FPrintf(hfile, "#define\tREVISION\t%s\n", rev);
  192.           if (!datemacro) {
  193.             FPrintf(hfile, "#define\tDATE\t\"%s.%s.%s\"\n", 
  194.                 day, month, year);
  195.           }
  196.           FPrintf(hfile, "#define\tVERS\t\"%s%s %s.%s\"\n", 
  197.               args->a_prefix ? args->a_prefix : "", 
  198.               args->a_name, ver, rev);
  199. #ifndef FIXED_AMIGADATE
  200.           if (datefmt != sasc_e)
  201. #endif
  202.             {
  203.               if (datemacro) 
  204.             FPrintf(hfile, "#define\tVSTRING\t\"%s%s %s.%s \""
  205.                 " %s \"\\n\\r\"\n", 
  206.                 args->a_prefix ? args->a_prefix : "", 
  207.                 args->a_name, ver, rev, datemacro);
  208.               else
  209.             FPrintf(hfile, "#define\tVSTRING\t\"%s%s %s.%s "
  210.                 "(%s.%s.%s)\\n\\r\"\n", 
  211.                 args->a_prefix ? args->a_prefix : "", 
  212.                 args->a_name, ver, rev, day, month, year);
  213.             }
  214.           if (datemacro) 
  215.             FPrintf(hfile, "#define\tVERSTAG\t"
  216.                 "\"\\0$VER: %s%s %s.%s%s \""
  217.                 " %s\n", 
  218.                 args->a_prefix ? args->a_prefix : "", 
  219.                 args->a_name, ver, rev, postfix, datemacro);
  220.           else
  221.             FPrintf(hfile, "#define\tVERSTAG\t"
  222.                 "\"\\0$VER: %s%s %s.%s%s "
  223.                 "(%s.%s.%s)\"\n", 
  224.                 args->a_prefix ? args->a_prefix : "", 
  225.                 args->a_name, ver, rev, postfix, day, month, year);
  226.           Close(hfile);
  227.         } else {
  228.           PrintFault(IoErr(), fnbuf);
  229.           goto found;
  230.         }
  231.  
  232.         if (args->a_ifile) {
  233.           strncpy(fnbuf, args->a_name, MAXPATHLEN);
  234.           strncat(fnbuf, "_rev.i", MAXPATHLEN);
  235.  
  236.           if (hfile = Open(fnbuf, MODE_NEWFILE)) {
  237.             FPrintf(hfile, "VERSION \tEQU\t%s\n", ver);
  238.             FPrintf(hfile, "REVISION\tEQU\t%s\n", rev);
  239.             FPrintf(hfile, 
  240.                 "DATE\tMACRO\n"
  241.                 "\t\tdc.b\t'%s.%s.%s'\n"
  242.                 "\tENDM\n", 
  243.                 day, month, year);
  244.             FPrintf(hfile, 
  245.                 "VERS\tMACRO\n"
  246.                 "\t\tdc.b\t'%s%s %s.%s'\n"
  247.                 "\tENDM\n",
  248.                 args->a_prefix ? args->a_prefix : "", 
  249.                 args->a_name, ver, rev);
  250.             FPrintf(hfile,
  251.                 "VSTRING\tMACRO\n"
  252.                 "\t\tdc.b\t'%s%s %s.%s (%s.%s.%s)',13,10,0\n"
  253.                 "\tENDM\n", 
  254.                 args->a_prefix ? args->a_prefix : "", 
  255.                 args->a_name, ver, rev, day, month, year);
  256.             FPrintf(hfile, 
  257.                 "VERSTAG\tMACRO\n"
  258.                 "\t\tdc.b\t0,'$VER: %s%s %s.%s%s (%s.%s.%s)',0\n"
  259.                 "\tENDM\n", 
  260.                 args->a_prefix ? args->a_prefix : "", 
  261.                 args->a_name, ver, rev, postfix, day, month, year);
  262.             
  263.             Close(hfile);
  264.             retval = RETURN_OK;
  265.           } else {
  266.             PrintFault(IoErr(), fnbuf);
  267.           }
  268.         } else {
  269.           retval = RETURN_OK;
  270.         }
  271.           } else {
  272.         Printf("%s:%ld: parse error with RCS $" "Id" "$\n",
  273.                args->a_file, line);
  274.           }
  275.  
  276.           goto found;
  277.         } else {
  278.           s = s + 1;
  279.         }
  280.       }
  281.     }
  282.     Printf("%s: can not found RCS \"$" "Id" "$\"\n", args->a_file);
  283.  
  284.       found:
  285.     Close(infile);
  286.       } else {
  287.     if (datefmt == err_e) {
  288.       PrintFault(ERROR_OBJECT_WRONG_TYPE, "RCSRev DATE");
  289.     } else {
  290.       PrintFault(IoErr(), args->a_file);
  291.     }
  292.       }
  293.     } else {
  294.       PrintFault(IoErr(), "rcsrev");
  295.       retval = RETURN_ERROR;
  296.     } 
  297.   }
  298.  
  299.   if (buffer) {
  300.     FreeVec(buffer);
  301.   } 
  302.   if (fnbuf) {
  303.     FreeVec(fnbuf);
  304.   }
  305.   if (!buffer || !fnbuf) {
  306.     PrintFault(ERROR_NO_FREE_STORE, "rcsrev");
  307.   }
  308.  
  309.   if (DOSBase)
  310.     CloseLibrary((struct Library *)DOSBase);
  311.  
  312.   return retval;
  313. }
  314.  
  315. /*
  316.  * Get next token from string *stringp, where tokens are nonempty
  317.  * strings separated by characters from delim.  
  318.  *
  319.  * Writes NULs into the string at *stringp to end tokens.
  320.  * delim need not remain constant from call to call.
  321.  * On return, *stringp points past the last NUL written (if there might
  322.  * be further tokens), or is NULL (if there are definitely no more tokens).
  323.  *
  324.  * If *stringp is NULL, strtoken returns NULL.
  325.  */
  326. static char *strsep(register char **stringp, register const char *delim)
  327. {
  328.   register char *s;
  329.   register const char *spanp;
  330.   register int c, sc;
  331.   char *tok;
  332.  
  333.   if ((s = *stringp) == NULL)
  334.     return (NULL);
  335.   for (tok = s;;) {
  336.     c = *s++;
  337.     spanp = delim;
  338.     do {
  339.       if ((sc = *spanp++) == c) {
  340.     if (c == 0)
  341.       s = NULL;
  342.     else
  343.       s[-1] = 0;
  344.     *stringp = s;
  345.     return (tok);
  346.       }
  347.     } while (sc != 0);
  348.   }
  349. }
  350.