home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / quot210s.zip / src / qsearch.c < prev    next >
C/C++ Source or Header  |  1998-09-07  |  9KB  |  352 lines

  1. /*
  2.  * qsearch.c
  3.  *
  4.  * Functions for searching a quote database. Note that the use of the
  5.  * GENERIC macro here is not because the #ifndef'd sections won't compile
  6.  * in the generic build; it's so that the GNU Rx library isn't required
  7.  * for the generic build, since the generic build doesn't use these
  8.  * functions.
  9.  *
  10.  *      Created: 27th January, 1997
  11.  * Version 1.00: 20th March, 1997
  12.  * Version 2.00: 24th November, 1997
  13.  * Version 2.10: 7th September, 1998
  14.  *
  15.  * (C) 1997-1998 Nicholas Paul Sheppard
  16.  *
  17.  * This file is distributed under the GNU General Public License. See the
  18.  * file copying.txt for details.
  19.  */
  20.  
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <gnu/gdbm.h>
  24. #ifndef GENERIC
  25. # include <gnu/rxposix.h>
  26. # include <gnu/rxall.h>
  27. #endif
  28. #include "quotes.h"
  29. #include "html.h"
  30.  
  31.  
  32. int QuoteFullSearchInit(QUOTEDB *pqdb, QUOTESEARCH *pqs)
  33. /*
  34.  * Find the first quote in a database, and initialise a structure to be used
  35.  * in finding the rest. The first key is returned in the szLastCode field of
  36.  * the QUOTESEARCH structure.
  37.  *
  38.  * QUOTEDB *pqdb    - the quote database to search
  39.  * QUOTESEARCH *pqs    - the structure to be initialised for further searching
  40.  *
  41.  * Returns:        - 0 if the database is empty
  42.  *              1 otherwise
  43.  */
  44. {
  45.     datum first;
  46.  
  47.     first = gdbm_firstkey(pqdb->dbfInfo);
  48.     if (first.dptr == NULL)
  49.         return (0);
  50.  
  51.     pqs->pqdb = pqdb;
  52.     strcpy(pqs->szLastCode, first.dptr);
  53.     free(first.dptr);
  54.  
  55.     return (1);
  56. }
  57.  
  58.  
  59. int QuoteFullSearchNext(QUOTESEARCH *pqs)
  60. /*
  61.  * Find the next quote in a database and update the structure to be used for
  62.  * finding the rest. The next key is returned in the szLastCode field of the
  63.  * QUOTESEARCH structure.
  64.  *
  65.  * QUOTESEARCH *qs    - the search structure
  66.  *
  67.  * Returns:        - 0 if there are no more quotes in the database
  68.  *              1 otherwise
  69.  */
  70. {
  71.     datum current, next;
  72.  
  73.     current.dptr = pqs->szLastCode;
  74.     current.dsize = strlen(pqs->szLastCode) + 1;
  75.     next = gdbm_nextkey(pqs->pqdb->dbfInfo, current);
  76.     if (next.dptr == NULL)
  77.         return (0);
  78.  
  79.     strcpy(pqs->szLastCode, next.dptr);
  80.     free(next.dptr);
  81.  
  82.     return (1);
  83. }
  84.  
  85.  
  86. void QuoteFullSearchEnd(QUOTESEARCH *pqs)
  87. /*
  88.  * Clean up after finishing a full search of the database. Currently, this
  89.  * function does nothing and only exists to make a full search look the
  90.  * same as other searches.
  91.  */
  92. {
  93. }
  94.  
  95. #ifndef GENERIC
  96. int QuoteKeySearchInit(QUOTEDB *pqdb, char *pszKeyword, QUOTESEARCH *pqs)
  97. /*
  98.  * Find the first quote in a database with a given keyword, and initialise
  99.  * a structure to be used for finding the rest. The first key is returned
  100.  * in the szLastCode field of the QUOTESEARCH structure.
  101.  *
  102.  * QUOTEDB *pqdb    - the quote database to search
  103.  * char *pszKeyword    - the keyword to search for
  104.  * QUOTESEARCH *pqs    - the structure to be initialised for further searching
  105.  *
  106.  * Returns:        - -1 if the regular expression is invalid
  107.  *               0 if there are no matching quotes in the database
  108.  *               1 otherwise
  109.  */
  110. {
  111.     QUOTEINFO *pqi;
  112.     int bDone, bFound;
  113.     int i;
  114.  
  115.     /* fill the QUOTESEARCH structure */
  116.     strcpy(pqs->szSearch, pszKeyword);
  117.     pqs->pqdb = pqdb;
  118.     if (regcomp(&(pqs->rxSearch), pszKeyword, REG_NOSUB | REG_EXTENDED | REG_ICASE))
  119.         return (-1);
  120.  
  121.     /* find the first quote with a matching keyword */
  122.     bFound = 0;
  123.     bDone = !QuoteFullSearchInit(pqdb, pqs);
  124.     while (!bDone) {
  125.         QuoteGetQuote(pqdb, pqs->szLastCode, &pqi, NULL);
  126.         for (i = 0; i < 5; i++)
  127.             if (!regexec(&(pqs->rxSearch), pqi->aszKeyword[i], 0, NULL, 0))
  128.                 bFound = 1;
  129.         QuoteFreeQuote(&pqi, NULL);
  130.         if (bFound)
  131.             bDone = 1;
  132.         else
  133.             bDone = !QuoteFullSearchNext(pqs);
  134.     }
  135.  
  136.     return (bFound);
  137. }
  138. #endif
  139.  
  140.  
  141. #ifndef GENERIC
  142. int QuoteKeySearchNext(QUOTESEARCH *pqs)
  143. /*
  144.  * Find the next quote in a database with a specified keyword.
  145.  *
  146.  * QUOTESEARCH *pqs    - the structure containing the search information
  147.  *
  148.  * Returns:        - 0 if there are no more matching quotes in the database
  149.  *              1 otherwise
  150.  */
  151. {
  152.     QUOTEINFO *pqi;
  153.     int bDone, bFound;
  154.     int i;
  155.  
  156.     bFound = 0;
  157.     bDone = !QuoteFullSearchNext(pqs);
  158.     while (!bDone) {
  159.         QuoteGetQuote(pqs->pqdb, pqs->szLastCode, &pqi, NULL);
  160.         for (i = 0; i < 5; i++)
  161.             if (!regexec(&(pqs->rxSearch), pqi->aszKeyword[i], 0, NULL, 0))
  162.                 bFound = 1;
  163.         QuoteFreeQuote(&pqi, NULL);
  164.         if (bFound)
  165.             bDone = 1;
  166.         else
  167.             bDone = !QuoteFullSearchNext(pqs);
  168.     }
  169.  
  170.     return (bFound);
  171. }
  172. #endif
  173.  
  174.  
  175. #ifndef GENERIC
  176. void QuoteKeySearchEnd(QUOTESEARCH *pqs)
  177. /*
  178.  * Clean up after completing a keyword search.
  179.  */
  180. {
  181.     regfree(&(pqs->rxSearch));
  182. }
  183. #endif
  184.  
  185.  
  186. #ifndef GENERIC
  187. int QuoteTextSearchInit(QUOTEDB *pqdb, char *pszText, QUOTESEARCH *pqs)
  188. /*
  189.  * Find the first quote in a database containing the specified text,
  190.  * and initialise a structure to be used for finding the rest. The
  191.  * first key is returned in the szLastCode field of the QUOTESEARCH
  192.  * structure.
  193.  *
  194.  * QUOTEDB *pqdb    - the quote database to search
  195.  * char *pszText    - the text to search for (regular expression)
  196.  * QUOTESEARCH *pqs    - the structure to be initialised for further searching
  197.  *
  198.  * Returns:        - -1 if the regular expression is invalid
  199.  *               0 if there are no matching quotes in the database
  200.  *               1 otherwise
  201.  */
  202. {
  203.     char *pszQuoteText;
  204.     int bDone, bFound;
  205.  
  206.     /* fill the QUOTESEARCH structure */
  207.     strcpy(pqs->szSearch, pszText);
  208.     pqs->pqdb = pqdb;
  209.     if (regcomp(&(pqs->rxSearch), pszText, REG_NOSUB | REG_EXTENDED | REG_ICASE))
  210.         return (-1);
  211.  
  212.     /* find the first quote with a matching keyword */
  213.     bFound = 0;
  214.     bDone = !QuoteFullSearchInit(pqdb, pqs);
  215.     while (!bDone) {
  216.         QuoteGetQuote(pqdb, pqs->szLastCode, NULL, &pszQuoteText);
  217.         HTMLMakePlain(pszQuoteText);
  218.         if (!regexec(&(pqs->rxSearch), pszQuoteText, 0, NULL, 0))
  219.             bFound = 1;
  220.         QuoteFreeQuote(NULL, &pszQuoteText);
  221.         if (bFound)
  222.             bDone = 1;
  223.         else
  224.             bDone = !QuoteFullSearchNext(pqs);
  225.     }
  226.  
  227.     return (bFound);
  228. }
  229. #endif
  230.  
  231.  
  232. #ifndef GENERIC
  233. int QuoteTextSearchNext(QUOTESEARCH *pqs)
  234. /*
  235.  * Find the next quote in a database containing the specified text.
  236.  *
  237.  * QUOTESEARCH *pqs    - the structure containing the search information
  238.  *
  239.  * Returns:        - 0 if there are no more matching quotes in the database
  240.  *              1 otherwise
  241.  */
  242. {
  243.     char *pszQuoteText;
  244.     int bDone, bFound;
  245.  
  246.     bFound = 0;
  247.     bDone = !QuoteFullSearchNext(pqs);
  248.     while (!bDone) {
  249.         QuoteGetQuote(pqs->pqdb, pqs->szLastCode, NULL, &pszQuoteText);
  250.         HTMLMakePlain(pszQuoteText);
  251.         if (!regexec(&(pqs->rxSearch), pszQuoteText, 0, NULL, 0))
  252.             bFound = 1;
  253.         QuoteFreeQuote(NULL, &pszQuoteText);
  254.         if (bFound)
  255.             bDone = 1;
  256.         else
  257.             bDone = !QuoteFullSearchNext(pqs);
  258.     }
  259.  
  260.     return (bFound);
  261. }
  262. #endif
  263.  
  264.  
  265. #ifndef GENERIC
  266. void QuoteTextSearchEnd(QUOTESEARCH *pqs)
  267. /*
  268.  * Clean up after completing a search of specified text.
  269.  */
  270. {
  271.     regfree(&(pqs->rxSearch));
  272. }
  273. #endif
  274.  
  275.  
  276. int QuoteAuthorSearchInit(QUOTEDB *pqdb, char *pszAuthor, QUOTESEARCH *pqs)
  277. /*
  278.  * Find the first quote in a database from a given author, and initialise a
  279.  * structure to be used for finding the rest. The first key is returned in
  280.  * the szLastCode field of the QUOTESEARCH structure.
  281.  *
  282.  * QUOTEDB *pqdb    - the quote database to search
  283.  * char *pszAuthor    - the author code to search for
  284.  * QUOTESEARCH *pqs    - the structure to be initialised for further searching
  285.  * Returns:        - 0 if there are no matching quotes in the database
  286.  *              1 otherwise
  287.  */
  288. {
  289.     QUOTEINFO *pqi;
  290.     int bDone, bFound;
  291.  
  292.     /* fill the QUOTESEARCH structure */
  293.     strcpy(pqs->szSearch, pszAuthor);
  294.     pqs->pqdb = pqdb;
  295.  
  296.     /* find the first quote with a matching keyword */
  297.     bFound = 0;
  298.     bDone = !QuoteFullSearchInit(pqdb, pqs);
  299.     while (!bDone) {
  300.         QuoteGetQuote(pqdb, pqs->szLastCode, &pqi, NULL);
  301.         if (strcmp(pszAuthor, pqi->szAuthorCode) == 0)
  302.             bFound = 1;
  303.         QuoteFreeQuote(&pqi, NULL);
  304.         if (bFound)
  305.             bDone = 1;
  306.         else
  307.             bDone = !QuoteFullSearchNext(pqs);
  308.     }
  309.  
  310.     return (bFound);
  311. }
  312.  
  313.  
  314. int QuoteAuthorSearchNext(QUOTESEARCH *pqs)
  315. /*
  316.  * Find the next quote in a database from a given author.
  317.  *
  318.  * QUOTESEARCH *pqs    - the structure containing the search information
  319.  *
  320.  * Returns:        - 0 if there are no more matching quotes in the database
  321.  *              1 otherwise
  322.  */
  323. {
  324.     QUOTEINFO *pqi;
  325.     int bDone, bFound;
  326.  
  327.     bFound = 0;
  328.     bDone = !QuoteFullSearchNext(pqs);
  329.     while (!bDone) {
  330.         QuoteGetQuote(pqs->pqdb, pqs->szLastCode, &pqi, NULL);
  331.         if (strcmp(pqs->szSearch, pqi->szAuthorCode) == 0)
  332.             bFound = 1;
  333.         QuoteFreeQuote(&pqi, NULL);
  334.         if (bFound)
  335.             bDone = 1;
  336.         else
  337.             bDone = !QuoteFullSearchNext(pqs);
  338.     }
  339.  
  340.     return (bFound);
  341. }
  342.  
  343.  
  344. void QuoteAuthorSearchEnd(QUOTESEARCH *pqs)
  345. /*
  346.  * Clean up after finishing an author search of the database. Currently,
  347.  * this function does nothing and only exists to make a full search look
  348.  * the same as other searches.
  349.  */
  350. {
  351. }
  352.