home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 143_01 / cb.c < prev    next >
Text File  |  1985-11-14  |  12KB  |  548 lines

  1. /*
  2. %CC1 $1.C -X -e5000
  3. %CLINK $1 DIO -S
  4. %DELETE    $1.CRL
  5. */
  6. /*******************************************************************
  7. *                 CB                       *
  8. ********************************************************************
  9. *          COPYRIGHT 1983 EUGENE    H. MALLORY           *
  10. *******************************************************************/
  11.  
  12. #include <bdscio.h>
  13. #include <dio.h>
  14.  
  15. #define    flush /**/
  16. #define    AND &&
  17. #define    OR ||
  18. #define    EQUAL ==
  19. #define    NOTEQUAL !=
  20. #define    NOT !
  21.  
  22. #define    LOOPTYPE 1
  23. #define    IFTYPE 2
  24. FUNCTION char *do_comment();
  25. FUNCTION char *do_begin();
  26. FUNCTION char *do_end();
  27. FUNCTION char *do_case();
  28. FUNCTION char *do_default();
  29. FUNCTION char *do_semi();
  30. FUNCTION char *do_paren();
  31. FUNCTION char *do_quote();
  32. FUNCTION char *do_string();
  33. FUNCTION char *do_next_word();
  34. FUNCTION char inline[MAXLINE];
  35. int indent,nlflag,step;
  36. int verb, verbx, verbstk[20];
  37.  
  38. main(argc,argv)
  39. char **argv;
  40. int argc;
  41.  
  42.   BEGIN
  43.     char c;
  44.     int    ii,jj,optionerr;
  45.     char *ss;
  46.     char *stgptr;
  47.     dioinit(&argc,argv);
  48.  
  49. /*********************************************************************
  50. *           ARGUMENT PROCESSING                     *
  51. *********************************************************************/
  52.  
  53.     step = 2;
  54.     optionerr =    FALSE;
  55.     for    (ii=argc-1;ii>0;ii--)
  56.     if (argv[ii][0] == '-')
  57.       THEN
  58.     for (ss    = &argv[ii][1];    *ss != '\0';)
  59.       LOOP
  60.         switch (toupper(*ss++))
  61.           BEGIN
  62.           case 'I':
  63.         step = atoi(ss);
  64.         break;
  65.           case 'H':
  66.         optionerr = TRUE;
  67.         break;
  68.           default:
  69.         fprintf(STDERR,"CB: Illegal option %c.\n",*--ss);
  70.         ss++;
  71.         optionerr = TRUE;
  72.         break;
  73.           END
  74.         while (isdigit(*ss)) 
  75.           LOOP
  76.         ss++;
  77.           ENDLOOP
  78.       ENDLOOP
  79.     for (jj=ii;jj<(argc-1);jj++) argv[jj] =    argv[jj+1];
  80.     argc--;
  81.       ENDIF
  82.  
  83.     if (optionerr) 
  84.       THEN
  85.     fprintf(STDERR,"CB: Formats a C    Program    with structured    indentation\n");
  86.     fprintf(STDERR,"CB: -In     n is indent step, default is 2\n");
  87.     fprintf(STDERR,"Ex. A:CB <T-UNFORM.C >T-FORMAT.C\n");
  88.     exit(0);
  89.       ENDIF
  90. /********************************************************************
  91. *              END OF ARGUMENT PROCESSING            *
  92. ********************************************************************/
  93.  
  94.     indent = 0;         /* start indent at 0 */
  95.     nlflag = 0;         /* set    to bol */
  96.     verbx = 0;        /* set verb stack empty    */
  97.     while (!getstring(inline))
  98.       LOOP
  99.     stgptr = inline;
  100.     while (*stgptr EQUAL ' ' OR *stgptr EQUAL '\t')    
  101.       LOOP
  102.         stgptr++;
  103.       ENDLOOP
  104.  
  105.     if (*stgptr EQUAL '\n')    
  106.       THEN
  107.         nlflag = -1;
  108.       ENDIF
  109.  
  110.  
  111.     if (is_begin(stgptr)) ;
  112.     else if    (is_loop(stgptr)) verb = LOOPTYPE;
  113.     else if    (is_if(stgptr))    verb = IFTYPE;
  114.     else verb = 0;
  115.     while (*stgptr NOTEQUAL    '\n')
  116.       LOOP
  117.         if (*stgptr    EQUAL ';') stgptr = do_semi(stgptr);
  118.         else if (is_comment(stgptr)) stgptr    = do_comment(stgptr);
  119.         else if (is_begin(stgptr)) stgptr =    do_begin(stgptr);
  120.         else if (is_default(stgptr)) stgptr    = do_default(stgptr);
  121.         else if (is_case(stgptr)) stgptr = do_case(stgptr);
  122.         else if (is_end(stgptr)) stgptr = do_end(stgptr);
  123.         else if (is_paren(stgptr)) stgptr =    do_paren(stgptr);
  124.         else if (is_quote(stgptr)) stgptr =    do_quote(stgptr);
  125.         else if (is_string(stgptr))    stgptr = do_string(stgptr);
  126.         else stgptr    = do_next_word(stgptr);
  127.       ENDLOOP
  128.     newline();
  129.       ENDLOOP
  130.     if (verbx NOTEQUAL 0) error("CB: Too few ENDs.");
  131.     dioflush();
  132.   END
  133.  
  134. FUNCTION is_comment(string)
  135. char string[];
  136.   BEGIN
  137.     if ((string[0] EQUAL '/') AND (string[1] EQUAL '*')) return    TRUE;
  138.     return FALSE;
  139.   END
  140.  
  141. FUNCTION is_quote(string)
  142. char string[];
  143.   BEGIN
  144.     if (string[0] EQUAL    '\'') return TRUE;
  145.     return FALSE;
  146.   END
  147.  
  148. FUNCTION is_paren(string)
  149. char string[];
  150.   BEGIN
  151.     if (string[0] EQUAL    '(') return TRUE;
  152.     return FALSE;
  153.   END
  154.  
  155. FUNCTION is_string(string)
  156. char string[];
  157.   BEGIN
  158.     if (string[0] EQUAL    '"') return TRUE;
  159.     return FALSE;
  160.   END
  161.  
  162. FUNCTION is_begin(string)
  163. char string[];
  164.   BEGIN
  165.     if (string[0] EQUAL    '{') return TRUE;
  166.     if (strmatch(string,"BEGIN")) return TRUE;
  167.     if (strmatch(string,"LOOP")) return    TRUE;
  168.     if (strmatch(string,"THEN")) return    TRUE;
  169.     return FALSE;
  170.   END
  171.  
  172. FUNCTION is_end(string)
  173. char string[];
  174.   BEGIN
  175.     if (string[0] EQUAL    '}') return TRUE;
  176.     if (strmatch(string,"ENDLOOP")) return TRUE;
  177.     if (strmatch(string,"ENDIF")) return TRUE;
  178.     if (strmatch(string,"END"))    return TRUE;
  179.     return FALSE;
  180.   END
  181.  
  182. FUNCTION is_case(string)
  183. char string[];
  184.   BEGIN
  185.     if (strmatch(string,"CASE")) return    TRUE;
  186.     return FALSE;
  187.   END
  188.  
  189. FUNCTION is_default(string)
  190. char string[];
  191.   BEGIN
  192.     if (strmatch(string,"default:")) return TRUE;
  193.     return FALSE;
  194.   END
  195.  
  196. FUNCTION is_if(string)
  197. char string[];
  198.   BEGIN
  199.     if (strmatch(string,"IF")) return TRUE;
  200.     if (strmatch(string,"else")) return    TRUE;
  201.     return FALSE;
  202.   END
  203.  
  204. FUNCTION is_loop(string)
  205. char string[];
  206.   BEGIN
  207.     if (strmatch(string,"WHILE")) return TRUE;
  208.     if (strmatch(string,"DO")) return TRUE;
  209.     if (strmatch(string,"FOR"))    return TRUE;
  210.     return FALSE;
  211.   END
  212.  
  213. FUNCTION pushv()
  214.   BEGIN
  215.     verbstk[verbx++] = verb;
  216.   END
  217.  
  218. FUNCTION pullv()
  219.   BEGIN
  220.     verb = verbstk[--verbx];
  221.     if (verbx <    0) error("CB: Too many ENDs.");
  222.     return verb;
  223.   END
  224.  
  225.  
  226. FUNCTION strmatch(s1,s2)
  227. char *s1, *s2;
  228.   BEGIN
  229.     while (*s2)    
  230.       LOOP
  231.     if (toupper(*s1++) NOTEQUAL *s2++) 
  232.       THEN
  233.         return FALSE;
  234.       ENDIF
  235.       ENDLOOP
  236.     if (isalpha(*s1)) return FALSE;
  237.     if (isdigit(*s1)) return FALSE;
  238.     if (*s1 EQUAL '_') return FALSE;
  239.     if (*s1 EQUAL ':') return FALSE;
  240.     if (*s1 EQUAL ';') return FALSE;
  241.     return TRUE;
  242.   END
  243.  
  244. FUNCTION newline()
  245.   BEGIN
  246.     if (nlflag < 0)
  247.       THEN
  248.     putchar('\n');
  249.     nlflag = 0;
  250.       ENDIF
  251.   END
  252.  
  253. FUNCTION char *do_comment(string)
  254. char *string;
  255.   BEGIN
  256.     if (string NOTEQUAL    inline)    tabin();
  257.     putchar(*string++);
  258.     putchar(*string++);
  259.     nlflag = -1;
  260.     while (TRUE)
  261.       LOOP
  262.     if (*string EQUAL '\n')    
  263.       THEN
  264.         if (getstring(inline))
  265.           THEN
  266.         error("CB: EOF encountered in comment.");
  267.           ENDIF
  268.         putchar('\n');
  269.         string = inline;
  270.         continue;
  271.       ENDIF
  272.     if (*string NOTEQUAL '*') 
  273.       THEN
  274.         if (is_comment(string)) 
  275.           THEN
  276.         string = do_comment(string);
  277.           ENDIF
  278.         else 
  279.           THEN
  280.         putchar(*string++);
  281.           ENDIF
  282.         continue;
  283.       ENDIF
  284.     else 
  285.       THEN
  286.         if (string[1] EQUAL    '/') /*    comment    end */
  287.           THEN
  288.         putchar(*string++);
  289.         putchar(*string++);
  290.         return string;
  291.           ENDIF
  292.         else 
  293.         putchar(*string++);
  294.       ENDIF
  295.       ENDLOOP
  296.   END
  297.  
  298. FUNCTION char *do_string(string)
  299. char *string;
  300.   BEGIN
  301.     tabin();
  302.     nlflag = -1;
  303.     putchar(*string++);
  304.     while (*string NOTEQUAL '"')
  305.       LOOP
  306.     putchar(*string);
  307.     if (*string EQUAL '\n')    error("CB: Double quote    unmatched at EOL.");
  308.     if (*string++ EQUAL '\\')
  309.     putchar(*string++);
  310.       ENDLOOP
  311.     putchar(*string++);
  312.     return string;
  313.   END
  314.  
  315. FUNCTION char *do_quote(string)
  316. char *string;
  317.   BEGIN
  318.     tabin();
  319.     nlflag = -1;
  320.     putchar(*string++);
  321.     while (*string NOTEQUAL '\'') 
  322.       LOOP
  323.     putchar(*string);
  324.     if (*string EQUAL '\n')    error("CB: Single quote    unmatched at EOL.");
  325.     if (*string++ EQUAL '\\') putchar(*string++);
  326.       ENDLOOP
  327.     putchar(*string++);
  328.     return string;
  329.   END
  330.  
  331. FUNCTION char *do_paren(string)
  332. char *string;
  333.   BEGIN
  334.     int    isave;
  335.     indent += step;
  336.     tabin();
  337.     nlflag = -1;
  338.     putchar(*string++);
  339.     while (*string NOTEQUAL ')') 
  340.       LOOP
  341.     if (*string EQUAL '\n')    
  342.       THEN
  343.         if (getstring(inline))
  344.           THEN
  345.         error("CB: EOF encountered in parens.");
  346.           ENDIF
  347.         nlflag = -1;
  348.         newline();
  349.         tabin();
  350.         nlflag = -1;
  351.         string = inline;
  352.         while (*string EQUAL ' ' OR    *string    EQUAL '\t') 
  353.           LOOP
  354.         string++;
  355.           ENDLOOP
  356.         continue;
  357.       ENDIF
  358.     if (*string EQUAL '(') string =    do_paren(string);
  359.     else if    (*string EQUAL '\'') string = do_quote(string);
  360.     else if    (*string EQUAL '"') string = do_string(string);
  361.     else putchar(*string++);
  362.       ENDLOOP
  363.     putchar(*string++);
  364.     indent -= step;
  365.     return string;
  366.   END
  367.  
  368. FUNCTION char *do_begin(string)
  369. char *string;
  370.   BEGIN
  371.     pushv();
  372.     indent += step;
  373.     newline();
  374.     tabin();
  375.     nlflag = -1;
  376.     flush
  377.     if (strmatch(string,"BEGIN")) 
  378.       THEN
  379.     if (verb EQUAL LOOPTYPE) printf("LOOP");
  380.     else if    (verb EQUAL IFTYPE) printf("THEN");
  381.     else printf("BEGIN");
  382.     string+=5;
  383.       ENDIF
  384.     if (strmatch(string,"THEN")) 
  385.       THEN
  386.     printf("THEN");
  387.     string+=4;
  388.       ENDIF
  389.     if (strmatch(string,"LOOP")) 
  390.       THEN
  391.     printf("LOOP");
  392.     string+=4;
  393.       ENDIF
  394.     if (*string    EQUAL '{') 
  395.       THEN
  396.     if (verb EQUAL LOOPTYPE) printf("LOOP");
  397.     else if    (verb EQUAL IFTYPE) printf("THEN");
  398.     else printf("BEGIN");
  399.     string+=1;
  400.       ENDIF
  401.     indent += step;
  402.     newline();
  403.     while (*string EQUAL ' ' OR    *string    EQUAL '\t') 
  404.       LOOP
  405.     string++;
  406.       ENDLOOP
  407.     return string;
  408.   END
  409.  
  410. FUNCTION char *do_end(string)
  411. char *string;
  412.   BEGIN
  413.     pullv();
  414.     indent -= step;
  415.     newline();
  416.     tabin();
  417.     nlflag = -1;
  418.     flush
  419.     if (strmatch(string,"ENDIF")) 
  420.       THEN
  421.     printf("ENDIF");
  422.     string+=5;
  423.       ENDIF
  424.     if (strmatch(string,"ENDLOOP")) 
  425.       THEN
  426.     printf("ENDLOOP");
  427.     string+=7;
  428.       ENDIF
  429.     if (strmatch(string,"END"))    
  430.       THEN
  431.     if (verb EQUAL LOOPTYPE) printf("ENDLOOP");
  432.     else if    (verb EQUAL IFTYPE) printf("ENDIF");
  433.     else printf("END");
  434.     string+=3;
  435.       ENDIF
  436.     if (*string    EQUAL '}') 
  437.       THEN
  438.     if (verb EQUAL LOOPTYPE) printf("ENDLOOP");
  439.     else if    (verb EQUAL IFTYPE) printf("ENDIF");
  440.     else printf("END");
  441.     string+=1;
  442.       ENDIF
  443.     indent -= step;
  444.     newline();
  445.     while (*string EQUAL ' ' OR    *string    EQUAL '\t') 
  446.       LOOP
  447.     string++;
  448.       ENDLOOP
  449.     return string;
  450.   END
  451.  
  452. FUNCTION char *do_case(string)
  453. char *string;
  454.   BEGIN
  455.     indent -= step;
  456.     newline();
  457.     tabin();
  458.     nlflag = -1;
  459.     flush
  460.     printf("CASE");
  461.     string += 4;
  462.     indent += step;
  463.     return string;
  464.   END
  465.  
  466. FUNCTION char *do_default(string)
  467. char *string;
  468.   BEGIN
  469.     indent -= step;
  470.     newline();
  471.     tabin();
  472.     nlflag = -1;
  473.     flush
  474.     printf("default:");
  475.     string+=8;
  476.     indent += step;
  477.     return string;
  478.   END
  479.  
  480. FUNCTION char *do_semi(string)
  481. char *string;
  482.   BEGIN
  483.     tabin();
  484.     nlflag = -1;
  485.     putchar(*string++);
  486.     while (*string EQUAL ' ' OR    *string    EQUAL '\t') 
  487.       LOOP
  488.     string++;
  489.       ENDLOOP
  490.     if (is_begin(string)) error("CB: BEGIN follows ;.");
  491.     else if (is_loop(string)) verb = LOOPTYPE;
  492.     else if (is_if(string)) verb = IFTYPE;
  493.     else verb =    0;
  494.     if (*string    NOTEQUAL '\n' AND NOT is_comment(string))
  495.       THEN
  496.     newline();
  497.       ENDIF
  498.     if (is_comment(string)) 
  499.       THEN
  500.     putchar(' ');
  501.     putchar(' ');
  502.     putchar('\t');
  503.       ENDIF
  504.     return string;
  505.   END
  506.  
  507. FUNCTION char *do_next_word(string)
  508. char *string;
  509.   BEGIN
  510.     tabin();
  511.     nlflag = -1;
  512.     while (TRUE)
  513.       LOOP
  514.     if (*string EQUAL '\n')    return string;
  515.     if (*string EQUAL ' ' OR *string EQUAL '\t') break;
  516.     if (*string EQUAL ';') return string;
  517.     if (*string EQUAL '}') return string;
  518.     if (*string EQUAL '{') return string;
  519.     if (*string EQUAL '\'')    return string;
  520.     if (*string EQUAL '"') return string;
  521.     if (*string EQUAL '(') return string;
  522.     if (is_comment(string))    return string;
  523.     putchar(*string++);
  524.       ENDLOOP
  525.     putchar(' ');
  526.     while (*string EQUAL ' ' OR    *string    EQUAL '\t') 
  527.       LOOP
  528.     string++;
  529.       ENDLOOP
  530.     return string;
  531.   END
  532.  
  533. FUNCTION tabin()
  534.   BEGIN
  535.     if (nlflag >= 0) 
  536.       THEN
  537.     while (nlflag+8    <= indent)
  538.       LOOP
  539.         putchar('\t');
  540.         nlflag+=8;
  541.       ENDLOOP
  542.     while (nlflag++    < indent) 
  543.       LOOP
  544.         putchar(' ');
  545.       ENDLOOP
  546.       ENDIF
  547.   END
  548.