home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 213_01 / cbprepr.c < prev    next >
Text File  |  1979-12-31  |  19KB  |  920 lines

  1. /* CBPREPR.C    VERS:- 01.00  DATE:- 09/26/86  TIME:- 09:36:05 PM */
  2. /*
  3. %CC1 $1.C -O -X -E6000
  4. %CLINK $1 DIO -S -E6000
  5. %DELETE $1.CRL 
  6. */
  7. /* 
  8. Description:
  9.  
  10. Filter to prepare C code for formatting:
  11.     add and delete white space to produce consistent text;
  12.     introduce newlines to produce one statment per line;
  13.     left justify all lines.
  14.  
  15. DIO redirection.
  16.  
  17. To indent according to control level, output from CBPREP
  18. must be filtered by CB, the formatting program written 
  19. by W.C. Colley and R. Hollinbeck and based on a unix utility.
  20.  
  21. CBPREP uses the routines getch() and comment() of CB.
  22.  
  23.  
  24. By J.A. Rupley, Tucson, Arizona
  25. Coded for BDS C compiler, version 1.50a
  26. */
  27.  
  28. #include "bdscio.h"
  29. #include "dio.h"
  30.  
  31. /*debug*/
  32. /*
  33. #define DEBUG
  34. */
  35.  
  36. int j;
  37. int cc;
  38. int peek;
  39. int sflag;
  40. int expr_flag;
  41. int lastchar;
  42. int c;
  43. int control_keys, else_key, do_key, case_key, default_key, flow_keys;
  44. int typedef_key, struct_key, union_key, c_keys, keys_total;
  45. int close_loc, paren_count, ctrl_count, last_count, last_key;
  46.  
  47. char string[200];
  48. char *keyword[30];
  49.  
  50. main(argc, argv)
  51. int argc;
  52. char *argv[];
  53. {
  54.     int k;
  55.     int count;
  56.  
  57.     dioinit(&argc, argv);
  58.  
  59.     /*exit if improper command line parameters*/
  60.     if (!_dioinflg)
  61.         use_mess();
  62.  
  63.     /*set up pointers to keyword strings*/
  64.     init_key();
  65.  
  66.     close_loc = paren_count = ctrl_count = last_count = 0;
  67.     last_key = keys_total + 1;
  68.     expr_flag = 0;
  69.     sflag = 0;
  70.     peek = -1;
  71.     j = 0;
  72.  
  73.     /*  Start of text manipulation.  */
  74.  
  75.     while (((c = getchr()) != EOF) && (c != CPMEOF))
  76.     {
  77.         /*at terminators reset control values*/
  78.         if (c == '}' || c == '{' || c == ':')
  79.             paren_count = ctrl_count = 0;
  80.  
  81.         switch (c)
  82.         {
  83.             /*no white space starting line*/
  84.             /*only single spaces elsewhere*/
  85.         case '\t' :
  86.             c = ' ';
  87.         case ' ' :
  88.             while (((peek = getchr()) == ' ') || (peek == '\t'))
  89.                 peek = -1;
  90.             if (j)
  91.                 string[j++] = c;
  92.             break;
  93.             /*at end of line, perform additional*/
  94.             /*formatting checks on entire line*/
  95.         case '\n' :
  96.             if (check_puts())
  97.                 printf("\n");
  98.             break;
  99.             /*block delimiters on separate line*/
  100.         case '}' :
  101.         case '{' :
  102.             if (j)
  103.                 if (check_puts())
  104.                     printf("\n");
  105.             string[j++] = c;
  106.             while (((peek = getchr()) == ' ') || (peek == '\t'))
  107.                 peek = -1;
  108.             if (peek != '\n')
  109.             {
  110.                 check_puts();
  111.                 printf("\n");
  112.             }
  113.             break;
  114.             /*space after, no space before ; and ,*/
  115.         case ';' :
  116.         case ',' :
  117.             if (j && (string[j - 1] == ' '))
  118.                 j--;
  119.             string[j++] = c;
  120.             if (((peek = getchr()) != ' ') && (peek != '\t'))
  121.                 string[j++] = ' ';
  122.             break;
  123.             /*remove some spaces adjacent to brackets/parentheses*/
  124.             /* -[- -]  -(- -) */
  125.             /*add space if identifier follows close parenthesis*/
  126.             /* )+ident  ]+ident*/
  127.         case '(' :
  128.         case '[' :
  129.             while (((peek = getchr()) == ' ') || (peek == '\t'))
  130.                 peek = -1;
  131.             if ((j > 1) && (string[j - 1] == ' ') &&
  132.                 isname_char(string[j - 2]))
  133.                 j--;
  134.             string[j++] = c;
  135.             break;
  136.         case ')' :
  137.         case ']' :
  138.             if (j && (string[j - 1] == ' '))
  139.                 j--;
  140.             string[j++] = c;
  141.             if (isname_char(peek = getchr()))
  142.                 string[j++] = ' ';
  143.             break;
  144.             /*pass over text*/
  145.             /*delete imbedded newlines*/
  146.         case '"' :
  147.         case '\'' :
  148.             string[j++] = c;
  149.             while ((cc = getchr()) != c)
  150.             {
  151.                 string[j++] = cc;
  152.                 if (cc == '\n')
  153.                     j--;
  154.                 if (cc == '\\')
  155.                     string[j++] = getchr();
  156.             }
  157.             string[j++] = cc;
  158.             break;
  159.         case '\\' :
  160.             string[j++] = c;
  161.             string[j++] = getchr();
  162.             break;
  163.             /*pass over #defines*/
  164.         case '#' :
  165.             if (j)
  166.                 if (check_puts())
  167.                     printf("\n");
  168.             string[j++] = c;
  169.             while ((cc = getchr()) != '\n')
  170.                 string[j++] = cc;
  171.             string[j++] = cc;
  172.             puts();
  173.             break;
  174.             /*pass over comments*/
  175.             /*add lead tab if comment follows text*/
  176.             /*if "/" not comment start, fall through to default*/
  177.             /*there is also comment check during operator output*/
  178.         case '/' :
  179.             if ((peek = getchr()) == '*')
  180.             {
  181.                 comment();
  182.                 break;
  183.             }
  184.         default :
  185.             if (isoperator(c))
  186.                 operators();
  187.             else
  188.                 string[j++] = c;
  189.             break;
  190.         }
  191.     }
  192.     dioflush();
  193.     exit();
  194. }
  195.  
  196.         /*page eject*/
  197. /*
  198. main routine to introduce and delete spaces from text with operators
  199. */
  200.  
  201. void operators()
  202. {
  203.     /*checks on special expression operators or operator pairs*/
  204.     /*remove lead and trail spaces as appropriate*/
  205.     peek = getchr();
  206.     if ((c == peek) && ((c == '+') || (c == '-')))
  207.     {
  208.         string[j++] = c;
  209.         string[j++] = peek;
  210.         peek = -1;
  211.         return;
  212.     }
  213.     while (string[j - 1] == ' ')
  214.         j--;
  215.     if ((c == '-') && (peek == '>'))
  216.     {
  217.         string[j++] = c;
  218.         string[j++] = peek;
  219.         peek = -1;
  220.         while (((c = getchr()) == ' ') || (c == '\t'))
  221.             ;
  222.         peek = c;
  223.         return;
  224.     }
  225.     if (c == '.')
  226.     {
  227.         string[j++] = c;
  228.         while (((c = getchr()) == ' ') || (c == '\t'))
  229.             ;
  230.         peek = c;
  231.         return;
  232.     }
  233.     while (((cc = getchr()) == ' ') || (cc == '\t'))
  234.         ;
  235.     peek = cc;
  236.  
  237.     /*test whether last character sequence is expression*/
  238.     /*for start of line (j=0), check_puts() tested end of prev line*/
  239.     if (j)
  240.         expr_flag = isexpression(string[j - 1]);
  241.     /*add lead space (trail space is as appropriate added below)*/
  242.     if (j && (string[j - 1] != '(') && (string[j - 1] != '['))
  243.         string[j++] = ' ';
  244.  
  245.     /*expr_flag TRUE is followed by a binary or assign operator*/
  246.     if (expr_flag)
  247.     {
  248.         while (isbinop(c))
  249.         {
  250.             peek = getchr();
  251.             if ((c == '/') && (peek == '*'))
  252.             {
  253.                 comment();        /*watch for comments*/
  254.                 return;
  255.             }
  256.             string[j++] = c;
  257.             while (((c = getchr()) == ' ') || (c == '\t'))
  258.                 ;
  259.             expr_flag = 0;
  260.         }
  261.         string[j++] = ' ';
  262.     }
  263.  
  264.     /*handling of unary operator sequences*/
  265.     /*for when expr_flag = 0 at entry to operators()*/
  266.     /*or on fall through from above block executed when expr_flag = 1*/
  267.     while (isoperator(c))
  268.     {
  269.         string[j++] = c;
  270.         while (((c = getchr()) == ' ') || (c == '\t'))
  271.             ;
  272.     }
  273.     peek = c;
  274.     return;
  275. }
  276.  
  277.         /*page eject*/
  278. /*
  279. return true if last character sequence is an expression;
  280. enter routine with string index j set at last character location + 1
  281. ie at the end of the string;
  282. */
  283.  
  284. /*last_count = string position of last keyword found*/
  285. /*last_key = identifier of last keyword*/
  286. /*paren_count = count of control exprsn parenthesis imbalance*/
  287. /*ctrl_count = string position after last parenthesis check*/
  288. /*close_loc = string position of close of parenthesis*/
  289. /*above externals reset as needed below or in check_puts()*/
  290.  
  291. int isexpression(testchar)
  292. char testchar;
  293. {
  294.     int k, l, count;
  295.     int pcount;
  296.     int temp;
  297.     char word[80];
  298.  
  299.     k = last_count;
  300.     last_key = keys_total + 1;
  301.     string[j] = '\0';
  302.  
  303.     /*can an open exprsn be closed*/
  304.     /*if so, set close_loc flag and exit if terminal ')'*/
  305.     if (paren_count)
  306.     {
  307.         count = end_paren(&string[ctrl_count], &paren_count);
  308.         if (!paren_count)
  309.         {
  310.             close_loc = ctrl_count += count;
  311.             if (!string[close_loc])
  312.                 return FALSE;
  313.         }
  314.         else
  315.             ctrl_count = strlen(string);
  316.     }
  317.  
  318.     /*check if previous word == expression*/
  319.     switch (testchar)
  320.     {
  321.     case '\'' :
  322.     case '"' :
  323.     case '_' :
  324.     case '+' :
  325.     case '-' :
  326.     case ']' :
  327.     case '.' :        /*for float constants*/
  328.         return TRUE;
  329.     default :
  330.         if (isdigit(testchar))
  331.             return TRUE;
  332.         if (!isalpha(testchar) && (testchar != ')'))
  333.             return FALSE;
  334.  
  335.         /*keywords are not expressions*/
  336.         /*and may change syntax for following operator*/
  337.  
  338.         /*locate last keyword in line*/
  339.         /*if a control keyword is met*/
  340.         /*check parenthesis balance for following expression*/
  341.         while (k < j)
  342.         {
  343.             count = next_alpha_word(&string[k], word);
  344.             k += count;
  345.             if (strlen(word) < 2 || strlen(word) > 8)
  346.                 continue;
  347.             for (l = 0; l <= keys_total; l++)
  348.                 if (!strcmp(word, keyword[l]))
  349.                 {
  350.                     last_count = k;
  351.                     last_key = l;
  352.                     if (l <= control_keys)
  353.                     {
  354.                         paren_count = 0;
  355.                         ctrl_count = last_count;
  356.                         count = end_paren(&string[ctrl_count], &paren_count);
  357.                         if (!paren_count)
  358.                             ctrl_count += count;
  359.                         else
  360.                             ctrl_count = strlen(string);
  361.                     }
  362.                     break;
  363.                 }
  364.         }
  365.  
  366.         /*set last_count and*/
  367.         /*return if no keyword*/
  368.         if (la