home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / TOOLS2.ZIP / CB.C next >
C/C++ Source or Header  |  1988-03-17  |  8KB  |  431 lines

  1. /*
  2.     HEADER:        CUG000.00;
  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 Portable C
  17.     by: William C. Colley, III (4 APR 1987)
  18.  
  19.     Modified for Lattice C Ver 1.01
  20.     by: John W. Kindschi Jr. (10-30-83)
  21.  
  22.     Swiped from CPIG'S UNIX system and modified to
  23.     run under BDS C by William C. Colley, III
  24.  
  25.  
  26. To use the program type the following command line:
  27.  
  28.     A>cb input.fil [output.fil]
  29.  
  30.     Where input.fil is the file to be pretty printed and [output.fil]
  31.     is the destination file. If no output file is specified, then
  32.     the output goes to standard output.
  33. */
  34.  
  35. #include <stdio.h>
  36.  
  37. /*
  38.  * Portability Note:  The AZTEC C compilers handle the binary/text file
  39.  * dichotomy differently from most other compilers.  Uncomment the following
  40.  * pair of #defines if you are running AZTEC C:
  41.  */
  42.  
  43. /*
  44. #define getc(f)        agetc(f)
  45. #define putc(c,f)    aputc(c,f)
  46. */
  47.  
  48. char cc, lchar, pchar, string[200];
  49. char *wif[] =    {   
  50.     "if",   NULL        };
  51. char *welse[] = {   
  52.     "else", NULL        };
  53. char *wfor[] =    {   
  54.     "for",  NULL        };
  55. char *wds[] =    {   
  56.     "case", "default",    NULL    };
  57.  
  58. int clevel, ct, iflev, ind[10], level, paren, sifflg[10], siflev[10];
  59. int sind[20][10], slevel[10], spflg[20][10], stabs[20][10];
  60. int aflg, bflg, eflg, ifflg = -1, pflg[10], qflg, sflg = 1;
  61. int c, j, lastchar, peek = -1, tabs;
  62. FILE *f1 = stdin, *f2 = stdout;
  63.  
  64. void comment(), gotelse(), ptabs(), put_str();
  65.  
  66. int main(argc,argv)
  67. int argc;
  68. char *argv[];
  69. {
  70.     int getchr(), get_nl(), get_str(), lookup();
  71.  
  72.     /* Initialize everything here */
  73.  
  74.     if ( argc > 3) 
  75.     {
  76.         fprintf(stderr,"Usage:  CB input.fil { output.fil }\n");  
  77.         return !0;
  78.     }
  79.     if (argc >= 2 && !(f1 = fopen(*++argv,"r"))) {
  80.         fprintf(stderr,"ERROR:  Cannot find file %s\n",*argv);  
  81.         return !0;
  82.     }
  83.     if (argc == 3 && !(f2 = fopen(*++argv,"w"))) {
  84.         fprintf(stderr,"ERROR:  Cannot create file %s\n",*argv);  
  85.         return !0;
  86.     }
  87.  
  88.     /* End of Initialization */
  89.  
  90.     while ((c = getchr()) != EOF) {
  91.         switch (c) {
  92.         default:    
  93.             string[j++] = c;
  94.             if (c != ',') lchar = c;
  95.             break;
  96.  
  97.         case ' ':
  98.         case '\t':    
  99.             if (lookup(welse) == 1) {
  100.                 gotelse();
  101.                 if (sflg == 0 || j > 0) string[j++] = c;
  102.                 put_str();    
  103.                 sflg = 0;  
  104.                 break;
  105.             }
  106.             if (sflg == 0 || j > 0) string[j++] = c;
  107.             break;
  108.  
  109.         case '\n':    
  110.             if (eflg = lookup(welse) == 1) gotelse();
  111.             put_str();  
  112.             fprintf(f2,"\n");  
  113.             sflg = 1;
  114.             if (eflg == 1) {  
  115.                 pflg[level]++;  
  116.                 tabs++; 
  117.             }
  118.             else if(pchar == lchar) aflg = 1;
  119.             break;
  120.  
  121.         case '{':    
  122.             if (lookup(welse) == 1) gotelse();
  123.             siflev[clevel] = iflev;     
  124.             sifflg[clevel] = ifflg;
  125.             iflev = ifflg = 0;  
  126.             clevel++;
  127.             if (sflg == 1 && pflg[level] != 0) {
  128.                 pflg[level]--;  
  129.                 tabs--;
  130.             }
  131.             string[j++] = c;  
  132.             put_str();  
  133.             get_nl();     
  134.             put_str();
  135.             fprintf(f2,"\n");  
  136.             tabs++;  
  137.             sflg = 1;
  138.             if (pflg[level] > 0) {
  139.                 ind[level] = 1;  
  140.                 level++;  
  141.                 slevel[level] = clevel;
  142.             }
  143.             break;
  144.  
  145.         case '}':    
  146.             clevel--;
  147.             if ((iflev = siflev[clevel]-1) < 0) iflev = 0;
  148.             ifflg = sifflg[clevel];     
  149.             put_str();  
  150.             tabs--;  
  151.             ptabs();
  152.             if ((peek = getchr()) == ';') {
  153.                 fprintf(f2,"%c;",c);  
  154.                 peek = -1;
  155.             }
  156.             else fprintf(f2,"%c",c);
  157.             get_nl();  
  158.             put_str();  
  159.             fprintf(f2,"\n");  
  160.             sflg = 1;
  161.             if (clevel < slevel[level] && level > 0) level--;
  162.             if (ind[level] != 0) {
  163.                 tabs -= pflg[level];  
  164.                 pflg[level] = ind[level] = 0;
  165.             }
  166.             break;
  167.  
  168.         case '"':
  169.         case '\'':    
  170.             string[j++] = c;
  171.             while ((cc = getchr()) != c) {
  172.                 string[j++] = cc;
  173.                 if (cc == '\\') string[j++] = getchr();
  174.                 if (cc == '\n') { 
  175.                     put_str();  
  176.                     sflg = 1; 
  177.                 }
  178.             }
  179.             string[j++] = cc;
  180.             if (get_nl() == 1) { 
  181.                 lchar = cc;  
  182.                 peek = '\n'; 
  183.             }
  184.             break;
  185.  
  186.         case ';':    
  187.             string[j++] = c;  
  188.             put_str();
  189.             if (pflg[level] > 0 && ind[level] == 0) {
  190.                 tabs -= pflg[level];  
  191.                 pflg[level] = 0;
  192.             }
  193.             get_nl();  
  194.             put_str();  
  195.             fprintf(f2,"\n");  
  196.             sflg = 1;
  197.             if(iflev > 0 && ifflg == 1){ 
  198.                 iflev--;  
  199.                 ifflg = 0; 
  200.             }
  201.             else iflev = 0;
  202.             break;
  203.  
  204.         case '\\':    
  205.             string[j++] = c;  
  206.             string[j++] = getchr();  
  207.             break;
  208.  
  209.         case '?':    
  210.             qflg = 1;  
  211.             string[j++] = c;  
  212.             break;
  213.  
  214.         case ':':    
  215.             string[j++] = c;
  216.             if (qflg == 1) { 
  217.                 qflg = 0;  
  218.                 break; 
  219.             }
  220.             if (!lookup(wds)) { 
  221.                 sflg = 0;  
  222.                 put_str(); 
  223.             }
  224.             else { 
  225.                 tabs--;    
  226.                 put_str();  
  227.                 tabs++; 
  228.             }
  229.             if ((peek = getchr()) == ';') {
  230.                 fprintf(f2,";");  
  231.                 peek = -1;
  232.             }
  233.             get_nl();  
  234.             put_str();  
  235.             fprintf(f2,"\n");  
  236.             sflg = 1;
  237.             break;
  238.  
  239.         case '/':    
  240.             string[j++] = c;
  241.             if ((peek = getchr()) != '*') break;
  242.             string[j++] = peek;  
  243.             peek = -1;     
  244.             comment();  
  245.             break;
  246.  
  247.         case ')':    
  248.             paren--;  
  249.             string[j++] = c;  
  250.             put_str();
  251.             if (get_nl() == 1) {
  252.                 peek = '\n';
  253.                 if (paren != 0) aflg = 1;
  254.                 else if (tabs > 0) {
  255.                     pflg[level]++;    
  256.                     tabs++;     
  257.                     ind[level] = 0;
  258.                 }
  259.             }
  260.             break;
  261.  
  262.         case '#':    
  263.             string[j++] = c;
  264.             while ((cc = getchr()) != '\n') string[j++] = cc;
  265.             string[j++] = cc;  
  266.             sflg = 0;  
  267.             put_str();  
  268.             sflg = 1;
  269.             break;
  270.  
  271.         case '(':    
  272.             string[j++] = c;  
  273.             paren++;
  274.             if (lookup(wfor) == 1) {
  275.                 while ((c = get_str()) != ';');
  276.                 ct = 0;
  277. cont:                
  278.                 while ((c = get_str()) != ')')
  279.                     if(c == '(') ct++;
  280.                 if (ct != 0) { 
  281.                     ct--;  
  282.                     goto cont; 
  283.                 }
  284.                 paren--;  
  285.                 put_str();
  286.                 if (get_nl() == 1) {
  287.                     peek = '\n';  
  288.                     pflg[level]++;
  289.                     tabs++;     
  290.                     ind[level] = 0;
  291.                 }
  292.                 break;
  293.             }
  294.             if (lookup(wif) == 1) {
  295.                 put_str();
  296.                 stabs[clevel][iflev] = tabs;
  297.                 spflg[clevel][iflev] = pflg[level];
  298.                 sind[clevel][iflev] = ind[level];
  299.                 iflev++;  
  300.                 ifflg = 1;
  301.             }
  302.         }
  303.     }
  304.     if (f2 != stdout && (ferror(f2) || fclose(f2))) {
  305.         fprintf(stderr,"ERROR:  Disk full\n");    
  306.         return !0;
  307.     }
  308.     fclose(f1);     
  309.     return 0;
  310. }
  311.  
  312. void ptabs()
  313. {
  314.     int i;
  315.  
  316.     for (i=0; i < tabs; i++) fprintf(f2,"\t");
  317. }
  318.  
  319. int getchr()
  320. {
  321.     if (peek < 0 && lastchar != ' ' && lastchar != '\t') pchar = lastchar;
  322.     lastchar = (peek < 0) ? getc(f1) : peek;  
  323.     peek = -1;
  324.     return lastchar;
  325. }
  326.  
  327. void put_str()
  328. {
  329.     if (j > 0) {
  330.         if (sflg != 0) {
  331.             ptabs();  
  332.             sflg = 0;
  333.             if (aflg == 1) {
  334.                 aflg = 0;
  335.                 if (tabs > 0) fprintf(f2,"    ");
  336.             }
  337.         }
  338.         string[j] = '\0';  
  339.         fprintf(f2,"%s",string);  
  340.         j = 0;
  341.     }
  342.     else if (sflg != 0) { 
  343.         sflg = 0;  
  344.         aflg = 0; 
  345.     }
  346. }
  347.  
  348. int lookup(tab)
  349. char *tab[];
  350. {
  351.     char r;
  352.     int i,kk,k,l;
  353.  
  354.     if (j < 1) return 0;
  355.     for (kk = 0; string[kk] == ' '; ++kk);
  356.     for (i = 0; tab[i] != 0; i++) {
  357.         l = 0;
  358.         for (k=kk; (r = tab[i][l++]) == string[k] && r != '\0'; ++k);
  359.         if (r == '\0' && (string[k] < 'a' || string[k] > 'z')) return 1;
  360.     }
  361.     return 0;
  362. }
  363.  
  364. int get_str()
  365. {
  366.     char ch;
  367.  
  368. beg:
  369.     if ((ch = string[j++] = getchr()) == '\\') {
  370.         string[j++] = getchr();     
  371.         goto beg;
  372.     }
  373.     if (ch == '\'' || ch == '"') {
  374.         while ((cc = string[j++] = getchr()) != ch)
  375.             if (cc == '\\') string[j++] = getchr();
  376.         goto beg;
  377.     }
  378.     if (ch == '\n') { 
  379.         put_str();  
  380.         aflg = 1;  
  381.         goto beg; 
  382.     }
  383.     else return ch;
  384. }
  385.  
  386. void gotelse()
  387. {
  388.     tabs = stabs[clevel][iflev];  
  389.     pflg[level] = spflg[clevel][iflev];
  390.     ind[level] = sind[clevel][iflev];  
  391.     ifflg = 1;
  392. }
  393.  
  394. int get_nl()
  395. {
  396.     while ((peek = getchr()) == '\t' || peek == ' ') {
  397.         string[j++] = peek;  
  398.         peek = -1;
  399.     }
  400.     if ((peek = getchr()) == '/') {
  401.         peek = -1;
  402.         if ((peek = getchr()) == '*') {
  403.             string[j++] = '/';    
  404.             string[j++] = '*';
  405.             peek = -1;    
  406.             comment();
  407.         }
  408.         else string[j++] = '/';
  409.     }
  410.     if ((peek = getchr()) == '\n') { 
  411.         peek = -1;     
  412.         return 1; 
  413.     }
  414.     return 0;
  415. }
  416.  
  417. void comment()
  418. {
  419. rep:
  420.     while ((c = string[j++] = getchr()) != '*')
  421.         if (c == '\n') { 
  422.             put_str();  
  423.             sflg = 1; 
  424.         }
  425. gotstar:
  426.     if ((c = string[j++] = getchr()) != '/') {
  427.         if (c == '*') goto gotstar;
  428.         goto rep;
  429.     }
  430. }
  431.