home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / extra18 / hilfe / ffhc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-09  |  8.1 KB  |  306 lines

  1. /* ------------------------------------------------- */
  2. /*                    FFHC.C                         */
  3. /*           Der Compiler des Hilfe-Pakets           */
  4. /*         (c) 1991 Axel Geßner & DMV-Verlag         */
  5. /* ------------------------------------------------- */
  6.  
  7. #ifndef __COMPACT__
  8. #error please use model compact \
  9.        (far data, near code pointers) !
  10. #endif
  11.  
  12. #include "ffhc.h"
  13.  
  14. tree_t *kwtree = NULL;     /* KeyWordTree         */
  15. char sname[13],            /* Name der Quelldatei */
  16.      dname[13];            /* Name der Zieldatei  */
  17. int (*cmpstr) (const char *s1, const char *s2);
  18.  
  19. int main (int argc, char *argv[])
  20. {
  21.   FILE *infile;
  22.  
  23.   checkparameters (argv);
  24.              /* prüfen der Parameter; initialisieren */
  25.   infile = readfile (sname);
  26.              /* Lesen der Datei; Aufbauen des Baums */
  27.   writefile (dname, kwtree, infile);
  28.              /* Schreiben der Datei */
  29.   return 0;  /* Exit mit 0 */
  30. }
  31.  
  32. void checkparameters (char **argv)
  33. {
  34.   char *s;
  35.  
  36.   printf (PROG);
  37.   if (!argv[1])
  38.     error ("Keine Quelldatei angegeben.\n" +
  39.            "Korrekter Aufruf: %s\n", USAGE);
  40.   if (!argv[2] || strchr (argv[2], '/')) {
  41.     strcpy (dname, strupr (argv[1]));
  42.     argv[3] = argv[2];
  43.          /* Options-Zeiger stets in argv[3] */
  44.   } else
  45.     strcpy (dname, strupr (argv[2]));
  46.   strcpy (sname, strupr (argv[1]));
  47.   if (!strchr (sname, '.'))
  48.     strcat (sname, S_EXT);
  49.   if (!strchr (dname, '.'))
  50.     strcat (dname, D_EXT);
  51.  
  52.   cmpstr = stricmp;
  53.   for (s = argv[3]; s && *s; s++) {
  54.     switch (*s) {
  55.       case '/' :
  56.           s++;
  57.           switch (toupper(*s)) {
  58.             case 'H' :
  59.                   /* HILFE kommt hierher */ ;
  60.                break;
  61.             case 'C' :
  62.                cmpstr = strcmp;
  63.                break;
  64.             case 'D' :
  65.                showindex (dname);
  66.                /* kein break;
  67.                   index terminiert selbst */
  68.             default :
  69.                error ("Unbekannte Kommandozeilen" +
  70.                       "option /%c.\n",*s);
  71.                break;
  72.           }
  73.         }
  74.   }
  75. }
  76.  
  77. void writefile (char *fname, tree_t *tree,
  78.                 FILE *infile)
  79. {
  80.   FILE *outfile = fopen (fname, "wb");
  81.  
  82.   if (outfile == NULL)
  83.     error ("Fehler beim Öffnen der Ausgabedatei %s.\n",
  84.            fname);
  85.  
  86.   printf ("\rSchreiben der Zieldatei %s ",fname);
  87.   fwrite ((void *) &header, sizeof (header), 1,
  88.                    outfile);
  89.   writetexts (tree, infile, outfile);
  90.   header.offs = ftell (outfile);
  91.                /* ab hier wird Inh.verz. geschrieben */
  92.   writetree (tree, outfile);
  93.   fputc (0, outfile);
  94.   printf ("\r%79s\n","");
  95.   fseek (outfile, 0, SEEK_SET);
  96.   fwrite ((void *) &header, sizeof (header), 1,
  97.                    outfile);
  98.   fclose (infile); fclose (outfile);
  99. }
  100.  
  101. void writetexts (tree_t *tree, FILE *infile,
  102.                  FILE *outfile)
  103. {
  104.   char *buf;
  105.   if (tree == NULL) return;
  106.   writetexts (tree->left, infile, outfile);
  107.   fseek (infile, tree->offs, SEEK_SET);
  108.   buf = (char *) calloc (tree->textlen+1, 1);
  109.   read ((void *) buf, tree->textlen, 1, infile);
  110.   /* buf = shrinkbuftext (buf);    */
  111.   tree->textlen = strlen (buf);
  112.   tree->offs = ftell (outfile);
  113.   fwrite (buf, tree->textlen, 1, outfile);
  114.   writetexts (tree->right, infile, outfile);
  115.   free ((void *) buf);
  116. }
  117.  
  118. void writetree (tree_t *tree, FILE *outfile)
  119. {
  120.   if (tree == NULL) return;
  121.   writetree (tree->left, outfile);
  122.   fwrite ((void *) tree->keyword,
  123.                    strlen (tree->keyword)+1, 1,
  124.                    outfile);
  125.   fwrite ((void *) &tree->offs, sizeof (tree->offs),
  126.                    1, outfile);
  127.   fwrite ((void *) &tree->textlen,
  128.                    sizeof (tree->textlen), 1,
  129.                    outfile);
  130.   writetree (tree->right, outfile);
  131.     /* Freigabe des Blatts */
  132.   free ((void *) tree->keyword);
  133.   free ((void *) tree);
  134. }
  135.  
  136. FILE *readfile (char *fname)
  137. {
  138.   char helpstr[MAX_KEYWORD+1], line[MAXLINE+1];
  139.   FILE *in = fopen (fname, "rb");
  140.   long offs;
  141.   char *s;
  142.   tree_t *t;
  143.  
  144.   if (in == NULL)
  145.     error ("Fehler beim Öffnen der Quelldatei %s.\n",
  146.            fname);
  147.   printf("Lesen der Quelldatei %s ",fname);
  148.   while (!feof(in)) {
  149.     checkforkeywords (in, fname, KEYWORDSTR, helpstr);
  150.     checkforkeywords (in, fname, HELPTEXTSTR, NULL);
  151.     kwtree = genleaf (helpstr, ftell (in), kwtree);
  152.     while (!feof (in)) {
  153.       long pos = ftell (in);
  154.       s = fgets (line, MAXLINE, in);
  155.       if (isalpha (*s)) {
  156.         fseek (in, pos, SEEK_SET);
  157.         break;
  158.       }
  159.     }
  160.     t = search (helpstr, kwtree);
  161.     t->textlen = ftell (in) - t->offs - 1;
  162.   }
  163.   return in;
  164. }
  165.  
  166. tree_t *search (char *name, tree_t *tree)
  167. {
  168.   if (tree == NULL) return NULL;
  169.   if (cmpstr (name, tree->keyword) < 0)
  170.     return search (name, tree->left);
  171.   else if (cmpstr (name, tree->keyword) > 0)
  172.     return search (name, tree->right);
  173.   else
  174.     return tree;
  175. }
  176.  
  177. void checkforkeywords (FILE *fp, char *fname,
  178.                        char *type, char *res)
  179. {
  180.   char *s;
  181.   char line[MAXLINE+1];
  182.   char keyw[MAX_KEYWORD+1], helpstr[MAX_KEYWORD+1];
  183.   long pos;
  184.  
  185.   while (!feof (fp)) {
  186.     s = fgets (line, MAXLINE, fp);
  187.     if (!isalpha (*s))
  188.       /* wenn 1. Spalte kein Buchstabe --> continue */
  189.       continue;
  190.     sscanf (line, "%[A-Za-z] %[A-Za-z]",
  191.             &keyw[0], &helpstr[0]);
  192.     if (stricmp (keyw, type))
  193.                  /* wenn kein KEYWORD oder TEXT ... */
  194.       error ("Kein »%s« an der erwarteten Stelle " +
  195.              "in Datei %s.\n", type, fname);
  196.     else
  197.       break;
  198.   }
  199.   if (res != NULL) strcpy (res, helpstr);
  200. }
  201.  
  202. FILE *skipnonalphas (FILE *fp)
  203. {
  204.   int c;
  205.  
  206.   while (!isalpha (c = fgetc (fp)))
  207.     ;
  208.   ungetc (c, fp);
  209.   return fp;
  210. }
  211.  
  212. tree_t *genleaf (char *name, long offs, tree_t *tree)
  213. {
  214.   tree_t *tt = NULL, *t = tree;
  215.                              /* tt hinkt hinterher */
  216.   int cmp;
  217.  
  218.   while (t != NULL) {
  219.     tt = t;
  220.     cmp = cmpstr (name, t->keyword);
  221.     if (cmp < 0)
  222.       t = t->left;
  223.     else if (cmp > 0)
  224.       t = t->right;
  225.     else
  226.       error ("Doppelter Hilfstextname %s in " +
  227.              "Quelldatei %s.\n", name, sname);
  228.   }
  229.   t = (tree_t *) calloc (1, sizeof (tree_t));
  230.   t->keyword = cpystr (name);
  231.   t->left = t->right = NULL;
  232.   t->offs = offs;
  233.   t->textlen = /* noch */ 0;
  234.   if (tt != NULL)
  235.     if (cmp < 0)
  236.       tt->left = t;
  237.     else
  238.       tt->right = t;
  239.  
  240.   return (tree == NULL ? t
  241.                 /* wenn 1. Aufruf, dann Wurzel in *t */
  242.                        : tree);
  243.                             /* danach immer in *tree */
  244. }
  245.  
  246. void showindex (char *fname)
  247. {
  248.   FILE *fp = fopen (fname, "rb");
  249.   int c;
  250.   long offs;
  251.  
  252.   if (fp == NULL)
  253.     error ("Fehler beim Öffnen der Datei %s zum " +
  254.            "Erstellen eines Schlüssel-\n" +
  255.            "wortverzeichnisses.\n", fname);
  256.   while ((c = fgetc (fp)) != 26)
  257.     ;
  258.   fread ((void *) &offs, sizeof (offs), 1, fp);
  259.                                   /* lesen des Offs. */
  260.   fseek (fp, offs, SEEK_SET);
  261.              /* springen zum ermittelten Dateioffset */
  262.  
  263.   while (!feof (fp)) {
  264.     char keyword[MAX_KEYWORD+1] = {""};
  265.     fscanf (fp, "%s", keyword);
  266.     c = fgetc (fp);
  267.     fread ((void *) &offs, sizeof (offs), 1, fp);
  268.     printf ("Schlüsselwort: %s   Dateioffset: %ld   ",
  269.             keyword, offs);
  270.     fread ((void *) &offs, sizeof (offs), 1, fp);
  271.                              /* offs zweckentfremdet */
  272.     printf ("Länge des Hilfstextes: %ld\n", offs);
  273.  
  274.     c = fgetc (fp);
  275.     if (c == 0)
  276.           /* wenn nach einem Satz direkt 0 kommt ... */
  277.       break;                          /* ... Abbruch */
  278.     else
  279.       ungetc (c, fp);
  280.   }
  281.   fclose (fp);
  282.   exit (0);       /* Beenden */
  283. }
  284.  
  285. char *cpystr (char *s)
  286. {
  287.   char *new = (char *) calloc (1, strlen (s)+1);
  288.   return strcpy (new, s);
  289. }
  290.  
  291. void error (const char *format, ...)
  292. {
  293.   va_list argptr;
  294.  
  295.   fputs ("\nFFHC: ", stderr);
  296.  
  297.   va_start (argptr, format);
  298.   vfprintf (stderr, format, argptr);
  299.   va_end (argptr)
  300.  
  301.   exit (0x0A);
  302. }
  303. /* ------------------------------------------------- */
  304. /*              Ende von FFHC.C                      */
  305.  
  306.