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

  1. /* ------------------------------------------------- */
  2. /*                   FFH-LIB.C                       */
  3. /*              FFast-Help-Library                   */
  4. /* Die Routinen dieser Datei können in ein belie-    */
  5. /* biges Programm eingebunden werden. Durch den      */
  6. /* Aufruf der Funktionen können die mit FFHC compi-  */
  7. /* lierten Hilfstexte verwendet werden.              */
  8. /*       (c) 1991 Axel Geßner & DMV-Verlag           */
  9. /* ------------------------------------------------- */
  10.  
  11. #include "ffh.h"
  12. #include "ffh-lib.h"
  13. #include <conio.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <dos.h>
  18. #include <alloc.h>
  19.  
  20. #define FRAME_FORE    WHITE
  21. #define FRAME_BACK    BLACK
  22. #define TEXT_FORE     LIGHTGRAY
  23. #define TEXT_BACK     BLACK
  24. #define HIGH_FORE     WHITE
  25. #define HIGH_BACK     BLACK
  26. #define HIGH_SEL_FORE BLACK
  27. #define HIGH_SEL_BACK LIGHTGRAY
  28. #define WIN_X1        16
  29. #define WIN_Y1         5
  30. #define WIN_X2        68
  31. #define WIN_Y2        22
  32. #define WIN_STYLE      2
  33. #define MAX_HELP_V    10
  34. #define MAX_XREFS     50
  35. #define MAX_PAGES     20
  36.  
  37. typedef struct list         /* Schlüsselwortliste    */
  38. {
  39.   char   *keyword;          /* Schlüsselwort         */
  40.   long   offs;              /* Dateioffset           */
  41.   long   textlen;           /* Länge des Hilfstextes */
  42.   struct list *prev, *next;
  43. } list_t;
  44.  
  45. /* --- PROTOTYPEN ---------------------------------- */
  46. /* Listenverwaltung                                  */
  47.  
  48. list_t *search (char *name, list_t *list);
  49.   /* sucht in der alphabetisch geordneten Liste      */
  50.   /* »list« nach »name«                              */
  51.  
  52. list_t *insert (char *name, long offs,
  53.                 long textlen, list_t *at);
  54.   /* ordnet die Daten als at->next in der Liste ein  */
  55.  
  56. list_t *dellist (list_t *list);
  57.   /* löscht die Liste »list« vollständig             */
  58.  
  59. /* Fensterverwaltung                                 */
  60.  
  61. static void box(int x1,int y1,int x2,int y2,int style);
  62.   /* zeichnet Rahmen mit den angeg. Koordinaten      */
  63.  
  64. static void mkwindow(int x1,int y1,int x2,int y2,
  65.                      int style,int fore,int back);
  66.   /* Öffnet Fenster                                  */
  67.  
  68. static void rmwindow(void);
  69.   /* schließt Fenster wieder                         */
  70.  
  71. static void setheader(char *s);
  72.   /* setzt eine Überschrift im Fenster               */
  73.  
  74. static void setfoot(char *s);
  75.   /* setzt Fußnote im Fenster                        */
  76.  
  77. /* System-Verwaltung */
  78.  
  79. static int getindex (void);
  80.   /* liefert den niedrigstmöglichen freien Index von */
  81.   /* »help_v« zurück; bzw. -1 für »vollen« Vektor    */
  82.  
  83. static char *gethelptext (int handle, char *keyword);
  84.   /* liefert in NEU ALLOKIERTEM Speicher den         */
  85.   /* eigentlichen Hilfstext zurück; ferner wird die  */
  86.   /* Liste eine Liste der Querverweise erzeugt       */
  87.  
  88. static char *outtext (char *s);
  89.   /* gibt den Text ab s abwärts oder aufwärts        */
  90.   /* gerichtet aus                                   */
  91.  
  92. /* DATEN */
  93. struct
  94. {
  95.   FILE   *fp;     /* Dateipointer auf die Hilfedatei */
  96.   list_t *list;   /* Liste für Inhaltsverzeichnis    */
  97. } help_v [MAX_HELP_V];
  98.             /* Vektor der verschiedenen Hilfedateien */
  99.  
  100. struct
  101. {
  102.   char name[MAX_KEYWORD+1];  /* Name des Bezeichners */
  103.   int  x, y;          /* Position auf dem Bildschirm */
  104. } xref_v [MAX_XREFS]; /* Vektor der Crossreferences  */
  105.  
  106. struct
  107. {
  108.   char   *start;      /* Start der aktuellen Seite   */
  109. } page_v [MAX_PAGES];
  110. int maxpage = 0;
  111.  
  112. static int initialized = 0;
  113. void *winback;       /* Hintergrund für Hilfefenster */
  114. struct text_info ti;
  115. int (*cmpstr) (const char *s1, const char *s2);
  116. int tabsize = 2;
  117.  
  118.  
  119. /* ------------------------------------------------- */
  120. /* Globale Steuer-Prozeduren                         */
  121.  
  122. void initFFHlib (void)
  123. {
  124.   int i;
  125.  
  126.   for (i = 0; i < MAX_HELP_V; i++) {
  127.     help_v[i].fp   = NULL;
  128.     help_v[i].list = NULL;
  129.   }
  130.   initialized = 1;
  131.   cmpstr = stricmp;
  132.   atexit (exitFFHlib);
  133. }
  134.  
  135. void exitFFHlib (void)
  136.   /* Exit-Func; von initFFHlib autom. installiert */
  137. {
  138.   int i;
  139.  
  140.   for (i = 0; i < MAX_HELP_V; i++) {
  141.     if (help_v[i].fp == NULL)
  142.       continue;
  143.     fclose (help_v[i].fp);
  144.     help_v[i].list = dellist (help_v[i].list);
  145.     help_v[i].fp = NULL;
  146.   }
  147.   initialized = 0;
  148. }
  149.  
  150. int inithelp (char *fname)
  151. {
  152.   FILE *fp;
  153.   int ndx = getindex ();
  154.  
  155.   fp = fopen (fname, "rb");
  156.   if (fp == NULL || !initialized || ndx == -1)
  157.     return -1;
  158.   help_v[ndx].fp = fp;
  159.   fread ((void *) &header, sizeof (header), 1, fp);
  160.   fseek (fp, header.offs, SEEK_SET);
  161.   while (!feof (fp)) {
  162.     char keyword[40] = {""};
  163.     int  c;
  164.     long offs, textlen;
  165.  
  166.     fscanf (fp, "%s", keyword);
  167.     c = fgetc (fp);
  168.     fread ((void *) &offs, sizeof (offs), 1, fp);
  169.     fread ((void *) &textlen, sizeof (textlen), 1, fp);
  170.     help_v[ndx].list = insert (keyword, offs, textlen,
  171.                                help_v[ndx].list);
  172.     c = fgetc (fp);
  173.     if (c == 0)
  174.       break;            /* Abbruch, da Endekriterium */
  175.     else
  176.       ungetc (c, fp);
  177.   }
  178.   return ndx;
  179. }
  180.  
  181. int exithelp (int handle)
  182. {
  183.   if (handle > MAX_HELP_V || help_v[handle].fp == NULL)
  184.     return -1;
  185.   fclose (help_v[handle].fp);
  186.   help_v[handle].fp = NULL;
  187.   help_v[handle].list = dellist (help_v[handle].list);
  188.   return handle;
  189. }
  190.  
  191. int showhelp (int handle, char *keyword)
  192. {
  193.   char *s = keyword;
  194.  
  195.   mkwindow (WIN_X1, WIN_Y1, WIN_X2, WIN_Y2,
  196.             WIN_STYLE, FRAME_FORE, FRAME_BACK);
  197.   setfoot ("PgUp/PgDn - Left/Right");
  198.   setheader ("FFast-Help");
  199.   do {
  200.     char *ss = gethelptext (handle, s);
  201.  
  202.     if (!ss) break;
  203.     textcolor (TEXT_FORE);
  204.     textcolor (TEXT_BACK);
  205.     s = outtext (ss);
  206.     free ((void *) ss);
  207.   } while (s);
  208.  
  209.   rmwindow ();
  210.   return handle;
  211. }
  212.  
  213. /* ------------------------------------------------- */
  214. /* System-Verwaltung                                 */
  215.  
  216. char *outtext (char *s)
  217. {
  218.   int key     = 0;
  219.   int sel     = 0;   /* sel = selected              */
  220.   int aktpage = 0;   /* momentan dargestellte Seite */
  221.   int aktxref = 0;   /* aktuelle xref               */
  222.  
  223.   while (key != 27) {
  224.     char *s_sav = s;
  225.  
  226.     clrscr ();
  227.     while (*s) {
  228.       if (wherey() == ti.winbottom-ti.wintop+1) {
  229.         page_v[maxpage++].start = s_sav;
  230.         goto end_while;
  231.       }
  232.       switch (*s) {
  233.         case '\t' : {
  234.             int i;
  235.             for (i = 1; i <= tabsize; i++)
  236.               putch (' ');
  237.           }
  238.           break;
  239.         case 'Γ'  :
  240.             s++;
  241.             if (aktxref != sel)
  242.               textcolor (HIGH_FORE);
  243.               textbackground (HIGH_BACK);
  244.             else
  245.               textcolor (HIGH_SEL_FORE);
  246.               textbackground (HIGH_SEL_BACK);
  247.             xref_v[aktxref].x = wherex();
  248.             xref_v[aktxref].y = wherey ();
  249.             cprintf ("%s", xref_v[aktxref].name);
  250.             s += strlen (xref_v[aktxref].name);
  251.             aktxref++;
  252.             break;
  253.         default :
  254.             textcolor (TEXT_FORE);
  255.             textbackground (TEXT_BACK);
  256.             putch (*s);
  257.             break;
  258.       }
  259.       s++;
  260.     }
  261. end_while:
  262.     key = getkey();
  263.     switch (key) {
  264.       case -77  : /* Cursor right */
  265.       case -80  : /* Cursor down */
  266.           if (sel < aktxref-1) sel++;
  267.                   /* aktxref höchst. bel. Element */
  268.           s = s_sav;
  269.           maxpage--;
  270.                   /* die Seite wird beibehalten   */
  271.           break;
  272.       case -75  : /* Cursor left */
  273.       case -72  : /* Cursor up */
  274.           if (sel != 0) sel--;
  275.           s = s_sav;
  276.           maxpage--;
  277.                   /* die Seite wird beibehalten  */
  278.           break;
  279.       case -73  : /* Page up */
  280.           if (aktpage != 0) aktpage--;
  281.           s = page_v[aktpage].start;
  282.           maxpage--;
  283.           break;
  284.       case -81  : /* Page down */
  285.           if (aktpage < maxpage)
  286.             aktpage++;
  287.           else
  288.             s = s_sav;
  289.           break;
  290.       case 13   : /* Return */
  291.           return xref_v[sel].name;
  292.       case 27   : /* Esc */
  293.           break;
  294.       default   : /* Andere Tasten: nichts tun */
  295.           break;
  296.     }
  297.     aktxref = 0;
  298.   }
  299.   return NULL;
  300. }
  301.  
  302. int getindex (void)    /* liefert freien Index */
  303. {
  304.   int i;
  305.  
  306.   for (i = 0; i < MAX_HELP_V; i++)
  307.     if (help_v[i].fp == NULL)     /* nicht verwendet */
  308.       return i;
  309.   return -1;
  310. }
  311.  
  312. char *gethelptext (int handle, char *keyword)
  313. {
  314.   list_t *l = search (keyword, help_v[handle].list);
  315.   char *s = (char *) calloc (l->textlen + 1,
  316.                      sizeof (char)), *ss;
  317.   FILE *fp = help_v[handle].fp;
  318.   char aktxref = 0;
  319.  
  320.   if (l == NULL) {
  321.     free ((void *) s);
  322.     return NULL;
  323.   }
  324.   fseek (fp, l->offs, SEEK_SET);
  325.   fread ((void *) s, l->textlen, 1, fp);
  326.  
  327.   for (ss = s; *s; s++) {
  328.     if (*s == 'Γ') {
  329.       char *org = ++s;
  330.       while (*s != 'Γ') s++;
  331.       strncpy (xref_v[aktxref].name,org, s-org);
  332.       xref_v[aktxref].name[s-org] = '\0';
  333.       aktxref++; s++;
  334.     }
  335.   }
  336.   return ss;
  337. }
  338.  
  339. int getkey (void)
  340. {
  341.   union REGS r;
  342.   r.h.ah = 0;
  343.   int86(0x16,&r,&r);
  344.   return (r.h.al == 0) ? -r.h.ah : r.h.al;
  345. }
  346.  
  347. /* ------------------------------------------------- */
  348. /* Listen-Verwaltung                                 */
  349.  
  350. list_t *search (char *name, list_t *list)
  351. {
  352.   list_t *l = list;
  353.   char toleft;
  354.  
  355.   if (cmpstr (name, list->keyword) == 0)
  356.     return list;
  357.   else
  358.     if (cmpstr (name, list->keyword) < 0)
  359.       l = l->prev, toleft = 1;
  360.     else
  361.       l = l->next, toleft = 0;
  362.  
  363.   switch (toleft) {
  364.     case 0 : /* nach rechts gehend */
  365.        while (l != NULL) {
  366.          if (!cmpstr (name, l->keyword))
  367.            break;
  368.          else
  369.            l = l->next;
  370.        }
  371.        return l;
  372.     case 1 : /* nach links gehend */
  373.        while (l != NULL) {
  374.          if (!cmpstr (name, l->keyword))
  375.            break;
  376.          else
  377.            l = l->prev;
  378.        }
  379.        return l;
  380.     }
  381.   return NULL;
  382. }
  383.  
  384. list_t *insert (char *name, long offs,
  385.                long textlen, list_t *at)
  386. {
  387.   if (at == NULL) {    /* allererstes Element */
  388.     at = (list_t *) calloc (1, sizeof (list_t));
  389.     at->keyword = (char *) calloc (strlen(name)+1,
  390.                            sizeof (char));
  391.     strcpy (at->keyword, name);
  392.     at->offs = offs;
  393.     at->textlen = textlen;
  394.   } else {
  395.     at->next = (list_t *) calloc (1, sizeof (list_t));
  396.     at->next->prev = at;
  397.     at = at->next;
  398.     at->keyword = (char *) calloc (strlen(name)+1,
  399.                            sizeof (char));
  400.     strcpy (at->keyword, name);
  401.     at->offs = offs;
  402.     at->textlen = textlen;
  403.   }
  404.   return at;
  405. }
  406.  
  407. list_t *dellist (list_t *list)
  408. {
  409.   list_t *n, *l = list;
  410.   while (l->next != NULL)
  411.     l = l->next;
  412.   l = list;
  413.   while (l != NULL) {
  414.     n = l->prev;
  415.     free ((void *) l->keyword);
  416.     free ((void *) l);
  417.     l = n;
  418.   }
  419.   return NULL;
  420. }
  421.  
  422. /* ------------------------------------------------- */
  423. /* Window-Verwaltung                                 */
  424.  
  425. void box(int x1,int y1,int x2,int y2,int style)
  426.                                   /* Zeichnet Rahmen */
  427. {
  428.   unsigned i;
  429.   unsigned hor,ver,lo,ro,lu,ru;
  430.   /* horiz,vert,links/rechts oben,links/rechts unten */
  431.  
  432.   switch (style) {
  433.     case 1  : hor = '─';
  434.               ver = '│';
  435.               lo = '┌';
  436.               ro = '┐';
  437.               lu = '└';
  438.               ru = '┘';
  439.               break;
  440.     case 2  : hor = '═';
  441.               ver = '║';
  442.               lo = '╔';
  443.               ro = '╗';
  444.               lu = '╚';
  445.               ru = '╝';
  446.               break;
  447.   }
  448.   gotoxy(x1, y1); putch(lo);
  449.   for (i = 1; i <= x2-x1-1; i++)
  450.     putch(hor);
  451.   putch(ro);
  452.   for (i = 1; i <= y2-y1-1; i++) {
  453.     gotoxy(x1, y1+i); putch(ver);
  454.     gotoxy(x2, y1+i); putch(ver);
  455.   }
  456.   gotoxy(x1,y2);putch(lu);
  457.   for (i = 1; i <= x2-x1-1; i++)
  458.     putch(hor);
  459.   putch(ru);
  460. }
  461.  
  462. void mkwindow(int x1,int y1,int x2,int y2,int style,
  463.               int fore,int back)
  464. {
  465.   winback = malloc((y2-y1+1)*(x2-x1+1)*2);
  466.   window(1,1,80,25);
  467.   gettext(x1,y1,x2,y2,winback);
  468.   textcolor (fore);
  469.   textbackground (back);
  470.   box (x1,y1,x2,y2,style);
  471.   window (x1+1, y1+1, x2-1, y2-1);
  472.   gettextinfo (&ti);
  473.   clrscr();
  474. }
  475.  
  476. void rmwindow(void)
  477. {
  478.   puttext(ti.winleft-1,ti.wintop-1,
  479.           ti.winright+1,ti.winbottom+1,winback);
  480.   window(ti.winleft-1,ti.wintop-1,
  481.          ti.winright+1,ti.winbottom+1);
  482.   free ((void *) winback);
  483. }
  484.  
  485. void setheader(char *s)
  486. {
  487.   int x1 = ti.winleft;
  488.   int x2 = ti.winright;
  489.   window(1,1,80,25);
  490.   gotoxy(x1+((x2-x1+1-strlen(s)) >> 1),ti.wintop-1);
  491.   cprintf("%s",s);
  492.   window(x1,ti.wintop,x2,ti.winbottom);
  493. }
  494.  
  495. void setfoot(char *s)
  496. {
  497.   window(1,1,80,25);
  498.   gotoxy(ti.winright+1-strlen(s),ti.winbottom+1);
  499.   cprintf("%s",s);
  500.   window(ti.winleft,ti.wintop,
  501.          ti.winright,ti.winbottom);
  502. }
  503. /* ------------------------------------------------- */
  504. /*                Ende von FFH-LIB.C                 */
  505.  
  506.