home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource5 / 344_01 / cb.c < prev    next >
C/C++ Source or Header  |  1990-12-12  |  14KB  |  537 lines

  1. /*
  2.         HEADER:         CUG236;
  3.         TITLE:          C Source Formatter;
  4.         DATE:           04/04/1987;
  5.         DESCRIPTION:    "Formats a C source program with proper indents for
  6.                         each statement.";
  7.         VERSION:        2.1;
  8.         KEYWORDS:       Pretty Printer;
  9.         FILENAME:       CB.C;
  10.         SEE-ALSO:       CB.DOC;
  11.         COMPILERS:      vanilla;
  12.         AUTHORS:        W. C. Colley III, J. W. Kindschi Jr.;
  13. */
  14.  
  15. /*
  16.         Modified for Turbo C and to clean up some problems
  17.         with "if", "else", "for" and comments.
  18.         by: Don Holland (5 Dec 1990)
  19.  
  20.         Modified for Portable C
  21.         by: William C. Colley, III (4 APR 1987)
  22.  
  23.         Modified for Lattice C Ver 1.01
  24.         by: John W. Kindschi Jr. (10-30-83)
  25.  
  26.         Swiped from CPIG'S UNIX system and modified to
  27.         run under BDS C by William C. Colley, III
  28.  
  29.  
  30. To use the program type the following command line:
  31.  
  32.         A>cb input.fil [output.fil]
  33.  
  34.         Where input.fil is the file to be pretty printed and [output.fil]
  35.         is the destination file. If no output file is specified, then
  36.         the output goes to standard output.
  37. */
  38.  
  39. #include <stdio.h>
  40. #include <ctype.h>
  41. #include <stddef.h>
  42.  
  43. /*
  44.  * Portability Note:  The AZTEC C compilers handle the binary/text file
  45.  * dichotomy differently from most other compilers.  Uncomment the following
  46.  * pair of #defines if you are running AZTEC C:
  47.  */
  48.  
  49. /*
  50. #define getc(f)         agetc(f)
  51. #define putc(c,f)       aputc(c,f)
  52. */
  53.  
  54. char cc, lchar, pchar, string[200];
  55. char *wif[] =   {   
  56.    "if",   NULL                };
  57. char *welse[] = {   
  58.    "else", NULL                };
  59. char *wfor[] =  {   
  60.    "for",  NULL                };
  61. char *wds[] =   {   
  62.    "case", "default",  NULL    };
  63.  
  64. int clevel, ct, iflev, ind[10], level, paren, sifflg[10], siflev[10];
  65. int sind[20][10], slevel[10], spflg[20][10], stabs[20][10];
  66. int aflg, bflg, eflg, ifflg = 0, pflg[10], qflg, sflg = 1;
  67. int c, j, lastchar, peek = -1, tabs, ifnlflg;       /* 12/5/90 */
  68. FILE *f1, *f2 = stdout;
  69.  
  70. void comment(), gotelse(), ptabs(), put_str();
  71.  
  72. /*************************************************************************/
  73.  
  74. int main(argc,argv)
  75.  
  76. int argc;
  77. char *argv[];
  78.  
  79. {
  80.  
  81.    int getchr(), get_nl(), get_str(), lookup();
  82.  
  83.    /* Initialize everything here */
  84.  
  85.    if (argc < 2 || argc > 3) {
  86.       fprintf(stderr,"Usage:  CB input.fil { output.fil }\n");  
  87.       return !0;
  88.    }
  89.    if (!(f1 = fopen(*++argv,"r"))) {
  90.       fprintf(stderr,"ERROR:  Cannot find file %s\n",*argv);  
  91.       return !0;
  92.    }
  93.    if (argc == 3 && !(f2 = fopen(*++argv,"w"))) {
  94.       fprintf(stderr,"ERROR:  Cannot create file %s\n",*argv);  
  95.       return !0;
  96.    }
  97.  
  98.    /* End of Initialization */
  99.  
  100.    while ((c = getchr()) != EOF) {
  101.       switch (c) {
  102.       default:
  103.          string[j++] = c;
  104.          if (c != ',')
  105.             lchar = c;
  106.          break;
  107.  
  108.       case ' ':
  109.       case '\t':  
  110.          string[j] = NULL;                 /* 12/5/90 */
  111.          if (!paren)                       /* 12/5/90 */
  112.             ifnlflg = 0;                   /* 12/5/90 */
  113.          if (lookup(welse)) {              /* 12/5/90 */
  114.             if (get_nl())                  /* 12/5/90 */
  115.                goto prelse;                /* 12/5/90 */
  116.             if (peek == '{') {             /* 12/5/90 */
  117.                string[j++] = ' ';          /* 12/5/90 */
  118.                c = '{';                    /* 12/5/90 */
  119.                peek = -1;                  /* 12/5/90 */
  120.                goto brelse;                /* 12/5/90 */
  121.             }                              /* 12/5/90 */
  122.             else                           /* 12/5/90 */
  123.                goto prelse;                /* 12/5/90 */
  124.          }                                 /* 12/5/90 */
  125.          if (sflg == 0 || j > 0)
  126.             string[j++] = c;
  127.          break;
  128.  
  129.       case '\n':  
  130.          string[j] = NULL;        /* 12/5/90 */
  131.          ifnlflg = 0;             /* 12/5/90 */
  132. prelse:                           /* 12/5/90 */
  133.          if (eflg = lookup(welse) == 1)
  134.             gotelse();
  135.          put_str();
  136.          fprintf(f2,"\n");
  137.          sflg = 1;
  138.          if (eflg == 1) {  
  139.             pflg[level]++;  
  140.             tabs++; 
  141.          }
  142.          else
  143.             if (pchar == lchar)
  144.                aflg = 1;
  145.          break;
  146.  
  147.       case '{':
  148.          ifnlflg = 0;               /* 12/5/90 */
  149. brelse:                             /* 12/5/90 */
  150.          if (lookup(welse)) {       /* 12/5/90 */
  151.             gotelse();
  152.             pflg[level]++;          /* 12/5/90 */
  153.             tabs++;                 /* 12/5/90 */
  154.          }                          /* 12/5/90 */
  155.          siflev[clevel] = iflev;  
  156.          sifflg[clevel] = ifflg;
  157.          iflev = ifflg = 0;  
  158.          clevel++;
  159.          if (sflg == 1 && pflg[level] != 0) {
  160.             pflg[level]--;  
  161.             tabs--;
  162.          }
  163.          string[j++] = c;  
  164.          put_str();  
  165.          get_nl();  
  166.          put_str();
  167.          fprintf(f2,"\n");  
  168.          tabs++;  
  169.          sflg = 1;
  170.          if (pflg[level] > 0) {
  171.             ind[level] = 1;  
  172.             level++;  
  173.             slevel[level] = clevel;
  174.          }
  175.          break;
  176.  
  177.       case '}':   
  178.          clevel--;
  179.          if ((iflev = siflev[clevel]-1) < 0)
  180.             iflev = 0;
  181.          ifflg = sifflg[clevel];  
  182.          put_str();  
  183.          tabs--;  
  184.          ptabs();
  185.          if ((peek = getchr()) == ';') {
  186.             fprintf(f2,"%c;",c);  
  187.             peek = -1;
  188.          }
  189.          else
  190.             fprintf(f2,"%c",c);
  191.          get_nl();  
  192.          put_str();  
  193.          fprintf(f2,"\n");  
  194.          sflg = 1;
  195.          if (clevel < slevel[level] && level > 0)
  196.             level--;
  197.          if (ind[level] != 0) {
  198.             tabs -= pflg[level];  
  199.             pflg[level] = ind[level] = 0;
  200.          }
  201.          break;
  202.  
  203.       case '"':
  204.       case '\'':  
  205.          string[j++] = c;
  206.          while ((cc = getchr()) != c) {
  207.             string[j++] = cc;
  208.             if (cc == '\\')
  209.                string[j++] = getchr();
  210.             if (cc == '\n') { 
  211.                put_str();  
  212.                sflg = 1; 
  213.             }
  214.          }
  215.          string[j++] = cc;
  216.          if (get_nl() == 1) { 
  217.             lchar = cc;  
  218.             peek = '\n'; 
  219.          }
  220.          break;
  221.  
  222.       case ';':   
  223.          string[j++] = c;  
  224.          put_str();
  225.          if (pflg[level] > 0 && ind[level] == 0) {
  226.             tabs -= pflg[level];  
  227.             pflg[level] = 0;
  228.          }
  229.          get_nl();  
  230.          put_str();  
  231.          fprintf(f2,"\n");  
  232.          sflg = 1;
  233.          if(iflev)                  /* 12/5/90 */
  234.             if (ifflg == 1)         /* 12/5/90 */
  235.                ifflg = iflev = 0;   /* 12/5/90 */
  236.             else {                  /* 12/5/90 */
  237.                ifflg--;             /* 12/5/90 */
  238.                iflev--;             /* 12/5/90 */
  239.             }                       /* 12/5/90 */
  240.          break;
  241.  
  242.       case '\\':  
  243.          string[j++] = c;  
  244.          string[j++] = getchr();  
  245.          break;
  246.  
  247.       case '?':   
  248.          qflg = 1;  
  249.          string[j++] = c;  
  250.          break;
  251.  
  252.       case ':':   
  253.          string[j++] = c;
  254.          if (qflg == 1) { 
  255.             qflg = 0;  
  256.             break; 
  257.          }
  258.          if (!lookup(wds)) { 
  259.             sflg = 0;  
  260.             put_str(); 
  261.          }
  262.          else { 
  263.             tabs--;  
  264.             put_str();  
  265.             tabs++; 
  266.          }
  267.          if ((peek = getchr()) == ';') {
  268.             fprintf(f2,";");  
  269.             peek = -1;
  270.          }
  271.          get_nl();  
  272.          put_str();  
  273.          fprintf(f2,"\n");  
  274.          sflg = 1;
  275.          break;
  276.  
  277.       case '/':   
  278.          string[j++] = c;
  279.          if ((peek = getchr()) != '*')
  280.             break;
  281.          string[j++] = peek;  
  282.          peek = -1;  
  283.          comment();  
  284.          get_nl();                      /* 12/5/90 */
  285.          if (peek != -1)