home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 255.lha / Pretty_v3.0 / pretty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-13  |  9.9 KB  |  461 lines

  1. /*
  2.         ) Copyright Richard G. McCallister 1986, 1988
  3.         Reproduction for commercial purposes prohibited without
  4.         permission in writing from the publisher.
  5. */
  6. #include <stdio.h>
  7. #ifndef MSDOS
  8. #include <exec/io.h> 
  9. #include <exec/types.h>
  10. #endif
  11. #include <fcntl.h>
  12. #include <time.h>
  13.  
  14. #ifdef MSDOS
  15. #include <malloc.h>
  16. #define index(x,y) strchr(x,y)
  17. char *strchr();
  18. #else
  19. char    *index();
  20. FILE    *freopen();
  21. #endif
  22.  
  23. #define CHAR_LIN 256
  24. #define SZ_TITLE 80
  25.  
  26. #define TAB    9
  27.  
  28. long time();
  29. #include "rgm.h"
  30. /* History
  31.     Ver. 2.00 : Nov. 9, 1986     R. McCallister
  32.             First Amiga Version
  33.     Ver. 2.01 : Dec. 10, 1986    R. McCallister
  34.             Subtitle defaults to current time and date for each file.
  35.     Ver. 3.00 : July 12, 1988   R. McCallister
  36.             Height and Width options changed.
  37. */
  38.  
  39. int line_no = 1;
  40. char title[SZ_TITLE] = "",subttl[SZ_TITLE] = "";
  41. int pagelen = 58;
  42. int lines_left = 58;
  43. int    tab = 4;
  44. int    width = 80;
  45. BOOL numflag = TRUE;
  46. BOOL invflag = FALSE;
  47. int page_no = 1;
  48. #define HEADER_SIZE 5
  49.  
  50. page_eject()
  51. {
  52.     printf("\014\n\n%-*.*s%s%5d\n%s\n\n",
  53.         width - 10, width - 10, title, "Page ", page_no, subttl);
  54.     lines_left = pagelen;
  55.     page_no++;
  56. }
  57. /* page */
  58. char *skip(s,c)
  59. char *s;
  60. char c;
  61. {
  62.     for(;;)
  63.     {
  64.         if (*s == c)
  65.             s++;
  66.         else
  67.             return(s);
  68.     }
  69. }
  70.  
  71.  
  72. /* sub=String Matching Routines */
  73. char *match_n(m,s,n,partial)
  74. char *m;    /* Pattern to be matched */
  75. char *s;    /* String being searched for a match */
  76. int n;       /* Maximum number of characters to search */
  77. int partial; /* TRUE if partial matching (including 0 character length matching)
  78.                  will return a pointer to the character after the last one
  79.                  matched; FALSE otherwise */
  80. {
  81.     int i;
  82.     char *new_s;
  83.  
  84.     for (;;n--)
  85.     {
  86.         if ( n == 0  )
  87.             return (s);
  88.         if ( *s == *m)
  89.         {
  90.             if (*m == ' ' && *(s + 1) == ' ')
  91.             {
  92.                 m--;
  93.                 n++;
  94.             }
  95.             s++;
  96.             m++;
  97.         }
  98.         else
  99.             if (*m == '[')
  100.             {
  101.                 for (i = 1;;i++)
  102.                     if (m[i] == ']' || m[i] == NULL)
  103.                         break;
  104.                 s = match_n(++m,s,i - 1,TRUE);
  105.                 m += i;
  106.                 n -= i;
  107.             }
  108.             else
  109.                 if (partial == TRUE)
  110.                     return (s);
  111.         else
  112.             return (NULL);
  113.     }
  114. }
  115.  
  116. char *match(m,s)
  117. char *m;
  118. char *s;
  119. {
  120.     return (match_n(m,s,strlen(m),FALSE));
  121. }
  122.  
  123. #define CHAR_LIN 256
  124.  
  125.  
  126. char s[CHAR_LIN];
  127. char s2[sizeof(s)];
  128.  
  129. char *untab();
  130.  
  131. /* page */
  132.  
  133. char *untab(s,s2,tab)
  134. char *s;
  135. char *s2;
  136. int  tab;
  137. {
  138.     int i;
  139.     int count;
  140.  
  141.     for (i = 0;;s++)
  142.     {
  143.         if (*s == TAB)
  144.         {
  145.             count = tab - (i - tab * (i / tab)) - 1;
  146.             for (; count >= 0 ; count--)
  147.             {
  148.                 s2[i++] = ' ';
  149.             }
  150.         }
  151.         else
  152.             s2[i++] = *s;
  153.         if (*s == NULL)
  154.             break;
  155.     }
  156.     return(s2);
  157. }
  158. /* sub=Read Loop*/
  159. /*page*/
  160. read_loop(argc,argv)
  161. int        argc;
  162. char    **argv;
  163. {
  164.     char     s[CHAR_LIN];
  165.     char    *p;
  166.     int        i;
  167.     long    the_time;
  168.  
  169.     line_no = 1;
  170.     page_no = 1;
  171.  
  172.     for (i = 1; i < argc; ++i)
  173.     {
  174.         p = argv[i];
  175.         if ( *p == '/')
  176.         {
  177.             ++p;
  178.             pars_opt(p);
  179.         }
  180.     }
  181.     /* Default subtitle set to current time and date*/
  182.     time (&the_time);
  183.     strcpy (subttl, ctime(&the_time));
  184.      subttl [strlen(subttl) - 1] = NULL;
  185.  
  186.     page_eject();
  187.     for (;;)
  188.     {
  189.         gets(s);
  190.         if (feof(stdin))
  191.             break;
  192.         pars_line(s);
  193.     }
  194. }
  195. /* sub= Main Routine */
  196. /*page*/
  197. main(argc,argv)
  198. char *argv[];
  199. int argc;
  200. {
  201.     int i;
  202.     char *p;
  203.     FILE    *fp2;    /* Handle for redirected stdin */
  204.     char    *temp;
  205.     int     files;    /* Number of files processed */
  206.  
  207.     files = 0;
  208.     for (i = 1; i < argc; ++i)
  209.     {
  210.         p = argv[i];
  211.         if ( *p != '/')
  212.         {
  213.             files++;
  214.             fp2 = freopen (p,"r",stdin);
  215.             if (fp2 == NULL)
  216.             {
  217.                 fprintf(stderr,"Can't open %s \n",p);
  218.                 exit(0);
  219.             }
  220.  
  221.             /* Default title set to name of input file */
  222.             strcpy (title, p);
  223.  
  224.             read_loop(argc,argv);
  225.         }
  226.     }
  227.     if (files == 0)
  228.         read_loop(argc,argv);
  229.     exit(0);
  230. }
  231. /* sub = Help! */
  232. /* page */
  233. help()
  234. {
  235.     fprintf(stderr,"\n Version 3.00   July 12, 1988");
  236.     fprintf(stderr,"\n PRETTY takes commands from comments in a C program or in the command");
  237.     fprintf(stderr,"\nline, to control the formatting of a C program listing.");
  238.     fprintf(stderr,"\nSyntax: pretty [<IN] [>OUT] [/aOUT] [/lX] [/non] [/oOUT]");
  239.     fprintf(stderr,"\n\t[/hX] [/sSUB] [/TX] [/tTITLE] [/?]");
  240.     fprintf(stderr,"\n");
  241.     fprintf(stderr,"\n<IN\tSpecifies IN as the input file.");
  242.     fprintf(stderr,"\n>OUT\tSpecifies output file OUT.");
  243.     fprintf(stderr,"\nIN\tSame as <IN");
  244.     fprintf(stderr,"\n/aOUT\tAppends output to end of file OUT.");
  245.     fprintf(stderr,"\n/lX\tSets initial line number to X (a decimal number)");
  246.     fprintf(stderr,"\n/non\tTurns off the printing of line numbers.");
  247.     fprintf(stderr,"\n/oOUT\tSame effect as >OUT.");
  248.     fprintf(stderr,"\n/hX\tSpecifies maximum of X lines per page (includes titles)");
  249.     fprintf(stderr,"\n\tDefault is 66.");
  250.     fprintf(stderr,"\n/sSUB\tCauses \"SUB\" to be the current subtitle.");
  251.     fprintf(stderr,"\n\tDefault is the current time and date.");
  252.     fprintf(stderr,"\n/TX\tSets tabs every Xth column. Default is 4.");
  253.     fprintf(stderr,"\n/tTITLE Causes \"TITLE\" to be used as the title. Default is the");
  254.     fprintf(stderr,"\n\tname of the file being printed (unless standard input is used).");
  255.     fprintf(stderr,"\n/?\tPrints this help message.");
  256.     fprintf(stderr,"\n\t(Hit RETURN or ENTER for more information)");
  257.     gets(s); /* Wait for RETURN */
  258.     fprintf(stderr,"\nThe following commands may be included in C program comments.");
  259.     fprintf(stderr,"\nThey must be the first non-whitespace in the comment, and the");
  260.     fprintf(stderr,"\ncomment must be the first non-whitespace on the line.");
  261.     fprintf(stderr,"\n");
  262.     fprintf(stderr,"\npage\tCauses a form feed.");
  263.     fprintf(stderr,"\nsu=SUB\tCauses \"SUB\" to be the current subtitle.");
  264.     fprintf(stderr,"\nti=TITLE Causes \"TITLE\" to be used as the title.");
  265.     fprintf(stderr,"\n");
  266.     exit (0);
  267.  
  268. }
  269. /* sub=Option Parser */
  270. /* page */
  271. pars_opt(p)
  272. char *p;
  273. /* History
  274.    5/1/86 - buffer s2 made static; title and subttl changed to use
  275.       SZ_TITLE to adjust their sizes.
  276.    6/6/86 - Header commands (h-, h+) implemented. Nonum command added.
  277. */
  278. {
  279.     FILE    *fp2; /* File pointer for a, o  options */
  280.  
  281.     switch(*p)
  282.     {
  283.  
  284.     case 'a':
  285.         fp2 = freopen (++p,"a",stdout);
  286.         if (fp2 != NULL)
  287.         {
  288.             fprintf(stderr,"Can't open %s \n",p);
  289.             exit(0);
  290.         }
  291.         break;
  292.  
  293.     case 'h':
  294.         sscanf(p + 1,"%d",&pagelen);
  295.         pagelen -= HEADER_SIZE;
  296.         break;
  297.  
  298.     case 'i':
  299.         if (match ("inv[isible]-",p) != NULL)
  300.             invflag = FALSE;
  301.         else if (match ("inv[isible][+]",p) != NULL)
  302.             invflag = TRUE;
  303.         break;
  304.  
  305.     case 'l':
  306.         sscanf(p + 1,"%d",&line_no);
  307.         break;
  308.  
  309.     case 'n':
  310.         if ( (match ("non[umber]",p) != NULL))
  311.             numflag = FALSE;
  312.         else if ( (match ("nu[mber]",p) != NULL))
  313.             numflag = TRUE;
  314.         break;
  315.  
  316.     case 'o':
  317.         fp2 = freopen (++p,"w",stdout);
  318.         if (fp2 != NULL)
  319.         {
  320.             fprintf(stderr,"Can't open %s \n",p);
  321.             exit(0);
  322.         }
  323.         break;
  324.  
  325.     case 'p':
  326.         sscanf(p + 1,"%d",&page_no);
  327.         break;
  328.  
  329.     case 's':
  330.         strcpy(subttl,p + 1);
  331.         break;
  332.  
  333.     case 't':
  334.         strcpy(title,p + 1);
  335.         break;
  336.  
  337.     case 'T':
  338.         sscanf(p + 1,"%d",&tab);
  339.         break;
  340.  
  341.     case '?':
  342.     case '-':
  343.         help();
  344.         break;
  345.     case 'w':
  346.         sscanf(p + 1,"%d",&width);
  347.         if (width > (unsigned int) 255)
  348.             width = 255;
  349.         break;
  350.     default:
  351.         break;
  352.     }
  353.     return(0);
  354. }
  355. /* sub= Print Line */
  356. /* page */
  357. #define LN_SIZE 6
  358.  
  359. pr_line (s, numflag, recursion)
  360. char    *s;
  361. BOOL    numflag;
  362. BOOL    recursion;
  363. {
  364.     char s2[CHAR_LIN + LN_SIZE];
  365.  
  366.     if (numflag != FALSE && recursion == FALSE)
  367.         sprintf(s2,"%4d: ", line_no);
  368.     else if (numflag == TRUE && recursion == TRUE)
  369.         strcpy (s2,"      ");
  370.     else
  371.         *s2 = NULL;
  372.     untab (s,s2 + strlen(s2), tab);
  373.     printf("%.*s",width,s2);
  374.  
  375.     if ( --lines_left <= 0)
  376.         page_eject();
  377.     else
  378.         printf ("\n");
  379.  
  380.     if (strlen (s2) > width)
  381.         pr_line (s2 + width, numflag, TRUE);
  382. }
  383. /* sub=Input Line Parser */
  384. /* page */
  385.  
  386. pars_line(s)
  387. char *s;
  388. /* History
  389.    5/1/86 - buffer s2 made static; title and subttl changed to use
  390.       SZ_TITLE to adjust their sizes.
  391.    6/6/86 - Header commands (h-, h+) implemented. Nonum command added.
  392. */
  393. {
  394.     char  this_inv;
  395.     char *p;
  396.     char *temp;
  397.     char comment;
  398.  
  399.     comment = TRUE;
  400.     p = skip(s,' ');
  401.     p = match("/*",s);
  402.     if (p == NULL)
  403.     {
  404.         p = skip(s,' ');
  405.         comment = FALSE;
  406.     }
  407.     else
  408.         p = skip(p,' ');
  409.     this_inv = TRUE;
  410.  
  411.     switch(*p)
  412.     {
  413.  
  414.     case 'p':
  415.         if (match ("page[ ]*/",p) != NULL && comment == TRUE)
  416.         {
  417.             page_eject();
  418.         }
  419.         else
  420.             this_inv = FALSE;
  421.         break;
  422.  
  423.     case 's':
  424.         if (match ("su[btitle ]=",p) != NULL)
  425.         {
  426.             strcpy(subttl,index(p,'=') + 1);
  427.             temp = index(subttl,'*');
  428.             if (*temp == '*' && *(temp + 1) == '/')
  429.                 *temp = NULL;
  430.         }
  431.         else
  432.             this_inv = FALSE;
  433.         break;
  434.  
  435.     case 't':
  436.         if (match ("ti[tle ]=",p) != NULL)
  437.         {
  438.             strcpy(title,index(p,'=') + 1);
  439.             temp = index(title,'*');
  440.             if (*temp == '*' && *(temp + 1) == '/')
  441.                 *temp = NULL;
  442.         }
  443.         else
  444.             this_inv = FALSE;
  445.         break;
  446.  
  447.     default:
  448.         this_inv = FALSE;
  449.         break;
  450.     }
  451.     if (invflag == TRUE && this_inv == TRUE)
  452.     {
  453.         s = "";
  454.     }
  455.     pr_line (s, numflag, FALSE);
  456.  
  457.     line_no++;
  458.  
  459.     return(0);
  460. }
  461.