home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / alde_c / misc / util / cb2 / cb.c next >
Encoding:
C/C++ Source or Header  |  1987-08-02  |  9.9 KB  |  558 lines

  1. #define VERS "CB  08/25/83  Vers 1.2 for IBM-PC\n\n"
  2. /*
  3.     Pretty-printer for C Programs
  4.  
  5.     Swiped from the CIPG's UNIX system and modified to run
  6.         under BDS C by William C. Colley, III
  7.  
  8.     Mods made July 1980
  9.  
  10.     *** REVISIONS ***
  11.  
  12.     Modified to run on the IBM-PC with C86 08/16/83  J.E.Will
  13.  
  14.     Put indent level option in  08/23/83   J.E.Will
  15.  
  16.     Change interface for single file name, old file is
  17.     renamed .BAK after program terminates. 08/25/83  J.E.Will
  18.  
  19.     *** END ***
  20.  
  21. */
  22.  
  23. #include <stdio.h>
  24.  
  25. int s_level[10];
  26. int c_level;
  27. int sp_flg[20][10];
  28. int s_ind[20][10];
  29. int s_if_lev[10];
  30. int s_if__flg[10];
  31. int if_lev;
  32. int if_flg;
  33. int level;
  34. int indent;        /* number of spaces to indent */
  35. static int ind[10] = {
  36.     0,0,0,0,0,0,0,0,0,0};
  37. int e_flg;
  38. int paren;
  39. static int p_flg[10] = {
  40.     0,0,0,0,0,0,0,0,0,0};
  41. char l_char;
  42. char p_char;
  43. int a_flg;
  44. int ct;
  45. int s_tabs[20][10];
  46. int q_flg;
  47. char *w_if_[2];
  48. char *w_else[2];
  49. char *w_for[2];
  50. char *w_ds[3];
  51. int j;
  52. char string[256];
  53. char cc;
  54. int s_flg;
  55. int b_flg;
  56. int peek;
  57. int tabs;
  58. char last_char;
  59. char c;
  60. char *w_kptr;
  61.  
  62. FILE *inpfil,*outfil,*fopen();
  63.  
  64. int comment(), putcoms(), getnl(), gotelse(), get_string(), lookup(),
  65.     indent_puts(), getchr(), p_tabs();
  66.  
  67. char *index();
  68.  
  69. /* code starts here, Jack */
  70.  
  71. main(argc,argv)
  72. int argc;
  73. char *argv[];
  74. {
  75.     int k;
  76.     printf(VERS);        /* tell the world about version */
  77.  
  78.     /*  Initialize everything here.  */
  79.  
  80.     if (argc < 2 || argc > 4)
  81.     {
  82.         printf("Usage:  CB input.fil [indent]\n\n");
  83.         printf("input.fil  - 'C' input source file in current directory\n");
  84.         printf("indent     - where 'indent' is a number from 1 to 8 equal\n");
  85.         printf("             to number of spaces for each indent level\n");
  86.         printf("             Default 4 if not supplied on cmd line\n");
  87.         printf("NOTES:\n");
  88.         printf("    - Original source is in input.BAK\n\n");
  89.         exit(99);
  90.     }
  91.  
  92.     /* get name and check that it"s not a back-up file */
  93.  
  94.     strcpy(string,argv[1]);
  95.     if((w_kptr = index(string,'.')) != 0)
  96.     {
  97.         if ((strcmp(w_kptr,".bak") == 0) || (strcmp(w_kptr,".BAK") == 0))
  98.         {
  99.             printf("Input file can not be a .BAK file!\n");
  100.             exit(99);
  101.         }
  102.     }
  103.  
  104.     if ((inpfil = fopen(argv[1],"r")) == 0)
  105.     {
  106.         printf("File not found: %s\n",argv[1]);
  107.         exit(99);
  108.     }
  109.  
  110.     unlink("CB.$$$");    /* delete any existing temp file */
  111.  
  112.     if ((outfil = fopen("CB.$$$","wr")) == 0)
  113.     {
  114.         printf("Could not create CB.$$$, the temp output file\n");
  115.         exit(99);
  116.     }
  117.     /* process indent option */
  118.  
  119.     indent = 4;        /* set default indent */
  120.  
  121.     if (argc == 3)
  122.     {
  123.         indent = atoi(argv[2]);
  124.         if ((indent < 1) || (indent > 8))
  125.         {
  126.             printf("Indent option value out of range, valid from 1 to 8.");
  127.             exit(99);
  128.         }
  129.     }
  130.     c_level = iflev = level = e_flg = paren = 0;
  131.     a_flg = q_flg = j = b_flg = tabs = 0;
  132.     if_flg = peek = -1;
  133.     s_flg = 1;
  134.     w_if_[0] = "if";
  135.     w_else[0] = "else";
  136.     w_for[0] = "for";
  137.     w_ds[0] = "case";
  138.     w_ds[1] = "default";
  139.     w_if_[1] = w_else[1] = w_for[1] = w_ds[2] = 0;
  140.  
  141.     /*  End of initialization.  */
  142.  
  143.     while((c = getchr()) != 032)
  144.     {
  145.     switch(c)
  146.     {
  147.     default:
  148.         string[j++] = c;
  149.         if(c != ',')l_char = c;
  150.         break;
  151.     case ' ':
  152.     case '\t':
  153.         if(lookup(w_else) == 1)
  154.         {
  155.         gotelse();
  156.         if(s_flg == 0 || j > 0)string[j++] = c;
  157.         indent_puts();
  158.         s_flg = 0;
  159.         break;
  160.         }
  161.         if(s_flg == 0 || j > 0)string[j++] = c;
  162.         break;
  163.     case '\n':
  164.         if(e_flg = lookup(w_else) == 1)gotelse();
  165.         indent_puts();
  166.         fprintf(outfil,"\n");
  167.         s_flg = 1;
  168.         if(e_flg == 1)
  169.         {
  170.         p_flg[level]++;
  171.         tabs++;
  172.         }
  173.         else
  174.         if(p_char == l_char)
  175.             a_flg = 1;
  176.         break;
  177.     case '{':
  178.         if(lookup(w_else) == 1)gotelse();
  179.         s_if_lev[c_level] = iflev;
  180.         s_if_flg[c_level] = if_flg;
  181.         if_lev = if_flg = 0;
  182.         c_level++;
  183.         if(s_flg == 1 && p_flg[level] != 0)
  184.         {
  185.         p_flg[level]--;
  186.         tabs--;
  187.         }
  188.         string[j++] = c;
  189.         indent_puts();
  190.         getnl();
  191.         indent_puts();
  192.         fprintf(outfil,"\n");
  193.         tabs++;
  194.         s_flg = 1;
  195.         if(p_flg[level] > 0)
  196.         {
  197.         ind[level] = 1;
  198.         level++;
  199.         s_level[level] = c_level;
  200.         }
  201.         break;
  202.     case '}':
  203.         c_level--;
  204.         if((if_lev = s_if_lev[c_level]-1) < 0)if_lev = 0;
  205.         if_flg = s_if_flg[c_level];
  206.         indent_puts();
  207.         tabs--;
  208.         p_tabs();
  209.         if((peek = getchr()) == ';')
  210.         {
  211.         fprintf(outfil,"%c;",c);
  212.         peek = -1;
  213.         }
  214.         else fprintf(outfil,"%c",c);
  215.         getnl();
  216.         indent_puts();
  217.         fprintf(outfil,"\n");
  218.         s_flg = 1;
  219.         if(c_level < s_level[level])if(level > 0)level--;
  220.         if(ind[level] != 0)
  221.         {
  222.         tabs -= p_flg[level];
  223.         p_flg[level] = 0;
  224.         ind[level] = 0;
  225.         }
  226.         break;
  227.     case '"':
  228.     case '\'':
  229.         string[j++] = c;
  230.         while((cc = getchr()) != c)
  231.         {
  232.         string[j++] = cc;
  233.         if(cc == '\\')
  234.         {
  235.             string[j++] = getchr();
  236.         }
  237.         if(cc == '\n')
  238.         {
  239.             indent_puts();
  240.             s_flg = 1;
  241.         }
  242.         }
  243.         string[j++] = cc;
  244.         if(getnl() == 1)
  245.         {
  246.         l_char = cc;
  247.         peek = '\n';
  248.         }
  249.         break;
  250.     case ';':
  251.         string[j++] = c;
  252.         indent_puts();
  253.         if(p_flg[level] > 0 && ind[level] == 0)
  254.         {
  255.         tabs -= p_flg[level];
  256.         p_flg[level] = 0;
  257.         }
  258.         getnl();
  259.         indent_puts();
  260.         fprintf(outfil,"\n");
  261.         s_flg = 1;
  262.         if(if_lev > 0)
  263.         if(if_flg == 1)
  264.         {
  265.             if_lev--;
  266.             if_flg = 0;
  267.         }
  268.         else if_lev = 00;
  269.         break;
  270.     case '\\':
  271.         string[j++] = c;
  272.         string[j++] = getchr();
  273.         break;
  274.     case '?':
  275.         q_flg = 1;
  276.         string[j++] = c;
  277.         break;
  278.     case ':':
  279.         string[j++] = c;
  280.         if(q_flg == 1)
  281.         {
  282.         q_flg = 0;
  283.         break;
  284.         }
  285.         if(lookup(w_ds) == 0)
  286.         {
  287.         s_flg = 0;
  288.         indent_puts();
  289.         }
  290.         else
  291.         {
  292.         tabs--;
  293.         indent_puts();
  294.         tabs++;
  295.         }
  296.         if((peek = getchr()) == ';')
  297.         {
  298.         fprintf(outfil,";");
  299.         peek = -1;
  300.         }
  301.         getnl();
  302.         indent_puts();
  303.         fprintf(outfil,"\n");
  304.         s_flg = 1;
  305.         break;
  306.     case '/':
  307.         string[j++] = c;
  308.         if((peek = getchr()) != '*')break;
  309.         string[j++] = peek;
  310.         peek = -1;
  311.         comment();
  312.         break;
  313.     case ')':
  314.         paren--;
  315.         string[j++] = c;
  316.         indent_puts();
  317.         if(getnl() == 1)
  318.         {
  319.         peek = '\n';
  320.         if(paren != 0)a_flg = 1;
  321.         else if(tabs > 0)
  322.         {
  323.             p_flg[level]++;
  324.             tabs++;
  325.             ind[level] = 0;
  326.         }
  327.         }
  328.         break;
  329.     case '#':
  330.         string[j++] = c;
  331.         while((cc = getchr()) != '\n')string[j++] = cc;
  332.         string[j++] = cc;
  333.         s_flg = 0;
  334.         indent_puts();
  335.         s_flg = 1;
  336.         break;
  337.     case '(':
  338.         string[j++] = c;
  339.         paren++;
  340.         if(lookup(w_for) == 1)
  341.         {
  342.         while((c = get_string()) != ';');
  343.         ct=0;
  344. cont:
  345.         while((c = get_string()) != ')')
  346.         {
  347.             if(c == '(') ct++;
  348.         }
  349.         if(ct != 0)
  350.         {
  351.             ct--;
  352.             goto cont;
  353.         }
  354.         paren--;
  355.         indent_puts();
  356.         if(getnl() == 1)
  357.         {
  358.             peek = '\n';
  359.             p_flg[level]++;
  360.             tabs++;
  361.             ind[level] = 0;
  362.         }
  363.         break;
  364.         }
  365.         if(lookup(w_if) == 1)
  366.         {
  367.         indent_puts();
  368.         s_tabs[c_level][if_lev] = tabs;
  369.         sp_flg[c_level][if_lev] = p_flg[level];
  370.         s_ind[c_level][if_lev] = ind[level];
  371.         if_lev++;
  372.         if_flg = 1;
  373.         }
  374.     }
  375.     }
  376.  
  377.     /* eof processing */
  378.  
  379.     fprintf(outfil,"\032");    /* throw in an EOF mark */
  380.     fclose(outfil);
  381.     fclose(inpfil);
  382.  
  383.     /* get origional name with a .BAK on it */
  384.  
  385.     strcpy(string,argv[1]);
  386.     if((w_kptr = index(string,'.')) == 0)
  387.     strcat(string,".BAK");
  388.     else
  389.     strcpy(w_kptr,".BAK");
  390.     unlink(string);        /* kill any .BAK file */
  391.     rename(argv[1],string);    /* origional is now .BAK */
  392.     rename("CB.$$$",argv[1]);    /* new now has origional name */
  393.     exit(0);            /* normal exit */
  394. }
  395. /* expand indent into tabs and spaces */
  396. p_tabs()
  397. {
  398.     int i,j,k;
  399.  
  400.     i = tabs * indent;        /* calc number of spaces */
  401.     j = i/8;            /* calc number of tab chars */
  402.     i -= j*8;            /* calc remaining spaces */
  403.  
  404.     for (k=0;k < j;k++) fprintf(outfil,"\t");
  405.     for (k=0;k < i;k++) fprintf(outfil," ");
  406. }
  407. /* get character from stream or return the saved one */
  408. getchr()
  409. {
  410.     if(peek < 0 && last_char != ' ' && last_char != '\t')p_char = last_char;
  411.     last_char = (peek<0) ? getc(inpfil):peek;
  412.     if (last_char == -1) last_char = 0x1a;
  413.     peek = -1;
  414.     return(last_char == '\r' ? getchr():last_char);
  415. }
  416. /* put string with indent logic */
  417. indent_puts()
  418. {
  419.     if(j > 0)
  420.     {
  421.     if(s_flg != 0)
  422.     {
  423.         if((tabs > 0) && (string[0] != '{') && (a_flg == 1)) tabs++;
  424.         p_tabs();
  425.         s_flg = 0;
  426.         if((tabs > 0) && (string[0] != '{') && (a_flg == 1)) tabs--;
  427.         a_flg = 0;
  428.     }
  429.     string[j] = '\0';
  430.     fprintf(outfil,"%s",string);
  431.     j = 0;
  432.     }
  433.     else
  434.     {
  435.     if(s_flg != 0)
  436.     {
  437.         s_flg = 0;
  438.         a_flg = 0;
  439.     }
  440.     }
  441. }
  442. /* search table for character string and return index number */
  443. lookup(tab)
  444. char *tab[];
  445. {
  446.     char r;
  447.     int l,kk,k,i;
  448.     if(j < 1)return(0);
  449.     kk=0;
  450.     while(string[kk] == ' ')kk++;
  451.     for(i=0; tab[i] != 0; i++)
  452.     {
  453.     l=0;
  454.     for(k=kk;(r = tab[i][l++]) == string[k] && r != '\0';k++);
  455.     if(r == '\0' && (string[k] < 'a' || string[k] > 'z'))return(1);
  456.     }
  457.     return(0);
  458. }
  459. /* read string between double quotes */
  460. get_string()
  461. {
  462.     char ch;
  463. beg:
  464.     if((ch = string[j++] = getchr()) == '\\')
  465.     {
  466.     string[j++] = getchr();
  467.     goto beg;
  468.     }
  469.     if(ch == '\'' || ch == '"')
  470.     {
  471.     while((cc = string[j++] = getchr()) != ch)
  472.       if(cc == '\\')
  473.          string[j++] = getchr();
  474.     goto beg;
  475.     }
  476.     if(ch == '\n')
  477.     {
  478.     indent_puts();
  479.     a_flg = 1;
  480.     goto beg;
  481.     }
  482.     else return(ch);
  483. }
  484. /* else processing */
  485. gotelse()
  486. {
  487.     tabs = s_tabs[c_level][if_lev];
  488.     p_flg[level] = sp_flg[c_level][if_lev];
  489.     ind[level] = s_ind[c_level][if_lev];
  490.     if_flg = 1;
  491. }
  492. /* read to new_line */
  493. getnl()
  494. {
  495.     while((peek = getchr()) == '\t' || peek == ' ')
  496.     {
  497.     string[j++] = peek;
  498.     peek = -1;
  499.     }
  500.     if((peek = getchr()) == '/')
  501.     {
  502.     peek = -1;
  503.     if((peek = getchr()) == '*')
  504.     {
  505.         string[j++] = '/';
  506.         string[j++] = '*';
  507.         peek = -1;
  508.         comment();
  509.     }
  510.     else string[j++] = '/';
  511.     }
  512.     if((peek = getchr()) == '\n')
  513.     {
  514.     peek = -1;
  515.     return(1);
  516.     }
  517.     return(0);
  518. }
  519. /* special edition of put string for comment processing */
  520. putcoms()
  521. {
  522.     if(j > 0)
  523.     {
  524.     if(s_flg != 0)
  525.     {
  526.         p_tabs();
  527.         s_flg = 0;
  528.     }
  529.     string[j] = '\0';
  530.     fprintf(outfil,"%s",string);
  531.     j = 0;
  532.     }
  533. }
  534. /* comment processing */
  535. comment()
  536. {
  537. rep:
  538.     while((c = string[j++] = getchr()) != '*')
  539.     if(c == '\n') putcoms();
  540.  
  541. gotstar:
  542.     if((c = string[j++] = getchr()) != '/')
  543.     {
  544.     if(c == '*') goto gotstar;
  545.     if(c == '\n') putcoms();
  546.     goto rep;
  547.     }
  548. }
  549.  
  550.  
  551. char *index(s, c)
  552. char *s;
  553. char c;
  554. {
  555.     while(*s != c) s++;
  556.     return s;
  557. }
  558.