home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / PROTC12A.ZIP / PROTOC.C < prev    next >
Text File  |  1990-07-28  |  19KB  |  600 lines

  1. /*
  2. **  PROTOC.C      by:  Mitch Fisher
  3. **
  4. **  Options available are:
  5. **          O         output to screen
  6. **
  7. **  Update 07/24/90
  8. **      Update included correcting problem with comment on same line as a
  9. **      function.
  10. **      Error occurred if () were in a single line comment - corrected.
  11. **      Program is BOUND so it can run under OS/2 and DOS
  12. **
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <process.h>
  19.  
  20. #include "protoc.h"
  21.  
  22. #define  min(x,y)    (x<y)?x:y
  23.  
  24. /*
  25.    Prototypes for Character functions in CHRFUNCS.OBJ
  26. */
  27.  
  28. int delchr(char *string, int loc);
  29. int inschr(char *string, int size, char chr, int loc);
  30. int poschr(char *string, char chr, int f1);
  31. int utcharsb(int ctrl, char *string, char ch);
  32. int cjust(char ch, char *s);
  33. int rjsut(char ch, char *s);
  34. int ljust(char ch, char *s);
  35. int snlbntb(char ch, int *nlb, int *ntb, char *s);
  36.  
  37.  
  38. /*  Global variables */
  39.  
  40. char                    comment = 0,             /*  Comment level */
  41.                         dquote = 0,              /*  Double Quote mode */
  42.                         squote = 0,              /*  Single Quote mode */
  43.                         funct = 0,               /*  function mode */
  44.                         hpath[64];               /*  Header Path */
  45.  
  46. unsigned                functline = 0,
  47.                         line = 0,
  48.                         level = 0;               /*  The level of Begin's and End's */
  49.  
  50.  
  51.  
  52.  
  53. /*
  54. **  Ensure_extension will make sure that 'string' has an appending 'ext'
  55. **  value if there only if there isn't one.
  56. */
  57.  
  58. void ensure_extension(string, ext)
  59. char                    *string,
  60.                         *ext;
  61.    {
  62.       char              *last_slash,
  63.                         *last_dot;
  64.  
  65.  
  66.  
  67.       last_slash = strrchr(string, '\\');
  68.       last_dot = strrchr(string, '.');
  69.  
  70.       if ( (last_dot < last_slash) || ( !last_dot ) )
  71.             strcat(string, ext);
  72.  
  73.    }
  74.  
  75. /*
  76. ** This procedure will get the nesting of BEGIN's and END's.  It will take
  77. ** account if the { or } is in a comment and it will also handle nested
  78. ** comments.
  79. */
  80.  
  81. void nesting(string)                         /*  Find the nesting levels */
  82. char               *string;                   /*  Pointer to the line of text from the file */
  83.  
  84.    {
  85.       do
  86.          {
  87.             if ( !comment )
  88.               {
  89.                  if ( ( *string == 0x22) && ( dquote == 1 ) )
  90.                        dquote = 0;
  91.                  else if ( *string == 0x22 )
  92.                        dquote = 1;
  93.  
  94.                  if ( !dquote )
  95.                     {
  96.                        if ( ( *string == 0x27) && ( squote == 1 ) )
  97.                              squote = 0;
  98.                        else if ( *string == 0x27 )
  99.                              squote = 1;
  100.                     }
  101.               }
  102.  
  103.             if ( (*string == '/') && (*(string + 1) == '*') ) /*  Is it a begin comment ? */
  104.                comment++;                                           /*  If so increment the comment variable */
  105.             if ( (*string == '*') && (*(string + 1) == '/') ) /*  Is it an end comment ? */
  106.                comment--;                                           /*  If so, decrement the comment variable */
  107.  
  108.             if ( (!comment) && (!squote) && (!dquote) ) /*  If the comment counter is 0 and quote modes are 0 */
  109.                {                                 /*  Check for {'s and }'s */
  110.                   if ( *string == '{' )       /*  Is it a { ? */
  111.                      level++;                    /*  If so, add one to the value */
  112.                   if ( *string == '}' )       /*  Is it an } ? */
  113.                      level--;                    /*  If so, decrement the value */
  114.                }
  115.          }  while ( *string++ );              /*  Do..While there is still a string */
  116.    }
  117.  
  118.  
  119.  
  120.  
  121. int iscomment(string)
  122. char                    *string;
  123.    {
  124.       int               first,
  125.                         secnd,
  126.                         comma,
  127.                         semi,
  128.                         paren;
  129.  
  130.       first = poschr(string, '/', 0);
  131.       secnd = poschr(string, '*', 0);
  132.       semi = poschr(string, ';', 0);
  133.       comma = poschr(string, '.', 0);
  134.       paren = poschr(string, '(', 0);
  135.  
  136.       if ( (!first) || (!secnd) )
  137.             return(0);
  138.  
  139.       if ( first == (secnd - 1) )
  140.          {
  141.             if ( (paren) && ( paren > first ) )
  142.                   return(1);
  143.  
  144.             if ( (paren) && ( paren < first ) )
  145.                   return(0);
  146.  
  147.             if ( (semi) && ( semi > first ) )
  148.                   return(1);
  149.  
  150.             if ( (comma) && ( comma > first ) )
  151.                   return(1);
  152.  
  153.             if ( (semi) && ( semi < first ) )
  154.                   return(0);
  155.  
  156.             if ( (comma) && ( comma < first ) )
  157.                   return(0);
  158.  
  159.             return(1);
  160.          }
  161.       return(0);
  162.    }
  163.  
  164.  
  165.  
  166. int isfunct(string)
  167. char                    *string;
  168.    {
  169.       int               last;
  170.       char              temp[256];
  171.  
  172.       if ( (comment) || (squote) || (dquote) )
  173.             return(0);
  174.  
  175.       if ( iscomment(string) )
  176.             return(0);
  177.  
  178.       strcpy(temp, string);
  179.       utcharsb(3, temp, ' ');
  180.       if ( temp[0] == '#' )
  181.             return(0);
  182.  
  183.       last = poschr(temp, ',', 1);
  184.  
  185.       if ( last )
  186.          {
  187.             temp[last - 1] = 0;
  188.  
  189.             if ( temp[strlen(temp) - 1] == ')' )
  190.                   return(0);
  191.          }
  192.  
  193.       if ( !poschr(string, ';', 0) && ( level == 0 ) )
  194.          {
  195.             if ( poschr(string, '(', 0 ) )
  196.                {
  197.                   if ( poschr(string, ')', 0 ) )
  198.                         return(1);
  199.                }
  200.          }
  201.       return(0);
  202.    }
  203.  
  204.  
  205.  
  206. void strip_array(string)
  207. char                    *string;
  208.    {
  209.       char              *ptr;
  210.  
  211.       int               first;
  212.  
  213.       ptr = string;
  214.       if ( !poschr(ptr, '[', 0 ) )
  215.             return;
  216.  
  217.       while(*ptr)
  218.          {
  219.             first = poschr(ptr, '[', 0);
  220.             if ( !first )
  221.                   break;
  222.  
  223.             ptr += first;
  224.             while( *ptr != ']' )
  225.                   delchr(ptr, 1);
  226.          }
  227.    }
  228.  
  229.  
  230. void strip_tab(string)
  231. char                    *string;
  232.    {
  233.       while ( *string )
  234.          {
  235.             if ( *string == '\t' )
  236.                   *string = ' ';
  237.  
  238.             *string++;
  239.          }
  240.    }
  241.  
  242.  
  243.  
  244. /*
  245. **  This procedure will print the function name if the line scanned has
  246. ** two (2) parenthesis '()' and no semicolon ';'
  247. */
  248.  
  249. void function(string, fp, direction)
  250. char                    *string;
  251. FILE                    *fp,
  252.                         *direction;
  253.    {
  254.       int               first;
  255.  
  256.       char              temp[256],
  257.                         original[256],
  258.                         proto[256],
  259.                         type[256],
  260.                         *front,
  261.                         hold,
  262.                         *ptr;
  263.  
  264.       int               oldlevel = level,
  265.                         count;
  266.  
  267.  
  268.       /*
  269.       **  If currently in a comment, quote, double quote of function,
  270.       **  return since a callable function may not be within any of the
  271.       **  above.
  272.       */
  273.  
  274.       if ( (comment) || (squote) || (dquote) || (level) )
  275.             return;
  276.  
  277.       if ( !isfunct(string) )
  278.             return;
  279.  
  280.       count = 0;
  281.       strcpy(temp, string);
  282.       strip_tab(temp);
  283.  
  284.       do
  285.          {
  286.             nesting(temp);
  287.  
  288.             if (level != oldlevel)
  289.                   break;
  290.  
  291.             utcharsb(3, temp, '\n');
  292.             if ( temp[0] == 0 )
  293.                {
  294.                   count++;
  295.                   continue;
  296.                }
  297.  
  298.             if ( funct )
  299.                {
  300.                   utcharsb(3, temp, ' ');
  301.  
  302.                   if ( iscomment(temp) )
  303.                      {
  304.                         count++;
  305.                         continue;
  306.                      }
  307.  
  308.                   first = poschr(temp, ';', 1);       /*  end in ';' */
  309.                   if ( first )
  310.                         temp[first - 1] = 0;
  311.                   else
  312.                      {
  313.                         first = poschr(temp, ',', 1); /*  end in ',' */
  314.                         temp[first - 1] = 0;
  315.                      }
  316.                   first = poschr(temp, ' ', 1);
  317.                   ptr = &temp[first];
  318.                   *ptr--;
  319.  
  320.                   while( isspace(*ptr) )
  321.                         *ptr--;
  322.  
  323.                   ptr += 2;
  324.  
  325.                   utcharsb(3, ptr, ' ');
  326.                   front = temp;
  327.                   if ( poschr(temp, ' ', 0) )
  328.                      {
  329.                         *ptr--;
  330.                         hold = *ptr;
  331.                         *ptr = 0;
  332.                         strcpy(type, front);
  333.                         strcat(type, " ");
  334.                         *ptr = hold;
  335.                         *ptr++;
  336.                      }
  337.                   else
  338.                      {
  339.                         *ptr--;
  340.                         strcat(type, temp);
  341.                         strcpy(temp, type);
  342.                         *ptr++;
  343.                      }
  344.                   utcharsb(3, temp, '\n');
  345.                   utcharsb(3, temp, ',');
  346.                   strcat(proto, temp);
  347.                   strcat(proto, ", ");
  348.                }
  349.  
  350.             if ( (isfunct(temp)) && (!funct) && ( level == 0 ) )
  351.                {
  352.                   first = poschr(temp, '(', 0);
  353.                   strcpy(original, temp);
  354.                   temp[first] = '\0';
  355.                   strcpy(proto, temp);
  356.                   funct = 1;
  357.                }
  358.             count++;
  359.  
  360.          } while ( fgets(temp, 132, fp) );
  361.  
  362.       if ( count == 1 )
  363.          {
  364.             strcpy(proto, original);
  365.             if ( proto[strlen(proto) - 2] == '(' )
  366.                {
  367.                   proto[strlen(proto) - 1] = 0;
  368.                   strcat(proto, "void)");
  369.                }
  370.          }
  371.       else
  372.          {
  373.             utcharsb(3, proto, ' ');
  374.             utcharsb(3, proto, ',');
  375.             strcat(proto, ")");
  376.          }
  377.  
  378.       /*
  379.       **  Delete any contents in an array
  380.       */
  381.       strip_array(proto);
  382.       fprintf(direction, "%s;\n", proto);
  383.       funct = 0;
  384.    }
  385.  
  386.  
  387.  
  388. /*
  389. **  The main program.  The input line may contain additional arguments
  390. **  that being O and/or F.
  391. */
  392.  
  393. void main(int argc, char *argv[])
  394.    {
  395.       char              string[256],             /*  Input string from the file */
  396.                         header[14],              /*  Header file name */
  397.                         *pram,                   /*  Parameter */
  398.                         *period,                 /*  The address of the . in the filename */
  399.                         pname[14],
  400.                         argstr[256];             /*  The name of the file to print */
  401.  
  402.       int               item = 1,                /*  Location within **ARGV */
  403.                         first,
  404.                         files = 0,
  405.                         OutOnly = 0,             /*  Output to screen only flag */
  406.                         options = 0,             /*  Number of options found */
  407.                         errtype = 0;             /*  Type of error that occured */
  408.  
  409.       FILE              *stream,                 /*  The file stream */
  410.                         *project,                /*  The project stream */
  411.                         *direction;              /*  The file direction stream */
  412.  
  413.  
  414.  
  415.       puts("\n\n\nPROTOC Prototype Generator Version 1.2 (OS/2 Dual Mode)\n(C) Mitchell Fisher, 1990\n\n");
  416.  
  417.       if ( argc == 1 )                           /*  If only one parameter error = 1 */
  418.             errtype = 1;                         /*  Set errortype */
  419.       else                                       /*  Otherwise... */
  420.             if ( argv[1][0] == '-' )             /*  Check to see if there is an option specified */
  421.                {
  422.                   pram = strupr(argv[1]);        /*  Uppercase the first parameter */
  423.                   item++;
  424.  
  425.                   if ( strlen(pram) > 3 )        /*  If option length > 3, error! */
  426.                         errtype = 2;             /*  Set errtype */
  427.  
  428.                   if ( strchr(pram, 'O') )       /*  If 'O' option */
  429.                      {
  430.                         OutOnly = 1;             /*  Set OutOnly flag */
  431.                         options++;               /*  Add one to options found */
  432.                      }
  433.  
  434.                   if ( (options == 1) && (strlen(pram) == 3) )  /*  If only one option found but pram has 2 parameters in it */
  435.                         errtype = 2;                            /*  Error! */
  436.                }
  437.  
  438.       if ( errtype )                             /*  If an error has occured */
  439.          {
  440.             switch ( errtype )
  441.                {
  442.                         case 1:  puts("Usage: PROTOC [-O] Project Name[.PRJ]");
  443.                                     puts("Where O = output to screen only.  Otherwise, output");
  444.                                     puts("is sent to .H file with project name.");
  445.                            break;
  446.  
  447.                         case 2:  puts("Error:  Illegal Parameter.");
  448.                            break;
  449.  
  450.                         case 3:  puts("Error:  Too many Parameters.");
  451.                }
  452.             exit(1);                              /*  Exit the program */
  453.          }
  454.  
  455.       strcpy(pname, strupr(argv[item]));
  456.  
  457.       if ( !poschr(pname, '.', 0 ) )
  458.          {
  459.             if ( strlen(pname) < 9 )
  460.                   strcat(pname, ".PRJ");
  461.          }
  462.  
  463.       if ( !OutOnly )
  464.          {
  465.  
  466.             /*
  467.             **  strip any extension
  468.             */
  469.  
  470.             strcpy(argstr, pname);
  471.             options = poschr(argstr, '.', 0);
  472.             if ( !options )
  473.                   options = strlen(argstr) + 1;
  474.  
  475.             argstr[options - 1] = '\0';
  476.             strcpy(header, argstr);
  477.             strcpy(header, strupr(header));
  478.             strcat(header, ".H");
  479.          }
  480.  
  481.       fprintf(stderr, "Creating Header file %s from project file %s\n", header, pname);
  482.       project = fopen(pname, "r");    /*  Open the project file */
  483.       if ( !project )
  484.          {
  485.             fprintf(stderr, "File '%s' not found\n", pname);
  486.             exit(1);
  487.          }
  488.  
  489.       if ( !OutOnly )
  490.             direction = fopen(header, "w");  /*  If not to screen set direction file */
  491.       else
  492.             direction = stderr;              /*  Otherwise to console */
  493.  
  494.       fprintf(direction, "%s\n", "/*");
  495.       fprintf(direction, "%s %s\n", "**  Function Prototypes for ", pname);
  496.       fprintf(direction, "%s\n", "*/\n");
  497.  
  498.       for(;;)                                    /*  While there are still files in **ARGV */
  499.          {
  500.             if ( (fgets(argstr, 132, project)) == NULL ) /*  Read from the project file into argstr */
  501.                   break;                                  /*  End the while if an EOF detected */
  502.  
  503.             /*
  504.             **  Delete any comilation conditions
  505.             */
  506.             first = poschr(argstr, '(', 0);
  507.             if ( first )
  508.                   argstr[first - 1] = 0;
  509.  
  510.             utcharsb(3, argstr, '\n');
  511.             utcharsb(3, argstr, ' ');
  512.  
  513.             strcpy(argstr, strupr(argstr));      /*  Convert filename into uppercase */
  514.  
  515.             /*
  516.             **  Check filename to check to see if it an Object (.OBJ)
  517.             **  or a library file (.LIB).  If so, bypass the file
  518.             */
  519.             period = strchr(argstr, '.');
  520.             if ( !strncmp(period, ".OBJ", 4) )
  521.                   continue;
  522.  
  523.             if ( !strncmp(period, ".LIB", 4) )
  524.                   continue;
  525.  
  526.             if ( (stream = fopen(argstr, "r")) == NULL)               /*  Open the file in ARGSTR */
  527.                {
  528.                   printf("\nFile '%s' not found.\n", argstr);   /*  Print error if file not found */
  529.                   item++;
  530.                   continue;                                     /*  Continue with WHILE loop */
  531.                }
  532.  
  533.             level = 0;              /*  Reset line number and level number */
  534.  
  535.             if ( !OutOnly )
  536.                   fprintf(stderr, "      Processing %s\n", argstr);
  537.  
  538.             files++;
  539.             /*
  540.             **  Write header comments
  541.             */
  542.             fprintf(direction, "\n%s\n", "/*");
  543.             fprintf(direction, "**  File: %s\n", argstr);
  544.             fprintf(direction, "%s\n", "*/\n");
  545.  
  546.             while ( fgets(string, 254, stream) )  /*  Get a line in the file */
  547.                {
  548.  
  549.                   utcharsb(3, string, '\n');
  550.                   nesting(string); /*  Check '{' '}' nesting */
  551.                   string[255] = 0;
  552.  
  553.                   if ( isfunct(string) )
  554.                         function(string, stream, direction);
  555.                }
  556.             fclose(stream);                      /*  Close the file */
  557.  
  558.             if ( (comment) || (squote) || (dquote) )
  559.                {
  560.                   fprintf(stderr, "Your source file %s has errors.\n");
  561.                   if ( comment )
  562.                      {
  563.                         fprintf(stderr, "      %d ", comment);
  564.                         if ( comment > 1 )
  565.                               fprintf(stderr, "comments were not ended.\n");
  566.                         else
  567.                               fprintf(stderr, "comment was not ended.\n");
  568.                      }
  569.  
  570.                   if ( squote )
  571.                      {
  572.                         fprintf(stderr, "      %d ", squote);
  573.                         if ( squote > 1 )
  574.                               fprintf(stderr, "single quotes are missing the ending quote.\n");
  575.                         else
  576.                               fprintf(stderr, "single quote is missing the ending quote.\n");
  577.                      }
  578.  
  579.                   if ( dquote )
  580.                      {
  581.                         fprintf(stderr, "      %d ", dquote);
  582.                         if ( dquote > 1 )
  583.                               fprintf(stderr, "double quotes are missing the ending quote.\n");
  584.                         else
  585.                               fprintf(stderr, "double quote is missing the ending quote.\n");
  586.                      }
  587.  
  588.                   exit(1);
  589.                }
  590.          }
  591.  
  592.  
  593.       if ( !OutOnly )                      /*  If output == printer, close the direction file */
  594.             fclose(direction);
  595.  
  596.       fclose(project);                     /*  Close the project file */
  597.       fprintf(stderr, "\n\n%d file(s) processed.\n", files);
  598.    }
  599.  
  600.