home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2958 < prev    next >
Internet Message Format  |  1991-03-03  |  51KB

  1. From: lee@sq.sq.com (Liam R. E. Quin)
  2. Newsgroups: alt.sources
  3. Subject: lq-text Full Text Retrieval Database Part 10/13
  4. Message-ID: <1991Mar4.021007.16849@sq.sq.com>
  5. Date: 4 Mar 91 02:10:07 GMT
  6.  
  7. : cut here --- cut here --
  8. : To unbundle, sh this file
  9. #! /bin/sh
  10. : part 10
  11. echo x - lq-text/src/menu/text.c 1>&2
  12. sed 's/^X//' >lq-text/src/menu/text.c <<'@@@End of lq-text/src/menu/text.c'
  13. X/* Use menu interface as a simple front end to a prototype
  14. X * text retrieval program...
  15. X *
  16. X * Liam R. Quin, September 11th 1989
  17. X * 
  18. X * $Id: text.c,v 1.7 90/10/13 03:07:14 lee Rel1-10 $
  19. X *
  20. X * $Log:    text.c,v $
  21. X * Revision 1.7  90/10/13  03:07:14  lee
  22. X * After Sabre-C.
  23. X * 
  24. X * Revision 1.6  90/10/04  16:28:25  lee
  25. X * SysV compat improved.
  26. X * 
  27. X * Revision 1.5  90/10/03  21:33:24  lee
  28. X * Some work to make it OK on BSD;
  29. X * Changed BSD to CURSESX for curses diffs.
  30. X * 
  31. X * Revision 1.4  90/08/29  21:51:16  lee
  32. X * lq-text browser
  33. X * 
  34. X * Revision 1.3  90/03/09  23:24:39  lee
  35. X * Added first hooks for pattern menu...
  36. X * 
  37. X * Revision 1.1  89/10/12  04:04:50  lee
  38. X * Initial revision
  39. X * 
  40. X *
  41. X */
  42. X
  43. X#ifndef BSD
  44. X#include <malloc.h>
  45. X#endif
  46. X#ifdef ultrix
  47. X# include <cursesX.h>
  48. X#else
  49. X# include <curses.h>
  50. X#endif
  51. X
  52. X#ifndef A_STANDOUT
  53. X# include "oldcurses.h"
  54. X#endif
  55. X
  56. X#include <ctype.h>
  57. X
  58. X#include "globals.h"
  59. X
  60. X#include "menu.h"
  61. X#include "error.h"
  62. X
  63. X#include <sys/types.h>
  64. X#include "fileinfo.h"
  65. X#include "wordinfo.h"
  66. X#include "wordrules.h"
  67. X#include "pblock.h"
  68. X#include "phrase.h"
  69. X#include "emalloc.h"
  70. X
  71. X#ifndef KEY_LEFT
  72. X# define KEY_LEFT '\b'
  73. X#endif
  74. X
  75. Xint MenuUsed = 0; /* (sigh) */
  76. X/* The above is needed because of a bug in "m". */
  77. X
  78. X/* Some handy macros */
  79. X#ifndef new
  80. X# define new(type) (type *) emalloc(sizeof(type))
  81. X#endif
  82. X
  83. X#ifndef STREQ /* STREQ is an optimisation due to Henry Spencer, utzoo!henry */
  84. X# define STREQ(henry,utzoo) ((*(henry)==(*(utzoo)))&&!strcmp((henry),(utzoo)))
  85. X#endif
  86. X
  87. Xchar *cmdname = (char *) 0;
  88. Xchar *progname = "[menu]";
  89. X
  90. X/** Unix system calls that need to be declared **/
  91. Xextern void exit();
  92. Xextern int unlink();
  93. X
  94. X/** Unix/C library functions that need to be declared **/
  95. Xextern int strcmp();
  96. Xextern char *getenv();
  97. Xextern char *strrchr();
  98. Xextern int getopt();
  99. X
  100. X/** Curses functions that need to be declared: **/
  101. X#ifndef beep
  102. X extern int beep();
  103. X#endif
  104. X#ifndef endwin
  105. X extern int endwin();
  106. X#endif
  107. X#ifdef A_STANDOUT
  108. X# ifndef isendwin
  109. X  extern int isendwin(); /* only needed on V.3.2 I think */
  110. X# endif
  111. X#endif
  112. X#ifndef keypad
  113. X extern int keypad();
  114. X#endif
  115. X#ifndef mvwaddstr
  116. X extern int mvwaddstr();
  117. X#endif
  118. X#ifndef mvwprintw
  119. X extern int mvwprintw();
  120. X#endif
  121. Xextern int waddstr(), wclear(), wclrtoeol();
  122. X#ifndef wmove
  123. X extern int wmove();
  124. X#endif
  125. X#ifndef wrefresh
  126. X extern int wrefresh();
  127. X#endif
  128. X#ifndef noecho
  129. X extern int noecho();
  130. X#endif
  131. X#ifndef nonl
  132. X extern int nonl();
  133. X#endif
  134. X#ifdef CURSESX
  135. X extern int w32addch();
  136. X#endif
  137. X
  138. X/** lqtext functions that need to be declared: **/
  139. Xextern void SetDefaults();
  140. X#ifndef efree
  141. Xextern void efree();
  142. X#endif
  143. X
  144. X/** libmenu functions that need to be declared **/
  145. Xextern int UseMenuBar();
  146. Xint AddPhrase();
  147. Xextern t_Menu *NewMenu();
  148. X
  149. X/** Functions within this file that must be declared: **/
  150. Xvoid ClearMessage(), SetMessage();
  151. Xvoid StartCurses(), EndCurses();
  152. Xextern int MySystem();
  153. Xvoid ShowInstructions(), ClearInstructions();
  154. Xvoid Usage();
  155. Xt_MenuBar *SetUpMenus();
  156. X
  157. X/** **/
  158. X
  159. Xstatic int PhraseCount = 0;
  160. X
  161. Xint
  162. Xmain(argc, argv)
  163. X    int argc; char *argv[];
  164. X{
  165. X    /* (unused) extern char *optarg; */
  166. X    /* (unused) extern int optind; */
  167. X    /** end getopts stuff **/
  168. X    t_MenuBar *MenuBar;
  169. X    void SetUpScreen();
  170. X
  171. X    int optchar; /** start getopts stuff **/
  172. X    int errflag = 0;
  173. X
  174. X    /* Make progname point to the last component of argv[0] */
  175. X    progname = strrchr(argv[0], '/');
  176. X    if (progname) {
  177. X    if (*++progname == '\0') {
  178. X        --progname; /* No Unix filename can do this! */
  179. X    }
  180. X    } else {
  181. X    progname = argv[0];
  182. X    }
  183. X    /* cmdname lets you say CMDNAME=`basename $0` in a shell script
  184. X     * for better error reporting
  185. X     */
  186. X    cmdname = getenv("CMDNAME");
  187. X
  188. X    SetDefaults(argc, argv);
  189. X
  190. X    while ((optchar = getopt(argc, argv, "z:ZvXV")) != EOF) {
  191. X    switch (optchar) {
  192. X    case 'z':
  193. X    case 'Z': /* already dealt with by Defaults */
  194. X        break;
  195. X    case 'X':
  196. X        Usage(0);
  197. X        /*NOTREACHED*/
  198. X        break;
  199. X    case 'V':
  200. X        error(ERR_FATAL, "Version: $Id: text.c,v 1.7 90/10/13 03:07:14 lee Rel1-10 $");
  201. X        /*NOTREACHED*/
  202. X        exit(1);
  203. X    case '?':
  204. X        errflag++;
  205. X    }
  206. X    }
  207. X    if (errflag) {
  208. X    Usage(1);
  209. X    }
  210. X
  211. X    StartCurses();
  212. X
  213. X    MenuBar = SetUpMenus();
  214. X
  215. X    SetUpScreen();
  216. X
  217. X    while (UseMenuBar(MenuBar) != -2) {
  218. X    if (PhraseCount == 0) {
  219. X        ShowInstructions();
  220. X    }
  221. X    }
  222. X
  223. X    EndCurses();
  224. X
  225. X    exit(0);
  226. X    /*NOTREACHED*/
  227. X    return 1; /* this is for lint and gcc -Wall... */
  228. X}
  229. X
  230. Xvoid
  231. XUsage(exitstatus)
  232. X    int exitstatus;
  233. X{
  234. X    if (cmdname) fprintf(stderr, "%s: ", cmdname);
  235. X    fprintf(stderr, "%s: usage: %s [-XV]\n", progname, progname);
  236. X    fprintf(stderr, "\t-X\t-- print this eXplanation\n");
  237. X    fprintf(stderr, "\t-V\t-- print %s version info\n", progname);
  238. X    exit(exitstatus);
  239. X}
  240. X
  241. Xstatic int ThisCol = 0;
  242. Xstatic int ThisRow = 5;
  243. X
  244. X/* A list of phrases: */
  245. Xstatic t_Phrase *PhraseList = (t_Phrase *) 0;
  246. X
  247. Xint
  248. XGetWords()
  249. X{
  250. X    int i;
  251. X    char Buffer[1024];
  252. X    char *q;
  253. X    t_Phrase *PP;
  254. X
  255. X    ThisRow = 5;
  256. X
  257. X    if (PhraseCount && PhraseList) {
  258. X    t_Phrase *p;
  259. X
  260. X    PP = PhraseList;
  261. X
  262. X    while (PP) {
  263. X        p = PP->Next;
  264. X        (void) efree((char *) PP);
  265. X                /* BUG: does not free everything: NOTDONE */
  266. X                    /* (I need a destructor function here!!!!!) */
  267. X        PP = p;
  268. X    }
  269. X    PhraseList = (t_Phrase *) 0;
  270. X    }
  271. X
  272. X    PhraseCount = 0;
  273. X
  274. X    for (i = 2; i < LINES; i++) {
  275. X    move(i ,0);
  276. X    clrtoeol();
  277. X    }
  278. X    SetMessage(
  279. X    "Type the words or phrases to look for, one per line, then press F1");
  280. X    move(ThisRow, ThisCol);
  281. X    refresh();
  282. X
  283. X    q = (char *) 0;
  284. X
  285. X    PhraseCount = 0;
  286. X
  287. X    while ((i = getch()) != KEY_F(1)) {
  288. Xdecode:
  289. X    if (i == KEY_F(1) || (ThisCol <= 1 && i == '\004')) {
  290. X        break;
  291. X    } else if (isprint(i)) {
  292. X        mvwaddch(stdscr, ThisRow, ThisCol, i);
  293. X        if (q == (char *) 0) q = Buffer;
  294. X        if (q - Buffer >= sizeof(Buffer)) {
  295. X        beep();
  296. X        } else {
  297. X        *q++ = i;
  298. X        *q = '\0';
  299. X        }
  300. X        ++ThisCol;
  301. X    } else switch (i) {
  302. X    case 'X' ^ 64: /* contol X */
  303. X    case 'U' ^ 64: /* ^U */
  304. X        /* delete to start of line */
  305. X        ThisCol = 0;
  306. X        move(ThisRow, ThisCol);
  307. X        clrtoeol();
  308. X        if (q != (char *) 0) q = Buffer;
  309. X        break;
  310. X    case 'W' ^ 64: /* control-W */
  311. X        if (ThisCol && q && q > Buffer) {
  312. X        *q = ' ';
  313. X        while (ThisCol > 0 && q > Buffer && isspace(*q)) {
  314. X            q--;
  315. X            --ThisCol;
  316. X        }
  317. X        while (ThisCol > 0 && q > Buffer && !isspace(*q)) {
  318. X            q--;
  319. X            --ThisCol;
  320. X        }
  321. X        *q = '\0';
  322. X        move(ThisRow, ThisCol);
  323. X        clrtoeol();
  324. X        } else if (!ThisCol) {
  325. X        beep();
  326. X        }
  327. X        break;
  328. X    case '\010': /* control-h */
  329. X    case '\177': /* DEL */
  330. X    case 255: /* DEL */
  331. X        mvwaddch(stdscr, ThisRow, ThisCol, ' ');
  332. X        if (ThisCol > 0) {
  333. X        --ThisCol;
  334. X        if (q != (char *) 0 && q > Buffer) --q;
  335. X        }
  336. X        break;
  337. X    case ' ':
  338. X    case '\t':
  339. X        ++ThisCol;
  340. X        if (q != (char *) 0) {
  341. X        if (q - Buffer >= sizeof(Buffer)) {
  342. X            beep();
  343. X        } else {
  344. X            *q++ = ' ';
  345. X            *q = '\0';
  346. X        }
  347. X        }
  348. X        break;
  349. X    case '\n':
  350. X    case '\r':
  351. X        /* Add word to list */
  352. X        if (q) {
  353. X        int ok;
  354. X        *q = '\0';
  355. X        if (*Buffer) {
  356. X            ok = AddPhrase(Buffer);
  357. X            PhraseCount += ok;
  358. X            if (ok) ++ThisRow;
  359. X        }
  360. X        }
  361. X        ThisCol = 0;
  362. X        q = (char *) 0;
  363. X        break;
  364. X    case '\033': /* ESC */
  365. X        switch (i = getch()) {
  366. X        case '0':
  367. X        case '1': case '2': case '3':
  368. X        case '4': case '5': case '6':
  369. X        case '7': case '8': case '9':
  370. X        i = KEY_F(i - '0');
  371. X        goto decode;
  372. X        default:
  373. X        beep();
  374. X        }
  375. X    default:
  376. X        beep();
  377. X    }
  378. X    if (ThisCol >= COLS - 1) {
  379. X        ThisCol = 0;
  380. X        ThisRow++;
  381. X    }
  382. X    if (ThisRow >= LINES) break;
  383. X    mvwaddch(stdscr, ThisRow, ThisCol, ' ');
  384. X    move(ThisRow, ThisCol);
  385. X    refresh();
  386. X    }
  387. X    if (q) {
  388. X    *q = '\0';
  389. X    if (*Buffer) PhraseCount += AddPhrase(Buffer);
  390. X    }
  391. X    SetMessage("Select MATCH ALL from the ALL WORDS menu to find files...");
  392. X    refresh();
  393. X    return 0;
  394. X}
  395. X
  396. Xint
  397. XAddPhrase(String)
  398. X    char *String;
  399. X{
  400. X    extern t_Phrase *String2Phrase();
  401. X    t_Phrase **PP;
  402. X
  403. X    if (!String || !*String) return 0;
  404. X
  405. X    /* Add it to the list */
  406. X    for (PP = &PhraseList; *PP; PP = &(*PP)->Next) {
  407. X    /* void */ ;
  408. X    }
  409. X
  410. X    (void) move(ThisRow, 0);
  411. X    clrtoeol();
  412. X
  413. X    if ((*PP = String2Phrase(String)) == (t_Phrase *) 0) {
  414. X    int spacecount = 0;
  415. X    char *p;
  416. X
  417. X    for (p = String; *p; p++) {
  418. X        if (*p == ' ') spacecount++;
  419. X    }
  420. X    switch (spacecount) {
  421. X        case 0: p = "This word does not"; break;
  422. X        case 1: p = "These words don't"; break; 
  423. X        case 2: p = "These words do not"; break;
  424. X        default: p = "None of these words"; break;
  425. X    }
  426. X    error(0,  "\
  427. X%s appear\n\
  428. Xin the database dictionary", p);
  429. X    return 0;
  430. X    }
  431. X    /* The user sees the phrases numbered from 1, not from zero */
  432. X    mvwprintw(stdscr, ThisRow, 0, "%-2d. %-7.7d %s", PhraseCount + 1,
  433. X                /* No matches yet */ 0, (*PP)->ModifiedString);
  434. X    return 1;
  435. X}
  436. X
  437. Xextern t_PhraseCaseMatch PhraseMatchLevel; /* Phrase.c */
  438. X
  439. Xint
  440. XMF_MatchAll()
  441. X{
  442. X    t_Phrase *PP;
  443. X    extern long MakeMatches();
  444. X    int Row = 5; /* as per ThisRow */
  445. X    long Total = 0;
  446. X
  447. X    if (PhraseList == (t_Phrase *) 0) {
  448. X    SetMessage(
  449. X    "Select NEW WORDS from the FILE menu and type words to match");
  450. X    return KEY_LEFT;
  451. X    }
  452. X
  453. X    mvwprintw(stdscr, LINES - 1, 0, "Searching...");
  454. X    refresh();
  455. X
  456. X    for (PP = PhraseList; PP != (t_Phrase *) 0; PP = PP->Next) {
  457. X    move(Row, 4);
  458. X    wclrtoeol(stdscr);
  459. X    PP->NumberOfMatches = MakeMatches(PP);
  460. X    Total += PP->NumberOfMatches;
  461. X    mvwprintw(stdscr, Row, 4, "%-7.7ld %s", PP->NumberOfMatches,
  462. X                            PP->ModifiedString);
  463. X    ++Row;
  464. X    }
  465. X    mvwprintw(stdscr, LINES - 1, 0, "Finished... ");
  466. X    if (Total) {
  467. X    SetMessage("Select BROWSE ALL from the ALL WORDS menu to see the files");
  468. X    } else {
  469. X    char *m;
  470. X
  471. X    switch (PhraseMatchLevel) {
  472. X    case PCM_HalfCase: /* this is the normal case */
  473. X    default:
  474. X        m = "(select ROUGH from the MATCHING menu, or choose new words)";
  475. X        break;
  476. X    case PCM_SameCase:
  477. X        m = "(select USER MATCHING from the MATCHING menu, or choose new words)";
  478. X        break;
  479. X    case PCM_AnyCase:
  480. X        m = "(not found --- choose new words or phrases)";
  481. X        break;
  482. X    }
  483. X    SetMessage(m);
  484. X    }
  485. X    refresh();
  486. X    return 0;
  487. X}
  488. X
  489. Xint
  490. XMF_SetAnyMatch()
  491. X{
  492. X    PhraseMatchLevel = PCM_AnyCase;
  493. X    return 0;
  494. X}
  495. X
  496. Xint
  497. XMF_SetRoughMatch()
  498. X{
  499. X    PhraseMatchLevel = PCM_AnyCase;
  500. X    return 0;
  501. X}
  502. X
  503. Xint
  504. XMF_SetUserMatch()
  505. X{
  506. X    PhraseMatchLevel = PCM_HalfCase;
  507. X    return 0;
  508. X}
  509. X
  510. Xint
  511. XMF_SetExactMatch()
  512. X{
  513. X    PhraseMatchLevel = PCM_SameCase;
  514. X    return 0;
  515. X}
  516. X
  517. Xlong
  518. XWriteFileList(Name, fp)
  519. X    char *Name;
  520. X    FILE *fp;
  521. X{
  522. X    extern t_FileInfo *GetFileInfo();
  523. X    extern long MakeMatches();
  524. X
  525. X    t_Phrase *PP;
  526. X    t_MatchList *Matches = (t_MatchList *) 0;
  527. X    t_FID FID = (t_FID) 0;
  528. X    t_FileInfo *FileInfo = (t_FileInfo *) 0;
  529. X    long Total = 0L;
  530. X
  531. X    /* For each phrase... */
  532. X    for (PP = PhraseList; PP != (t_Phrase *) 0; PP = PP->Next) {
  533. X
  534. X    if (!PP || !PP->Matches) continue;
  535. X
  536. X    /* For each match */
  537. X    for (Matches = PP->Matches; Matches != (t_MatchList *) 0;
  538. X                        Matches = Matches->Next) {
  539. X        if (Matches->Match != (t_Match *) 0) {
  540. X        if (Matches->Match->Where->FID != FID || !FileInfo) {
  541. X            if (FileInfo) (void) efree((char *) FileInfo);
  542. X            FileInfo = GetFileInfo(FID = Matches->Match->Where->FID);
  543. X        }
  544. X
  545. X        fprintf(fp, "%s%ul %u %s",
  546. X                 FileInfo ? "" : "# ",
  547. X                 Matches->Match->Where->BlockInFile,
  548. X                 Matches->Match->Where->WordInBlock,
  549. X                 FileInfo ? FileInfo->Name : " unknown_"
  550. X        );
  551. X        if (FileInfo) {
  552. X            fputc('\n', fp);
  553. X            ++Total;
  554. X        } else {
  555. X            fprintf(fp, "%ld\n", (long) FID);
  556. X        }
  557. X        }
  558. X    }
  559. X    }
  560. X    return Total;
  561. X}
  562. X
  563. X/* TODO
  564. X * -- use signal handling to ensure that the tmp file gets removed
  565. X * even if there is an interrupt....
  566. X * NOTDONE FIXME
  567. X */
  568. Xint
  569. XMF_BrowseAll()
  570. X{
  571. X    extern char *mktemp();
  572. X
  573. X    char *t;
  574. X    FILE *fp = (FILE *) 0;
  575. X    char TmpBuf[30]; /* enough for /tmp/text=a124356\0 */
  576. X#ifndef LQSHOW
  577. X# define LQSHOW "lqshow"
  578. X#endif
  579. X    char SystemBuffer[sizeof(LQSHOW) + sizeof(" -f  ") + sizeof TmpBuf + 3];
  580. X            /* the +3 above is for spaces and a trailing \0 */
  581. X    long Total;
  582. X
  583. X    if (PhraseCount == 0) {
  584. X    SetMessage("select NEW WORDS from the FILE menu first.");
  585. X    return 0;
  586. X    }
  587. X
  588. X    ClearMessage();
  589. X
  590. X    (void) sprintf(TmpBuf, "/tmp/text=XXXXXX");
  591. X    t = mktemp(TmpBuf);
  592. X
  593. X    if (t == (char *) 0 || (fp = fopen(t, "w")) == (FILE *) 0) {
  594. X    error(0, "\
  595. XCan't create tempory file\n\
  596. X(\"%s\")\n\
  597. Xto hold the list of matches,\n\
  598. Xsorry.\n\
  599. X", t ? t : "[internal_error]");
  600. X    return -1;
  601. X    }
  602. X
  603. X    Total = WriteFileList(t, fp);
  604. X    (void) fclose(fp);
  605. X
  606. X    if (Total) { 
  607. X#ifdef CURSESX
  608. X    /* lqshow works in raw mode, so no need to fiddle tty settings */
  609. X#else
  610. X    /* We need to set the tty modes for lqshow: */
  611. X    (void) nocbreak();
  612. X    (void) echo();
  613. X    (void) nl();
  614. X    (void) keypad(stdscr, FALSE);
  615. X#endif
  616. X    clearok(stdscr, TRUE);
  617. X    (void) sprintf(SystemBuffer, "%s -f %s", LQSHOW, t);
  618. X    (void) system(SystemBuffer);
  619. X#ifndef CURSESX
  620. X    (void) cbreak();
  621. X    (void) noecho();
  622. X    (void) nonl();
  623. X    (void) keypad(stdscr, TRUE);
  624. X#endif
  625. X    SetMessage("(save the matches using SAVE LIST from the FILE menu)");
  626. X    } else {
  627. X    SetMessage("(no matches; select MATCH ALL before BROWSE ALL)");
  628. X    }
  629. X
  630. X    if (t) (void) unlink(t);
  631. X
  632. X    return 0;
  633. X}
  634. X
  635. Xint
  636. XMF_EndProg()
  637. X{
  638. X    endwin();
  639. X    exit();
  640. X    /*NOTREACHED*/
  641. X    return (-1);
  642. X}
  643. X
  644. Xint
  645. XMF_OpenList()
  646. X{
  647. X    beep(); /* NOTDONE */
  648. X    SetMessage("Function OPEN LIST unimplemented -- sorry");
  649. X    return 0;
  650. X}
  651. X
  652. Xint
  653. XMF_SaveList()
  654. X{
  655. X    extern char *AskForString();
  656. X
  657. X    char *FileName;
  658. X    FILE *fp;
  659. X    t_Phrase *PP;
  660. X
  661. X    if (PhraseCount == 0) {
  662. X    SetMessage("No matches... nothing to save");
  663. X    return 0;
  664. X    }
  665. X
  666. X    FileName = AskForString(
  667. X    "Enter the name of a file in which to save the list:",
  668. X                    2048, (WINDOW *) 0, 7, 5);
  669. X    if (FileName == (char *) 0) {
  670. X    beep();
  671. X    return 0;
  672. X    }
  673. X
  674. X    if ((fp = fopen(FileName, "r")) != (FILE *) 0) {
  675. X    char *yorn;
  676. X    char *Result = (char *) 0;
  677. X
  678. X    (void) fclose(fp);
  679. X
  680. X    yorn = "\
  681. XThe file already exists.  Type  replace  to replace it, \n\
  682. Xor type  keep  to keep it as it is, and then press Enter: ";
  683. X    
  684. X    while (!Result || !STREQ(Result, "replace")) {
  685. X        /* the 7 is max(strlen("replace"), strlen("keep")), the
  686. X         * longest allowed input string
  687. X         */
  688. X        Result = AskForString(yorn, 7, (WINDOW *) 0, 7, 5);
  689. X        if (STREQ(Result, "keep")) {
  690. X        SetMessage("(the list of matches was not saved)");
  691. X        (void) efree((char *) Result);
  692. X        (void) efree(FileName);
  693. X        return 0;
  694. X        }
  695. X    }
  696. X    if (Result) (void) efree(Result);
  697. X    }
  698. X
  699. X    if ((fp = fopen(FileName, "w")) == (FILE *) 0) {
  700. X    SetMessage("Couldn't creat the file to save the list of matches");
  701. X    beep();
  702. X    refresh();
  703. X    (void) efree(FileName);
  704. X    return 0;
  705. X    }
  706. X
  707. X    /* get rid of any lingering dialogue boxes... */
  708. X    SetMessage("Saving list...");
  709. X    (void) refresh();
  710. X
  711. X    fprintf(fp, "## file created automatically by lqtext -- do not edit!\n");
  712. X
  713. X    /* Write out the list of phrases */
  714. X    for (PP = PhraseList; PP != (t_Phrase *) 0; PP = PP->Next) {
  715. X    (void) fprintf(fp, "## %s\n", PP->OriginalString);
  716. X    }
  717. X
  718. X    (void) WriteFileList(FileName, fp);
  719. X
  720. X    (void) fclose(fp);
  721. X    SetMessage("List saved.  Type   q   if you want to quit now.");
  722. X    return 0;
  723. X}
  724. X
  725. Xint
  726. XMF_ViewFile()
  727. X{
  728. X    extern char *AskForString();
  729. X    char *p;
  730. X
  731. X    p = AskForString(
  732. X        "Enter a filename:                  ", 2048, (WINDOW *) 0, 5, 5);
  733. X
  734. X    if (p && *p) {
  735. X    int Retval;
  736. X    char *sysbuf = emalloc(strlen(p) + sizeof(PAGER) + 3);
  737. X
  738. X    (void) sprintf(sysbuf, "%s %s", PAGER, p);
  739. X    Retval = MySystem(sysbuf);
  740. X    (void) efree(sysbuf);
  741. X    return Retval;
  742. X    } else {
  743. X    beep();
  744. X    }
  745. X    return 0;
  746. X}
  747. X
  748. Xint
  749. XMF_ListFiles()
  750. X{
  751. X#ifndef LQFILE
  752. X# define LQFILE "lqfile"
  753. X#endif
  754. X#ifndef PAGER
  755. X# define PAGER "more"
  756. X#endif
  757. X    char *buf = emalloc(sizeof(LQFILE) + sizeof(PAGER) + 6);
  758. X    int Retval = 0;
  759. X
  760. X    /* +4 is for "-a | " and \0 */
  761. X    if (!buf) {
  762. X    beep();
  763. X    return -1;
  764. X    }
  765. X
  766. X    (void) sprintf(buf, "%s -a | %s", LQFILE, PAGER);
  767. X    Retval = MySystem(buf);
  768. X    (void) efree(buf);
  769. X    return Retval;
  770. X}
  771. X
  772. Xint
  773. XMF_AddNewFile()
  774. X{
  775. X    extern char *AskForString();
  776. X    char *p;
  777. X
  778. X    p = AskForString(
  779. X        "Enter a file to add:                  ", 2048, (WINDOW *) 0, 5, 5);
  780. X
  781. X    if (p && *p) {
  782. X    char sysbuf[2048 + 50];
  783. X
  784. X    (void) sprintf(sysbuf, "lqaddfile -v \"%s\"", p);
  785. X    (void) MySystem(sysbuf);
  786. X    } else {
  787. X    beep();
  788. X    }
  789. X    return 0;
  790. X}
  791. X
  792. X
  793. Xint
  794. XMF_NotDone()
  795. X{
  796. X    mvwaddstr(stdscr, LINES - 1, 1, "NOTDONE");
  797. X    return 0;
  798. X}
  799. X
  800. Xstatic t_MenuBar *MainMenuBar;
  801. X
  802. Xt_MenuBar *
  803. XSetUpMenus()
  804. X{
  805. X    t_Menu *Menu;
  806. X
  807. X    MainMenuBar = new(t_MenuBar);
  808. X
  809. X    if (MainMenuBar == (t_MenuBar *) 0) {
  810. X    error(ERR_FATAL|ERR_MEMORY, "Not enough memory for main menu bar");
  811. X    }
  812. X    MainMenuBar->MenuBarId = 0; /* Private (oh for c++) */
  813. X    MainMenuBar->HowManyMenus = 0;
  814. X    MainMenuBar->SelectedMenu = 0;
  815. X    MainMenuBar->ScrollOffset = 0;
  816. X
  817. X    /* Now some menus: */
  818. X
  819. X    Menu = NewMenu("File");
  820. X
  821. X    Menu->Description = "\
  822. X File Operations -- \n\
  823. X  New Words -- selecting files based on keywords; \n\
  824. X  Save/Open List -- remembering a list of files for later use \n\
  825. X  Finish -- leave the program (you can also type \"q\") \n\
  826. X\n\
  827. X You probably want to use \"New Words\" to start with, \n\
  828. X and then use the \"All Words\" menu to see the result.";
  829. X
  830. X    Menu->Items = (t_MenuItem *) emalloc(sizeof(t_MenuItem) * 4);
  831. X
  832. X    Menu->Items[0].Name = "New Words";
  833. X    Menu->Items[0].NameLength = 0;
  834. X    Menu->Items[0].Function = GetWords;
  835. X    Menu->Items[0].Description =
  836. X"Type in a new list of words\n\
  837. Xfor which to search";
  838. X
  839. X    Menu->Items[1].Name = "Save List";
  840. X    Menu->Items[1].NameLength = 0;
  841. X    Menu->Items[1].Function = MF_SaveList;
  842. X    Menu->Items[1].Description =
  843. X"Save List -- Save the list of files that\n\
  844. Xyou have found in a file";
  845. X
  846. X    Menu->Items[2].Name = "Open List";
  847. X    Menu->Items[2].NameLength = 0;
  848. X    Menu->Items[2].Function = MF_OpenList;
  849. X    Menu->Items[2].Description =
  850. X"Open List -- Open a list of filenames\n\
  851. Xthat you previously saved";
  852. X
  853. X    Menu->Items[3].Name = "Finish";
  854. X    Menu->Items[3].NameLength = 0;
  855. X    Menu->Items[3].Function = MF_EndProg;
  856. X    Menu->Items[3].Description = "Finish -- leave the program";
  857. X
  858. X    Menu->HowManyItems = 4;
  859. X
  860. X    MainMenuBar->Menus[MainMenuBar->HowManyMenus++] = Menu;
  861. X
  862. X    /* Now choosing words */
  863. X    Menu = NewMenu("All Words");
  864. X
  865. X    Menu->Description = "\
  866. X Main Word Menu\n\
  867. X  Once you have typed one or more phrases using \n\
  868. X  \"New Words\" from the \"File\" menu, you can \n\
  869. X  use this menu to find the list of files which \n\
  870. X  contain the phrases, and then you can look at \n\
  871. X  the files with \"Browse All\".\
  872. X ";
  873. X    Menu->Items = (t_MenuItem *) emalloc(sizeof(t_MenuItem) * 3);
  874. X    Menu->Items[0].Name = "Match All";
  875. X    Menu->Items[0].NameLength = 0;
  876. X    Menu->Items[0].Function = MF_MatchAll;
  877. X    Menu->Items[0].Description =
  878. X"Look for files containing\n\
  879. Xthe phrases you have entered.";
  880. X    Menu->Items[1].Name = "Browse All";
  881. X    Menu->Items[1].NameLength = 0;
  882. X    Menu->Items[1].Function = MF_BrowseAll;
  883. X    Menu->Items[1].Description =
  884. X"Browse through the matches (if any)\n";
  885. X    Menu->HowManyItems = 2;
  886. X
  887. X    MainMenuBar->Menus[MainMenuBar->HowManyMenus++] = Menu;
  888. X
  889. X    /* Setting match level */
  890. X    Menu = NewMenu("Matching");
  891. X
  892. X    Menu->Description = "\
  893. XMatching Menu\n\
  894. X Use this menu if you want finer control over \n\
  895. X the way phrases are matched.\n\
  896. X\n\
  897. X The \"Rough Matching\" option will generally \n\
  898. X produce the most matches.\n\
  899. X After you have changed the match level, \n\
  900. X you have to use \"Match All\" from the \n\
  901. X \"All Words\" menu.\
  902. X";
  903. X    Menu->Items = (t_MenuItem *) emalloc(sizeof(t_MenuItem) * 3);
  904. X
  905. X    Menu->Items[0].Name = "Exact Matching";
  906. X    Menu->Items[0].NameLength = 0;
  907. X    Menu->Items[0].Function = MF_SetExactMatch;
  908. X    Menu->Items[0].Description =
  909. X"Match phrases as exactly as possible,\n\
  910. Xincluding Case, pluralS and Possessive's";
  911. X
  912. X    Menu->SelectedLine = 1; /* the default */
  913. X    Menu->Items[1].Name = "User Matching";
  914. X    Menu->Items[1].NameLength = 0;
  915. X    Menu->Items[1].Function = MF_SetUserMatch;
  916. X    Menu->Items[1].Description =
  917. X"Match phrases roughly, but match Case,\n\
  918. XpluralS and so on exactly when given";
  919. X
  920. X    Menu->Items[2].Name = "Rough Matching";
  921. X    Menu->Items[2].NameLength = 0;
  922. X    Menu->Items[2].Function = MF_SetRoughMatch;
  923. X    Menu->Items[2].Description =
  924. X"Ensure that words in phrases are in\n\
  925. Xthe same order as you type, but don't\n\
  926. Xbother about cAsE, plurals, etc.";
  927. X
  928. X    Menu->HowManyItems = 3;
  929. X
  930. X    MainMenuBar->Menus[MainMenuBar->HowManyMenus++] = Menu;
  931. X
  932. X    /* Indexing files... */
  933. X    Menu = NewMenu("Indexing");
  934. X
  935. X    Menu->Description = "\
  936. XIndexing Menu\n\
  937. X Use this menu to add new files to the index, \n\
  938. X to examine the list of indexed files, or\n\
  939. X to examine the files themselves.\
  940. X";
  941. X    Menu->Items = (t_MenuItem *) emalloc(sizeof(t_MenuItem) * 3);
  942. X    Menu->Items[0].Name = "Add New file";
  943. X    Menu->Items[0].NameLength = 0;
  944. X    Menu->Items[0].Function = MF_AddNewFile;
  945. X    Menu->Items[0].Description = "\
  946. XAdd a new file to the index, \n\
  947. Xso that it can be found later. ";
  948. X
  949. X    Menu->Items[1].Name = "List Index";
  950. X    Menu->Items[1].NameLength = 0;
  951. X    Menu->Items[1].Function = MF_ListFiles;
  952. X    Menu->Items[1].Description = "\
  953. XSee the list of files that are \n\
  954. Xalready in the index.";
  955. X
  956. X    Menu->Items[2].Name = "View File";
  957. X    Menu->Items[2].NameLength = 0;
  958. X    Menu->Items[2].Function = MF_ViewFile;
  959. X    Menu->Items[2].Description = "Look at a file (using pg) ";
  960. X
  961. X    Menu->HowManyItems = 3;
  962. X
  963. X    MainMenuBar->Menus[MainMenuBar->HowManyMenus++] = Menu;
  964. X
  965. X    /* Patterns... */
  966. X    Menu = NewMenu("Patterns");
  967. X
  968. X    Menu->Description = "\
  969. XPatterns Menu\n\
  970. X This menu lets you specify the order in which files \n\
  971. X are presented, and also how inexact words --- like \n\
  972. X \"someth*\"  or  \"Is[ia][ia]*h\" --- are matched. \n\
  973. X See the explanations of the individual menu items \n\
  974. X for more details of what they do.\
  975. X";
  976. X    Menu->Items = (t_MenuItem *) emalloc(sizeof(t_MenuItem) * 9);
  977. X    Menu->Items[0].Name = "Prefer All";
  978. X    Menu->Items[0].NameLength = 0;
  979. X    Menu->Items[0].Function = MF_NotDone;
  980. X    Menu->Items[0].Description = "\
  981. XPut files containing all of the phrases \n\
  982. Xfirst in the list when browsing. ";
  983. X
  984. X    Menu->Items[1].Name = "Prefer Most";
  985. X    Menu->Items[1].NameLength = 0;
  986. X    Menu->Items[1].Function = MF_NotDone;
  987. X    Menu->Items[1].Description = "\
  988. XPut the files containing the most matches\n\
  989. Xfirst in the list when browsing.";
  990. X
  991. X    Menu->Items[2].Name = "Prefer Oldest";
  992. X    Menu->Items[2].NameLength = 0;
  993. X    Menu->Items[2].Function = MF_NotDone;
  994. X    Menu->Items[2].Description = "\
  995. XPut the oldest files entered into the database \n\
  996. Xfirst in the list when browsing. ";
  997. X
  998. X    Menu->Items[3].Name = "Unsorted";
  999. X    Menu->Items[3].NameLength = 0;
  1000. X    Menu->Items[3].Function = MF_NotDone;
  1001. X    Menu->Items[3].Description = "\
  1002. XDon't bother sorting the list of files before browsing; \n\
  1003. Xthis is usually the fastest option.";
  1004. X
  1005. X    Menu->Items[4].Name = "Reverse";
  1006. X    Menu->Items[4].NameLength = 0;
  1007. X    Menu->Items[4].Function = MF_NotDone;
  1008. X    Menu->Items[4].Description = "\
  1009. XReverse the order in which files are presented \n\
  1010. X(so, for example, if they are to be sorted on \n\
  1011. Xthe number of matches, you will get the files \n\
  1012. Xwith only one match before those containing several \n\
  1013. Xmatches, and so on) ";
  1014. X
  1015. X    Menu->Items[5].Name = "No Patterns";
  1016. X    Menu->Items[5].NameLength = 0;
  1017. X    Menu->Items[5].Function = MF_NotDone;
  1018. X    Menu->Items[5].Description = "Don't allow patterns in words or phrases. ";
  1019. X
  1020. X    Menu->Items[6].Name = "Simple Patterns";
  1021. X    Menu->Items[6].NameLength = 0;
  1022. X    Menu->Items[6].Function = MF_NotDone;
  1023. X    Menu->Items[6].Description = "\
  1024. XWhen you type words to be matched, a * will \n\
  1025. Xmean any sequence of characters, and a ? a single character, \n\
  1026. Xso that  *day  would find all occurrences of Monday, Tuesday, \n\
  1027. XHoliday, and so on, whilst   bo?  would look for all \n\
  1028. Xthree-letter words beginning in \"bo\", such as box and boy. ";
  1029. X
  1030. X    Menu->Items[7].Name = "Complex patterns";
  1031. X    Menu->Items[7].NameLength = 0;
  1032. X    Menu->Items[7].Function = MF_NotDone;
  1033. X    Menu->Items[7].Description = "\
  1034. XAllow full (\"egrep\"-style) regular expressions when looking for \n\
  1035. Xwords.  This means that when you are entering NEW WORDS to search \n\
  1036. Xfor, certain characters have special meaning: \n\
  1037. X x*    matches any number of \"x\", where \"x\" can be anything;\n\
  1038. X .     matches a single character (letter or digit);\n\
  1039. X a|b   means either \"a\" or \"b\" (within a single word); \n\
  1040. X [xyz] matches a single character that's an x, y or z; you\n\
  1041. X       can use a - to represent a range, as in [a-zA-Z0-9],\n\
  1042. X       and of course [aeiou]* would mean 0 or more vowels.\n\
  1043. XSee the User Reference Book for more detail on this.\n\
  1044. X";
  1045. X
  1046. X    Menu->HowManyItems = 8;
  1047. X
  1048. X    MainMenuBar->Menus[MainMenuBar->HowManyMenus++] = Menu;
  1049. X
  1050. X    return MainMenuBar;
  1051. X}
  1052. X
  1053. XWINDOW *WordInfoBox = 0;
  1054. X
  1055. Xvoid
  1056. XSetUpScreen()
  1057. X{
  1058. X    /* Put some important info on the screen itself...
  1059. X     * One could use menus to change the screen display, perhaps.
  1060. X     * A more general program would use a screen form to do this.
  1061. X     */
  1062. X
  1063. X    /* First, version information */
  1064. X    mvwprintw(stdscr, 10, 0, "%s revision %s", progname, "$Revision: 1.7 $");
  1065. X    mvwaddstr(stdscr, 11, 0, "[press return to continue]");
  1066. X    refresh();
  1067. X    (void) getch();
  1068. X    clear();
  1069. X    refresh();
  1070. X
  1071. X    /* Now, we want to tell the user what to do... */
  1072. X    ShowInstructions();
  1073. X}
  1074. X
  1075. Xvoid
  1076. XSetMessage(s)
  1077. X    char *s;
  1078. X{
  1079. X    move(3, 1);
  1080. X    clrtoeol();
  1081. X    mvwaddstr(stdscr, 3, 1, s);
  1082. X}
  1083. X
  1084. Xvoid
  1085. XClearMessage()
  1086. X{
  1087. X    move(3, 1);
  1088. X    clrtoeol();
  1089. X}
  1090. X
  1091. Xvoid
  1092. XShowInstructions()
  1093. X{
  1094. X    char *s;
  1095. X
  1096. X    s =  "\
  1097. XUse the arrow keys to choose a menu at the top of the screen, \n\
  1098. Xand then use the space bar to select it. \n\
  1099. XUse the up and down arrow keys to choose a command, \n\
  1100. Xand then press space. \n\
  1101. XYou can press  x  for an eXplanation of any menu or menu item. \n\
  1102. X\n\
  1103. XYou probably want to start by selecting the FILE menu,\n\
  1104. Xand choosing NEW WORDS from it. \n\
  1105. X";
  1106. X    
  1107. X    ClearInstructions();
  1108. X    mvwaddstr(stdscr, LINES - 12, 3, s);
  1109. X    refresh();
  1110. X}
  1111. X
  1112. Xvoid
  1113. XClearInstructions()
  1114. X{
  1115. X    int i;
  1116. X
  1117. X    /* get rid of "Type the list... and press F1" */
  1118. X    /* ClearMessage(); */
  1119. X    /* get rid of the instructions */
  1120. X    for (i = LINES - 12; i < LINES; i++) {
  1121. X    if (PhraseCount - 5 < i) { /* don't overwrite phrases */
  1122. X        move(i, 0);
  1123. X        clrtoeol();
  1124. X    }
  1125. X    }
  1126. X}
  1127. X
  1128. Xvoid
  1129. XStartCurses()
  1130. X{
  1131. X    if (InCurses) {
  1132. X    error(ERR_FATAL|ERR_INTERNAL, "StartCurses() called in curses mode");
  1133. X    }
  1134. X    (void) initscr();
  1135. X    InCurses = 1;
  1136. X    (void) cbreak();
  1137. X    (void) noecho();
  1138. X    (void) nonl();
  1139. X    (void) keypad(stdscr, TRUE);
  1140. X}
  1141. X
  1142. Xvoid
  1143. XEndCurses()
  1144. X{
  1145. X    clear();
  1146. X    (void) refresh();
  1147. X
  1148. X    InCurses = 0;
  1149. X    (void) endwin();
  1150. X}
  1151. @@@End of lq-text/src/menu/text.c
  1152. echo x - lq-text/src/menu/ultrixhack.h 1>&2
  1153. sed 's/^X//' >lq-text/src/menu/ultrixhack.h <<'@@@End of lq-text/src/menu/ultrixhack.h'
  1154. X#define ACS_BSSS '+'
  1155. X#define ACS_SBSS '+'
  1156. X#define ACS_SSBS '+'
  1157. X#define ACS_SSSB '+'
  1158. X#define ACS_HLINE '='
  1159. X#define ACS_LARROW '>'
  1160. X#define ACS_LLCORNER '+'
  1161. X#define ACS_LRCORNER '+'
  1162. X#define ACS_RARROW '<'
  1163. X#define ACS_VLINE '|'
  1164. X#define KEY_HELP 999 /* an unlikely key to be pressed */
  1165. @@@End of lq-text/src/menu/ultrixhack.h
  1166. echo x - lq-text/src/saber.project 1>&2
  1167. sed 's/^X//' >lq-text/src/saber.project <<'@@@End of lq-text/src/saber.project'
  1168. X/* Saber-C Project File */
  1169. X/* Set current directory */
  1170. Xcd /home/lee/lq-text/src
  1171. X/* Options for project */
  1172. Xunsetopt ansi
  1173. Xunsetopt auto_compile
  1174. Xsetopt auto_reload
  1175. Xsetopt auto_replace
  1176. Xunsetopt batch_load
  1177. Xunsetopt batch_run
  1178. Xunsetopt cc_prog
  1179. Xsetopt ccargs               -g
  1180. Xunsetopt create_file
  1181. Xunsetopt debug_child
  1182. Xunsetopt echo
  1183. Xsetopt edit_jobs            5
  1184. Xunsetopt eight_bit
  1185. Xsetopt line_edit
  1186. Xunsetopt line_meta
  1187. Xsetopt lint_load            2
  1188. Xsetopt lint_run             2
  1189. Xsetopt list_action
  1190. Xunsetopt load_flags
  1191. Xunsetopt long_not_int
  1192. Xunsetopt make_args
  1193. Xsetopt make_hfiles
  1194. Xunsetopt make_offset
  1195. Xunsetopt make_prog
  1196. Xsetopt make_symbol          #
  1197. Xsetopt mem_config           16384
  1198. Xunsetopt mem_trace
  1199. Xsetopt num_proc             1
  1200. Xsetopt page_cmds            22
  1201. Xsetopt page_list            10
  1202. Xsetopt page_load            22
  1203. Xunsetopt path
  1204. Xsetopt proto_path           . /stage/saber_dir30/sun4-40/proto /stage/saber_dir30/sun4-40/../common/proto
  1205. Xunsetopt preprocessor
  1206. Xsetopt program_name         a.out
  1207. Xunsetopt print_custom
  1208. Xsetopt print_pointer
  1209. Xsetopt print_string         20
  1210. Xunsetopt save_memory
  1211. Xsetopt sbrk_size            1048576
  1212. Xsetopt src_err              3
  1213. Xsetopt src_step             1
  1214. Xsetopt src_stop             3
  1215. Xsetopt sys_load_flags       -L/lib -L/usr/lib -L/usr/local/lib -I/usr/include -Dunix -Dsun -Dsparc -I. -I./h -I../h
  1216. Xunsetopt tab_stop
  1217. Xunsetopt terse_suppress
  1218. Xunsetopt terse_where
  1219. Xsetopt unset_value          191
  1220. Xunsetopt win_fork_nodup
  1221. Xunsetopt win_no_raise
  1222. Xunsetopt win_message_list
  1223. Xunsetopt win_project_list
  1224. X/* Suppressions for project */
  1225. X
  1226. X/* Contents of project */
  1227. Xload  /lib/libc.a
  1228. Xload -g\ -DASCIITRACE\ -DBSD\ -USYSV\ -Dsdbm\ -DSDBM\ -DDUFF\ -DDUPERROR\ -DSPLITERROR\ -ULiamSysV sdbm/sdbm.c sdbm/pair.c sdbm/hash.c
  1229. X/* load -I./h\ -DBSD\ -Dsdbm\ -DASCIITRACE lqtext/lqaddfile.c */
  1230. Xload -g\ -DASCIITRACE\ -DBSD\ -USYSV\ -Dsdbm\ -I../h liblqtext/DocPath.c liblqtext/Defaults.c liblqtext/FileList.c liblqtext/Phrase.c liblqtext/Root.c liblqtext/WordInfo.c liblqtext/malloc.c liblqtext/numbers.c liblqtext/pblock.c liblqtext/smalldb.c
  1231. Xload -I./h\ -DBSD\ -Dsdbm\ -DASCIITRACE\ -USYSV liblqtext/FilterType.c
  1232. Xload -g\ -DASCIITRACE\ -DBSD\ -USYSV\ -Dsdbm\ -I../h liblqtext/asciitrace.c liblqtext/cmdname.c
  1233. Xload  lib/liblqtext.a
  1234. Xload -I./h\ -DBSD\ -Dsdbm\ -DASCIITRACE lqtext/wordtable.c
  1235. Xlink
  1236. X
  1237. X/* Signals caught and ignored */
  1238. Xcatch HUP
  1239. Xcatch INT
  1240. Xcatch QUIT
  1241. Xcatch ILL
  1242. Xcatch TRAP
  1243. Xcatch IOT
  1244. Xcatch EMT
  1245. Xcatch FPE
  1246. Xcatch KILL
  1247. Xcatch BUS
  1248. Xcatch SEGV
  1249. Xcatch SYS
  1250. Xcatch PIPE
  1251. Xcatch TERM
  1252. Xcatch URG
  1253. Xcatch STOP
  1254. Xcatch TSTP
  1255. Xcatch TTIN
  1256. Xcatch TTOU
  1257. Xcatch IO
  1258. Xcatch XCPU
  1259. Xcatch XFSZ
  1260. Xcatch VTALRM
  1261. Xcatch PROF
  1262. Xcatch LOST
  1263. Xcatch USR1
  1264. Xcatch USR2
  1265. Xignore ALRM
  1266. Xignore CONT
  1267. Xignore CHLD
  1268. Xignore WINCH
  1269. X
  1270. X/* Status of project */
  1271. @@@End of lq-text/src/saber.project
  1272. echo x - lq-text/src/test/Makefile 1>&2
  1273. sed 's/^X//' >lq-text/src/test/Makefile <<'@@@End of lq-text/src/test/Makefile'
  1274. X# Makefile for LQ-Text, a full text retrieval package by Liam R. Quin
  1275. X# This Makefile belongs in the "src/test" directory.
  1276. X#
  1277. X# Note that most of the actual configuration is done in ../Makefile and
  1278. X# in ../h/global.h, and not here.
  1279. X#
  1280. X# $Id: Makefile,v 1.3 90/10/08 21:15:10 lee Exp $
  1281. X
  1282. X#
  1283. X# $Log:    Makefile,v $
  1284. X# Revision 1.3  90/10/08  21:15:10  lee
  1285. X# Cope with non-writeable numbers.c and SixBit.c
  1286. X# 
  1287. X# Revision 1.2  90/10/06  01:27:05  lee
  1288. X# Prepared for first Beta release.
  1289. X# 
  1290. X# Revision 1.1  90/08/09  19:17:53  lee
  1291. X# Initial revision
  1292. X# 
  1293. X# 
  1294. X#
  1295. X
  1296. XPWD=test
  1297. X
  1298. X# no rules for the first 4 yet, sorry
  1299. XTARGETS = MaxWid TryHash put trywid dbmtry TryRoot TryNum NumberTest
  1300. XTESTPROGS = MaxWid TryHash put trywid dbmtry TryRoot TryNum NumberTest 
  1301. X
  1302. XTESTBIN=../testbin
  1303. XMODE=755
  1304. XOWNER=lee
  1305. X
  1306. XEXTRA=-I../h
  1307. X
  1308. Xall: $(TARGETS)
  1309. X
  1310. Xsaber_src:
  1311. X
  1312. Xsaber_obj:
  1313. X
  1314. X# for ndbm (simplest), leave empty or use -lndbm if you need it
  1315. X# for sdbm (best so far), use ../lib/libsdbm.a
  1316. X# for gdbm... well, I dunno.
  1317. XDBMLIBS=../lib/libsdbm.a
  1318. X# DBMLIBS=-lndbm
  1319. X# DBMLIBS=ndbm.o bcopy.o
  1320. X
  1321. XLIAMLIB=../lib/liblq.a
  1322. XTEXTLIB=../lib/liblqtext.a
  1323. X
  1324. Xinstall: all
  1325. X    @test -d $(TESTBIN) || mkdir $(TESTBIN)
  1326. X    for i in $(TESTPROGS); do cp "$$i" $(TESTBIN); \
  1327. X    strip "$(TESTBIN)/$$i" ; \
  1328. X    chmod $(MODE) "$(TESTBIN)/$$i" ; \
  1329. X    chown $(OWNER) "$(TESTBIN)/$$i" ; \
  1330. X    done
  1331. X
  1332. Xtidy:
  1333. X    /bin/rm -f *.o core
  1334. X
  1335. Xclean: tidy
  1336. X    /bin/rm -f $(TARGETS) $(TEST) numbers.c
  1337. X
  1338. Xdepend:
  1339. X    mkdep $(CFLAGS) *.c
  1340. X
  1341. XMaxWid: MaxWid.o $(TEXTLIB) $(LIAMLIB) $(DBMLIBS)
  1342. X    $(CC) $(CFLAGS) -o MaxWid MaxWid.o $(TEXTLIB) $(LIAMLIB) $(DBMLIBS)
  1343. X
  1344. XTryHash: TryHash.o $(TEXTLIB) $(LIAMLIB)
  1345. X    $(CC) $(CFLAGS) -o TryHash TryHash.o $(TEXTLIB)
  1346. X
  1347. XTryNum: TryNum.o $(TEXTLIB) $(LIAMLIB)
  1348. X    $(CC) $(CFLAGS) -o TryNum TryNum.o $(TEXTLIB) $(LIAMLIB)
  1349. X
  1350. XTryRoot: TryRoot.o $(TEXTLIB) $(LIAMLIB) $(DBMLIBS)
  1351. X    $(CC) $(CFLAGS) -o TryRoot TryRoot.o $(TEXTLIB) $(LIAMLIB) $(DBMLIBS)
  1352. X
  1353. Xdbmtry: dbmtry.o $(TEXTLIB) $(LIAMLIB) $(DBMLIBS)
  1354. X    $(CC) $(CFLAGS) -o dbmtry dbmtry.o $(TEXTLIB) $(LIAMLIB) $(DBMLIBS)
  1355. X
  1356. Xput: put.o
  1357. X    $(CC) $(CFLAGS) -o put put.o
  1358. X
  1359. Xtrywid: trywid.o $(TEXTLIB) $(LIAMLIB) $(DBMLIBS)
  1360. X    $(CC) $(CFLAGS) -o trywid trywid.o $(TEXTLIB) $(LIAMLIB) $(DBMLIBS)
  1361. X
  1362. Xnumbers.c: ../liblqtext/numbers.c
  1363. X    /bin/rm -f numbers.c
  1364. X    cp ../liblqtext/numbers.c .
  1365. X
  1366. XNumberTest: numbers.o
  1367. X    $(CC) $(CFLAGS) -DTESTNUMBERS -o NumberTest numbers.c
  1368. X
  1369. X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
  1370. X# DO NOT DELETE THIS LINE -- mkdep uses it.
  1371. X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
  1372. X
  1373. XMaxWid.o: MaxWid.c ../h/globals.h 
  1374. XTryHash.o: TryHash.c ../h/globals.h
  1375. XTryNum.o: TryNum.c ../h/globals.h ../h/numbers.h
  1376. XTryNum.o: ../h/emalloc.h
  1377. XTryRoot.o: TryRoot.c 
  1378. XTryRoot.o: ../h/fileinfo.h ../h/wordinfo.h ../h/pblock.h ../h/wordrules.h
  1379. Xdbmtry.o: dbmtry.c ../h/globals.h 
  1380. Xdbmtry.o: ../h/smalldb.h ../h/ozmadbm.h ../h/db.h
  1381. Xlqmalloc.o: lqmalloc.c 
  1382. Xput.o: put.c 
  1383. Xtrywid.o: trywid.c ../h/globals.h
  1384. Xtrywid.o: ../h/fileinfo.h
  1385. Xtrywid.o: ../h/wordinfo.h ../h/pblock.h
  1386. X
  1387. X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
  1388. @@@End of lq-text/src/test/Makefile
  1389. echo x - lq-text/src/test/MaxWid.c 1>&2
  1390. sed 's/^X//' >lq-text/src/test/MaxWid.c <<'@@@End of lq-text/src/test/MaxWid.c'
  1391. X/* MaxWid.c -- Copyright 1989 Liam R. Quin.  All Rights Reserved.
  1392. X * This code is NOT in the public domain.
  1393. X * See the file COPYRIGHT for full details.
  1394. X */
  1395. X
  1396. X#include "globals.h" /* defines and declarations for database filenames */
  1397. X
  1398. X#include <stdio.h>
  1399. Xextern void SetDefaults();
  1400. Xextern void exit();
  1401. X
  1402. Xint
  1403. Xmain(argc, argv)
  1404. X    int argc;
  1405. X    char *argv[];
  1406. X{
  1407. X    extern unsigned long GetMaxWID();
  1408. X
  1409. X    SetDefaults(argc, argv);
  1410. X
  1411. X    printf("Max Word Identifier (MaxWID) is %lu\n", GetMaxWID());
  1412. X    return 0;
  1413. X}
  1414. @@@End of lq-text/src/test/MaxWid.c
  1415. echo x - lq-text/src/test/TryHash.c 1>&2
  1416. sed 's/^X//' >lq-text/src/test/TryHash.c <<'@@@End of lq-text/src/test/TryHash.c'
  1417. X/* $Header: /usr/src/cmd/lq-text/src/test/RCS/TryHash.c,v 1.1 90/08/09 19:17:43 lee Rel1-10 $
  1418. X *
  1419. X * $Log:    TryHash.c,v $
  1420. X * Revision 1.1  90/08/09  19:17:43  lee
  1421. X * Initial revision
  1422. X * 
  1423. X *
  1424. X */
  1425. X
  1426. X
  1427. X#ifdef SYSV
  1428. X extern int _flsbuf();
  1429. X#endif
  1430. X#include <stdio.h>
  1431. X
  1432. X#include "globals.h" /* defines and declarations for database filenames */
  1433. X
  1434. X#define HASHSIZ 4096
  1435. X
  1436. Xint AsciiTrace = 1;
  1437. Xchar *progname = "TryHash";
  1438. X
  1439. X/** Unix library functions: **/
  1440. Xextern int strlen();
  1441. X
  1442. Xint
  1443. XHash0(String)
  1444. X    char *String;
  1445. X{
  1446. X    register int Result = strlen(String);
  1447. X    register char *q;
  1448. X
  1449. X    for (q = String; *q; q++) {
  1450. X    Result = ((Result * 211) | *q) & (HASHSIZ - 1);
  1451. X    }
  1452. X    return Result;
  1453. X}
  1454. X
  1455. Xint
  1456. XHash1(str) /* Ozan's ... */
  1457. X    register char *str;
  1458. X{
  1459. X    register unsigned long n = 0;
  1460. X    register int len = strlen(str);
  1461. X
  1462. X#ifdef DUFF
  1463. X
  1464. X#define HASHC    n = *str++ + 65599 * n
  1465. X
  1466. X    if (len > 0) {
  1467. X    register int loop = (len + 8 - 1) >> 3;
  1468. X
  1469. X    switch(len & (8 - 1)) {
  1470. X    case 0:    do {
  1471. X        HASHC;    case 7:    HASHC;
  1472. X    case 6:    HASHC;    case 5:    HASHC;
  1473. X    case 4:    HASHC;    case 3:    HASHC;
  1474. X    case 2:    HASHC;    case 1:    HASHC;
  1475. X        } while (--loop);
  1476. X    }
  1477. X
  1478. X    }
  1479. X#else
  1480. X    while (len--)
  1481. X    n = *str++ + 65599 * n;
  1482. X#endif
  1483. X    return n & (HASHSIZ - 1);
  1484. X}
  1485. X
  1486. Xtypedef int (* t_ifp)();
  1487. Xt_ifp HashTab[] = {
  1488. X    Hash0,
  1489. X    Hash1
  1490. X#define MAXHASHF 2 /* CHANGE ME: number of hash functions */
  1491. X};
  1492. X
  1493. Xint
  1494. Xmain()
  1495. X{
  1496. X    char Buffer[1000];
  1497. X    int i;
  1498. X    t_ifp f;
  1499. X
  1500. X    while (gets(Buffer) != (char *) 0) {
  1501. X    printf("%s:", Buffer);
  1502. X    for (i = 0; i < MAXHASHF; i++) {
  1503. X        f = HashTab[i];
  1504. X        printf("\t%d", (* f)(Buffer));
  1505. X    }
  1506. X    putchar('\n');
  1507. X    }
  1508. X    return 0;
  1509. X}
  1510. @@@End of lq-text/src/test/TryHash.c
  1511. echo x - lq-text/src/test/TryNum.c 1>&2
  1512. sed 's/^X//' >lq-text/src/test/TryNum.c <<'@@@End of lq-text/src/test/TryNum.c'
  1513. X/* TryNum.c -- Copyright 1989 Liam R. Quin.  All Rights Reserved.
  1514. X * This code is NOT in the public domain.
  1515. X * See the file COPYRIGHT for full details.
  1516. X */
  1517. X
  1518. X/* For testing number routines from numbers.c */
  1519. X
  1520. X/* $Header: /usr/src/cmd/lq-text/src/test/RCS/TryNum.c,v 1.2 90/08/29 21:53:25 lee Rel1-10 $
  1521. X *
  1522. X * $Log:    TryNum.c,v $
  1523. X * Revision 1.2  90/08/29  21:53:25  lee
  1524. X * Test for variable-sozed numbers
  1525. X * 
  1526. X * Revision 1.1  90/08/09  19:17:44  lee
  1527. X * Initial revision
  1528. X * 
  1529. X * Revision 1.2  89/09/16  21:16:04  lee
  1530. X * First demonstratable version.
  1531. X * 
  1532. X * Revision 1.1  89/09/07  21:05:50  lee
  1533. X * Initial revision
  1534. X * 
  1535. X */
  1536. X
  1537. X#include <stdio.h>
  1538. X#include "globals.h"
  1539. X#include "numbers.h"
  1540. X
  1541. X#include "emalloc.h"
  1542. X
  1543. X/** Unix system calls that need to be declared **/
  1544. Xextern void exit();
  1545. X
  1546. X/** Unix Library Functions that need to be declared **/
  1547. Xextern int strcmp();
  1548. Xextern void perror();
  1549. Xextern int strlen();
  1550. Xextern char *strcpy();
  1551. X
  1552. X/** Functions from this file that need to be declared: **/
  1553. Xvoid dostrings();
  1554. X
  1555. X/** **/
  1556. X
  1557. Xchar *progname = "@(#) $Header: /usr/src/cmd/lq-text/src/test/RCS/TryNum.c,v 1.2 90/08/29 21:53:25 lee Rel1-10 $";
  1558. Xint AsciiTrace = 0;
  1559. X
  1560. Xint
  1561. Xmain(ac, av)
  1562. X    int ac;
  1563. X    char *av[];
  1564. X{
  1565. X    FILE *f;
  1566. X    unsigned long L;
  1567. X
  1568. X    progname = av[0]; /* leave the full path */
  1569. X
  1570. X    if (ac == 3 && !strcmp(av[1], "-s")) {
  1571. X    dostrings(av[2]);
  1572. X    exit(0);
  1573. X    }
  1574. X
  1575. X    if (ac != 2) {
  1576. X    fprintf(stderr, "Usage: %s file, or %s -s string\n", av[0], av[0]);
  1577. X    exit(1);
  1578. X    }
  1579. X
  1580. X    if ((f = fopen(av[1], "r")) == (FILE *) 0) {
  1581. X    extern int errno;
  1582. X    int e = errno;
  1583. X    fprintf(stderr, "%s: can't open file ", av[0]);
  1584. X    errno = e;
  1585. X    perror(av[1]);
  1586. X    exit(1);
  1587. X    }
  1588. X
  1589. X    for (;;) {
  1590. X    L = fReadNumber(f);
  1591. X    printf("%ld\n", L);
  1592. X    fflush(stdout);
  1593. X    if (feof(f)) break;
  1594. X    }
  1595. X
  1596. X    (void) fclose(f);
  1597. X
  1598. X    exit(0);
  1599. X    /*NOTREACHED*/
  1600. X    return 1; /* for lint */
  1601. X}
  1602. X
  1603. Xvoid
  1604. Xdostrings(string)
  1605. X    char *string;
  1606. X{
  1607. X    int len;
  1608. X    char *Buf;
  1609. X    char *End;
  1610. X
  1611. X    len = strlen(string);
  1612. X
  1613. X    /* the extra bytes allow sReadNumber to over-run */
  1614. X    if ((Buf = emalloc(len + sizeof(unsigned long) + 1)) == (char *) 0) {
  1615. X    fprintf(stderr, "%s: Not enough memory\n", progname);
  1616. X    exit(1);
  1617. X    }
  1618. X
  1619. X    (void) strcpy(Buf, string);
  1620. X
  1621. X    End = &Buf[len];
  1622. X    string = Buf;
  1623. X
  1624. X    while (string < End) {
  1625. X    printf("%lu\n", sReadNumber(&string));
  1626. X    }
  1627. X}
  1628. @@@End of lq-text/src/test/TryNum.c
  1629. echo x - lq-text/src/test/TryRoot.c 1>&2
  1630. sed 's/^X//' >lq-text/src/test/TryRoot.c <<'@@@End of lq-text/src/test/TryRoot.c'
  1631. X/* TryRoot.c -- Copyright 1989 Liam R. Quin.  All Rights Reserved.
  1632. X * This code is NOT in the public domain.
  1633. X * See the file COPYRIGHT for full details.
  1634. X *
  1635. X * $Header: /usr/src/cmd/lq-text/src/test/RCS/TryRoot.c,v 1.1 90/08/09 19:17:45 lee Rel1-10 $
  1636. X *
  1637. X * $Log:    TryRoot.c,v $
  1638. X * Revision 1.1  90/08/09  19:17:45  lee
  1639. X * Initial revision
  1640. X * 
  1641. X *
  1642. X */
  1643. X
  1644. X#include <stdio.h>
  1645. X#include <ctype.h>
  1646. X#include <sys/types.h>
  1647. X#include "fileinfo.h" /* this is needed by wordinfo.h */
  1648. X#include "wordinfo.h"
  1649. X#include "wordrules.h" /* for the flags, etc */
  1650. X
  1651. Xchar *progname = "TryRoot";
  1652. X
  1653. X/** Unix/C Library Functions: **/
  1654. Xextern int strlen();
  1655. X#ifndef tolower
  1656. Xextern int tolower();
  1657. X#endif
  1658. X
  1659. X/** lqtext library functions: **/
  1660. Xextern char *WordRoot();
  1661. Xextern void SetDefaults();
  1662. X
  1663. X/** **/
  1664. X
  1665. Xint
  1666. Xmain(argc, argv)
  1667. X    int argc;
  1668. X    char *argv[];
  1669. X{
  1670. X    t_WordInfo W;
  1671. X
  1672. X    SetDefaults(argc, argv);
  1673. X
  1674. X    while (--argc) {
  1675. X    extern char *UnFlag();
  1676. X    extern char *TryRoot();
  1677. X
  1678. X    char *s;
  1679. X    W.Word = *++argv;
  1680. X    W.Length = strlen(*argv);
  1681. X    W.WordPlace.Flags = 0;
  1682. X
  1683. X    printf("%s --> ", *argv);
  1684. X    if (isupper(W.Word[0])) {
  1685. X        W.WordPlace.Flags |= WPF_UPPERCASE;
  1686. X    }
  1687. X    for (s = W.Word; *s; s++) {
  1688. X        *s = tolower(*s);
  1689. X    }
  1690. X    s = WordRoot(&W);
  1691. X    printf("%s [%d] -->", s, W.WordPlace.Flags);
  1692. X    printf("%s", UnFlag(&W, W.WordPlace.Flags));
  1693. X    printf(" [%d]\n", W.WordPlace.Flags);
  1694. X    }
  1695. X    return 0;
  1696. X}
  1697. @@@End of lq-text/src/test/TryRoot.c
  1698. echo x - lq-text/src/test/dbmtry.c 1>&2
  1699. sed 's/^X//' >lq-text/src/test/dbmtry.c <<'@@@End of lq-text/src/test/dbmtry.c'
  1700. X/* dbmtry.c -- Copyright 1989 Liam R. Quin.  All Rights Reserved.
  1701. X * This code is NOT in the public domain.
  1702. X * See the file COPYRIGHT for full details.
  1703. X */
  1704. X
  1705. X/* If you have problems with the dbm interface, try this program.
  1706. X * If it fails with ALERT messages when given an argument of 300 or so,
  1707. X * you almost certainly have a faulty dbm.
  1708. X *
  1709. X * On SysV, by the way, check for delitem() calling bcopy() with
  1710. X * overlapping arguments...
  1711. X *
  1712. X * $Header: /usr/src/cmd/lq-text/src/test/RCS/dbmtry.c,v 1.5 91/03/03 00:47:56 lee Exp $
  1713. X *
  1714. X * $Log:    dbmtry.c,v $
  1715. X * Revision 1.5  91/03/03  00:47:56  lee
  1716. X * added sys/types.h for ozmahash
  1717. X * 
  1718. X * Revision 1.4  90/08/09  19:17:47  lee
  1719. X * *** empty log message ***
  1720. X * 
  1721. X * Revision 1.3  90/07/27  17:41:54  lee
  1722. X * *** empty log message ***
  1723. X * 
  1724. X * Revision 1.2  89/09/16  21:16:15  lee
  1725. X * First demonstratable version.
  1726. X * 
  1727. X * Revision 1.1  89/09/07  21:05:54  lee
  1728. X * Initial revision
  1729. X * 
  1730. X */
  1731. X
  1732. X#include "globals.h" /* defines and declarations for database filenames */
  1733. X
  1734. X#include <stdio.h>
  1735. X#include <fcntl.h>
  1736. X#ifdef ozmahash
  1737. X# include <sys/types.h>
  1738. X#endif
  1739. X#include "smalldb.h"
  1740. X
  1741. Xchar *progname = "dbmtry";
  1742. X
  1743. X/** Unix system calls: **/
  1744. Xextern void exit();
  1745. X
  1746. X/** Unix Library Functions: **/
  1747. Xextern int atoi();
  1748. Xextern int strlen();
  1749. Xextern void perror();
  1750. X
  1751. X/** Routines in this file which need declaring: **/
  1752. Xvoid printvalues();
  1753. X
  1754. X/** **/
  1755. X
  1756. X
  1757. Xint
  1758. Xmain(ac, av)
  1759. X    int ac;
  1760. X    char *av[];
  1761. X{
  1762. X    DBM *db;
  1763. X    int max = atoi(av[1]);
  1764. X    int i;
  1765. X    datum key, data;
  1766. X    char dbuf[30];
  1767. X
  1768. X
  1769. X    if (ac <= 1) {
  1770. X    fprintf(stderr, "Usage: %s maxkey\n", av[0]);
  1771. X    exit(1);
  1772. X    }
  1773. X
  1774. X    if ((db = startdb("/tmp/trydbm")) == (DBM *) 0) {
  1775. X    fprintf(stderr, "dbmopen 1 failed\n");
  1776. X    exit(1);
  1777. X    }
  1778. X
  1779. X    for (i = 1; i <= max; i++) {
  1780. X    char buf[20];
  1781. X    register int s_val;
  1782. X
  1783. X    if ((i % 500) == 0) {
  1784. X        (void) fprintf(stderr, "\r%d ", i);
  1785. X        (void) fflush(stderr);
  1786. X    }
  1787. X    sprintf(buf, "%d", i);
  1788. X    sprintf(dbuf, "%d data item here", i);
  1789. X        /* Note: the number is at the start to help speed the
  1790. X         * strcmp, as it is most likely to differ
  1791. X         */
  1792. X    key.dsize = strlen(buf) + 1; /* include th nul so we can strcmp() */
  1793. X    key.dptr = buf;
  1794. X    data.dptr = dbuf;
  1795. X    data.dsize = strlen(dbuf) + 1;
  1796. X    s_val = dbm_store(db, key, data, DBM_INSERT);
  1797. X    if (s_val != 0) {
  1798. X        printf("store %d returned %d\n", i, s_val);
  1799. X    }
  1800. X    }
  1801. X
  1802. X    enddb(db);
  1803. X
  1804. X    printvalues(max);
  1805. X    return 0;
  1806. X}
  1807. X
  1808. Xvoid
  1809. Xprintvalues(max)
  1810. X    int max;
  1811. X{
  1812. X    DBM *db;
  1813. X    int i;
  1814. X    datum key, data;
  1815. X
  1816. X    db = startdb("/tmp/trydbm");
  1817. X
  1818. X    if (!db) {
  1819. X    fprintf(stderr, "Unable to open database ");
  1820. X    perror("/tmp/trydbm");
  1821. X    exit(1);
  1822. X    }
  1823. X
  1824. X    for (i = 1; i <= max; i++) {
  1825. X    char buf[20];
  1826. X
  1827. X    sprintf(buf, "%d", i);
  1828. X    key.dsize = strlen(buf) + 1;
  1829. X    key.dptr = buf;
  1830. X    data = dbm_fetch(db, key);
  1831. X
  1832. X    if (data.dsize == 0) {
  1833. X        printf("ALERT! Item %d has been lost! ALERT!\n", i);
  1834. X    } else {
  1835. X        char *Buf[100];
  1836. X        (void) sprintf(Buf, "%d data item here", i);
  1837. X        if (strcmp(Buf, data.dptr) != 0) {
  1838. X        printf("%d: Corrupt: \"%s\" != \"%s\"\n",
  1839. X                i, data.dptr, Buf);
  1840. X        /* NOTE: no use using STREQ, as the strings are usually
  1841. X         * the same.
  1842. X         */
  1843. X        }
  1844. X    }
  1845. X    }
  1846. X
  1847. X    enddb(db);
  1848. X}
  1849. @@@End of lq-text/src/test/dbmtry.c
  1850. echo x - lq-text/src/test/numbers.c 1>&2
  1851. sed 's/^X//' >lq-text/src/test/numbers.c <<'@@@End of lq-text/src/test/numbers.c'
  1852. X/* numbers.c -- Copyright 1989 Liam R. Quin.  All Rights Reserved.
  1853. X * This code is NOT in the public domain.
  1854. X * See the file COPYRIGHT for full details.
  1855. X */
  1856. X
  1857. X/* Routines to read and write numbers in a compressed format, preserving
  1858. X * block boundaries.
  1859. X * The actual compression seems to be about 50%, as most numbers turn
  1860. X * out to fit in 16 bits.  Interestingly, there is room for another one
  1861. X * or two bits, I think, that could be used for something else, in the
  1862. X * main pblock index.  For example, it could mark whether words were
  1863. X * plural/-"ing"/"un"-/ with 2 bits.
  1864. X *
  1865. X * $Header: /usr/src/cmd/lq-text/src/test/RCS/numbers.c,v 1.2 90/10/03 21:13:21 lee Rel1-10 $
  1866. X *
  1867. X * $Log:    numbers.c,v $
  1868. X * Revision 1.2  90/10/03  21:13:21  lee
  1869. X * Added a cast.
  1870. X * 
  1871. X * Revision 1.3  90/08/09  19:16:49  lee
  1872. X * BSD lint and fixes...
  1873. X * 
  1874. X * Revision 1.2  90/04/18  19:47:13  lee
  1875. X * More flexible (and slightly more compact) number format.
  1876. X * 
  1877. X * Revision 2.2  89/10/08  20:46:36  lee
  1878. X * Working version of nx-text engine.  Addfile and wordinfo work OK.
  1879. X * 
  1880. X * Revision 2.1  89/10/02  01:15:15  lee
  1881. X * New index format, with Block/WordInBlock/Flags/BytesSkipped info.
  1882. X * 
  1883. X * Revision 1.2  89/09/16  21:16:26  lee
  1884. X * First demonstratable version.
  1885. X * 
  1886. X * Revision 1.1  89/09/07  21:06:01  lee
  1887. X * Initial revision
  1888. X * 
  1889. X *
  1890. X */
  1891. X
  1892. X#include "globals.h"
  1893. X
  1894. X#ifdef SYSV
  1895. X    extern int _filbuf(), _flsbuf();
  1896. X#endif
  1897. X#include <stdio.h>
  1898. X#include "numbers.h"
  1899. X
  1900. X/* ReadNumber and WriteNumber take/return a long, using a compression
  1901. X * algorithm to reduce the amount of data taken.
  1902. X * The current algorithm is simply like internet addresses:
  1903. X * a 0 in the top bit followed by a 0 means it's one byte
  1904. X * a 0 followed by a 1 means it's 2 bytes
  1905. X * a 1 followed by a 0 means it's 3 bytes, and
  1906. X * a 1 followed by a 1 means it's 4 bytes.
  1907. X * A better alternative might simply use a 1 in the top bit, hence fitting
  1908. X * 7 bits into each bytes.  The advantages of considering more than
  1909. X * one number at a time and using compress-style LS packing are not clear.
  1910. X * In particular, speed of recovery is an issue too.
  1911. X *
  1912. X * The routines use (char *) pointers instead of files prefixes with an s.
  1913. X * see numbers.h for some related macros.
  1914. X *
  1915. X */
  1916. X
  1917. X
  1918. X#ifdef TESTNUMBERS
  1919. Xchar *progname;
  1920. X
  1921. Xint
  1922. Xmain(ac, av)
  1923. X    int ac;
  1924. X    char *av[];
  1925. X{
  1926. X    extern long atol();
  1927. X    FILE *f;
  1928. X    extern FILE *fopen();
  1929. X
  1930. X    progname = av[0];
  1931. X
  1932. X    while (--ac) {
  1933. X    unsigned long L = atol(*++av);
  1934. X    unsigned long L2;
  1935. X
  1936. X    f = fopen("/tmp/boy", "w");
  1937. X    printf("Write %u\n", L);
  1938. X    fWriteNumber(f, L);
  1939. X    fclose(f);
  1940. X    f = fopen("/tmp/boy", "r");
  1941. X    L2 = fReadNumber(f);
  1942. X    printf("Read %u\n", L2);
  1943. X    if (L != L2) {
  1944. X        printf("**** ERROR **** %ld != %ld\n", L, L2);
  1945. X    }
  1946. X    fclose(f);
  1947. X    }
  1948. X    return 0;
  1949. X}
  1950. X#endif /*TESTNUMBERS*/
  1951. X
  1952. XINLINE void
  1953. XfWriteNumber(f, Number)
  1954. X    FILE *f;
  1955. X    unsigned long Number;
  1956. X{
  1957. X    /* Compressed numbers:
  1958. X     * 7 bit numbers --> single byte;
  1959. X     * 8...14 bits --> 2 bytes
  1960. X     * 15...21 bits --> 3 bytes
  1961. X     * 22..28 bits --> 4 bytes
  1962. X     * 29..32 bits --> 5 bytes
  1963. X     */
  1964. X    while (Number > 0177) {
  1965. X    putc((Number & 0177) | 0200, f);
  1966. X    Number >>= 7;
  1967. X    }
  1968. X    putc(Number & 0177, f);
  1969. X}
  1970. X
  1971. X#define PutC(ch, S)  (*((*S)++) = (char) (ch))
  1972. X
  1973. XINLINE void
  1974. XsWriteNumber(s, Number)
  1975. X    char **s;
  1976. X    unsigned long Number;
  1977. X{
  1978. X    /* Compressed numbers:
  1979. X     * 7 bit numbers --> single byte;
  1980. X     * 8...14 bits --> 2 bytes
  1981. X     * 15...21 bits --> 3 bytes
  1982. X     * 22..28 bits --> 4 bytes
  1983. X     * 29..32 bits --> 5 bytes
  1984. X     */
  1985. X    while (Number > 0177) {
  1986. X    PutC((Number & 0177) | 0200, s);
  1987. X    Number >>= 7;
  1988. X    }
  1989. X    PutC(Number & 0177, s);
  1990. X}
  1991. X
  1992. XINLINE unsigned long
  1993. XfReadNumber(f)
  1994. X    FILE *f;
  1995. X{
  1996. X    unsigned long Result = 0L;
  1997. X    int ThereIsMore;
  1998. X    int Shift = 0;
  1999. X
  2000. X    /* Read a number, 7 bits at a time, lsb first, until there is
  2001. X     * a byte without the top bit set -- that's the most significant
  2002. X     * byte, and there is no more of this number.
  2003. X     */
  2004. X    do {
  2005. X    Result |= ((ThereIsMore = getc(f)) & 0177) << Shift;
  2006. X    ThereIsMore &= 0200;
  2007. X    Shift += 7;
  2008. X    } while (ThereIsMore);
  2009. X    return Result;
  2010. X}
  2011. X
  2012. X#define GetC(S) \
  2013. X    ( (unsigned int) * (unsigned char *) ((* (unsigned char **)S)++) )
  2014. X
  2015. XINLINE unsigned long
  2016. XsReadNumber(s)
  2017. X    char **s;
  2018. X{
  2019. X    unsigned long Result = 0L;
  2020. X    int ThereIsMore;
  2021. X    int Shift = 0;
  2022. X
  2023. X    /* Read a number, 7 bits at a time, lsb first, until there is
  2024. X     * a byte without the top bit set -- that's the most significant
  2025. X     * byte, and there is no more of this number.
  2026. X     */
  2027. X    do {
  2028. X    Result |= ((ThereIsMore = GetC(s)) & 0177) << Shift;
  2029. X    ThereIsMore &= 0200;
  2030. X    Shift += 7;
  2031. X    } while (ThereIsMore);
  2032. X    return Result;
  2033. X}
  2034. @@@End of lq-text/src/test/numbers.c
  2035. echo x - lq-text/src/test/put.c 1>&2
  2036. sed 's/^X//' >lq-text/src/test/put.c <<'@@@End of lq-text/src/test/put.c'
  2037. X/* put.c -- Copyright 1989 Liam R. Quin.  All Rights Reserved.
  2038. X * This code is NOT in the public domain.
  2039. X * See the file COPYRIGHT for full details.
  2040. X */
  2041. X
  2042. X/* This is useful if your echo doesn't grok \ddd.
  2043. X * Use put [string|number]*, numbers wih a leading 0 are octal.
  2044. X * Use -s to mean that the next argument is a string.  Use -s -s to print
  2045. X * the string "-s".
  2046. X *
  2047. X * $Header: /usr/src/cmd/lq-text/src/test/RCS/put.c,v 1.1 90/08/09 19:17:50 lee Rel1-10 $
  2048. X *
  2049. X * $Log:    put.c,v $
  2050. X * Revision 1.1  90/08/09  19:17:50  lee
  2051. X * Initial revision
  2052. X * 
  2053. X * Revision 1.2  89/09/16  21:18:32  lee
  2054. X * First demonstratable version.
  2055. X * 
  2056. X * Revision 1.1  89/09/07  21:06:10  lee
  2057. X * Initial revision
  2058. X * 
  2059. X *
  2060. X */
  2061. X
  2062. X#ifdef SYSV
  2063. X    extern int _flsbuf(); /* keep lint ang gcc -Wall happy */
  2064. X#endif
  2065. X#include <stdio.h>
  2066. X#include <ctype.h>
  2067. X
  2068. X/** Unix/C Library Functions: **/
  2069. Xextern int atoi(), strcmp();
  2070. X/** **/
  2071. X
  2072. Xint
  2073. Xmain(ac, av)
  2074. X    int ac;
  2075. X    char *av[];
  2076. X{
  2077. X    while (--ac) {
  2078. X    ++av;
  2079. X    if (isdigit(**av)) {
  2080. X        if (**av == '0') {
  2081. X        int o;
  2082. X
  2083. X        sscanf(*av, "%o", &o);
  2084. X        putchar(o);
  2085. X        } else {
  2086. X        putchar(atoi(*av));
  2087. X        }
  2088. X    } else {
  2089. X        if (ac > 1 && !strcmp(*av, "-s")) {
  2090. X        --ac;
  2091. X        ++av;
  2092. X        }
  2093. X        printf("%s", *av);
  2094. X    }
  2095. X    }
  2096. X}
  2097. @@@End of lq-text/src/test/put.c
  2098. echo end of part 10
  2099. -- 
  2100. Liam R. E. Quin,  lee@sq.com, SoftQuad Inc., Toronto, +1 (416) 963-8337
  2101.