home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / most-3.2 / part01 / search.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  5.2 KB  |  194 lines

  1. #include "most.h"
  2. #include "externs.h"
  3. #include "buffer.h"
  4. #include "line.h"
  5.  
  6. int CASE_SENSITIVE = 0;
  7. char SEARCH_STR[80];
  8. int SEARCH_DIR = 1;
  9.  
  10. #define upcase(ch) ((!CASE_SENSITIVE && (ch <= 'z') && (ch >= 'a')) ? ch &= 0xDF : ch)
  11.  
  12. /* This routine returns the 1 + position of first match of key in str.
  13.    key is modified to match the case of str. */
  14. /* We should try to optimize this routine */
  15. /* searches from beg up to but not including end */
  16. unsigned char *forw_search_region(unsigned char *beg,unsigned char *end, unsigned char *key)
  17. {
  18.     char ch, ch2,char1,work[80];
  19.     unsigned char *pos;
  20.     int key_len,j, str_len;
  21.  
  22.     if (CASE_SENSITIVE)
  23.       {
  24.           strcpy(work,key);
  25.           key_len = strlen(key);
  26.       }
  27.     else
  28.       {
  29.           /* upcase key */
  30.           key_len = 0;
  31.           while (ch = key[key_len],ch != '\0')
  32.             {
  33.                 ch = upcase(ch);
  34.                 work[key_len++] = ch;        /* null char is ok */
  35.             }
  36.       }
  37.     
  38.     str_len = (int) (end - beg);
  39.     if (str_len < key_len) return (EOB);
  40.     str_len = str_len - key_len; /* effective length */
  41.     end -= key_len;
  42.           
  43.     char1 = work[0];
  44.     
  45.     while(1)
  46.       {
  47.           while (ch = *beg, ch = upcase(ch), ch != char1)
  48.             {
  49.                 if (beg > end) return(EOB);
  50.                 beg++;
  51.             }
  52.           beg++;
  53.           /* so we have a position of possible match */
  54.  
  55.           j = 1;
  56.           pos = beg;  /* save this position so we start from here again */
  57.           while(ch = *beg++, ch = upcase(ch),
  58.                 ch2 = work[j++], (ch == ch2) && (j <= key_len));
  59.  
  60.           if (j > key_len)
  61.             {
  62.                 /* make key match 'key' in beg */
  63.                 beg = pos - 1;  /* skip back to beginning of match */
  64.                 for (j = 0; j < key_len; j++) key[j] = *beg++;
  65.                 return(pos - 1);
  66.             }
  67.           
  68.           else beg = pos;
  69.       }
  70. }
  71.  
  72.  
  73. unsigned char *back_search_region(unsigned char *beg,unsigned char *end, unsigned char *key)
  74. {
  75.     char ch, ch2,char1,work[80];
  76.     unsigned char *pos;
  77.     int key_len,j, str_len;
  78.  
  79.     if (CASE_SENSITIVE)
  80.       {
  81.           strcpy(work,key);
  82.           key_len = strlen(key);
  83.       }
  84.     else
  85.       {
  86.           /* upcase key */
  87.           key_len = 0;
  88.           while (ch = key[key_len],ch != '\0')
  89.             {
  90.                 ch = upcase(ch);
  91.                 work[key_len++] = ch;        /* null char is ok */
  92.             }
  93.       }
  94.     
  95.     str_len = (int) (end - beg);
  96.     if (str_len < key_len) return (EOB);
  97.     str_len = str_len - key_len; /* effective length */
  98.     beg += key_len;
  99.           
  100.     char1 = work[key_len - 1];
  101.     
  102.     while(1)
  103.       {
  104.           while (ch = *end, ch = upcase(ch), ch != char1)
  105.             {
  106.                 if (beg > end) return(EOB);
  107.                 end--;
  108.             }
  109.           end--;
  110.           /* so we have a position of possible match */
  111.  
  112.           j = key_len - 2;
  113.           pos = end;  /* save this position so we start from here again */
  114.           while(ch = *end--, ch = upcase(ch),
  115.                 ch2 = work[j], (ch == ch2) && (j >= 0)) j--;
  116.  
  117.           if (j < 0)
  118.             {
  119.                 /* make key match 'key' in beg */
  120.                 end = pos +  1;  /* skip back to beginning of match */
  121.                 for (j = key_len; j > 0; j--) key[j - 1] = *end--;
  122.                 return(end + 1);
  123.             }
  124.           
  125.           else end = pos;
  126.       }
  127. }
  128.  
  129.  
  130.  
  131. int search(unsigned char *from, int repeat, int *col)
  132. {
  133.     /* return the line match was found as well as line number,
  134.        search from i on; assume that line_array match the i so we need
  135.        no initial lookup */
  136.  
  137.     int test,j,save_line, the_col, row;
  138.     char ch, string[80];
  139.     unsigned char *pos, *save_pos, *found_at;
  140.  
  141.     if ((from < BEG) || (from > EOB)) return(-1);
  142.     save_pos = C_POS;
  143.     save_line = C_LINE;
  144.     found_at = EOB;
  145.     *col = 0;
  146.  
  147.     pos = from;
  148.     if (SEARCH_STR[0] != '\0')
  149.       {
  150.           test = repeat && (pos < EOB) && (pos >= BEG);
  151.           while(test)
  152.             {
  153.                 if (SEARCH_DIR == 1)
  154.                   pos = forw_search_region(pos,EOB,(unsigned char*) SEARCH_STR);
  155.                 else
  156.                   pos = back_search_region(BEG,pos,(unsigned char*) SEARCH_STR);
  157.                 
  158.                 
  159.                 if (pos < EOB)
  160.                   {
  161.                       repeat--;
  162.                       found_at = pos;
  163.                       if (SEARCH_DIR == 1)
  164.                         pos += strlen(SEARCH_STR);
  165.                       else pos--;
  166.                   }
  167.                 test = repeat && (pos < EOB) && (pos >= BEG);
  168.             }
  169.       }
  170.     
  171.     if (repeat) /* not found */
  172.       {
  173.           *col = 0;
  174.           if (SEARCH_STR[0] == '\0')
  175.             message("Search string not specified.",1);
  176.           else
  177.             {
  178.                 (void) sprintf(string,"%s NOT FOUND.",SEARCH_STR);
  179.                 message(string,1);
  180.             }
  181.           
  182.           row = -1;
  183.       }
  184.     else /* if ( !MOST_T_OPT && !MOST_B_OPT) */   /* expand tabs to get col correct */
  185.       {
  186.           find_row_column(found_at,&row,&the_col);
  187.           *col = apparant_distance(found_at);
  188.       }
  189.     C_POS = save_pos;
  190.     C_LINE = save_line;
  191.     if (row > 0) CURS_POS = found_at;
  192.     return( row );
  193. }
  194.