home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lynx2.8.1dev.10.tar.gz / lynx2.8.1dev.10.tar / lynx2-8 / src / LYSearch.c < prev    next >
C/C++ Source or Header  |  1998-03-25  |  11KB  |  386 lines

  1. #include <HTUtils.h>
  2. #include <tcp.h>
  3. #include <LYUtils.h>
  4. #include <LYStrings.h>
  5. #include <LYSearch.h>
  6. #include <LYGlobalDefs.h>
  7. #include <GridText.h>
  8. #include <LYSignal.h>
  9.  
  10. #include <LYLeaks.h>
  11.  
  12. #define FREE(x) if (x) {free(x); x = NULL;}
  13.  
  14. /*
  15.  *  Search for the target string inside of the links
  16.  *  that are currently displayed on the screen beginning
  17.  *  with the one after the currently selected one.
  18.  *  If found set cur to the new value and return TRUE.
  19.  *  If not found do not reset cur and return FALSE.
  20.  */
  21.  
  22. PRIVATE int check_for_target_in_links ARGS2(
  23.     int *,        cur,
  24.     char *,        new_target)
  25. {
  26.     int i = *cur + 1;
  27.     OptionType *option;
  28.     char *stars = NULL, *cp;
  29.  
  30.     if (nlinks == 0)
  31.     return(FALSE);
  32.  
  33.     for (; i < nlinks; i++) {
  34.         /*
  35.      *  Search the hightext string, and hightext2 if present,
  36.      *  taking the case_sensitive setting into account. - FM
  37.      */
  38.     if (((links[i].hightext != NULL && case_sensitive == TRUE) &&
  39.          LYno_attr_char_strstr(links[i].hightext, new_target)) ||
  40.         ((links[i].hightext != NULL && case_sensitive == FALSE) &&
  41.          LYno_attr_char_case_strstr(links[i].hightext, new_target))) {
  42.         break;
  43.     }
  44.     if (((links[i].hightext2 != NULL && case_sensitive == TRUE) &&
  45.          LYno_attr_char_strstr(links[i].hightext2, new_target)) ||
  46.         ((links[i].hightext2 != NULL && case_sensitive == FALSE) &&
  47.          LYno_attr_char_case_strstr(links[i].hightext2, new_target))) {
  48.         break;
  49.     }
  50.  
  51.     /*
  52.      *  Search the relevant form fields, taking the
  53.      *  case_sensitive setting into account. - FM
  54.      */
  55.     if ((links[i].form != NULL && links[i].form->value != NULL) &&
  56.         links[i].form->type != F_HIDDEN_TYPE) {
  57.         if (links[i].form->type == F_PASSWORD_TYPE) {
  58.             /*
  59.          *  Check the actual, hidden password, and then
  60.          *  the displayed string. - FM
  61.          */
  62.         if (((case_sensitive == TRUE) &&
  63.              LYno_attr_char_strstr(links[i].form->value,
  64.                        new_target)) ||
  65.             ((case_sensitive == FALSE) &&
  66.              LYno_attr_char_case_strstr(links[i].form->value,
  67.                         new_target))) {
  68.             break;
  69.         }
  70.         StrAllocCopy(stars, links[i].form->value);
  71.         for (cp = stars; *cp != '\0'; cp++)
  72.             *cp = '*';
  73.         if (((case_sensitive == TRUE) &&
  74.              LYno_attr_char_strstr(stars, new_target)) ||
  75.             ((case_sensitive == FALSE) &&
  76.              LYno_attr_char_case_strstr(stars, new_target))) {
  77.             FREE(stars);
  78.             break;
  79.         }
  80.         FREE(stars);
  81.         } else if (links[i].form->type == F_OPTION_LIST_TYPE) {
  82.         /*
  83.          *  Search the option strings that are displayed
  84.          *  when the popup is invoked. - FM
  85.          */
  86.         option = links[i].form->select_list;
  87.         while (option != NULL) {
  88.             if (((option->name != NULL &&
  89.               case_sensitive == TRUE) &&
  90.              LYno_attr_char_strstr(option->name, new_target)) ||
  91.             ((option->name != NULL &&
  92.               case_sensitive == FALSE) &&
  93.              LYno_attr_char_case_strstr(option->name,
  94.                             new_target))) {
  95.             break;
  96.             }
  97.             option = option->next;
  98.         }
  99.         if (option != NULL) {
  100.             break;
  101.         }
  102.         } else if (links[i].form->type == F_RADIO_TYPE) {
  103.         /*
  104.          *  Search for checked or unchecked parens. - FM
  105.          */
  106.             if (links[i].form->num_value) {
  107.             cp = checked_radio;
  108.         } else {
  109.             cp = unchecked_radio;
  110.         }
  111.         if (((case_sensitive == TRUE) &&
  112.              LYno_attr_char_strstr(cp, new_target)) ||
  113.             ((case_sensitive == FALSE) &&
  114.              LYno_attr_char_case_strstr(cp, new_target))) {
  115.             break;
  116.         }
  117.         } else if (links[i].form->type == F_CHECKBOX_TYPE) {
  118.         /*
  119.          *  Search for checked or unchecked square brackets. - FM
  120.          */
  121.             if (links[i].form->num_value) {
  122.             cp = checked_box;
  123.         } else {
  124.             cp = unchecked_box;
  125.         }
  126.         if (((case_sensitive == TRUE) &&
  127.              LYno_attr_char_strstr(cp, new_target)) ||
  128.             ((case_sensitive == FALSE) &&
  129.              LYno_attr_char_case_strstr(cp, new_target))) {
  130.             break;
  131.         }
  132.         } else {
  133.             /*
  134.          *  Check the values intended for display.
  135.          *  May have been found already via the
  136.          *  hightext search, but make sure here
  137.          *  that the entire value is searched. - FM
  138.          */
  139.         if (((case_sensitive == TRUE) &&
  140.              LYno_attr_char_strstr(links[i].form->value,
  141.                        new_target)) ||
  142.             ((case_sensitive == FALSE) &&
  143.              LYno_attr_char_case_strstr(links[i].form->value,
  144.                         new_target))) {
  145.             break;
  146.         }
  147.         }
  148.     }
  149.     }
  150.  
  151.     if (i == nlinks)
  152.     return(FALSE);
  153.  
  154.     *cur = i;
  155.     return(TRUE);
  156. }
  157.  
  158. /*
  159.  *  Textsearch checks the prev_target variable to see if it is empty.
  160.  *  If it is then it requests a new search string.  It then searches 
  161.  *  the current file for the next instance of the search string and
  162.  *  finds the line number that the string is on
  163.  * 
  164.  *  This is the primary USER search engine and is case sensitive
  165.  *  or case insensitive depending on the 'case_sensitive' global
  166.  *  variable
  167.  *
  168.  */
  169.         
  170. PUBLIC BOOL textsearch ARGS3(
  171.     document *,    cur_doc,
  172.     char *,        prev_target,
  173.     BOOL,        next)
  174. {
  175.     int offset;
  176.     int oldcur = cur_doc->link;
  177.     static char prev_target_buffer[512]; /* Search string buffer */
  178.     static BOOL first = TRUE;
  179.     char *cp;
  180.     int ch = 0, recall;
  181.     int QueryTotal;
  182.     int QueryNum;
  183.     BOOLEAN FirstRecall = TRUE;
  184.  
  185.     /*
  186.      *  Initialize the search string buffer. - FM
  187.      */
  188.     if (first) {
  189.     *prev_target_buffer = '\0';
  190.     first = FALSE;
  191.     }
  192.  
  193.     QueryTotal = (search_queries ? HTList_count(search_queries) : 0);
  194.     recall = ((QueryTotal >= 1) ? RECALL : NORECALL);
  195.     QueryNum = QueryTotal;
  196.  
  197.     if (next)
  198.         /*
  199.      *  LYK_NEXT was pressed, so copy the
  200.      *  buffer into prev_target. - FM
  201.      */
  202.     strcpy(prev_target, prev_target_buffer);
  203.  
  204.     if (strlen(prev_target) == 0 ) {
  205.         /*
  206.      *  This is a new WHEREIS search ('/'), or
  207.      *  LYK_NEXT was pressed but there was no
  208.      *  previous search, so we need to get a
  209.      *  search string from the user. - FM
  210.      */
  211.     _statusline(ENTER_WHEREIS_QUERY);
  212.  
  213.     if ((ch = LYgetstr(prev_target, VISIBLE,
  214.                    sizeof(prev_target_buffer), recall)) < 0) {
  215.         /*
  216.          *  User cancelled the search via ^G.
  217.          *  Restore prev_target and return. - FM
  218.          */
  219.         strcpy(prev_target, prev_target_buffer);
  220.         _statusline(CANCELLED);
  221.         sleep(InfoSecs);
  222.         return(FALSE);
  223.     }
  224.     }
  225.  
  226. check_recall:
  227.     if (strlen(prev_target) == 0 &&
  228.         !(recall && (ch == UPARROW || ch == DNARROW))) {
  229.         /*
  230.      *  No entry.  Simply return, retaining the current buffer.
  231.      *  Because prev_target is now reset, highlighting of the
  232.      *  previous search string will no longer occur, but it can
  233.      *  be used again via LYK_NEXT.   - FM
  234.      */
  235.         _statusline(CANCELLED);
  236.         sleep(InfoSecs);
  237.     return(FALSE);
  238.     }
  239.  
  240.     if (recall && ch == UPARROW) {
  241.     if (FirstRecall) {
  242.         /*
  243.          *  Use the current string or last query in the list. - FM
  244.          */
  245.         FirstRecall = FALSE;
  246.         if (*prev_target_buffer) {
  247.             for (QueryNum = (QueryTotal - 1); QueryNum > 0; QueryNum--) {
  248.             if ((cp = (char *)HTList_objectAt(search_queries,
  249.                                   QueryNum)) != NULL &&
  250.                 !strcmp(prev_target_buffer, cp)) {
  251.                 break;
  252.             }
  253.          }
  254.          } else {
  255.         QueryNum = 0;
  256.          }
  257.     } else {
  258.         /*
  259.          *  Go back to the previous query in the list. - FM
  260.          */
  261.         QueryNum++;
  262.     }
  263.     if (QueryNum >= QueryTotal)
  264.         /*
  265.          *  Roll around to the last query in the list. - FM
  266.          */
  267.         QueryNum = 0;
  268.     if ((cp = (char *)HTList_objectAt(search_queries,
  269.                           QueryNum)) != NULL) {
  270.         strcpy(prev_target, cp);
  271.         if (*prev_target_buffer &&
  272.             !strcmp(prev_target_buffer, prev_target)) {
  273.         _statusline(EDIT_CURRENT_QUERY);
  274.         } else if ((*prev_target_buffer && QueryTotal == 2) ||
  275.                (!(*prev_target_buffer) && QueryTotal == 1)) {
  276.         _statusline(EDIT_THE_PREV_QUERY);
  277.         } else {
  278.         _statusline(EDIT_A_PREV_QUERY);
  279.         }
  280.         if ((ch = LYgetstr(prev_target, VISIBLE,
  281.                        sizeof(prev_target_buffer), recall)) < 0) {
  282.             /*
  283.          *  User cancelled the search via ^G.
  284.          *  Restore prev_target and return. - FM
  285.          */
  286.         strcpy(prev_target, prev_target_buffer);
  287.         _statusline(CANCELLED);
  288.         sleep(InfoSecs);
  289.         return(FALSE);
  290.         }
  291.         goto check_recall;
  292.     }
  293.     } else if (recall && ch == DNARROW) {
  294.     if (FirstRecall) {
  295.         /*
  296.          *  Use the current string or first query in the list. - FM
  297.          */
  298.         FirstRecall = FALSE;
  299.         if (*prev_target_buffer) {
  300.             for (QueryNum = 0; QueryNum < (QueryTotal - 1); QueryNum++) {
  301.             if ((cp = (char *)HTList_objectAt(search_queries,
  302.                                   QueryNum)) != NULL &&
  303.                 !strcmp(prev_target_buffer, cp)) {
  304.                 break;
  305.             }
  306.         }
  307.         } else {
  308.         QueryNum = QueryTotal - 1;
  309.         }
  310.     } else {
  311.         /*
  312.          *  Advance to the next query in the list. - FM
  313.          */
  314.         QueryNum--;
  315.     }
  316.     if (QueryNum < 0)
  317.         /*
  318.          *  Roll around to the first query in the list. - FM
  319.          */
  320.         QueryNum = QueryTotal - 1;
  321.     if ((cp = (char *)HTList_objectAt(search_queries,
  322.                           QueryNum)) != NULL) {
  323.         strcpy(prev_target, cp);
  324.         if (*prev_target_buffer &&
  325.             !strcmp(prev_target_buffer, prev_target)) {
  326.         _statusline(EDIT_CURRENT_QUERY);
  327.         } else if ((*prev_target_buffer && QueryTotal == 2) ||
  328.                (!(*prev_target_buffer) && QueryTotal == 1)) {
  329.         _statusline(EDIT_THE_PREV_QUERY);
  330.         } else {
  331.         _statusline(EDIT_A_PREV_QUERY);
  332.         }
  333.         if ((ch = LYgetstr(prev_target, VISIBLE,
  334.                    sizeof(prev_target_buffer), recall)) < 0) {
  335.             /*
  336.          *  User cancelled the search via ^G.
  337.          *  Restore prev_target and return. - FM
  338.          */
  339.         strcpy(prev_target, prev_target_buffer);
  340.         _statusline(CANCELLED);
  341.         sleep(InfoSecs);
  342.         return(FALSE);
  343.         }
  344.         goto check_recall;
  345.     }
  346.     }
  347.     /*
  348.      *  Replace the search string buffer with the new target. - FM
  349.      */
  350.     strcpy(prev_target_buffer, prev_target);
  351.     HTAddSearchQuery(prev_target_buffer);
  352.  
  353.     /*
  354.      *  Search the links on the currently displayed page for
  355.      *  the string, starting after the current link. - FM
  356.      */
  357.     if (check_for_target_in_links(&cur_doc->link, prev_target)) {
  358.     /*
  359.      *  Found in link, changed cur, we're done.
  360.      */
  361.     highlight(OFF, oldcur, prev_target);
  362.     return(TRUE); 
  363.     }
  364.     
  365.     /*
  366.      *  We'll search the text starting from the
  367.      *  link we are on, or the next page.
  368.      */
  369.     if (nlinks == 0)
  370.     offset = (display_lines - 1);
  371.     else
  372.     offset = links[cur_doc->link].ly - 1;
  373.  
  374.     /*
  375.      *  Resume search, this time for all text.
  376.      *  Set www_search_result if string found,
  377.      *  and position the hit near top of screen.
  378.      */
  379.     www_user_search((cur_doc->line + offset), cur_doc, prev_target);
  380.     if (cur_doc->link != oldcur) {
  381.     highlight(OFF, oldcur, prev_target);
  382.     return(TRUE);
  383.     }
  384.     return(www_search_result > 0);
  385. }
  386.