home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_07_07 / v7n7075a.txt < prev    next >
Text File  |  1989-05-29  |  8KB  |  303 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 command 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 == last_line_deleted) || */ ( 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 like 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 declarations in func_proto buffer */
  92.         {
  93.         if ( strcmp(yytext,"register") == 0 )  /* this is slow, needs 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 == ',' )
  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.             /* yerror("SORRY! cannot handle comma separated param decls");*/
  113.         /* yyerror does an exit so this never returns */
  114.         }
  115.         if ( c == '\n' )
  116.         continue;  /* heuristic, ignore during func prototype write out */
  117.         if ( skip_white && c == ' ' )
  118.         continue;  /* heuristic, ignore during func prototype write out */
  119.         if ( c == ' ' && send_comma )
  120.         continue;
  121.         if ( c == '{' )   /* oops , we have moved into the compound statement */
  122.         {
  123.         c = ')';
  124.         send_comma = FALSE;
  125.         proto_flag = FALSE; 
  126.         skip_white = TRUE;
  127.         }
  128.         else if ( c == ';' )
  129.         {
  130.         ed_delete();  /* sed script delete param decl lines */
  131.             /* may be the same line if mult decls on same line */
  132.         skip_white = TRUE;
  133.         send_comma = TRUE;
  134.         last_char = c;
  135.         save_root = TRUE;
  136.         for ( rp = 0 ; rp < ROOTSIZE ; rp++ )
  137.             root[rp] = 0;
  138.         rp = 0;
  139.         continue;
  140.         }
  141.         if ( send_comma && c != ')' )
  142.         {
  143.         func_proto[fp++] = ',';
  144.         func_proto[fp++] = c;
  145.         if ( save_root )
  146.             root[rp++] = c;
  147.         send_comma = FALSE;
  148.         }
  149.         else
  150.         {
  151.         func_proto[fp++] = c;
  152.         if ( save_root )
  153.             root[rp++] = c;
  154.         skip_white = FALSE;
  155.         }
  156.         if ( c == ')' )
  157.         {
  158.         func_proto[fp++] = '\0';
  159.         if ( efd )
  160.             {
  161.             ed_flush();        /* write out any existing delete lines */
  162.             fprintf(efd,"%di\\\n%s\n",lineno,func_proto);
  163.             }
  164.         if ( pfd )
  165.             {
  166.             char decl[DECL_SIZE];
  167.  
  168.             fp = 0;
  169.             while ( ( c = func_proto[fp]) != ' ' && c !='(' 
  170.                 && c != '\t' && c != '\n' && fp < DECL_SIZE-1 )
  171.             decl[fp++] = c;
  172.             decl[fp] = '\0';
  173.             if ( strcmp(decl,"static") == 0 || strcmp(decl,"local") == 0
  174.             || strcmp(decl,"main") == 0)
  175.             ;    /* do not put out func protos for static funcs or main */
  176.             else
  177.             {
  178.             if ( findsym(decl) ) /* NIL if not found */
  179.                 fprintf(pfd,"extern %s;\n",func_proto);
  180.             else
  181.                 fprintf(pfd,"extern int %s;\n",func_proto);
  182.             for ( k = 0 ; k < PROTO_SIZE ; k++ )
  183.                 func_proto[k] = 0;
  184.             }
  185.             }
  186.         }
  187.         last_char = c;
  188.         }
  189.     }
  190.     if ( i == BUFSIZ )
  191.         {
  192.         printf("Something went wrong! yytext[i] where i is %d\n",i);
  193.         exit(1);
  194.         }
  195.     }
  196.  
  197. /*--------------------------------------------------------------------------*/
  198. /* write_proto - called by grammar to write out start of function prototype */
  199. void write_proto(mode)
  200.     int mode;
  201.     {
  202.     char c;
  203.     char *p = pb;
  204.     int ch;
  205.     int save_chars = FALSE;
  206.     int first_one = TRUE;    /* new lines backed up over */
  207.  
  208.     if ( mode == NOARGS )
  209.     {
  210.     ch = lex_input();  /* May be a problem if whitespace, maybe skip white? */
  211.     lex_unput(ch);
  212.     if ( ch == ';' || ch == ',' )
  213.         return;      /* not a func prototype, it is an external func decl */
  214.     }
  215.  
  216.     proto_flag = TRUE;
  217.     fp = 0;        /* index into func_proto char buffer */
  218.  
  219.     /* search back thru saved text for  form feed, ';' or } */
  220.     /* actually want to search back past the func type decl which may */
  221.     /* actually be on a previous line. */
  222.     if ( --p < &b[0] )   /* test for wrap around */
  223.     p = &b[WINDOW_SIZE-1];
  224.     c = *p;
  225.     first_one = TRUE;
  226.     while (  c != '\0'  && c != '\014' && c != ';' && c != '}' )
  227.     {
  228.     if ( c == '\n' )   /* allow it to back up over new lines */
  229.         {
  230.         c = ' ';
  231.         if ( efd && first_one )  /* assumes decl on first preceding line */
  232.         {
  233.         lineno -= 1;
  234.         ed_delete();
  235.         lineno += 1;
  236.         first_one = FALSE;
  237.         }
  238.         }
  239.     if ( c == '(' )  /* we have backed over the original param list */
  240.         {
  241.         save_chars = TRUE;  /* so start saving chars */
  242.         if ( mode == NOARGS )
  243.         {
  244.         push('d'); push('i');push('o'); push('v');
  245.         }
  246.         }
  247.     if ( save_chars )
  248.         {
  249.         if ( c == '\t' )
  250.         push(' ');
  251.         else if ( c == '\n' )
  252.         ;    /* do nothing, ignore new lines */
  253.         else
  254.         push(c); 
  255.         }
  256.     if ( --p < &b[0] )
  257.         p = &b[WINDOW_SIZE-1];
  258.     c = *p;
  259.     }
  260.  
  261.     while ( ((ch = pop()) == ' ') || ch == '\t' || ch == '\n')
  262.     ;    /* skip over initial spaces and tabs and newlines */
  263.     push(ch);  /* restore the last character */
  264.     while ( (ch = pop() ) != EOF )
  265.     func_proto[fp++] = ch;
  266.     }
  267.  
  268. /*-------------------------------------------------------------------------------*/
  269.  
  270. void push(c)
  271.     char c;
  272.     {
  273.     if ( stkptr < STACK_SIZE )
  274.     cstack[stkptr++] = c;
  275.     else
  276.     {
  277.     yyerror("stack push overflow\n");
  278.     exit(1);
  279.     }
  280.     }
  281.  
  282. int pop()
  283.     {
  284.     if ( stkptr > 0 )
  285.     return( cstack[--stkptr] );
  286.     else
  287.     return EOF;
  288.     }
  289. /*------------------------------------------------------------------------*/
  290. /* preloadsyms - store the basic function decl types into the symbol table */
  291. preloadsyms()
  292.     {
  293.     storesym("int",0);
  294.     storesym("float",0);
  295.     storesym("double",0);
  296.     storesym("unsigned",0);
  297.     storesym("long",0);
  298.     storesym("struct",0);  /* not a basic type but it serves our purpose */
  299.     storesym("char",0);
  300.     storesym("void",0);
  301.     }
  302.  
  303.