home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 296_01 / subs.c < prev    next >
C/C++ Source or Header  |  1989-10-03  |  9KB  |  301 lines

  1. /* subs.c - misc functions used by the c to c++ program - cdh */
  2.  
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include "ctocxx.h"
  7.  
  8. #define PROTO_SIZE 2000
  9. #define WINDOW_SIZE 2000
  10. #define STACK_SIZE 200
  11. #define ROOTSIZE 100
  12. #define DECL_SIZE 200
  13.  
  14. extern char *yytext;
  15. extern FILE *pfd;
  16. extern FILE *efd;
  17. int proto_flag = FALSE;
  18. static char b[WINDOW_SIZE];
  19. static char *pb = b;
  20. static char cstack[STACK_SIZE]={0};
  21. static int stkptr = 0;
  22. static char func_proto[PROTO_SIZE];
  23. static int fp = 0;
  24. static int i = 0;
  25. int lineno = 0;
  26. void push();
  27. void ed_flush();
  28. int pop();
  29. SYMPTR findsym();
  30. extern struct symbol *storesym();
  31. /*---------------------------------------------------------------------*/
  32. static int last_line_deleted = 0;
  33. static int start = 0;
  34. static int stop = 0;
  35.  
  36. /* ed_delete - add cmd to delete the current line number to sed script */
  37. /* This function may be called with the same line to be deleted */
  38. /* in which case it is ignored */
  39. void ed_delete()
  40.     {
  41.     if ( !efd || ( lineno == stop) )
  42.         return;
  43.  
  44.     if ( start == 0 )
  45.         {
  46.         start = stop = lineno;
  47.         return;
  48.         }
  49.  
  50.     if ( lineno == stop+1 )
  51.         {
  52.         stop += 1;
  53.         return;
  54.         }
  55.  
  56.     ed_flush();   /* may get here with lineno way beyond start,stop */
  57.     start = stop = lineno; 
  58.     }
  59.  
  60. void ed_flush()
  61.     {
  62.     if ( !efd || start == 0 )
  63.         return;
  64.     if ( start == stop )
  65.         fprintf(efd,"%dd\n",stop);
  66.     else
  67.         fprintf(efd,"%d,%dd\n",start,stop);
  68. /*    last_line_deleted = stop; */
  69.     start = stop = 0;
  70.     }
  71.  
  72. /*---------------------------------------------------------------------*/
  73. /* stuff - this is called by the lexer to remember a lot of prior text */
  74. void stuff()
  75.     {
  76.     char c;
  77.     static int send_comma = FALSE;
  78.     static int skip_white = TRUE;
  79.     static char last_char = 0;
  80.     static int save_root = TRUE; /* the root part of a parameter decl */
  81.     static char root[ROOTSIZE];  /* for comma lists -  struct foo *p,a,*t; */
  82.     static int rp;      /* index into root char array e.g. 'struct foo '*/
  83.     int k;
  84.  
  85.     i = 0;
  86.     while ( (c = yytext[i++]) != '\0'  && i < BUFSIZ )
  87.         {
  88.         if ( pb >= &b[WINDOW_SIZE-1] )
  89.             pb = b;
  90.         *pb++ = c;
  91.         if ( proto_flag  )  /* save the param decls in func_proto buffer */
  92.             {
  93.             if ( strcmp(yytext,"register") == 0 )  /* slow, fix up later */
  94.                 continue;
  95.             if ( c == '\t' )   /* change all tabs to spaces */
  96.                 c = ' ';
  97.             if ( c == ' ' && (last_char == ' ' || last_char == '(') )
  98.                 continue;
  99.             if ( c == ',' ) /* handling comma lists was added almost last */
  100.                 {
  101.                 func_proto[fp++] = c;
  102.                 if ( save_root )
  103.                     {
  104.                     save_root = FALSE;
  105.                     while ( root[rp] != ' ' && rp != 0 )
  106.                         rp--;
  107.                     root[rp+1] = '\0';
  108.                     }
  109.                 strcat(func_proto,root);
  110.                 fp += strlen(root);
  111.                 continue;
  112.                 }
  113.             if ( c == '\n' )
  114.                 continue;  /* heuristic, ignore during func proto output */
  115.             if ( skip_white && c == ' ' )
  116.                 continue;  /* heuristic, ignore during func proto output */
  117.             if ( c == ' ' && send_comma )
  118.                 continue;
  119.             if ( c == '{' )   /* we have moved into the compound statement */
  120.                 {
  121.                 c = ')';
  122.                 send_comma = FALSE;
  123.                 proto_flag = FALSE; 
  124.                 skip_white = TRUE;
  125.                 }
  126.             else if ( c == ';' )
  127.                 {
  128.                 ed_delete();  /* sed script delete param decl lines */
  129.                     /* may be the same line if mult decls on same line */
  130.                 skip_white = TRUE;
  131.                 send_comma = TRUE;
  132.                 last_char = c;
  133.                 save_root = TRUE;
  134.                 for ( rp = 0 ; rp < ROOTSIZE ; rp++ )
  135.                     root[rp] = 0;
  136.                 rp = 0;
  137.                 continue;
  138.                 }
  139.             if ( send_comma && c != ')' )
  140.                 {
  141.                 func_proto[fp++] = ',';
  142.                 func_proto[fp++] = c;
  143.                 if ( save_root )
  144.                     root[rp++] = c;
  145.                 send_comma = FALSE;
  146.                 }
  147.             else
  148.                 {
  149.                 func_proto[fp++] = c;
  150.                 if ( save_root )
  151.                     root[rp++] = c;
  152.                 skip_white = FALSE;
  153.                 }
  154.             if ( c == ')' )
  155.                 {
  156.                 func_proto[fp++] = '\0';
  157.                 if ( efd )
  158.                     {
  159.                     ed_flush(); /* write out any existing delete lines */
  160.                     fprintf(efd,"%di\\\n%s\n",lineno,func_proto);
  161.                     }
  162.                 if ( pfd )
  163.                     {
  164.                     char decl[DECL_SIZE];
  165.  
  166.                     fp = 0;
  167.                     while ( ( c = func_proto[fp]) != ' ' && c !='(' 
  168.                           && c != '\t' && c != '\n' && fp < DECL_SIZE-1 )
  169.                         decl[fp++] = c;
  170.                     decl[fp] = '\0';
  171.                     if ( strcmp(decl,"static") == 0
  172.                         || strcmp(decl,"main") == 0)
  173.                         ;  /* no func protos for static funcs or main */
  174.                     else
  175.                         {
  176.                         if ( findsym(decl) ) /* NIL if not found */
  177.                             fprintf(pfd,"extern %s;\n",func_proto);
  178.                         else
  179.                             fprintf(pfd,"extern int %s;\n",func_proto);
  180.                         for ( k = 0 ; k < PROTO_SIZE ; k++ )
  181.                             func_proto[k] = 0;
  182.                         }
  183.                     }
  184.                 }
  185.             last_char = c;
  186.             }
  187.         }      /* end of while loop */
  188.     if ( i == BUFSIZ )
  189.         {
  190.         printf("Something went wrong! yytext[i] where i is %d\n",i);
  191.         exit(1);
  192.         }
  193.     }
  194.  
  195. /*----------------------------------------------------------------------*/
  196. /* write_proto - called by grammar to write out start of function proto */
  197. void write_proto(mode)
  198.     int mode;
  199.     {
  200.     char c;
  201.     char *p = pb;
  202.     int ch;
  203.     int save_chars = FALSE;
  204.     int first_one = TRUE;    /* new lines backed up over */
  205.  
  206.     if ( mode == NOARGS )
  207.         {
  208.         ch = lex_input();  /* problem if whitespace? Maybe skip white? */
  209.         lex_unput(ch);
  210.         if ( ch == ';' || ch == ',' )
  211.             return;      /* not a func prototype, an extern func decl */
  212.         }
  213.  
  214.     proto_flag = TRUE;
  215.     fp = 0;             /* index into func_proto char buffer */
  216.  
  217.     /* search back thru saved text for  form feed, ';' or } */
  218.     /* actually want to search back past the func type decl */
  219.     /* which may actually be on a previous line. */
  220.     if ( --p < &b[0] )   /* test for wrap around */
  221.         p = &b[WINDOW_SIZE-1];
  222.     c = *p;
  223.     first_one = TRUE;
  224.     while (  c != '\0'  && c != '\014' && c != ';' && c != '}' )
  225.         {
  226.         if ( c == '\n' )   /* allow it to back up over new lines */
  227.             {
  228.             c = ' ';
  229.             if ( efd && first_one ) /* assumes decl on 1st preceding line */
  230.                 {
  231.                 lineno -= 1;
  232.                 ed_delete();
  233.                 lineno += 1;
  234.                 first_one = FALSE;
  235.                 }
  236.             }
  237.         if ( c == '(' )  /* we have backed over the original param list */
  238.             {
  239.             save_chars = TRUE;  /* so start saving chars */
  240.             if ( mode == NOARGS )
  241.                 {
  242.                 push('d'); push('i');push('o'); push('v');
  243.                 }
  244.             }
  245.         if ( save_chars )
  246.             {
  247.             if ( c == '\t' )
  248.                 push(' ');
  249.             else if ( c == '\n' )
  250.                 ;       /* do nothing, ignore new lines */
  251.             else
  252.                 push(c); 
  253.             }
  254.         if ( --p < &b[0] )
  255.             p = &b[WINDOW_SIZE-1];
  256.         c = *p;
  257.         }
  258.  
  259.     while ( ((ch = pop()) == ' ') || ch == '\t' || ch == '\n')
  260.         ;       /* skip over initial spaces and tabs and newlines */
  261.     push(ch);  /* restore the last character */
  262.     while ( (ch = pop() ) != EOF )
  263.         func_proto[fp++] = ch;
  264.     }
  265.  
  266. /*---------------------------------------------------------------------*/
  267.  
  268. void push(c)
  269.     char c;
  270.     {
  271.     if ( stkptr < STACK_SIZE )
  272.         cstack[stkptr++] = c;
  273.     else
  274.         {
  275.         yyerror("stack push overflow\n");
  276.         exit(1);
  277.         }
  278.     }
  279.  
  280. int pop()
  281.     {
  282.     if ( stkptr > 0 )
  283.         return( cstack[--stkptr] );
  284.     else
  285.         return EOF;
  286.     }
  287. /*------------------------------------------------------------------------*/
  288. /* preloadsyms - store the basic function decl types into the symbol table */
  289. preloadsyms()
  290.     {
  291.     storesym("int",0);
  292.     storesym("float",0);
  293.     storesym("double",0);
  294.     storesym("unsigned",0);
  295.     storesym("long",0);
  296.     storesym("struct",0);  /* not a basic type but it serves our purpose */
  297.     storesym("char",0);
  298.     storesym("void",0);
  299.     }
  300.  
  301.