home *** CD-ROM | disk | FTP | other *** search
- /* This quick hack can be used to generate Product-Info files from a typical
- "Contents" file. It creates subdirectories in the current directory,
- one for each "Product" found in the Contents file (and with the same name),
- and generates a Product-Info file within that directory.
-
- This code is Public Domain. -Fred Fish
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
-
- #ifndef TRUE
- #define TRUE 1
- #endif
-
- #ifndef FALSE
- #define FALSE 0
- #endif
-
- char buffer[4096];
- char *bufp;
- int buflen;
-
- char shortdesc[256];
-
- char productname[256];
- char filename[256];
-
- FILE *fout;
-
- int
- read_new_entry ()
- {
- int thisch;
- int usech;
- int prevch;
- int prevprevch;
-
- prevch = '\000';
- thisch = '\000';
- bufp = buffer;
- *bufp = '\000';
-
- /* Discard all leading whitespace */
-
- do
- {
- thisch = getchar ();
- if (thisch == EOF)
- {
- return (0);
- }
- }
- while (isspace (thisch));
- ungetc (thisch, stdin);
-
- /* Collect everything up to the next pair of double newlines or EOF into
- the buffer, compressing out extra whitespace and converting newlines
- into whitespace. */
-
- for (;;)
- {
- prevprevch = prevch;
- prevch = thisch;
- thisch = getchar ();
-
- if (thisch == EOF)
- {
- ungetc (thisch, stdin);
- break;
- }
- else if (thisch == '\n' && (prevch == '\n'))
- {
- break;
- }
- else if (thisch == '\n')
- {
- usech = ' ';
- }
- else if (thisch == '\t')
- {
- usech = ' ';
- }
- else
- {
- usech = thisch;
- }
-
- if (isspace (usech) && isspace (prevch) && (prevprevch != '.'))
- {
- /* Compress out repeated whitespace except for two spaces following
- a previous end of a sentance. */
- continue;
- }
-
- if (isspace (usech) && (prevch == '-'))
- {
- /* Eat occurances of "- " that are generated by hyphenated lines. */
- bufp--;
- continue;
- }
-
- *bufp++ = usech;
- }
- *bufp = '\000';
- return (1);
- }
-
- void
- remove_it (start, end)
- char *start;
- char *end;
- {
- if (*start == ',')
- {
- /* The clause we are removing starts in the middle of a sentance. */
- if ((*end == '.') || (*end == '\000'))
- {
- /* The clause is the last one of the sentance, so build end of
- sentance and set up to start shuffling with next sentance. */
- *start++ = '.';
- *start++ = ' ';
- *start++ = ' ';
- if (*end != '\000')
- {
- end++;
- }
- while (isspace (*end))
- {
- end++;
- }
- }
- else if (*end == ',')
- {
- /* The clause is entirely within the middle of the sentance,
- so just shuffle it away. */
- }
- else if (*end == ' ')
- {
- /* The clause we are removing is only the leading part of a clause of
- the sentance, so keep the ',' that separates it from the previous
- part of the sentance. */
- start++;
- }
- else
- {
- fprintf (stderr, "%s: problem shuffling out '", productname);
- while (start < end)
- {
- fputc (*start++, stderr);
- }
- fputc ('\'', stderr);
- fputc ('\n', stderr);
- return;
- }
- }
- else if ((*start == ' ') && isupper (*(start + 1)))
- {
- /* The clause we are removing starts a sentance, so skip over the
- leading blank and position to start shuffling into the place where
- the old sentance started. */
- start++;
- if ((*end == '.') || (*end == '\000'))
- {
- /* The clause is a complete sentance, position to start shuffle
- with next sentance. */
- if (*end != '\000')
- {
- end++;
- }
- while (isspace (*end))
- {
- end++;
- }
- }
- else if ((*end == ',') || (*end == ' '))
- {
- /* The clause starts a sentance, so position to start with
- next clause, and capitalize it. This is true even if it
- is only a portion of the starting clause (the word following
- the portion becomes capitalized). */
- end++;
- while (isspace (*end))
- {
- end++;
- }
- *end = toupper (*end);
- }
- else
- {
- fprintf (stderr, "%s: problem shuffling out '", productname);
- while (start < end)
- {
- fputc (*start++, stderr);
- }
- fputc ('\'', stderr);
- fputc ('\n', stderr);
- return;
- }
- }
-
- /* Shuffle all the characters down to fill the hole and null terminate
- the result. */
-
- while (*end != '\000')
- {
- *start++ = *end++;
- }
- *start = '\000';
- }
-
- /* Try to pick off the author information from the end of the description.
- Account for multiple authors separated by ',' characters, and strip
- out any '.' characters, which are occasionally found at the end.
- Separate the author info from the end of the description by writing
- a null byte into it's first character. */
-
- void
- extract_author ()
- {
- char *foundit;
- char *scan;
- int length;
- int neednewline;
-
- foundit = strstr (bufp, "Author:");
- length = 7;
- if (foundit == NULL)
- {
- foundit = strstr (bufp, "Authors:");
- length = 8;
- }
- if (foundit != NULL)
- {
- fprintf (fout, ".author\n");
- scan = foundit;
- scan += length;
- while (isspace (*scan))
- {
- scan++;
- }
- neednewline = FALSE;
- while (*scan != '\000')
- {
- neednewline = TRUE;
- if ((strncmp (scan, "amiga port by ", 14) == 0) ||
- (strncmp (scan, "Amiga port by ", 14) == 0))
- {
- scan += 14;
- }
- if ((strncmp (scan, "ported to amiga by ", 19) == 0))
- {
- scan += 19;
- }
- if (*scan == '.')
- {
- /* eat it */
- scan++;
- }
- else if (*scan == ',')
- {
- fputc ('\n', fout);
- scan++;
- while (isspace (*scan))
- {
- scan++;
- }
- }
- else
- {
- fputc (*scan, fout);
- scan++;
- }
- }
- if (neednewline)
- {
- fputc ('\n', fout);
- }
- remove_it (foundit, scan);
- }
- }
-
- /* Try to extract version information, and remove it from the buffer in
- the process. */
-
- void
- extract_current_version ()
- {
- char *foundit;
- char *scan;
- int length;
- char ver[256];
- char *verp;
-
- foundit = strstr (bufp, " Version ");
- length = 9;
- if (foundit == NULL)
- {
- foundit = strstr (bufp, " This is version ");
- length = 17;
- }
- if (foundit == NULL)
- {
- foundit = strstr (bufp, ", version ");
- length = 10;
- }
- if (foundit != NULL)
- {
- fprintf (fout, ".version\n");
- scan = foundit + length;
- while (isspace (*scan))
- {
- scan++;
- }
- verp = ver;
- while ((*scan != '\000') && (*scan != ',') &&
- (!((*scan == '.') && (*(scan + 1) == ' '))))
- {
- *verp++ = *scan++;
- }
- if ((verp - ver) > 16)
- {
- fprintf (fout, "?.?\n");
- return;
- }
- *verp = '\000';
- fprintf (fout, "%s\n", ver);
- strcat (shortdesc, ", V");
- strcat (shortdesc, ver);
- remove_it (foundit, scan);
- }
- }
-
- /* Try to extract previous version information, and remove it from the buffer in
- the process. */
-
- void
- extract_update_to ()
- {
- char *foundit;
- char *scan;
- int length;
- char *verp;
- char *refp;
- char ver[256];
- char ref[256];
-
- foundit = strstr (bufp, " An update to version ");
- length = 22;
- if (foundit == NULL)
- {
- foundit = strstr (bufp, ", an update to version ");
- length = 23;
- }
- if (foundit != NULL)
- {
- scan = foundit + length;
- while (isspace (*scan))
- {
- scan++;
- }
- /* Suck out the old version number */
- verp = ver;
- while (!isspace (*scan) && (*scan != ','))
- {
- *verp++ = *scan++;
- }
- *verp = '\000';
-
- /* look for " on disk " */
- if (strncmp (scan, " on disk ", 9) == 0)
- {
- scan += 9;
-
- /* look for "number " */
- if (strncmp (scan, "number ", 7) == 0)
- {
- scan += 7;
- }
- /* look for '#' */
- if (*scan == '#')
- {
- scan++;
- }
- /* Suck out the old disk number */
- refp = ref;
- while ((*scan != '.') && (*scan != ','))
- {
- *refp++ = *scan++;
- }
- *refp = '\000';
- if ((atoi (ref) <= 0) || (atoi (ref) > 999) || (strlen (ref) > 3))
- {
- fprintf (stderr, "%s: '%s' is not a disk number\n",
- productname, ref);
- }
- else
- {
- fprintf (fout, ".reference\n");
- fprintf (fout, "AmigaLibDisk%d:%s/\n", atoi (ref), productname);
- fprintf (fout, "%s\n", ver);
- remove_it (foundit, scan);
- }
- }
- }
- }
-
- /* Try to extract source information, and remove it from the buffer in
- the process. */
-
- void
- extract_source_information ()
- {
- char *foundit;
- char *scan;
- int length;
- char src[256];
- char *srcp;
- char *descp;
-
- foundit = strstr (bufp, " Includes source");
- length = 16;
- if (foundit == NULL)
- {
- foundit = strstr (bufp, ", includes source");
- length = 17;
- }
- if (foundit != NULL)
- {
- fprintf (fout, ".source\n");
- scan = foundit + length;
- strcpy (src, "Includes source");
- if (strncmp (scan, " in ", 4) != 0)
- {
- /* Generally when a Contents file says "Includes source.", without
- specifying the source, it is implied that the source is in C. */
- strcat (src, " in C");
- srcp = src + strlen (src);
- descp = "C";
- }
- else
- {
- strcat (src, " in ");
- scan += 4;
- srcp = src + strlen (src);
- descp = srcp;
- while (isspace (*scan))
- {
- scan++;
- }
- while ((*scan != '\000') && (*scan != ',') && (*scan != '.'))
- {
- *srcp++ = *scan++;
- }
- }
- *srcp = '\000';
- strcat (shortdesc, ", ");
- strcat (shortdesc, descp);
- strcat (shortdesc, " source");
- *srcp++ = '.';
- *srcp = '\000';
- fprintf (fout, "%s\n", src);
- remove_it (foundit, scan);
- }
- }
-
- /* Try to remove "Binary only." */
-
- void
- remove_binary_only ()
- {
- char *foundit;
- char *scan;
- int length;
-
- foundit = strstr (bufp, " Binary only");
- length = 12;
- if (foundit == NULL)
- {
- foundit = strstr (bufp, ", binary only");
- length = 13;
- }
- if (foundit != NULL)
- {
- scan = foundit + length;
- remove_it (foundit, scan);
- }
- }
-
- /* Try to find and remove "Shareware" */
-
- void
- extract_shareware ()
- {
- char *foundit;
- char *scan;
- int length;
-
- foundit = strstr (bufp, " Shareware");
- length = 10;
- if (foundit == NULL)
- {
- foundit = strstr (bufp, ", shareware");
- length = 11;
- }
- if (foundit != NULL)
- {
- fprintf (fout, ".distribution\nShareware\n");
- scan = foundit + length;
- strcat (shortdesc, ", shareware");
- remove_it (foundit, scan);
- }
- }
-
- /* Try to find and remove "Public Domain" */
-
- void
- extract_public_domain ()
- {
- char *foundit;
- char *scan;
- int length;
-
- foundit = strstr (bufp, " Public domain");
- length = 14;
- if (foundit == NULL)
- {
- foundit = strstr (bufp, ", public domain");
- length = 15;
- }
- if (foundit != NULL)
- {
- fprintf (fout, ".distribution\nPublic Domain\n");
- scan = foundit + length;
- remove_it (foundit, scan);
- strcat (shortdesc, ", PD");
- }
- }
-
- /* Try to find and remove "freeware" */
-
- void
- extract_freeware ()
- {
- char *foundit;
- char *scan;
- int length;
-
- foundit = strstr (bufp, " Freeware");
- length = 9;
- if (foundit == NULL)
- {
- foundit = strstr (bufp, ", freeware");
- length = 10;
- }
- if (foundit != NULL)
- {
- fprintf (fout, ".distribution\nFreeware\n");
- scan = foundit + length;
- strcat (shortdesc, ", freeware");
- remove_it (foundit, scan);
- }
- }
-
- /* Output lines of description text, limiting each line to 75 characters. */
-
- void
- write_description ()
- {
- char *descp;
-
- fprintf (fout, ".description\n");
- while (*bufp != '\000')
- {
- while (isspace (*bufp))
- {
- bufp++;
- }
- descp = bufp;
- if (strlen (bufp) > 75)
- {
- bufp += 75;
- while ((bufp > descp) && (!isspace (*bufp)))
- {
- bufp--;
- }
- while ((bufp > descp) && (isspace (*bufp)))
- {
- bufp--;
- }
- bufp++;
- *bufp++ = '\000';
- }
- else
- {
- while (*bufp != '\000')
- {
- bufp++;
- }
- }
- if (*descp != '\000')
- {
- fprintf (fout, "%s\n", descp);
- }
- }
- }
-
- void
- write_described_by ()
- {
- fprintf (fout, ".described-by\n");
- fprintf (fout, "Automatically generated from Contents file by c2pi program.\n");
- }
-
- void
- write_short ()
- {
- fprintf (fout, ".short\n");
- shortdesc[40] = '\000';
- fprintf (fout, "%s\n", shortdesc);
- }
-
- void
- write_product_info ()
- {
- char *namep;
-
- /* Ignore Contents file header "This is disk ..." */
-
- if (strncmp (buffer, "This is disk", 12) == 0)
- {
- return;
- }
-
- /* Ignore Contents file headers "========..." */
-
- if (strncmp (buffer, "==========", 10) == 0)
- {
- return;
- }
-
- /* Pick off the first word as the product name */
-
- bufp = buffer;
- namep = productname;
- while (!isspace (*bufp))
- {
- *namep++ = *bufp++;
- }
- *namep = '\000';
-
- /* Make a directory by that name and create a Product-Info file
- within it. */
-
- mkdir (productname, 0775);
- sprintf (filename, "%s/Product-Info", productname);
- if ((fout = fopen (filename, "w")) == NULL)
- {
- perror (filename);
- return;
- }
- fprintf (fout, ".name\n%s\n", productname);
- sprintf (shortdesc, "%s", productname);
-
- /* Skip leading whitespace on description. */
-
- while (isspace (*bufp))
- {
- bufp++;
- }
-
- buflen = strlen (bufp);
- for (;;)
- {
- extract_author ();
- extract_current_version ();
- extract_update_to ();
- extract_source_information ();
- remove_binary_only ();
- extract_shareware ();
- extract_public_domain ();
- extract_freeware ();
- if (strlen (bufp) == buflen)
- {
- break; /* No change this iteration */
- }
- else
- {
- buflen = strlen (bufp);
- }
- }
- write_description ();
- write_described_by ();
- write_short ();
- }
-
- main ()
- {
- while (read_new_entry ())
- {
- write_product_info ();
- }
- }
-