home *** CD-ROM | disk | FTP | other *** search
/ cs.rhul.ac.uk / www.cs.rhul.ac.uk.zip / www.cs.rhul.ac.uk / pub / rdp / rdp_cs3460.tar / pr_c_aux.c < prev    next >
C/C++ Source or Header  |  1998-05-07  |  7KB  |  179 lines

  1. /*******************************************************************************
  2. *
  3. * RDP release 1.50 by Adrian Johnstone (A.Johnstone@rhbnc.ac.uk) 20 December 1997
  4. *
  5. * pr_c_aux.c - pretty printer semantic routines
  6. *
  7. * This file may be freely distributed. Please mail improvements to the author.
  8. *
  9. *******************************************************************************/
  10. #include <stdio.h>
  11. #include "scan.h"
  12. #include "textio.h"
  13. #include "pr_c_aux.h"
  14.  
  15. static int lexeme_count = 0; 
  16. static int eoln_count = 0; 
  17. static int comment_count = 0; 
  18. static int last_line = 1; 
  19. static FILE * outputfile; 
  20. unsigned long indent_size = 2l; 
  21. unsigned long comment_start = 30l; 
  22.  
  23.  
  24. static int space_table[K_TOP][K_TOP]= {
  25. /*                                               K
  26.                                C                 E
  27.                                L                 Y        O  P
  28.                       B        O           F     W        P  R  P
  29.                       L  B     S           I     O        E  E  U
  30.                       O  L  C  E           E     R        N  P  N
  31.                       C  O  H  _           L     D        _  R  C
  32.                       K  C  A  B  C        D  K  _     M  B  O  T
  33.                       _  K  R  R  O  D     _  E  I     O  R  C  U  S
  34.                       C  _  A  A  M  I     D  Y  N     N  A  E  A  T
  35.                       L  O  C  C  M  A  E  E  W  D  I  A  C  S  T  R
  36.                       O  P  T  K  E  D  O  L  O  E  T  D  K  S  I  I
  37.                       S  E  E  E  N  I  L  I  R  N  E  I  E  O  O  N
  38.                       E  N  R  T  T  C  N  M  D  T  M  C  T  R  N  G
  39.                       ---------------------------------------------- */
  40. /* BLOCK_CLOSE    */ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, 
  41. /* BLOCK_OPEN     */ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  42. /* CHARACTER      */ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  43. /* CLOSE_BRACKET  */ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, 
  44. /* COMMENT        */ {1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1}, 
  45. /* DIADIC         */ {1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1}, 
  46. /* EOLN           */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  47. /* FIELD_DELIM    */ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  48. /* KEYWORD        */ {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, 
  49. /* KEYWORD_INDENT */ {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0}, 
  50. /* ITEM           */ {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1}, 
  51. /* MONADIC        */ {1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1}, 
  52. /* OPEN_BRACKET   */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  53. /* PREPROCSSOR    */ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1}, 
  54. /* PUNCTUATION    */ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 
  55. /* STRING         */ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}
  56. }; 
  57.  
  58. void pretty_open(char * sourcefilename, char * outputfilename)
  59. {
  60.   if (strcmp(sourcefilename, outputfilename)== 0)
  61.     text_message(TEXT_FATAL, "temporary output filename is the same as the source filename"); 
  62.   
  63.   if (* outputfilename == '-')
  64.     outputfile = stdout; 
  65.   else if ((outputfile = fopen(outputfilename, "w"))== NULL)
  66.     text_message(TEXT_FATAL, "unable to open output file \'%s\'", outputfilename); 
  67. }
  68.  
  69. void pretty_close(char * sourcefilename, char * outputfilename)
  70. {
  71.   unsigned long useful_lexeme_count = lexeme_count - comment_count - eoln_count; 
  72.   char * backup_filename = text_force_filetype(sourcefilename, "bak"); 
  73.   
  74.   fclose(outputfile); 
  75.   
  76.   remove(backup_filename); 
  77.   
  78.   if (rename(sourcefilename, backup_filename)!= 0)
  79.     text_message(TEXT_FATAL, "unable to rename \'%s\' to \'%s\'\n", sourcefilename, backup_filename); 
  80.   
  81.   if (rename(outputfilename, sourcefilename)!= 0)
  82.     text_message(TEXT_FATAL, "unable to rename \'%s\' to \'%s\'\n", outputfilename, sourcefilename); 
  83.   
  84.   text_printf("%s,%lu,%lu,%.2lf\n", sourcefilename, 
  85.   last_line, 
  86.   useful_lexeme_count, 
  87.   (double) useful_lexeme_count /(double) last_line); 
  88. }
  89.  
  90. void pretty_print(char * lexeme, enum kinds kind, unsigned long column, unsigned long line)
  91. {
  92.   static int last_kind = K_EOLN; 
  93.   static unsigned long indentation = 0; 
  94.   static int temporary_indent = 0; 
  95.   static int printed = 0; 
  96.   
  97.   lexeme_count++;             /* bump lexeme counter for statistics */
  98.   last_line = line;           /* remember the highest line number seen */
  99.   
  100.   if (kind == K_BLOCK_CLOSE)
  101.     indentation--; 
  102.   else if (last_kind == K_BLOCK_OPEN)
  103.     indentation++; 
  104.   
  105.   if (last_kind == K_EOLN)    /* do indentation */
  106.   {
  107.     unsigned long indent_count, space_count; 
  108.     
  109.     if (temporary_indent && kind != K_BLOCK_OPEN) /* add an indent of we aren't opening a block */
  110.       indentation++; 
  111.     
  112.     for (indent_count = 0; indent_count < indentation; indent_count++)
  113.       if (!((column == 1)&&(kind == K_COMMENT))) /* Don't indent comments that start in column 1 */
  114.       if (indent_size == 0)
  115.     {
  116.       fprintf(outputfile, "\t");  /* indent using a tab */
  117.       printed += text_get_tab_width(); 
  118.     }
  119.     else
  120.       for (space_count = 0; space_count < indent_size; space_count++)
  121.       printed += fprintf(outputfile, " "); 
  122.     
  123.     if (temporary_indent && kind != K_BLOCK_OPEN) /* reset temporary indent */
  124.       indentation--; 
  125.     
  126.     temporary_indent = 0; 
  127.   }
  128.   
  129.   if (space_table[last_kind][kind]) /* insert space if necessary */
  130.     printed += fprintf(outputfile, " "); 
  131.   
  132.   /* Print the lexeme: some kinds need special actions */
  133.   switch (kind)
  134.   {
  135.     case K_EOLN: 
  136.     fprintf(outputfile, "\n"); 
  137.     eoln_count++; 
  138.     printed = 0; 
  139.     break; 
  140.     
  141.     case K_COMMENT: 
  142.     comment_count++; 
  143.     if (last_kind != K_EOLN)  /* comments that aren't first on a line move to middle */
  144.       do
  145.       printed += fprintf(outputfile, " "); 
  146.     while (printed <(int) comment_start); 
  147.       
  148.     printed += fprintf(outputfile, "/*%s*/", lexeme); 
  149.     break; 
  150.     
  151.     case K_STRING: 
  152.     printed += fprintf(outputfile, "\""); 
  153.     printed += text_print_C_string_file(outputfile, lexeme); 
  154.     printed += fprintf(outputfile, "\""); 
  155.     break; 
  156.     
  157.     case K_CHARACTER: 
  158.     printed += fprintf(outputfile, "\'"); 
  159.     printed += text_print_C_char_file(outputfile, lexeme); 
  160.     printed += fprintf(outputfile, "\'"); 
  161.     break; 
  162.     
  163.     case K_PREPROCESSOR: 
  164.     printed += fprintf(outputfile, "#%s", lexeme); 
  165.     break; 
  166.     
  167.     default: 
  168.     printed += fprintf(outputfile, "%s", lexeme); 
  169.     break; 
  170.   }
  171.   
  172.   if (kind == K_KEYWORD_INDENT) /* Set an indent for next line */
  173.     temporary_indent = 1; 
  174.   
  175.   last_kind = kind; 
  176. }
  177. /* End of pr_c_aux.c */
  178.  
  179.