home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume4 / rolodex / part2 / search.c < prev    next >
C/C++ Source or Header  |  1986-11-30  |  9KB  |  359 lines

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