home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1990 / 03 / stevens.lst < prev    next >
File List  |  1990-02-13  |  15KB  |  489 lines

  1. C PROGRAMMING COLUMN
  2. by Al Stevens
  3.  
  4. [LISTING ONE]
  5.  
  6. /* ------------ dir.h ----------- */
  7.  
  8. /* Substitute Lattice directory functions for
  9.  * Turbo C directory functions
  10.  */
  11.  
  12. #include <dos.h>
  13.  
  14. #define ffblk FILEINFO
  15. #define ff_name name
  16.  
  17. #define findfirst(path,ff,attr) dfind(ff,path,attr)
  18. #define findnext(ff) dnext(ff)
  19.  
  20.  
  21. [LISTING TWO]
  22.  
  23. /* ---------- search.c ----------- */
  24.  
  25. /* 
  26.  * the TEXTSRCH retrieval process
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <curses.h>
  32. #include "textsrch.h"
  33.  
  34. static char fnames[MAXFILES] [65];
  35. static int fctr;
  36.  
  37. static void select_text(void);
  38. static void display_page(WINDOW *file_selector, int pg);
  39. void display_text(char *fname);
  40.  
  41. /* ---- process the result of a query expression search ---- */
  42. void process_result(struct bitmap map1)
  43. {
  44.     int i;
  45.     extern int file_count;
  46.     for (i = 0; i < file_count; i++)
  47.         if (getbit(&map1, i))
  48.             strncpy(fnames[fctr++], text_filename(i), 64);
  49.     initscr();                 /* initialize curses */
  50.     select_text();             /* select a file to view */
  51.     endwin();                  /* turn off curses */
  52.     fctr = 0;
  53. }
  54.  
  55. /* ------- search the data base for a word match -------- */
  56. struct bitmap search(char *word)
  57. {
  58.     struct bitmap map1;
  59.  
  60.     memset(&map1, 0xff, sizeof (struct bitmap));
  61.     if (srchtree(word) != 0)
  62.         map1 = search_index(word);
  63.     return map1;
  64. }
  65.  
  66. #define HEIGHT 8
  67. #define WIDTH 70
  68. #define HOMEY 3
  69. #define HOMEX 3
  70.  
  71. #define ESC 27
  72.  
  73. /* --- select text file from those satisfying the query ---- */
  74. static void select_text(void)
  75. {
  76.     WINDOW *file_selector;
  77.     int selector = 0; /*selector cursor relative to the table */
  78.     int cursor = 0;   /*selector cursor relative to the screen*/
  79.     int keystroke = 0;
  80.  
  81.     /* --- use a window with a border to display the files -- */
  82.     file_selector = newwin(HEIGHT+2, WIDTH+2, HOMEY, HOMEX);
  83.  
  84.     keypad(file_selector, 1);       /* turn on keypad mode    */
  85.     noecho();                       /* turn off echo mode     */
  86.     wsetscrreg(file_selector, 1, HEIGHT);/* set scroll limits */
  87.  
  88.     /* -------- display the first page of the table --------- */
  89.     display_page(file_selector, 0);
  90.  
  91.     while (keystroke != ESC)    {
  92.         /* ----- draw the window frame ------ */
  93.         box(file_selector, VERT_DOUBLE, HORIZ_DOUBLE);
  94.  
  95.         /* ------------ fill the selector window ------------ */
  96.         mvwaddstr(file_selector, cursor+1, 1, "->");
  97.         wrefresh(file_selector);
  98.  
  99.         /* -------------- make a selection ------------------ */
  100.         keystroke = wgetch(file_selector);/* read a keystroke */
  101.         mvwaddstr(file_selector, cursor+1, 1, "  ");
  102.         switch (keystroke)  {
  103.  
  104.             case KEY_HOME:
  105.                 /* -------- Home key (to top of list) ------- */
  106.                 selector = cursor = 0;
  107.                 display_page(file_selector, 0);
  108.                 break;
  109.  
  110.             case KEY_END:
  111.                 /* ------- End key (to bottom of list) ------ */
  112.                 selector = fctr - HEIGHT;
  113.                 if (selector < 0)   {
  114.                     selector = 0;
  115.                     cursor = fctr-1;
  116.                 }
  117.                 else
  118.                     cursor = HEIGHT-1;
  119.                 display_page(file_selector, selector);
  120.                 break;
  121.  
  122.             case KEY_DOWN:
  123.                 /* - down arrow (move the selector cursor) -- */
  124.                 /* --------- test at bottom of list --------- */
  125.                 if (selector < fctr-1)  {
  126.                     selector++;
  127.                     /* ------ test at bottom of window ------ */
  128.                     if (cursor < HEIGHT-1)
  129.                         cursor++;
  130.                     else    {
  131.                         /* ---- scroll the window up one ---- */
  132.                         scroll(file_selector);
  133.                         /* --- paint the new bottom line ---- */
  134.                         mvwprintw(file_selector, cursor+1, 3,
  135.                             fnames[selector]);
  136.                     }
  137.                 }
  138.                 break;
  139.  
  140.             case KEY_UP:
  141.                 /* --- up arrow (move the selector cursor) -- */
  142.                 /* ----------- test at top of list ---------- */
  143.                 if (selector)   {
  144.                     --selector;
  145.                     /* -------- test at top of window ------- */
  146.                     if (cursor)
  147.                         --cursor;
  148.                     else    {
  149.                         /* --- scroll the window down one --- */
  150.                         winsertln(file_selector);
  151.                         /* ----- paint the new top line ----- */
  152.                         mvwprintw(file_selector, 1, 3,
  153.                             fnames[selector]);
  154.                     }
  155.                 }
  156.                 break;
  157.  
  158.             case '\n':
  159.                 /* -- user selected a file, go display it --- */
  160.                 display_text(fnames[selector]);
  161.                 break;
  162.  
  163.             case ESC:
  164.                 /* --------- exit from the display ---------- */
  165.                 break;
  166.  
  167.             default:
  168.                 /* ----------- invalid keystroke ------------ */
  169.                 beep();
  170.                 break;
  171.         }
  172.     }
  173.     delwin(file_selector);  /* delete the selector window */
  174.     clear();                /* clear the standard window  */
  175.     refresh();
  176. }
  177.  
  178. /* ------ display a page of the file selector window ------- */
  179. static void display_page(WINDOW *file_selector, int line)
  180. {
  181.     int y = 0;
  182.     werase(file_selector);
  183.     while (line < fctr && y < HEIGHT)
  184.         mvwprintw(file_selector, ++y, 3, fnames[line++]);
  185. }
  186.  
  187.  
  188. [LISTING THREE]
  189.  
  190. /* ---------------- display.c ----------------- */
  191.  
  192. /* Display a text file on the screen.
  193.  * User may scroll and page the file.
  194.  * Highlight key words from the search.
  195.  * User may jump to the next and previous key word.
  196.  */
  197.  
  198. #include <stdio.h>
  199. #include <stdlib.h>
  200. #include <curses.h>
  201. #include <ctype.h>
  202. #include <string.h>
  203. #include "textsrch.h"
  204.  
  205. #define ESC 27
  206.  
  207. /* ----------- header block for a line of text ----------- */
  208. struct textline {
  209.     char keys[5];               /* offsets to key words     */
  210.     struct textline *nextline;  /* pointer to next line     */
  211.     char text;                  /* first character of text  */
  212. };
  213.  
  214. /* --------- listhead for text line linked list -------- */
  215. struct textline *firstline;
  216. struct textline *lastline;
  217.  
  218. int pagemarked(int topline);
  219. static void do_display(FILE *fp);
  220. static void findkeys(struct textline *thisline);
  221. static void display_textpage(WINDOW *text_window, int line);
  222.  
  223. /* ---------- display the text in a selected file --------- */
  224. void display_text(char *filepath)
  225. {
  226.     FILE *fp;
  227.  
  228.     fp = fopen(filepath, "r");
  229.     if (fp != NULL) {
  230.         do_display(fp);
  231.         fclose(fp);
  232.     }
  233.     else    {
  234.         /* ----- the selected file does not exist ----- */
  235.         char ermsg[80];
  236.         sprintf(ermsg, "%s: No such file", filepath);
  237.         error_handler(ermsg);
  238.     }
  239. }
  240.  
  241. static void do_display(FILE *fp)
  242. {
  243.     char line[120];
  244.     WINDOW *text_window;
  245.     int keystroke = 0;
  246.     int topline = 0;
  247.     int linect = 0;
  248.     struct textline *thisline;
  249.  
  250.     firstline = lastline = NULL;
  251.  
  252.     /* --------- read the text file into the heap ------- */
  253.     while (fgets(line, sizeof line, fp) != NULL)    {
  254.         line[78] = '\0';
  255.         thisline =
  256.             malloc(sizeof(struct textline)+strlen(line)+1);
  257.         if (thisline == NULL)
  258.             break;      /* no more room */
  259.  
  260.         /* ----- clear the text line record space -------- */
  261.         memset(thisline, '\0', sizeof(struct textline) +
  262.                         strlen(line)+1);
  263.  
  264.         /* ---- build the text line linked list entry ---- */
  265.         if (lastline != NULL)
  266.             lastline->nextline = thisline;
  267.         lastline = thisline;
  268.         if (firstline == NULL)
  269.             firstline = thisline;
  270.         thisline->nextline = NULL;
  271.         strcpy(&thisline->text, line);
  272.  
  273.         /* ------------ mark the key words ------------ */
  274.         findkeys(thisline);
  275.         linect++;
  276.     }
  277.  
  278.     /* ------- build a window to display the text ------- */
  279.     text_window = newwin(LINES, COLS, 0, 0);
  280.     keypad(text_window, 1);     /* turn on keypad mode    */
  281.  
  282.     while (keystroke != ESC)    {
  283.         /* --- display the text and draw the window frame --- */
  284.         display_textpage(text_window, topline);
  285.         box(text_window, VERT_SINGLE, HORIZ_SINGLE);
  286.         wrefresh(text_window);
  287.  
  288.         /* ------------ read a keystroke ------------- */
  289.         keystroke = wgetch(text_window);
  290.         switch (keystroke)  {
  291.             case KEY_HOME:
  292.                 /* ------- Home key (to top of file) ------ */
  293.                 topline = 0;
  294.                 break;
  295.             case KEY_DOWN:
  296.                 /* --- down arrow (scroll up) ---- */
  297.                 if (topline < linect-(LINES-2))
  298.                     topline++;
  299.                 break;
  300.             case KEY_UP:
  301.                 /* ----- up arrow (scroll down) ---- */
  302.                 if (topline)
  303.                     --topline;
  304.                 break;
  305.             case KEY_PGUP:
  306.                 /* -------- PgUp key (previous page) -------- */
  307.                 topline -= LINES-2;
  308.                 if (topline < 0)
  309.                     topline = 0;
  310.                 break;
  311.             case KEY_PGDN:
  312.                 /* -------- PgDn key (next page) ------------ */
  313.                 topline += LINES-2;
  314.                 if (topline <= linect-(LINES-2))
  315.                     break;
  316.             case KEY_END:
  317.                 /* ------- End key (to bottom of file) ------ */
  318.                 topline = linect-(LINES-2);
  319.                 if (topline < 0)
  320.                     topline = 0;
  321.                 break;
  322.             case KEY_RIGHT:
  323.                 /* - Right arrow. Go to next marked key word  */
  324.                 do  {
  325.                     /* -- repeat PGDN until we find a mark -- */
  326.                     topline += LINES-2;
  327.                     if (topline > linect-(LINES-2)) {
  328.                         topline = linect-(LINES-2);
  329.                         if (topline < 0)
  330.                             topline = 0;
  331.                     }
  332.                     if (pagemarked(topline))
  333.                         break;
  334.                 }   while (topline &&
  335.                         topline < linect-(LINES-2));
  336.                 break;
  337.             case KEY_LEFT:
  338.                 /* Left arrow. Go to previous marked key word */
  339.                 do  {
  340.                     /* -- repeat PGUP until we find a mark -- */
  341.                     topline -= LINES-2;
  342.                     if (topline < 0)
  343.                         topline = 0;
  344.                     if (pagemarked(topline))
  345.                         break;
  346.                 }   while (topline > 0);
  347.                 break;
  348.             case ESC:
  349.                 break;
  350.             default:
  351.                 beep();
  352.                 break;
  353.         }
  354.     }
  355.     /* -------- clean up and exit --------- */
  356.     wclear(text_window);
  357.     wrefresh(text_window);
  358.     delwin(text_window);
  359.     thisline = firstline;
  360.     while (thisline != NULL)    {
  361.         free(thisline);
  362.         thisline = thisline-> nextline;
  363.     }
  364. }
  365.  
  366. /* ---- test a page to see if a marked keyword is on it ---- */
  367. int pagemarked(int topline)
  368. {
  369.     struct textline *tl = firstline;
  370.     int line;
  371.     while (topline-- && tl != NULL)
  372.         tl = tl->nextline;
  373.     for (line = 0; tl != NULL && line < LINES-2; line++)    {
  374.         if (*tl->keys)
  375.             break;
  376.         tl = tl->nextline;
  377.     }
  378.     return *tl->keys;
  379. }
  380.  
  381. #define iswhite(c) ((c)==' '||(c)=='\t'||(c)=='\n')
  382.  
  383. /* ---- Find the key words in a line of text. Mark their
  384.    character positions in the text structure ------- */
  385. static void findkeys(struct textline *thisline)
  386. {
  387.     char *cp = &thisline->text;
  388.     int ofptr = 0;
  389.  
  390.     while (*cp && ofptr < 5)    {
  391.         struct postfix *pf = pftokens;/* the query expression */
  392.         while (iswhite(*cp))  /* skip the white space */
  393.             cp++;
  394.         if (*cp)    {
  395.             /* ---- test this word against each argument in the
  396.                 query expression ------- */
  397.             while (pf->pfix != TERM)    {
  398.                 if (pf->pfix == OPERAND &&
  399.                         strnicmp(cp, pf->pfixop,
  400.                             strlen(pf->pfixop)) == 0)
  401.                     break;
  402.                 pf++;
  403.             }
  404.             if (pf->pfix != TERM)
  405.                 /* ----- the word matches a query argument.
  406.                    Put its offset into the line's header --- */
  407.                 thisline->keys[ofptr++] =
  408.                     (cp - &thisline->text) & 255;
  409.  
  410.             /* --- skip to the next word in the line --- */
  411.             while (*cp && !iswhite(*cp))
  412.                 cp++;
  413.         }
  414.     }
  415. }
  416.  
  417. /* --- display page of text starting with specified line --- */
  418. static void display_textpage(WINDOW *text_window, int line)
  419. {
  420.     struct textline *thisline = firstline;
  421.     int y = 1;
  422.  
  423.     wclear(text_window);
  424.     wmove(text_window, 0, 0);
  425.  
  426.     /* ---- point to the first line of the page ----- */
  427.     while (line-- && thisline != NULL)
  428.         thisline = thisline->nextline;
  429.  
  430.     /* ------- display all the lines on the page ------ */
  431.     while (thisline != NULL && y < LINES-1) {
  432.         char *cp = &thisline->text;
  433.         char *kp = thisline->keys;
  434.         char off = 0;
  435.         wmove(text_window, y++, 1);
  436.  
  437.         /* ------ a character at a time -------- */
  438.         while (*cp) {
  439.             /* --- is this character position a key word? --- */
  440.             if (*kp && off == *kp)  {
  441.                 wstandout(text_window); /* highlight key words*/
  442.                 kp++;
  443.             }
  444.  
  445.             /* ---- is this character white space? ---- */
  446.             if (iswhite(*cp))
  447.                 wstandend(text_window); /* turn off hightlight*/
  448.  
  449.             /* ---- write the character to the window ------ */
  450.             waddch(text_window, *cp);
  451.             off++;
  452.             cp++;
  453.         }
  454.         /* -------- a line at a time ---------- */
  455.         thisline = thisline->nextline;
  456.     }
  457. }
  458.  
  459.  
  460. [LISTING FOUR]
  461.  
  462. /* ------------- error.c ------------- */
  463.  
  464. /* General-purpose error handler */
  465.  
  466. #include <curses.h>
  467. #include <string.h>
  468.  
  469. void error_handler(char *ermsg)
  470. {
  471.     int x, y;
  472.     WINDOW *error_window;
  473.  
  474.     x = (COLS - (strlen(ermsg)+2)) / 2;
  475.     y = LINES/2-1;
  476.     error_window = newwin(3, 2+strlen(ermsg), y, x);
  477.     box(error_window, VERT_SINGLE, HORIZ_SINGLE);
  478.     mvwprintw(error_window, 1, 1, ermsg);
  479.     wrefresh(error_window);
  480.     beep();
  481.     getch();
  482.     wclear(error_window);
  483.     wrefresh(error_window);
  484.     delwin(error_window);
  485. }
  486.  
  487.  
  488.  
  489.