home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / rcsit2 / rcsit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  13.5 KB  |  672 lines

  1. #ifndef lint
  2. static char *RCSid = "$Header: rcsit.c,v 1.26 86/03/27 14:16:01 mcooper Exp $";
  3. #endif
  4.  
  5. /*
  6.  *---------------------------------------------------------
  7.  * $Source: /w/mcooper/src/rcsit/RCS/rcsit.c,v $
  8.  * $Revision: 1.26 $
  9.  * $Date: 86/03/27 14:16:01 $
  10.  * $State: Exp $
  11.  * $Author: mcooper $
  12.  * $Locker: mcooper $
  13.  *---------------------------------------------------------
  14.  * Michael Cooper (mcooper@usc-oberon.arpa)
  15.  * University Computing Services,
  16.  * University of Southern California,
  17.  * Los Angeles, California,   90089-0251
  18.  * (213) 743-3462
  19.  *---------------------------------------------------------
  20.  *
  21.  * $Log:    rcsit.c,v $
  22.  * Revision 1.26  86/03/27  14:16:01  mcooper
  23.  * Added usage() message.
  24.  * Moved $Header$ into object for ident.
  25.  * 
  26.  * Revision 1.25  86/02/26  15:03:45  mcooper
  27.  * Added -Fheader_file option.
  28.  * 
  29.  * Revision 1.24  86/02/06  10:58:59  mcooper
  30.  * Fixed default error message.
  31.  * 
  32.  * Revision 1.23  86/02/03  14:17:07  mcooper
  33.  * Added the type ``Pascal''.
  34.  * Also deleted log messages up until 1.17
  35.  * (first mod.sources release).
  36.  * 
  37.  * Revision 1.22  85/12/19  14:24:35  mcooper
  38.  * Added more patches from Joe Chapman (joe@cca-unix.ARPA)
  39.  * for TeX support.  Also used his suggestion for
  40.  * checking to see if only one of the file spec. flags
  41.  * is set.
  42.  * 
  43.  * Revision 1.21  85/12/18  11:05:50  mcooper
  44.  * Added "#ifndef lint" to the default header for .c 
  45.  * files.  This keeps lint quite about the:
  46.  * 
  47.  *     static char RCSid
  48.  * 
  49.  * Revision 1.20  85/12/18  10:21:24  mcooper
  50.  * Added patches from Joe Chapman (joe@cca-unix.ARPA)
  51.  * to keep from dereferencing NULL on the 68K.
  52.  * 
  53.  * Revision 1.19  85/12/16  17:34:11  mcooper
  54.  * Changed .header.* --> .header.*
  55.  * More appropriate name.
  56.  * 
  57.  * Revision 1.18  85/11/26  17:03:32  mcooper
  58.  * Change message telling of what header was added.
  59.  * 
  60.  */
  61.  
  62. /*
  63.  * rcsit --     Prepare files for RCS.  rcsit puts the correct headings
  64.  *        at the top of files to prepare them for RCS headings
  65.  *        and log tracking.
  66.  *
  67.  * Michael Cooper    (mcooper@usc-oberon.arpa)
  68.  * University Computing Services, USC
  69.  *
  70.  * 9-16-85
  71.  */
  72.  
  73. #include <stdio.h>
  74. #include <ctype.h>
  75. #include <sys/file.h>
  76.  
  77. #ifdef NULL
  78. #undef NULL
  79. #endif
  80. #define NULL        '\0'
  81. #define LENGTH        132        /* length of line */
  82. #define TRUE        1
  83. #define FALSE        0
  84. #define USAGE "[ -chfsmMxp ] [ -qad ] [ -I{flags} ] [ -R{flags} ] \
  85. \n\t\t[ -H{directory} ] [ -F header_file ] file [ file1 file2 ... ]\n"
  86.  
  87. #ifdef DEBUG
  88.  int debugon = TRUE;
  89. #else
  90.  int debugon = FALSE;
  91. #endif
  92.  
  93. static char     *progname;        /* program name */
  94. static char     *rcsdir;
  95.  
  96. /*
  97.  * Messages to be printed for the user.
  98.  */
  99. static char    *msg_name;        
  100. static char     *m_stdc = "Standard C",
  101.         *m_include = "C Include",
  102.         *m_fortran = "Fortran",
  103.         *m_pascal = "Pascal",
  104.         *m_make    = "Makefile",
  105.         *m_shell = "Shell Script",
  106.         *m_manual = "Manual",
  107.         *m_tex = "TeX";
  108.  
  109. /*
  110.  * The default headers to put at the beginning of the file(s).
  111.  * Notice that the words Header and Log do not appear here
  112.  * because RCS will put in the keyword substitutions when rcsit.c
  113.  * is co'ed.
  114.  */
  115. static char    *header;
  116. static char    *h_stdc = 
  117. "#ifndef lint\nstatic char *RCSid = \"$%s$\";\n#endif\n\n/*\n * $%s$\n */\n\n";
  118. static char    *h_include = 
  119.     "/*\n * $%s$\n *\n * $%s$\n */\n\n";
  120. static char    *h_make =
  121.     "#\n# $%s$\n#\n# $%s$\n#\n";
  122. static char     *h_manual =
  123.     "...\n... $%s$\n... \n... $%s$\n...\n";
  124. static char     *h_fortran =
  125.     "c\nc $%s$\nc\nc $%s$\nc\n";
  126. static char    *h_tex =
  127.     "%% $%s$\n%%\n%% $%s$\n%%\n";
  128. static char    *h_pascal = 
  129.     "(*\n * $%s$\n *\n * $%s$\n *)\n\n";
  130.  
  131. /*
  132.  * Header file names
  133.  */
  134. static char    *header_c     = ".header.c";        /* .c header */
  135. static char     *header_h     = ".header.h";        /* .h header */
  136. static char     *header_f     = ".header.f";        /* .f header */
  137. static char     *header_p     = ".header.p";        /* .p header */
  138. static char     *header_man     = ".header.man";    /* man header */
  139. static char    *header_make    = ".header.make";    /* make header */
  140. static char    *header_sh    = ".header.sh";        /* sh script header */
  141. static char    *header_tex    = ".header.tex";    /* TeX header */
  142. static char    *tpath;                    /* path to header */
  143. static char    tfile[BUFSIZ];                /* header file */
  144. static char    tbuf[BUFSIZ];                /* current tfile */
  145.  
  146. /*
  147.  * Command line flags
  148.  */
  149. int    Iflag    = FALSE;            /* run ci(1) */
  150. int    rcsflag = FALSE;            /* run rcs(1) */
  151. int    aflag    = TRUE;                /* do auto guess */
  152. int    dflag    = TRUE;                /* creat RCS dir. */
  153. int    qflag    = FALSE;            /* be quiet! */
  154. int     cflag    = FALSE;            /* std c file */
  155. int    fflag    = FALSE;            /* fortran file */
  156. int    pflag    = FALSE;            /* pascal file */
  157. int    hflag    = FALSE;            /* include file */
  158. int    sflag    = FALSE;            /* shell script */
  159. int     mflag    = FALSE;            /* Makefile */
  160. int    Mflag    = FALSE;            /* manual */
  161. int    Hflag    = FALSE;            /* header flag */
  162. int    Fflag    = FALSE;            /* header file flag */
  163. int    xflag    = FALSE;            /* TeX flag */
  164.  
  165. main(argc, argv)
  166. int    argc;
  167. char     *argv[];
  168. {
  169.     int x;
  170.     char    tmp[LENGTH];
  171.     char    *file;
  172.     char    *flags;
  173.     char     *tmpfile = "/tmp/rcsitXXXXXX";
  174.     char     *mktemp();
  175.     char    *gettmp();
  176.     char    *getenv();
  177.     FILE     *fd, 
  178.         *fdtmp,
  179.         *fopen();
  180.  
  181.     progname = *argv;
  182.     for (x = 1; x < argc; x++) {
  183.         if (argv[x][0] != '-')
  184.             break;
  185.         switch (argv[x][1]) {
  186.             case 'a':
  187.                 aflag = FALSE;
  188.                 break;
  189.             case 'q':
  190.                 qflag = TRUE;
  191.                 break;
  192.             case 'd':
  193.                 dflag = FALSE;
  194.                 break;
  195.             case 'f':
  196.                 fflag = TRUE;
  197.                 break;
  198.             case 'h':
  199.                 hflag = TRUE;
  200.                 break;
  201.             case 's':
  202.                 sflag = TRUE;    
  203.                 break;
  204.             case 'm':
  205.                 mflag = TRUE;
  206.                 break;
  207.             case 'M':
  208.                 Mflag = TRUE;
  209.                 break;
  210.             case 'i':
  211.             case 'I':
  212.                 Iflag = TRUE;
  213.                 flags = &argv[x][2];
  214.                 break;
  215.             case 'r':
  216.             case 'R':
  217.                 rcsflag = TRUE;
  218.                 flags = &argv[x][2];
  219.                 break;
  220.             case 'F':
  221.                 Fflag = TRUE;
  222.                 strcpy(tfile, &argv[x][2]);
  223.                 msg_name = &argv[x][2];
  224.                 break;
  225.             case 'H':
  226.                 Hflag = TRUE;
  227.                 tpath = &argv[x][2];
  228.                 break;
  229.             case 'c':
  230.                 cflag = TRUE;
  231.                 break;
  232.             case 'x':
  233.                 xflag = TRUE;
  234.                 break;
  235.             case 'p':
  236.                 pflag = TRUE;
  237.                 break;
  238.             default:
  239.                 usage();
  240.         }
  241.     }
  242.     argc -= (x - 1);
  243.     argv += (x - 1);
  244.  
  245.     if(hflag + mflag + Mflag + cflag + sflag + fflag + xflag + pflag > 1)
  246.         fatal("Only ONE of -c,-f,-m,-M,-h,-s,-p,-x may be specified.");
  247.     if(Iflag && rcsflag) 
  248.         fatal("Only ONE of ``-i'' and ``-r'' may be specified.");
  249.  
  250.     if(cflag || hflag || mflag || Mflag || fflag || sflag || xflag || pflag)
  251.         aflag = FALSE;
  252.  
  253.     if((rcsdir = getenv("RCSDIR")) == NULL)
  254.         rcsdir = "RCS";
  255.     if(Iflag && dflag)
  256.         checkdir();    /* Make RCS directory for ci */
  257.  
  258.     if((tpath == NULL || *tpath == NULL) && 
  259.         ((tpath = getenv("TEMPLATE")) == NULL))
  260.         if((tpath = getenv("HOME")) == NULL)
  261.             fatal(
  262.               "Cannot find environment variable HOME or TEMPLATE");
  263.  
  264.     /*
  265.      * make tmp file once.
  266.      */
  267.     mktemp(tmpfile);
  268.  
  269.     while (--argc) {    /* Main loop */
  270.         file = *++argv;
  271.         debug(sprintf(tmp, "...file (*++argv) = %s...", file));
  272.  
  273.         if(access(file, 4) != 0)
  274.             fatal(
  275.         "Cannot access %s.  No read permission OR file does not exist.",
  276.                 file);
  277.         if((fdtmp = fopen(tmpfile, "w")) == NULL) {
  278.             fatal("Cannot open tmpfile (%s).", tmpfile);
  279.         }
  280.  
  281.         if(!Fflag)
  282.             if(aflag)
  283.                 auto_guess(file); /* try and guess file type */
  284.             else
  285.                 set_flags();      /* check and set flags */
  286.  
  287.         if(Hflag && !Fflag) {
  288.             /*
  289.              * first get names of headers, then create
  290.              * path name to it.
  291.              */
  292.             get_temp();
  293.             sprintf(tfile, "%s/%s", tpath, tbuf);
  294.         }
  295.         if(access(tfile, 0) == 0 && (Hflag || Fflag)) {
  296.             if(!qflag || debugon)
  297.                 printf("Adding %s header file to %s...",
  298.                     msg_name, file);
  299.             copy(tfile, tmpfile, "w");
  300.             copy(file, tmpfile, "a");
  301.         } else {
  302.             if(!qflag || debugon)
  303.                 printf(
  304.                 "Adding default header (%s format) to %s...",
  305.                     msg_name, file);
  306.             /*
  307.              * put the Keywords into header string
  308.              */
  309.             sprintf(tmp, header, "Header", "Log");
  310.             fputs(tmp, fdtmp);
  311.             /*
  312.              * fclose'em, just in case.
  313.              */
  314.             fclose(fdtmp);
  315.             copy(file, tmpfile, "a");
  316.         }
  317.         unlink(file);
  318.         copy(tmpfile, file, "w");
  319.         unlink(tmpfile);
  320.  
  321.         if(!qflag || debugon)
  322.             printf("done.\n");
  323.  
  324.         if(Iflag){
  325.             rcs("ci", file, flags);
  326.             if(Mflag){    /* kludge to tell rcs about manuals */
  327.                 rcs("rcs", file, "c'... '");
  328.                 /*
  329.                  * kludge part 2 - if the user tried a ci
  330.                  * with a -l option, then the header is
  331.                  * messed up in the currently checked out
  332.                  * man file.  So we have to co the file to 
  333.                  * clean up the header.  Plus we use the
  334.                  * -l option of co to insure file locking.
  335.                  */
  336.                 if(checkfor("l", flags)){
  337.                     unlink(file);
  338.                     rcs("co", file, "l");
  339.                 }
  340.             }
  341.         }
  342.         if(rcsflag)
  343.             rcs("rcs", file, flags);
  344.     }
  345. }
  346.  
  347. /*
  348.  * debug - print (useless) debugging info.
  349.  */
  350.  
  351. debug(msg)
  352. char *msg;
  353. {
  354. #ifdef DEBUG
  355.     fprintf(stderr, msg);
  356.     putchar ('\n');
  357. #endif
  358. }
  359.  
  360. /*
  361.  * auto_guess - try and be intelligent and guess type of file
  362.  *        by looking at the suffix or the whole name
  363.  *        in the case of a makefile.
  364.  */
  365.  
  366. auto_guess(file)
  367. char    *file;
  368. {
  369.     char *suffix;
  370.     char *rindex();
  371.  
  372.     suffix = rindex(file, '.')+1;
  373.     if((strcmp(file, "makefile") == 0) || (strcmp(file, "Makefile") == 0) ||
  374.         (strcmp(suffix, "mk") == 0)) {    /* sys V std suffix */
  375.         mflag = TRUE;
  376.         sflag = FALSE;
  377.         cflag = FALSE;
  378.         hflag = FALSE;
  379.         Mflag = FALSE;
  380.         fflag = FALSE;
  381.         xflag = FALSE;
  382.         pflag = FALSE;
  383.     }
  384.     if((strcmp(suffix, "sh") == 0) || (strcmp(suffix, "csh") == 0)) {
  385.         sflag = TRUE;
  386.         cflag = FALSE;
  387.         hflag = FALSE;
  388.         mflag = FALSE;
  389.         Mflag = FALSE;
  390.         fflag = FALSE;
  391.         xflag = FALSE;
  392.         pflag = FALSE;
  393.     }
  394.     if(strcmp(suffix, "tex") == 0) {
  395.         xflag = TRUE;
  396.         sflag = FALSE;
  397.         cflag = FALSE;
  398.         hflag = FALSE;
  399.         mflag = FALSE;
  400.         Mflag = FALSE;
  401.         fflag = FALSE;
  402.         pflag = FALSE;
  403.     }
  404.     if(strcmp(suffix, "c") == 0){
  405.         cflag = TRUE;
  406.         hflag = FALSE;
  407.         mflag = FALSE;
  408.         Mflag = FALSE;
  409.         sflag = FALSE;
  410.         fflag = FALSE;
  411.         xflag = FALSE;
  412.         pflag = FALSE;
  413.     }
  414.     if(strcmp(suffix, "h") == 0){
  415.         hflag = TRUE;
  416.         cflag = FALSE;
  417.         mflag = FALSE;
  418.         Mflag = FALSE;
  419.         sflag = FALSE;
  420.         fflag = FALSE;
  421.         xflag = FALSE;
  422.         pflag = FALSE;
  423.     }
  424.     if(strcmp(suffix, "f") == 0){
  425.         fflag = TRUE;
  426.         hflag = FALSE;
  427.         cflag = FALSE;
  428.         mflag = FALSE;
  429.         Mflag = FALSE;
  430.         sflag = FALSE;
  431.         xflag = FALSE;
  432.         pflag = FALSE;
  433.     }
  434.     if(strcmp(suffix, "p") == 0){
  435.         pflag = TRUE;
  436.         hflag = FALSE;
  437.         cflag = FALSE;
  438.         mflag = FALSE;
  439.         Mflag = FALSE;
  440.         sflag = FALSE;
  441.         xflag = FALSE;
  442.         fflag = FALSE;
  443.     }
  444.     if(isdigit(*suffix) != 0) {
  445.         Mflag = TRUE;
  446.         hflag = FALSE;
  447.         cflag = FALSE;
  448.         mflag = FALSE;
  449.         sflag = FALSE;
  450.         fflag = FALSE;
  451.         xflag = FALSE;
  452.         pflag = FALSE;
  453.     }
  454.     set_flags();
  455.     if(!qflag || debugon)
  456.         printf("Hmm.  This file looks like a %s file.\n", msg_name);
  457. }
  458.  
  459. /*
  460.  * set_flags - set & check flags
  461.  */
  462.  
  463. set_flags()
  464. {
  465.     if(cflag || hflag || mflag || Mflag || sflag || fflag || xflag) {
  466.         if(cflag) {
  467.             msg_name = m_stdc;
  468.             header = h_stdc;
  469.         }
  470.         if(hflag) {
  471.             msg_name = m_include;
  472.             header = h_include;
  473.         }
  474.         if(mflag) {
  475.             msg_name = m_make;
  476.             header = h_make;
  477.         }
  478.         if(Mflag) {
  479.             msg_name = m_manual;
  480.             header = h_manual;
  481.         }
  482.         if(sflag) {
  483.             msg_name = m_shell;
  484.             header = h_make;
  485.         }
  486.         if(fflag) {
  487.             msg_name = m_fortran;
  488.             header = h_fortran;
  489.         }
  490.         if(xflag) {
  491.             msg_name = m_tex;
  492.             header = h_tex;
  493.         }
  494.         if(pflag) {
  495.             msg_name = m_pascal;
  496.             header = h_pascal;
  497.         }
  498.     } else {
  499.         cflag = TRUE;
  500.         set_flags();
  501.     }
  502. }
  503.  
  504. /*
  505.  * copy from -> to
  506.  */
  507.  
  508. copy(from, to, mode)
  509. char *from;
  510. char *to;
  511. char *mode;
  512. {
  513.     FILE *fdfrom, *fdto, *fopen();
  514.     char tmp[LENGTH];
  515.     char s[LENGTH];
  516.  
  517.     if((fdfrom = fopen(from, "r")) == NULL) {
  518.         fatal("Cannot open %s for reading.",from);
  519.     }
  520.     if((fdto = fopen(to, mode)) == NULL) {
  521.         fatal("Cannot open %s for \"%s\".",to,mode);
  522.     }
  523.     while(fgets(s, sizeof(s), fdfrom) != NULL)
  524.         fputs(s, fdto);
  525.     fclose(fdfrom);
  526.     fclose(fdto);
  527. }
  528.  
  529. /*
  530.  * Run RCS's rcsprog on file with flags.
  531.  */
  532.  
  533. rcs(rcsprog, file, flags)
  534. char *rcsprog;
  535. char *file;
  536. char *flags;
  537. {
  538.     char buf[LENGTH];
  539.     char tmp[LENGTH];
  540.  
  541.     if(!checkfor("q", flags) && qflag)
  542.         flags = "q";
  543.     if(!flags || !*flags)
  544.         sprintf(buf, "%s %s", rcsprog, file);
  545.     else
  546.         sprintf(buf, "%s -%s %s", rcsprog, flags, file);
  547.     debug(sprintf(tmp,"Running ``%s''...\n", buf));
  548.     if(!qflag)
  549.         lineprint(sprintf(tmp, "Start of ``%s''", buf));
  550.     system(buf);
  551.     if(!qflag)
  552.         lineprint(sprintf(tmp, "End of ``%s''", buf));
  553. }
  554.  
  555. /*
  556.  * checkdir - make RCS directory if not present.
  557.  */
  558.  
  559. checkdir()
  560. {
  561.     if(access("RCS", 0) != 0){
  562.         if(!qflag || debugon)
  563.             printf("Cannot find \"RCS\" directory.  Creating...\n");
  564.         if(strcmp(rcsdir, "RCS") != 0) { 
  565.             if(symlink(rcsdir, "RCS") != 0)
  566.                 fatal("Symbolic link of %s to RCS failed.", 
  567.                     rcsdir);
  568.         } else {
  569.             if(mkdir(rcsdir, 0755) != 0)
  570.                 fatal("Cannot create \"%s\" directory.", 
  571.                     rcsdir);
  572.         }
  573.     }
  574. }
  575.  
  576. /*
  577.  * checkfor(x, str) -- check for x in str.  Return 1 (TRUE) if exists.
  578.  *            Otherwise 0 (FALSE).
  579.  */
  580.  
  581. checkfor(x, str)
  582. char     *x;
  583. char     *str;
  584. {
  585.     if (!str)
  586.         return(FALSE);
  587.     while(*str) {
  588.         if(strcmp(str, x) == 0)
  589.             return(TRUE);
  590.         *str++;
  591.     }
  592.     return(FALSE);
  593. }
  594.  
  595. /*
  596.  * lineprint - print msg in a nice line
  597.  */
  598.  
  599. lineprint(msg)
  600. char *msg;
  601. {
  602.     int len, left, right, x;
  603.  
  604.     len = strlen(msg);
  605.     right = (75-len)/2;
  606.     left = right;
  607.     for(x = 0; x < right; ++x)
  608.         putchar('-');
  609.     printf("[ %s ]", msg);
  610.     for(x = 0; x < left; ++x)
  611.         putchar('-');
  612.     putchar('\n');
  613. }
  614.  
  615. /*
  616.  * fatal - print error and then exit(1).
  617.  */
  618. fatal(format, str)
  619. char *format;
  620. {
  621.     static char namefmt[100];
  622.  
  623.     sprintf(namefmt, "%s: %s\n", progname, format);
  624.     _doprnt(namefmt, &str, stderr);
  625.     exit(1);
  626. }
  627.  
  628. /*
  629.  * zap str with NULL's
  630.  */
  631.  
  632. zap(str)
  633. char str[];
  634. {
  635.     int i, x;
  636.  
  637.     i = strlen(str);
  638.     for(x = 0; x <= i; )
  639.         str[x++] = NULL;
  640. }
  641.  
  642. /*
  643.  * get header names
  644.  */
  645.  
  646. get_temp()
  647. {
  648.     zap(tbuf);
  649.     if(mflag)
  650.         strcpy(tbuf, header_make);
  651.     if(Mflag)
  652.         strcpy(tbuf, header_man);
  653.     if(hflag)
  654.         strcpy(tbuf, header_h);
  655.     if(cflag)
  656.         strcpy(tbuf, header_c);
  657.     if(sflag)
  658.         strcpy(tbuf, header_sh);
  659.     if(fflag)
  660.         strcpy(tbuf, header_f);
  661.     if(xflag)
  662.         strcpy(tbuf, header_tex);
  663.     if(pflag)
  664.         strcpy(tbuf, header_p);
  665. }
  666.  
  667. usage()
  668. {
  669.     fprintf(stderr, "usage: %s ", progname);
  670.     fprintf(stderr, USAGE);
  671. }
  672.