home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 2 / DATAFILE_PDCD2.iso / utilities3 / discindex / DiscIndex / Source / C / Search < prev    next >
Text File  |  1994-08-03  |  7KB  |  258 lines

  1. /* DiscIndex 1.00
  2.  * Record searching code
  3.  * By Neil A Carson 1994 A.D.
  4.  */
  5.  
  6. #include <ctype.h>
  7. #include <string.h>
  8.  
  9. #include "dbox.h"
  10. #include "discindex.h"
  11. #include "visdelay.h"
  12. #include "werr.h"
  13.  
  14. extern dbox find_dbox, matches_dbox;
  15. extern BOOL find_open, matches_open;
  16. extern match_win_type match_win_info;
  17. extern search_win_type search_win_info;
  18.  
  19. extern void fill_in_matches(dbox, match_win_type *);
  20.  
  21. void matches_event_handler(dbox, void *);
  22. void do_search(search_win_type *s);
  23. void searchnstore(int, int, match_type, search_win_type *);
  24. void clean_up(void);
  25. BOOL mem_find(BOOL case_sens, char *start, char *to_match);
  26.  
  27. void search(void)
  28. {
  29.     BOOL filling = TRUE, all_go = FALSE;
  30.  
  31.     if (!find_open)
  32.     {
  33.         find_dbox = dbox_new("Find");
  34.         dbox_show(find_dbox);
  35.     }
  36.  
  37.     if (search_win_info.fields & disc_name) dbox_setnumeric(find_dbox, 2, 1);
  38.         else dbox_setnumeric(find_dbox, 2, 0);
  39.     if (search_win_info.fields & disc_desc) dbox_setnumeric(find_dbox, 3, 1);
  40.         else dbox_setnumeric(find_dbox, 3, 0);
  41.     if (search_win_info.fields & file_name) dbox_setnumeric(find_dbox, 4, 1);
  42.         else dbox_setnumeric(find_dbox, 4, 0);
  43.     if (search_win_info.fields & file_desc) dbox_setnumeric(find_dbox, 5, 1);
  44.         else dbox_setnumeric(find_dbox, 5, 0);
  45.     if (search_win_info.case_sensitive) dbox_setnumeric(find_dbox,8,1);
  46.         else dbox_setnumeric(find_dbox, 8, 0);
  47.     dbox_setfield(find_dbox, 11, search_win_info.string);
  48.  
  49.     if (find_open) return;
  50.     find_open = TRUE;
  51.  
  52.     while (filling)
  53.     {
  54.         switch(dbox_fillin(find_dbox))
  55.         {
  56.             case 12:
  57.             if (!dbox_persist())
  58.             {
  59.                 all_go = TRUE;
  60.                 filling = FALSE;
  61.             }
  62.             break;
  63.  
  64.             case dbox_CLOSE:
  65.             filling = FALSE;
  66.             break;
  67.  
  68.             default: break;
  69.         }
  70.     }
  71.  
  72.     search_win_info.fields = 0;
  73.     if (dbox_getnumeric(find_dbox, 2)) search_win_info.fields |= disc_name;
  74.     if (dbox_getnumeric(find_dbox, 3)) search_win_info.fields |= disc_desc;
  75.     if (dbox_getnumeric(find_dbox, 4)) search_win_info.fields |= file_name;
  76.     if (dbox_getnumeric(find_dbox, 5)) search_win_info.fields |= file_desc;
  77.     search_win_info.case_sensitive = dbox_getnumeric(find_dbox, 8);
  78.     dbox_getfield(find_dbox, 11, search_win_info.string, 32);
  79.     dbox_dispose(&find_dbox);
  80.     find_open = FALSE;
  81.  
  82.     if (!all_go) return;
  83.  
  84.     if (search_win_info.fields == 0)
  85.     {
  86.         werr(0, "With search criteria like that, nothing will happen!");
  87.         return;
  88.     }
  89.     match_win_info.no = 0;
  90.     visdelay_begin();
  91.     memset(&match_win_info, 0, sizeof(match_win_type));
  92.     do_search(&search_win_info);
  93.     visdelay_end();
  94.     if (match_win_info.matches == 0)
  95.     {
  96.         werr(0, "None found, sorry!");
  97.         return;
  98.     }
  99.     clean_up();
  100. }
  101.  
  102. void do_search(search_win_type *s)
  103. {
  104.     disc_type *disc;
  105.     int disc_cnt, file_cnt;
  106.  
  107.     for (disc_cnt = 0; disc_cnt < records.no; disc_cnt ++)
  108.     {
  109.         disc = disc_locate(disc_cnt);
  110.         if (disc == 0) werr(1, "Flawed disc numbering in search!");
  111.         if (s->fields & disc_name)
  112.         {
  113.             searchnstore(disc_cnt, -1, match_dname, s);
  114.             if (match_win_info.no == 16) return;
  115.         }
  116.         if (s->fields & disc_desc)
  117.         {
  118.             searchnstore(disc_cnt, -1, match_ddesc, s);
  119.             if (match_win_info.no == 16) return;
  120.         }
  121.  
  122.         if (disc->files != 0)
  123.         {
  124.             if ((s->fields & file_name) || (s->fields & file_desc))
  125.             {
  126.                 for (file_cnt = 0; file_cnt < disc->no; file_cnt ++)
  127.                 {
  128.                     if (s->fields & file_name)
  129.                     {
  130.                         searchnstore(disc_cnt, file_cnt, match_fname, s);
  131.                         if (match_win_info.no == 16) return;
  132.                     }
  133.                     if (s->fields & file_desc)
  134.                     {
  135.                         searchnstore(disc_cnt, file_cnt, match_fdesc, s);
  136.                         if (match_win_info.no == 16) return;
  137.                     }
  138.                 }
  139.             }
  140.         }
  141.     }
  142. }
  143.  
  144. void searchnstore(int disc, int file, match_type to_match, search_win_type *s)
  145. {
  146.     char string[32];
  147.     disc_type *d;
  148.  
  149.     d = disc_locate(disc);
  150.     if (d == 0)
  151.         werr(1, "Attempt to get non-existent disc!");
  152.  
  153.     switch(to_match)
  154.     {
  155.         case match_dname:
  156.         strncpy(string, d->disc_name, 31);
  157.         break;
  158.  
  159.         case match_ddesc:
  160.         strncpy(string, d->disc_desc, 31);
  161.         break;
  162.  
  163.         case match_fname:
  164.         strncpy(string, d->files[file].name, 31);
  165.         break;
  166.  
  167.         case match_fdesc:
  168.         strncpy(string, d->files[file].desc, 31);
  169.         break;
  170.  
  171.         default: werr(1, "Fatal call to searchnstore!");
  172.     }
  173.  
  174.     string[31] = 0;
  175.     if (!mem_find(s->case_sensitive, string, s->string)) return;
  176.  
  177.     /* Now we have found something, store it! */
  178.  
  179.     match_win_info.disc_nos[match_win_info.no] = disc;
  180.     if (file != -1) match_win_info.file_nos[match_win_info.no] = file;
  181.         else match_win_info.file_nos[match_win_info.no] = 0;
  182.     match_win_info.matches[match_win_info.no] = to_match;
  183.     if (file != -1) match_win_info.matches[match_win_info.no] |= show_fname;
  184.     match_win_info.no ++;
  185. }
  186.  
  187. void clean_up(void)
  188. {
  189.     if (!matches_open)
  190.     {
  191.         matches_dbox = dbox_new("Matches");
  192.         dbox_eventhandler(matches_dbox, matches_event_handler, 0);
  193.         dbox_showstatic(matches_dbox);
  194.         matches_open = TRUE;
  195.     }
  196.     fill_in_matches(matches_dbox, &match_win_info);
  197. }
  198.  
  199. /* Fast(ish) function for finding a string in a given area of memory.
  200.  * Returns NULL is string not found
  201.  */
  202. BOOL mem_find(BOOL case_sens, char *start, char *to_match)
  203. {
  204.     char lhs[32], rhs[32];
  205.     int len, cnt, lcnt;
  206.     BOOL matched;
  207.  
  208.     len = strlen(to_match);
  209.     strncpy(lhs, start, 32);
  210.     lhs[31] = 0;
  211.     strncpy(rhs, to_match, 32);
  212.     rhs[31] = 0;
  213.     if (!case_sens)
  214.         for (cnt = 0; cnt < 32; cnt ++)
  215.         {
  216.             lhs[cnt] = (char) toupper(lhs[cnt]);
  217.             rhs[cnt] = (char) toupper(rhs[cnt]);
  218.         }
  219.  
  220.     for (cnt = 0; cnt < 32; cnt ++)
  221.     {
  222.         if (lhs[cnt] == rhs[0])
  223.         {
  224.             matched = TRUE;
  225.             for (lcnt = 0; lcnt < len; lcnt ++)
  226.             {
  227.                 if (lhs[cnt+lcnt] != rhs[lcnt]) matched = FALSE;
  228.                 if ((matched == FALSE) || ((lcnt + cnt) >= 32)) break;
  229.             }
  230.             if (matched) return TRUE;
  231.         }
  232.     }
  233.     return FALSE;
  234. }
  235.  
  236. void matches_event_handler(dbox d, void *handle)
  237. {
  238.     dbox_field f;
  239.     int disc;
  240.  
  241.     handle = handle;
  242.  
  243.     f = dbox_get(d);
  244.  
  245.     if (f == dbox_CLOSE)
  246.     {
  247.         dbox_eventhandler(d, 0, 0);
  248.         dbox_dispose(&d);
  249.         matches_open = FALSE;
  250.         return;
  251.     }
  252.     /* Otherwise it must be a disc icon */
  253.  
  254.     disc = (f - 3) / 3;
  255.     if (disc < match_win_info.no)
  256.         set_current_disc(match_win_info.disc_nos[disc]);
  257. }
  258.