home *** CD-ROM | disk | FTP | other *** search
-
- /***********************************************************************
- * *
- * Autor : Gerhard Leibrock, Neuhäuselerstr. 12, 66459 Kirkel *
- * *
- * Programmname :GAdoc *
- * *
- * Version : 1.0 ** Fertig am : 01.03.1995 *
- * *
- * Programmart : *
- * *
- * Aufruf : GAdoc *
- * *
- * Rückgabewerte: int Werte *
- * *
- * NULL : Arbeit erfolgreich beendet *
- * sonst : Arbeit abgebrochen (Speicher knapp, etc.) *
- * *
- * Beschreibung : *
- * *
- * Anfangsdatum : 10.02.1995 ## letzte Änderung : 01.03.1995 *
- * *
- ***********************************************************************/
-
- char *VER = "$VER: GAdoc 1.1 (c) Gerhard Leibrock (01.03.95)";
-
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
-
-
- typedef enum{FALSE, TRUE} BOOL;
-
-
- void WriteTexinfo
- (FILE *fptr, char *filename, char *author,
- char *project, char *version, char *copyright, BOOL amiga_support)
- {
- /* To obtain the system-time -> Included as the date of extraction */
- time_t t;
-
- /* To eliminate path-symbols like `:' or `/'; */
- int i;
-
- time(&t);
-
-
- for(i=strlen(filename)-1; i>=0; i--)
- if(filename[i] == ':' || filename[i]=='/') break;
-
- if(amiga_support) fputs("\\input amigatexinfo\n", fptr);
- fputs("\\input texinfo @c -*-Texinfo-*-\n\n", fptr);
- fprintf(fptr,
- "@setfilename %s.guide\n"
- "@settitle Autodocs for %s\n"
- "@finalout\n@setchapternewpage on\n\n"
- "@titlepage\n@title Autodocs for %s\n"
- "@subtitle Documentation taken from source code\n"
- "@subtitle \n"
- "@subtitle Version %s\n"
- "@subtitle \n"
- "@subtitle Printed version\n"
- "@subtitle \n"
- "@subtitle Extracted %s\n"
- "@subtitle \n"
- "@author %s\n\n"
- "@page\n@vskip 0pt plus 1filll\n"
- "Copyright @copyright{} by %s\n"
- "@end titlepage\n\n"
- "@ifinfo\n@node Top\n@top\n@unnumbered\n\n"
- "@center Autodocs for %s\n"
- "Written by %s\n"
- "@copyright{} Copyright by %s\n"
- "Documentation taken directly from source code\n\n"
- "Extracted %s\n\n"
- #if 0
- "Docs generated using GAdoc, (c) by Gerhard Leibrock, Feb 1995\n\n"
- #endif
- "@end ifinfo\n\n\n"
- "@menu\n",
- &filename[i+1], project, project, version, ctime(&t), author, copyright,
- project, author, copyright, ctime(&t));
- }
-
- int main(int argc, char *argv[])
- {
- FILE *ein;
- FILE *aus_menue, *aus_daten;
-
- int i, j;
-
- char fname[64];
-
- #define MAX_LINE_LENGTH 80
- char zk[MAX_LINE_LENGTH], zk1[MAX_LINE_LENGTH], zk2[MAX_LINE_LENGTH];
-
- /* Name des Programmautors */
- char author[50];
- /* Wie heisst dads Projekt? */
- char project[50];
- /* Welche Version hat es? */
- char version[50];
- /* Wer hat das Copyright? */
- char copyright[50];
-
-
-
- unsigned int zeile = NULL;
-
- BOOL autodoc_mode=FALSE;
-
- /* Schluesselworte fuer Auto-DOCS */
- char *keywords[] = {"NAME", "SYNOPSIS", "FUNCTION", "INPUTS", "RESULT",
- "EXAMPLE", "NOTES", "BUGS"};
- BOOL autodoc = FALSE;
- BOOL first_key = FALSE;
- BOOL see_also = FALSE; /* Im @ref{} Modus */
- BOOL see_also_found = FALSE; /* SEE ALSO schon vorgekommen */
- BOOL key_found = FALSE;
- BOOL key[sizeof(keywords) / sizeof(char**)];
-
- /* Programminteren Schluesselwoerter */
- char *internal_keywords[] = {"NAME", "COPYRIGHT", "FUNCTION", "AUTHOR",
- "NOTES", "VERSION"};
- BOOL internal_key[sizeof(internal_keywords) / sizeof(char**)];
- BOOL internal = FALSE; /* Internal schon mal aufgerufen? */
- BOOL internal_mode = FALSE;
- /* Zum Aussteigen beim Einlesen der Datei bei Endkennung */
- BOOL internal_ende = FALSE;
-
- /* */
- BOOL first_internal = FALSE;
- /* Zuletzt aktives Schluesselwort */
- int last_key = -1;
-
- /* Extrahieren der als intern deklarierten Docs? */
- BOOL extract_internal = FALSE;
- /* Include amiga support? */
- BOOL amiga_support = FALSE;
-
- char *token; /* Zum Aufsplitten der Eingabe-Datei */
-
- BOOL convert_comment = FALSE;
-
-
- if(argc<3 || argc>6)
- {
- puts("This prgram extracts the AutoDOCs from your source-files\n"
- "and produces two TeXinfo-files out of it:\n"
- "<texinfo_file>.menu AND <texinfo_file>.data\n"
- "The *.menu file is the main part, use it with makeinfo.");
- printf("Syntax:\n"
- "\t%s <source> <texinfo_file> [-i] [-amiga] [-c]\n"
- "\t -i: Also extract internal documentation\n"
- "\t -c: Convert \\* to /* and *\\ to */\n"
- "\t -amiga: Include amiga support for texinfo\n"
- "(c) Gerhard Leibrock, 1995\n", argv[0]);
- printf("Warning: Lines are limited to %ld chars!\n", sizeof(zk));
- exit(0);
- }
-
- /* Testen, ob der Benutzer AUCH die als INTERN deklarierten Autodocs
- erhalten moechte */
- if(argc>=4)
- for(i=3; i<argc; i++)
- {
- if(!strcmp(argv[i], "-i"))
- {
- if(extract_internal)
- {
- printf("-i: Specified twice (See argument #%d)\n", i+1);
- exit(0);
- }
- else
- extract_internal = TRUE;
- }
- else if(!strcmp(argv[i], "-amiga"))
- {
- if(amiga_support)
- {
- printf("-a: Specified twice (See argument #%d)\n", i+1);
- exit(0);
- }
- else
- amiga_support = TRUE;
- }
- else if(!strcmp(argv[i], "-c"))
- {
- if(convert_comment)
- {
- printf("-c: Specified twice (See argument #%d)\n", i+1);
- exit(0);
- }
- else
- convert_comment = TRUE;
- }
- else
- {
- printf("Unknown argument: %s\n", argv[i]);
- exit(0);
- }
- } /* Schleife ueber die Argumente beim Aufruf */
-
-
- /* Open the source-file */
- if(!(ein=fopen(argv[1], "r")))
- {
- printf("Could not open file ``%s''.\n", argv[1]);
- exit(0);
- }
-
- /* Open the output file, which contains the document description and
- toc */
- strcpy(fname, argv[2]); strcat(fname, ".menu");
- if(!(aus_menue=fopen(fname, "w")))
- {
- printf("Could not open file %s.\n", fname);
- fclose(ein);
- exit(0);
- }
-
- /* Open the file, which will contain the function descriptions,
- ``fname'' will be used later agin and contains the filename */
- strcpy(fname, argv[2]); strcat(fname, ".data");
- if(!(aus_daten=fopen(fname, "w")))
- {
- printf("Could not open file %s!\n", fname);
- fclose(ein); fclose(aus_menue);
- exit(0);
- }
-
-
- for(i=0; i<sizeof(keywords) / sizeof(char**); i++) key[i]=FALSE;
- for(i=0; i<sizeof(internal_keywords) / sizeof(char**); i++)
- internal_key[i]=FALSE;
-
-
- /* Vorbelegen der Variablen */
- strncpy(author, "Unknown", 50);
- strncpy(project, argv[1], 50);
- strcpy(version, "0.0");
-
-
- while ( fgets(zk, sizeof(zk), ein) )
- {
- zeile++;
-
- /* Wir sind im Autodoc-Modus */
- if(autodoc_mode)
- {
- if(!strncmp(zk, "*********", 9) || !strncmp(zk, ";********", 9)
- ||!strncmp(zk, "%********", 9) )
- {/* Endkennung erreicht */
- /* Testen, ob es Schluesselwoerter gibt, zu denen nichts
- geschrieben wurde und zuruecksetzen */
- for(i=0; i<sizeof(keywords) / sizeof(char**); i++)
- {
- if(!key[i]) fprintf(aus_daten, "\n@code{%s}\n", keywords[i]);
- key[i]=FALSE;
- }
-
- /* SEE ALSO schon aufgetaucht? */
- if(!see_also_found) fputs("\n@code{SEE ALSO}\n", aus_daten);
-
- key_found = FALSE;
- first_key=FALSE;
- autodoc_mode = FALSE;
- if(!see_also) fputs("@end example\n", aus_daten);
- see_also = FALSE; see_also_found = FALSE;
- fputs("\n\n\n", aus_daten);
- /* Testen, ob es Schluesselwoerter gibt, zu denen nichts
- geschrieben wurde. */
- }
- else /* Teste, auf Anfang fuer Autodoc-Modus */
- {
- key_found = FALSE;
- /* Keine Endkennung, vielleicht aber ein neues Schlüsselwort? */
-
- /* Ueberlese erstes Zeichen und alle TABs, Leerzeichen */
- strcpy(zk1, zk);
- token = strtok(&zk[1], " \t\n");
-
- if(token)
- {
- if(!strcmp(token, "SEE"))
- {
- token = strtok(NULL," \t\n");
- if(!strcmp(token, "ALSO"))
- {
- if(see_also_found)
- {
- printf( "Error Line %u: Either keyword SEE ALSO used twice"
- "or in wrong order.\n", zeile);
- exit(0);
- }
- /* Nun setzen wir alle Kennungen fuer Schluesselwoerter auf
- gefunden, falls diese noch nicht gefunden worden sind, da
- SEE ALSO das letzte zu akzeptierende Schluesselwort ist.
- Ausserdem schreiben wir die Schluesselworte, da alle
- vorkommen sollen */
- for(i=0; i<sizeof(keywords) / sizeof(char**); i++)
- {
- if(!key[i]) fprintf(aus_daten, "\n@code{%s}\n", keywords[i]);
- key[i]=TRUE;
- }
-
- /* Schluesselwort "SEE ALSO" */
- if(first_key) fputs("@end example\n", aus_daten);
- first_key=TRUE;
- key_found=TRUE;
- see_also = TRUE; see_also_found = TRUE;
- strcpy(zk1, "SEE ALSO");
- }
- }
- else {
- for(i=0; i< sizeof(keywords) / sizeof(char**); i++)
- {
- if(!strcmp(token, keywords[i]))
- {
- if(key[i] == TRUE)
- {
- printf("Error Line %u: Either keyword %s used twice"
- " or in wrong order\n",
- zeile, keywords[i]);
- exit(0);
- }
- /* Alle Schluesselwoerter, die vor diesem in der Reihenfolge
- stehen, werden als belegt gekennzeichnet */
- for(j=0; j<i; j++)
- {
- if(!key[j]) fprintf(aus_daten, "\n@code{%s}\n", keywords[j]);
- key[j]=TRUE;
- }
- key[i]=TRUE;
- if(first_key) fputs("@end example\n", aus_daten);
- first_key=TRUE;
- key_found=TRUE;
- see_also = FALSE;
- strcpy(zk1, keywords[i]);
- break;
- }
- } /* Suche nach Keyword */
- } /* ELSE */
- }
- if(!key_found) {
- if(see_also)
- {
- token = strtok(&zk[1], " ,\t\n");
- if(token) strcpy(zk1, token);
- else zk1[0] = '\0';
- while(token != NULL)
- {
- /* Ueberlesen des Textes vor ``/'' */
- for(i=0; i<strlen(token); i++)
- {
- if(token[i]=='/') {
- zk1[i]=NULL;
- strcpy(zk2, &token[i+1]);
- break; }
- }
-
- /* Ist zk1 != Dateiname, dann wird ein Objekt ausserhalb
- referenziert, sonst koennen wir den Dateinamen weglassen */
- if(!strcmp(zk1, argv[1]))
- {
- fprintf(aus_daten, "@ref{%s}.\n", zk2);
- }
- else
- {
- /* Nun referenzieren in eine andere Datei */
- fprintf(aus_daten, "@xref{%s, , %s, %s, Autodoc-file %s}.\n",
- zk2, zk2, zk1, zk1);
- }
-
- token = strtok(NULL," ,\t\n");
- }
- }
- else
- {
- if(convert_comment)
- {
- for(i=0; i<strlen(zk1); i++)
- if(zk1[i] == '\\') zk1[i] = '/';
-
- }
- fputs(&zk1[1], aus_daten);
- }
- }
- /* Wir ignorieren das erste Zeichen links */
- else
- {
- fprintf(aus_daten, "\n@code{%s}\n", zk1);
- if(!see_also) fputs("\n@example\n", aus_daten);
- key_found = FALSE;
- }
- } /* keine Endkennung */
- }
- else /* Nicht im Autodoc-Modus */
- { /* Autodoc-Modus startet mit einer Zeile, bei der das erste Zeichen
- keine Rolle spielt, dann aber 6 '*' folgen, dann durch ein
- Leerzeichen getrennt der Name der Funktion und dann durch ein
- Leerzeichen getrennt beliebige Zeichen */
- i = sscanf(&zk[1], "****** %s %s", zk1, zk2);
- /* zk1: Name der Funktion, zk2 -> Beliebiger Rest */
- if(i>=1) /* Anfangskennzeichen */
- {
- if(!autodoc) /* Erster Eintrag? */
- {
- autodoc = TRUE;
- WriteTexinfo(
- aus_menue, argv[2], author, project, version,
- copyright, amiga_support);
- }
- autodoc_mode = TRUE;
-
- /* Ueberlese den Teil vor ``/'' */
- token = strtok(zk1, "/");
- token = strtok(NULL, " \n\t");
-
- /* Menue-Datei */
- fprintf(aus_menue, "* %s::\n", token);
- fprintf(aus_daten, "@node %s\n"
- "@chapter %s\n"
- "@findex %s\n\n",
- token, token, token);
-
- }
-
- /* Modus fuer die internen Funktionen */
- i = sscanf(&zk[1], "****i* %s %s", zk1, zk2);
- /* zk1: Name der Funktion, zk2 -> Beliebiger Rest */
- if(i>=1) /* Anfangskennzeichen */
- {
- /* Wir sollen auch die internen Docs extrahieren? */
- if(extract_internal)
- {
- if(!autodoc) /* Erster Eintrag ueberhaupt? */
- {
- autodoc = TRUE;
- WriteTexinfo(
- aus_menue, argv[2], author, project, version,
- copyright, amiga_support);
- }
- autodoc_mode = TRUE;
-
- /* Ueberlese den Teil vor ``/'' */
- token = strtok(zk1, "/");
- token = strtok(NULL, " \n\t");
-
- /* Menue-Datei */
- fprintf(aus_menue, "* %s:: Internal function\n", token);
- fprintf(aus_daten, "@node %s\n"
- "@chapter %s\n"
- "@findex %s (Internal function)\n\n"
- "@center ONLY FOR INTERNAL USE: @b{%s}\n\n",
- token, token, token, token);
- }
- else /* ueberlesen der INTERNEN Funktionsdokumentation */
- {
- BOOL haben_ende = FALSE;
- while ( fgets(zk, sizeof(zk), ein) && !haben_ende )
- {
- zeile++;
- if(!strncmp(zk, "*********", 9) || !strncmp(zk, ";********", 9)
- ||!strncmp(zk, "%********", 9) )
- {
- haben_ende = TRUE;
- break;
- }
- } /* fgets() */
- if(!haben_ende)
- {
- printf("Error: End of file occured during internal docs.\n");
- exit(0);
- }
- } /* Ueberlesen der internen Dokumentation */
- } /* BLOCK zum Lesen der internen Dokumentation */
-
- /* Ausfuellen der Slots (Fuer AUTHOR, etc): */
- i = sscanf(&zk[1], "****h* %s %s", zk1, zk2);
- /* zk1: Name der Funktion, zk2 -> Beliebiger Rest */
- if(i>=1) /* Anfangskennzeichen */
- {
- internal_ende = FALSE;
-
- if(autodoc) {
- printf("Error Line %u: Header specified after autodocs.\n",
- zeile);
- exit(0); }
-
- if(internal) {
- printf("Error Line %u: Second time header gets specified.\n", zeile);
- exit(0); }
-
- /* Ueberlese den Teil vor ``/'' */
- token = strtok(zk1, "/");
- token = strtok(NULL, " \n\t");
-
- /* Menue-Datei */
- fprintf(aus_daten, "@node About_%s\n"
- "@chapter About_%s\n"
- "@findex About_%s\n\n",
- token, token, token);
-
- strcpy(zk2, token);
- /* Nun solange lesen, bis wir die internal-Sachen abgearbeitet haben */
- while ( fgets(zk, sizeof(zk), ein) && !internal_ende )
- {
- zeile++;
- if(!strncmp(zk, "*********", 9) || !strncmp(zk, ";********", 9)
- ||!strncmp(zk, "%********", 9) )
- {/* Endkennung erreicht */
- for(i=0; i<sizeof(internal_keywords) / sizeof(char**); i++)
- internal_key[i]=FALSE;
-
- internal_mode = FALSE;
- internal = TRUE;
- if(!see_also) fputs("@end example\n", aus_daten);
- fputs("\n\n\n", aus_daten);
- internal_ende = TRUE;
- }
- else /* Teste, auf Anfang fuer Internal-Modus */
- {
- /* Ueberlese erstes Zeichen und alle TABs, Leerzeichen */
- strcpy(zk1, zk);
- token = strtok(&zk[1], " \t\n");
-
- /* Schleifenvariable i dient spaeter als Indikator fuer
- das Auffinden eines Schluesselwortes. Mit dem Setzen auf
- einen Wert ausserhalb des Schluesselwort-Bereichs setzen
- wir den Test fuers Finden auf FALSE */
- i=sizeof(internal_keywords) / sizeof(char**);
-
- if(token)
- {
- for(i=0; i< sizeof(internal_keywords) / sizeof(char**); i++)
- {
- if(!strcmp(token, internal_keywords[i]))
- {
- last_key = i;
- if(internal_key[i] == TRUE)
- {
- printf("Error Line %u: Keyword %s used twice.\n",
- zeile, keywords[i]);
- exit(0);
- }
- if(first_internal) fputs("@end example\n", aus_daten);
- first_internal=TRUE;
- internal_key[i] = TRUE;
- strcpy(zk1, internal_keywords[i]);
- break;
- }
- } /* Suche nach Keyword */
- }
-
- /* Keyword? */
- if(i!=sizeof(internal_keywords) / sizeof(char**))
- {
- fprintf(aus_daten, "\n@code{%s}\n", zk1);
- fputs("\n@example\n", aus_daten);
- }
- else /* Wir haben kein Schluesselwort */
- {
- if(convert_comment)
- {
- for(i=0; i<strlen(zk1); i++)
- if(zk1[i] == '\\') zk1[i] = '/';
- }
- strcpy(zk, zk1);
- token = zk;
- token = strpbrk(zk," \t");
- switch(last_key)
- {
- case 3: /* AUTHOR */
- strncpy(author, token, 50);
- break;
-
- case 0: /* NAME */
- strncpy(project, token, 50);
- break;
-
- case 5: /* VERSION */
- strncpy(version, token, 50);
- break;
-
- case 1: /* COPYRIGHT*/
- strncpy(copyright, token, 50);
- break;
- }
- last_key = -1;
- fputs(&zk1[1], aus_daten);
- }
- } /* keine Endkennung */
- } /* fgets() */
- /* Ende mit einlesen -> Kein Fehler, wenn internal == TRUE */
- if(!internal) {
- printf("Error: End of file occured during internal block.\n");
- exit(0);
- }
-
- WriteTexinfo(aus_menue, argv[2], author, project, version,
- copyright, amiga_support);
- fprintf(aus_menue, "* About_%s::\n", zk2);
-
- internal_mode = TRUE;
- autodoc = TRUE;
- } /* Internal-Kennung (AUTHOR, etc.) */
-
- }/* Nicht im Autodoc_modus */
-
- } /* fgets() */
-
- if(autodoc_mode) puts("Error: End of file during autodoc mode!");
- else
- {
- /* Eliminate path specifiers like "/" and ":" */
- for(i=strlen(fname)-1; i>=0; i--)
- if(fname[i] == ':' || fname[i]=='/') break;
- fprintf(aus_menue, "* Function Index::\n@end menu\n\n@include %s\n\n",
- &fname[i+1]);
- fprintf(aus_menue, "@page\n@node Function Index\n\n"
- "@unnumbered Function Index\n\n"
- "@printindex fn\n@contents\n@bye\n");
- fputs("\n\n", aus_daten);
- }
-
- } /* main() */
-
-
- /* Eine Extrawurst f"ur den DICE Compiler, der den Start von der WB
- eigenwillig handhabt. */
- #ifdef _DCC
- void wbmain(void)
- {
- main();
- }
- #endif
-
-
-
-
-
-