home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / rolodex / part02 / search.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-01-30  |  9.0 KB  |  360 lines

  1. /* search.c */
  2. #include <stdio.h>
  3. #include <ctype.h>
  4.  
  5. #ifdef TMC
  6. #include <ctools.h>
  7. #else
  8. #include "ctools.h"
  9. #endif
  10. #include "args.h"
  11. #include "menu.h"
  12. #include "mem.h"
  13.  
  14. #include "rolofilz.h"
  15. #include "rolodefs.h"
  16. #include "datadef.h"
  17. #include "choices.h"
  18.  
  19.  
  20. char *select_search_string ()
  21.  
  22. /* returns 0 if user wants to quit, otherwise returns a user-provided string */
  23.  
  24. {
  25.   int rval;        
  26.   char *response;
  27.   rval = rolo_menu_data_help_or_abort (        
  28.               "Enter string to search for: ",
  29.               SEARCHSTRINGHELP,
  30.               "string to search for",
  31.               &response
  32.           );
  33.   switch (rval) {          
  34.     case MENU_ABORT :
  35.       return(0);
  36.       /* break; */
  37.     case MENU_DATA :
  38.       return(copystr(response));
  39.       /* break; */
  40.   }
  41.  
  42.   return(0);
  43. }  
  44.   
  45.  
  46. select_field_to_search_by (ptr_index,ptr_name) int *ptr_index; char **ptr_name;
  47.  
  48. /* returns -1 if the user wishes to abort, otherwise returns 0. */
  49. /* if the user wishes to search by a user-defined field, *ptr_index is OTHER */
  50. /* and *ptr_name is the user-provided name of the field. */
  51.  
  52. {
  53.   char *response;
  54.   int nchoices = N_BASIC_FIELDS;
  55.   int field_index,rval;
  56.   
  57.   redo :
  58.   
  59.   /* list out each basic field that the user can search by.   The user is */
  60.   /* also given an option to search by a user-provided field.   At the */
  61.   /* moment you cannot search by 'Date Updated' */
  62.   
  63.   display_field_names();  
  64.   
  65.   /* reask : */
  66.   
  67.   rval = rolo_menu_number_help_or_abort (
  68.        "Number of item to search by? ",
  69.        1,nchoices,&field_index
  70.     );
  71.     
  72.   switch (rval) {
  73.         
  74.     case MENU_ABORT :
  75.       return(-1);
  76.       /* break; */
  77.       
  78.     case MENU_HELP :
  79.       cathelpfile(FIELDSEARCHHELP,"entering search field",1);
  80.       any_char_to_continue();
  81.       goto redo;
  82.       /* break; */
  83.       
  84.     case MENU_DATA :
  85.     
  86.       if (field_index != nchoices) {
  87.          *ptr_index = field_index - 1;
  88.          *ptr_name = copystr(Field_Names[*ptr_index]);
  89.          return(0);
  90.       }
  91.       
  92.       /* the user wants to search by a user-specified field */
  93.       
  94.       else {
  95.         
  96.          /* reask2 : */
  97.         
  98.          rval = rolo_menu_data_help_or_abort (
  99.                     "Name of user-defined field? ",
  100.                     USERFIELDHELP,
  101.                     "name of user field to search by",
  102.                     &response
  103.                  );
  104.          switch (rval) {
  105.            case MENU_ABORT :
  106.              return(-1);
  107.              /* break; */
  108.            case MENU_DATA :
  109.              *ptr_index = OTHER;
  110.              *ptr_name = copystr(response);           
  111.              return(0);         
  112.              /* break; */
  113.          }
  114.       }
  115.       break;
  116.   }
  117.   return(0);
  118. }  
  119.       
  120.  
  121. match_by_name_or_company (search_string,sslen) char *search_string; int sslen;
  122.  
  123. {
  124.   char *name,*company;
  125.   Ptr_Rolo_Entry lentry;        
  126.   Ptr_Rolo_List rlist;
  127.   int count = 0;
  128.   
  129.   rlist = Begin_Rlist;
  130.   while (rlist != 0) {  
  131.     lentry = get_entry(rlist);
  132.     name = get_basic_rolo_field((int) R_NAME,lentry);
  133.     company = get_basic_rolo_field((int) R_COMPANY,lentry);
  134.     if (strncsearch(name,strlen(name),search_string,sslen) ||
  135.         strncsearch(company,strlen(company),search_string,sslen)) {
  136.        set_matched(rlist);
  137.        count++;
  138.     }
  139.   }
  140.   return(count);
  141.   
  142. }
  143.  
  144.  
  145. match_link (rlink,field_index,field_name,fnlen,search_string,sslen)
  146.  
  147.   /* if a match is present, sets the 'matched' field in the link, and */
  148.   /* returns 1, otherwise returns 0. */
  149.  
  150.   Ptr_Rolo_List rlink;
  151.   int field_index;
  152.   char *field_name;
  153.   int fnlen;
  154.   char *search_string;
  155.   int sslen;
  156.   
  157. {
  158.   Ptr_Rolo_Entry lentry;        
  159.   char *field;
  160.   char name[100];
  161.   int j;
  162.         
  163.   lentry = get_entry(rlink);
  164.   
  165.   if (field_index == OTHER) {
  166.      for (j = 0; j < get_n_others(lentry); j++) {
  167.          field = get_other_field(j,lentry);
  168.          while (*field != ':') *field++;
  169.          *field = '\0';
  170.          remove_excess_blanks(name,get_other_field(j,lentry));
  171.          *field++ = ':';
  172.          if (0 != nocase_compare(name,strlen(name),field_name,fnlen)) {
  173.             continue;
  174.          }
  175.          if (strncsearch(field,strlen(field),search_string,sslen)) {
  176.             set_matched(rlink);
  177.             return(1);
  178.          }
  179.      }
  180.      return(0);
  181.   }
  182.   else {
  183.      field = get_basic_rolo_field(field_index,lentry);
  184.      if (strncsearch(field,strlen(field),search_string,sslen)) {
  185.         set_matched(rlink);
  186.         return(1);
  187.      }
  188.      return(0);
  189.   }
  190.  
  191. }
  192.  
  193.  
  194. find_all_matches (field_index,field_name,search_string,ptr_first_match) 
  195.  
  196.   /* mark every entry in the rolodex which matches against the search_string */
  197.   /* If the search_string is a substring of the data in the given field then */
  198.   /* that is a match.  Return the number of matches.  If there are any */
  199.   /* matches *ptr_first_match will contain the first matching link. */
  200.  
  201.   int field_index;
  202.   char *field_name, *search_string;
  203.   Ptr_Rolo_List *ptr_first_match;
  204.  
  205. {  
  206.   char buffer[100];    
  207.   int fnlen,sslen;
  208.   int count = 0;
  209.   Ptr_Rolo_List rlist = Begin_Rlist;
  210.   
  211.   remove_excess_blanks(buffer,field_name);
  212.   fnlen = strlen(buffer);
  213.   sslen = strlen(search_string);
  214.   
  215.   while (rlist != 0) {  
  216.     unset_matched(rlist);
  217.     if (match_link(rlist,field_index,buffer,fnlen,search_string,sslen)) {
  218.        if (count++ == 0) *ptr_first_match = rlist;
  219.     }
  220.     rlist = get_next_link(rlist);
  221.   }    
  222.   
  223.   return(count);
  224.   
  225. }
  226.  
  227.  
  228. rolo_search_mode (field_index,field_name,search_string)
  229.  
  230.   int field_index;
  231.   char *field_name;
  232.   char *search_string;
  233.  
  234. {
  235.   int rval,n,j,menuval,ival;
  236.   char *response;
  237.   Ptr_Rolo_List first_match,rmatch,rlist;
  238.  
  239.   /* mark every entry in the rolodex that satisfies the search criteria */
  240.   /* and return the number of items so marked. */
  241.   
  242.   in_search_mode = 1;
  243.   n = find_all_matches(field_index,field_name,search_string,&first_match);
  244.  
  245.   if (n == 0) {
  246.      printf (
  247.          "No match found for search string '%s' for field '%s'\n",
  248.          search_string,
  249.          field_name
  250.       );
  251.       sleep(2);
  252.       goto rtn;
  253.   }
  254.  
  255.   /* if the match is unique, just display the entry. */
  256.   
  257.   else if (n == 1) {
  258.      display_entry(get_entry(first_match));
  259.      switch (entry_action(first_match)) {
  260.        case E_CONTINUE :
  261.          printf("No further matches...\n");
  262.          sleep(2);
  263.          break;
  264.        default :
  265.          break;
  266.      }
  267.      goto rtn;
  268.   }
  269.  
  270.   /* if there are too many matches to itemize them on a single small */
  271.   /* screen, tell the user that there are lots of matches and suggest */
  272.   /* he specify a better search string, but give him the option of */
  273.   /* iterating through every match. */
  274.   
  275.   else if (n > MAXMATCHES) {
  276.      clear_the_screen();
  277.      printf("There are %d entries that match '%s' !\n",n,search_string);
  278.      printf("Type 'v' to view them one by one,\n");
  279.      printf("or '\\' to abort and enter a more specific search string: ");
  280.      rval = rolo_menu_data_help_or_abort (
  281.                  "",MANYMATCHHELP,"many matching entries",&response
  282.               );
  283.      if (rval == MENU_ABORT) goto rtn;              
  284.      display_list_of_entries(Begin_Rlist);
  285.      goto rtn;
  286.   }
  287.  
  288.   /* there are a small number of matching entries.  List the name of each */
  289.   /* matching entry and let the user select which one he wants to view, */
  290.   /* or whether he wants to iterate through each matching entry. */
  291.   
  292.   else {
  293.      relist :
  294.      summarize_entry_list(Begin_Rlist,search_string);
  295.      cathelpfile(PICKENTRYMENU,(char *)NULL,0);  
  296.      rval = menu_match (
  297.           &menuval,&response,
  298.           ": ",
  299.           0,1,0,1,4,
  300.           "\\",S_ABORT,
  301.           "?",S_HELP,
  302.           "Help",S_HELP,
  303.           "",S_SCAN_ONE_BY_ONE
  304.        );
  305.      switch (rval) {    
  306.        case MENU_MATCH :
  307.          switch (menuval) {
  308.            case S_HELP :
  309.              cathelpfile(PICKENTRYHELP,"selecting entry to view",1);
  310.              any_char_to_continue();
  311.              goto relist;
  312.              /* break; */
  313.            case S_ABORT :
  314.              goto rtn;
  315.              /* break; */
  316.            case S_SCAN_ONE_BY_ONE :
  317.              display_list_of_entries(Begin_Rlist);
  318.              goto rtn;
  319.              /* break; */
  320.          }
  321.          break;
  322.          
  323.        /* make sure the user entered a valid integer, ival */
  324.        /* if so, find the ivalth entry marked as matched in the rolodex */
  325.        /* and display it. */
  326.          
  327.        case MENU_NO_MATCH : 
  328.          ival = str_to_pos_int(response,1,n);
  329.          if (ival < 0) {
  330.             printf("Not a valid number... Please try again\n");
  331.             sleep(2);
  332.             goto relist;
  333.          }
  334.          rlist = Begin_Rlist;
  335.          for (j = 0; j < ival; j++) {
  336.              while (rlist != 0) {
  337.                if (get_matched(rmatch = rlist)) break;
  338.                rlist = get_next_link(rlist);
  339.              }
  340.              if (rlist != 0) rlist = get_next_link(rlist);                
  341.          }
  342.          display_entry(get_entry(rmatch));
  343.          switch (entry_action(rmatch)) {
  344.            case E_CONTINUE :
  345.            case E_PREV :
  346.              goto relist;
  347.              /* break; */
  348.            default :
  349.              goto rtn;
  350.              /* break; */
  351.          }
  352.          /* break; */
  353.      }
  354.   }
  355.  
  356.   rtn :
  357.   in_search_mode = 0;
  358.   
  359. }
  360.