home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
most423.zip
/
search.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-28
|
6KB
|
248 lines
#include <stdio.h>
#include "most.h"
#include "externs.h"
#include "buffer.h"
#include "line.h"
#include "file.h"
#include "display.h"
#include "window.h"
int CASE_SENSITIVE = 0;
char SEARCH_STR[80];
int SEARCH_DIR = 1;
#define upcase(ch) ((!CASE_SENSITIVE && (ch <= 'z') && (ch >= 'a')) ? ch &= 0xDF : ch)
/* This routine returns the 1 + position of first match of key in str.
key is modified to match the case of str. */
/* We should try to optimize this routine */
/* searches from beg up to but not including end */
unsigned char *forw_search_region(unsigned char *beg,unsigned char *end, unsigned char *key)
{
char ch, ch2,char1,work[80];
unsigned char *pos;
int key_len,j, str_len;
if (CASE_SENSITIVE)
{
strcpy(work,key);
key_len = strlen(key);
}
else
{
/* upcase key */
key_len = 0;
while (ch = key[key_len],ch != '\0')
{
ch = upcase(ch);
work[key_len++] = ch; /* null char is ok */
}
}
str_len = (int) (end - beg);
if (str_len < key_len) return (EOB);
str_len = str_len - key_len; /* effective length */
end -= key_len;
char1 = work[0];
while(1)
{
while (ch = *beg, ch = upcase(ch), ch != char1)
{
if (beg > end) return(EOB);
beg++;
}
beg++;
/* so we have a position of possible match */
j = 1;
pos = beg; /* save this position so we start from here again */
while(1)
{
ch = *beg++;
if ((ch == 8) && (beg + 2 < end) && (MOST_V_OPT == 0) &&
((work[j - 1] == upcase(*beg)) || (*beg == '_')))
{
ch = *(beg + 1);
beg += 2;
}
else if ((ch == '_') && (beg + 2 < end))
{
ch = *beg++;
if (ch == 8) ch = *beg++;
else
{
ch = '_';
beg--;
}
}
ch = upcase(ch),
ch2 = work[j++];
if ((ch != ch2) || (j > key_len)) break;
}
if (j > key_len) return pos - 1;
/* make key match 'key' in beg */
/* beg = pos - 1; skip back to beginning of match
for (j = 0; j < key_len; j++) key[j] = *beg++;
return(pos - 1); */
else beg = pos;
}
}
unsigned char *back_search_region(unsigned char *beg,unsigned char *end, unsigned char *key)
{
char ch, ch2,char1,work[80];
unsigned char *pos;
int key_len,j, str_len;
if (CASE_SENSITIVE)
{
strcpy(work,key);
key_len = strlen(key);
}
else
{
/* upcase key */
key_len = 0;
while (ch = key[key_len],ch != '\0')
{
ch = upcase(ch);
work[key_len++] = ch; /* null char is ok */
}
}
str_len = (int) (end - beg);
if (str_len < key_len) return (EOB);
str_len = str_len - key_len; /* effective length */
beg += key_len;
char1 = work[key_len - 1];
while(1)
{
while (ch = *end, ch = upcase(ch), ch != char1)
{
if (beg > end) return(EOB);
end--;
}
end--;
/* so we have a position of possible match */
j = key_len - 2;
pos = end; /* save this position so we start from here again */
while (1)
{
ch = *end--;
if ((ch == 8) && (beg <= end - 2) && (MOST_V_OPT == 0) &&
((work[j + 1] == upcase(*end)) || (*end == '_')))
{
ch = *(end - 1);
end -= 2;
}
else if ((ch == '_') && (beg <= end - 2) && (MOST_V_OPT == 0))
{
ch = *end--;
if (ch == 8) ch = *end--;
else
{
ch = '_';
end++;
}
}
ch = upcase(ch),
ch2 = work[j];
if ((ch != ch2) || (j < 0)) break;
j--;
}
if (j < 0) return end + 2;
else end = pos;
}
}
int search(unsigned char *from, int repeat, int *col)
{
/* return the line match was found as well as line number,
search from i on; assume that line_array match the i so we need
no initial lookup */
int test, save_line, the_col, row, s_len;
char string[80];
unsigned char *pos;
int ofs, found_ofs, pos_ofs;
if ((from < BEG) || (from > EOB)) return(-1);
ofs = C_POS - BEG;
save_line = C_LINE;
found_ofs = EOB - BEG;
*col = 0;
s_len = strlen(SEARCH_STR);
pos = from;
if (SEARCH_STR[0] != '\0')
{
test = repeat && (pos < EOB) && (pos >= BEG);
while(test)
{
if (SEARCH_DIR == 1)
{
more_time:
pos = forw_search_region(pos,EOB,(unsigned char*) SEARCH_STR);
if ((pos >= EOB) && (BUF->fd != -1))
{
pos_ofs = EOB - BEG;
read_file_dsc(10);
/* This might need an adjustment */
pos = BEG + (pos_ofs - s_len);
if (pos < BEG) pos = BEG;
goto more_time;
}
}
else
pos = back_search_region(BEG,pos,(unsigned char*) SEARCH_STR);
if (pos < EOB)
{
repeat--;
found_ofs = pos - BEG;
if (SEARCH_DIR == 1)
pos += s_len;
else pos--;
}
test = repeat && (pos < EOB) && (pos >= BEG);
}
}
if (repeat) /* not found */
{
*col = 0;
if (SEARCH_STR[0] == '\0')
message("Search string not specified.",1);
else
{
(void) sprintf(string,"%s NOT FOUND.",SEARCH_STR);
message(string,1);
}
row = -1;
}
else /* if ( !MOST_T_OPT && !MOST_B_OPT) */ /* expand tabs to get col correct */
{
find_row_column(BEG + found_ofs,&row,&the_col);
*col = apparant_distance(BEG + found_ofs);
}
C_POS = BEG + ofs;
C_LINE = save_line;
if (row > 0) CURS_POS = BEG + found_ofs;
return( row );
}