home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / tools / pitools / c2pi.c < prev    next >
C/C++ Source or Header  |  1994-03-23  |  14KB  |  705 lines

  1. /* This quick hack can be used to generate Product-Info files from a typical
  2.    "Contents" file.  It creates subdirectories in the current directory,
  3.    one for each "Product" found in the Contents file (and with the same name),
  4.    and generates a Product-Info file within that directory.
  5.  
  6.    This code is Public Domain.  -Fred Fish
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <ctype.h>
  11. #include <string.h>
  12.  
  13. #ifndef TRUE
  14. #define TRUE 1
  15. #endif
  16.  
  17. #ifndef FALSE
  18. #define FALSE 0
  19. #endif
  20.  
  21. char buffer[4096];
  22. char *bufp;
  23. int buflen;
  24.  
  25. char shortdesc[256];
  26.  
  27. char productname[256];
  28. char filename[256];
  29.  
  30. FILE *fout;
  31.  
  32. int
  33. read_new_entry ()
  34. {
  35.   int thisch;
  36.   int usech;
  37.   int prevch;
  38.   int prevprevch;
  39.  
  40.   prevch = '\000';
  41.   thisch = '\000';
  42.   bufp = buffer;
  43.   *bufp = '\000';
  44.  
  45.   /* Discard all leading whitespace */
  46.  
  47.   do
  48.     {
  49.       thisch = getchar ();
  50.       if (thisch == EOF)
  51.     {
  52.       return (0);
  53.     }
  54.     }
  55.   while (isspace (thisch));
  56.   ungetc (thisch, stdin);
  57.  
  58.   /* Collect everything up to the next pair of double newlines or EOF into
  59.      the buffer, compressing out extra whitespace and converting newlines
  60.      into whitespace. */
  61.  
  62.   for (;;)
  63.     {
  64.       prevprevch = prevch;
  65.       prevch = thisch;
  66.       thisch = getchar ();
  67.  
  68.       if (thisch == EOF)
  69.     {
  70.       ungetc (thisch, stdin);
  71.       break;
  72.     }
  73.       else if (thisch == '\n' && (prevch == '\n'))
  74.     {
  75.       break;
  76.     }
  77.       else if (thisch == '\n')
  78.     {
  79.       usech = ' ';
  80.     }
  81.       else if (thisch == '\t')
  82.     {
  83.       usech = ' ';
  84.     }
  85.       else
  86.     {
  87.       usech = thisch;
  88.     }
  89.  
  90.       if (isspace (usech) && isspace (prevch) && (prevprevch != '.'))
  91.     {
  92.       /* Compress out repeated whitespace except for two spaces following
  93.          a previous end of a sentance. */
  94.       continue;
  95.     }
  96.  
  97.       if (isspace (usech) && (prevch == '-'))
  98.     {
  99.       /* Eat occurances of "- " that are generated by hyphenated lines. */
  100.       bufp--;
  101.       continue;
  102.     }
  103.  
  104.       *bufp++ = usech;
  105.     }
  106.   *bufp = '\000';
  107.   return (1);
  108. }
  109.  
  110. void
  111. remove_it (start, end)
  112. char *start;
  113. char *end;
  114. {
  115.   if (*start == ',')
  116.     {
  117.       /* The clause we are removing starts in the middle of a sentance. */
  118.       if ((*end == '.') || (*end == '\000'))
  119.     {
  120.       /* The clause is the last one of the sentance, so build end of
  121.          sentance and set up to start shuffling with next sentance. */
  122.       *start++ = '.';
  123.       *start++ = ' ';
  124.       *start++ = ' ';
  125.       if (*end != '\000')
  126.         {
  127.           end++;
  128.         }
  129.       while (isspace (*end))
  130.         {
  131.           end++;
  132.         }
  133.     }
  134.       else if (*end == ',')
  135.     {
  136.       /* The clause is entirely within the middle of the sentance,
  137.          so just shuffle it away. */
  138.     }
  139.       else if (*end == ' ')
  140.     {
  141.       /* The clause we are removing is only the leading part of a clause of
  142.          the sentance, so keep the ',' that separates it from the previous
  143.          part of the sentance. */
  144.       start++;
  145.     }
  146.       else
  147.     {
  148.       fprintf (stderr, "%s: problem shuffling out '", productname);
  149.       while (start < end)
  150.         {
  151.           fputc (*start++, stderr);
  152.         }
  153.       fputc ('\'', stderr);
  154.       fputc ('\n', stderr);
  155.       return;
  156.     }
  157.     }
  158.   else if ((*start == ' ') && isupper (*(start + 1)))
  159.     {
  160.       /* The clause we are removing starts a sentance, so skip over the
  161.      leading blank and position to start shuffling into the place where
  162.      the old sentance started. */
  163.       start++;
  164.       if ((*end == '.') || (*end == '\000'))
  165.     {
  166.       /* The clause is a complete sentance, position to start shuffle
  167.          with next sentance. */
  168.       if (*end != '\000')
  169.         {
  170.           end++;
  171.         }
  172.       while (isspace (*end))
  173.         {
  174.           end++;
  175.         }
  176.     }
  177.       else if ((*end == ',') || (*end == ' '))
  178.     {
  179.       /* The clause starts a sentance, so position to start with
  180.          next clause, and capitalize it.  This is true even if it
  181.          is only a portion of the starting clause (the word following
  182.          the portion becomes capitalized). */
  183.       end++;
  184.       while (isspace (*end))
  185.         {
  186.           end++;
  187.         }
  188.       *end = toupper (*end);
  189.     }
  190.       else
  191.     {
  192.       fprintf (stderr, "%s: problem shuffling out '", productname);
  193.       while (start < end)
  194.         {
  195.           fputc (*start++, stderr);
  196.         }
  197.       fputc ('\'', stderr);
  198.       fputc ('\n', stderr);
  199.       return;
  200.     }
  201.     }
  202.  
  203.   /* Shuffle all the characters down to fill the hole and null terminate
  204.      the result. */
  205.  
  206.   while (*end != '\000')
  207.     {
  208.       *start++ = *end++;
  209.     }
  210.   *start = '\000';
  211. }
  212.  
  213. /* Try to pick off the author information from the end of the description.
  214.    Account for multiple authors separated by ',' characters, and strip
  215.    out any '.' characters, which are occasionally found at the end.
  216.    Separate the author info from the end of the description by writing
  217.    a null byte into it's first character.  */
  218.  
  219. void
  220. extract_author ()
  221. {
  222.   char *foundit;
  223.   char *scan;
  224.   int length;
  225.   int neednewline;
  226.  
  227.   foundit = strstr (bufp, "Author:");
  228.   length = 7;
  229.   if (foundit == NULL)
  230.     {
  231.       foundit = strstr (bufp, "Authors:");
  232.       length = 8;
  233.     }
  234.   if (foundit != NULL)
  235.     {
  236.       fprintf (fout, ".author\n");
  237.       scan = foundit;
  238.       scan += length;
  239.       while (isspace (*scan))
  240.     {
  241.       scan++;
  242.     }
  243.       neednewline = FALSE;
  244.       while (*scan != '\000')
  245.     {
  246.       neednewline = TRUE;
  247.       if ((strncmp (scan, "amiga port by ", 14) == 0) ||
  248.           (strncmp (scan, "Amiga port by ", 14) == 0))
  249.         {
  250.           scan += 14;
  251.         }
  252.       if ((strncmp (scan, "ported to amiga by ", 19) == 0))
  253.         {
  254.           scan += 19;
  255.         }
  256.       if (*scan == '.')
  257.         {
  258.           /* eat it */
  259.           scan++;
  260.         }
  261.       else if (*scan == ',')
  262.         {
  263.           fputc ('\n', fout);
  264.           scan++;
  265.           while (isspace (*scan))
  266.         {
  267.           scan++;
  268.         }
  269.         }
  270.       else
  271.         {
  272.           fputc (*scan, fout);
  273.           scan++;
  274.         }
  275.     }
  276.       if (neednewline)
  277.     {
  278.       fputc ('\n', fout);
  279.     }
  280.       remove_it (foundit, scan);
  281.     }
  282. }
  283.  
  284. /* Try to extract version information, and remove it from the buffer in
  285.    the process. */
  286.  
  287. void
  288. extract_current_version ()
  289. {
  290.   char *foundit;
  291.   char *scan;
  292.   int length;
  293.   char ver[256];
  294.   char *verp;
  295.  
  296.   foundit = strstr (bufp, " Version ");
  297.   length = 9;
  298.   if (foundit == NULL)
  299.     {
  300.       foundit = strstr (bufp, " This is version ");
  301.       length = 17;
  302.     }
  303.   if (foundit == NULL)
  304.     {
  305.       foundit = strstr (bufp, ", version ");
  306.       length = 10;
  307.     }
  308.   if (foundit != NULL)
  309.     {
  310.       fprintf (fout, ".version\n");
  311.       scan = foundit + length;
  312.       while (isspace (*scan))
  313.     {
  314.       scan++;
  315.     }
  316.       verp = ver;
  317.       while ((*scan != '\000') && (*scan != ',') &&
  318.          (!((*scan == '.') && (*(scan + 1) == ' '))))
  319.     {
  320.       *verp++ = *scan++;
  321.     }
  322.       if ((verp - ver) > 16)
  323.     {
  324.       fprintf (fout, "?.?\n");
  325.       return;
  326.     }
  327.       *verp = '\000';
  328.       fprintf (fout, "%s\n", ver);
  329.       strcat (shortdesc, ", V");
  330.       strcat (shortdesc, ver);
  331.       remove_it (foundit, scan);
  332.     }
  333. }
  334.  
  335. /* Try to extract previous version information, and remove it from the buffer in
  336.    the process. */
  337.  
  338. void
  339. extract_update_to ()
  340. {
  341.   char *foundit;
  342.   char *scan;
  343.   int length;
  344.   char *verp;
  345.   char *refp;
  346.   char ver[256];
  347.   char ref[256];
  348.  
  349.   foundit = strstr (bufp, " An update to version ");
  350.   length = 22;
  351.   if (foundit == NULL)
  352.     {
  353.       foundit = strstr (bufp, ", an update to version ");
  354.       length = 23;
  355.     }
  356.   if (foundit != NULL)
  357.     {
  358.       scan = foundit + length;
  359.       while (isspace (*scan))
  360.     {
  361.       scan++;
  362.     }
  363.       /* Suck out the old version number */
  364.       verp = ver;
  365.       while (!isspace (*scan) && (*scan != ','))
  366.     {
  367.       *verp++ = *scan++;
  368.     }
  369.       *verp = '\000';
  370.  
  371.       /* look for " on disk " */
  372.       if (strncmp (scan, " on disk ", 9) == 0)
  373.     {
  374.       scan += 9;
  375.  
  376.       /* look for "number " */
  377.       if (strncmp (scan, "number ", 7) == 0)
  378.         {
  379.           scan += 7;
  380.         }
  381.       /* look for '#' */
  382.       if (*scan == '#')
  383.         {
  384.           scan++;
  385.         }
  386.       /* Suck out the old disk number */
  387.       refp = ref;
  388.       while ((*scan != '.') && (*scan != ','))
  389.         {
  390.           *refp++ = *scan++;
  391.         }
  392.       *refp = '\000';
  393.       if ((atoi (ref) <= 0) || (atoi (ref) > 999) || (strlen (ref) > 3))
  394.         {
  395.           fprintf (stderr, "%s: '%s' is not a disk number\n",
  396.                productname, ref);
  397.         }
  398.       else
  399.         {
  400.           fprintf (fout, ".reference\n");
  401.           fprintf (fout, "AmigaLibDisk%d:%s/\n", atoi (ref), productname);
  402.           fprintf (fout, "%s\n", ver);
  403.           remove_it (foundit, scan);
  404.         }
  405.     }
  406.     }
  407. }
  408.  
  409. /* Try to extract source information, and remove it