|
Packit |
b099d7 |
/* $XConsortium: TextFind.c /main/6 1995/09/19 23:17:17 cde-sun $ */
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Motif
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are free software; you can
|
|
Packit |
b099d7 |
* redistribute them and/or modify them under the terms of the GNU
|
|
Packit |
b099d7 |
* Lesser General Public License as published by the Free Software
|
|
Packit |
b099d7 |
* Foundation; either version 2 of the License, or (at your option)
|
|
Packit |
b099d7 |
* any later version.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are distributed in the hope that
|
|
Packit |
b099d7 |
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
Packit |
b099d7 |
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
Packit |
b099d7 |
* PURPOSE. See the GNU Lesser General Public License for more
|
|
Packit |
b099d7 |
* details.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b099d7 |
* License along with these librararies and programs; if not, write
|
|
Packit |
b099d7 |
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
Packit |
b099d7 |
* Floor, Boston, MA 02110-1301 USA
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* HISTORY
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
b099d7 |
#include <config.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
|
|
Packit |
b099d7 |
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#include <ctype.h>
|
|
Packit |
b099d7 |
#include <X11/Xmd.h>
|
|
Packit |
b099d7 |
#include <Xm/XmosP.h> /* for <stdlib.h>, and wcstombs() */
|
|
Packit |
b099d7 |
#include "XmI.h"
|
|
Packit |
b099d7 |
#include "TextI.h"
|
|
Packit |
b099d7 |
#include "TextStrSoI.h"
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmTextFindStringBackwards(Widget w,
|
|
Packit |
b099d7 |
XmTextPosition start,
|
|
Packit |
b099d7 |
char* search_string,
|
|
Packit |
b099d7 |
XmTextPosition *position)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
register int i;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
XmSourceData data = ((XmTextWidget)w)->text.source->data;
|
|
Packit |
b099d7 |
Boolean return_val = False, match = False;
|
|
Packit |
b099d7 |
int search_length = 0;
|
|
Packit |
b099d7 |
char *ptr, *end_ptr, *tmp_ptr, *end_of_data;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
search_length = _XmTextCountCharacters(search_string,strlen(search_string));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!search_length || !data->length || search_length > data->length)
|
|
Packit |
b099d7 |
return FALSE;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Search can be broken into three phases for fastest search:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* - search from data_end - strlen(search_string) back until
|
|
Packit |
b099d7 |
* base search is at gap_end. This is a fast simple compare
|
|
Packit |
b099d7 |
* that doesn't worry about incursions into the gap.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* - search from gap_start-strlen(search_string) until the base
|
|
Packit |
b099d7 |
* of the search is moved across the gap.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* - search from start up to gap_start-strlen(search_string).
|
|
Packit |
b099d7 |
* This is a fast simple compare that doesn't worry about
|
|
Packit |
b099d7 |
* incursions into the gap.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
switch ((int)tw->text.char_size) {
|
|
Packit |
b099d7 |
case 1: {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Make sure you don't search past end of data. End of data is... */
|
|
Packit |
b099d7 |
end_of_data = data->ptr + data->length +
|
|
Packit |
b099d7 |
(data->gap_end - data->gap_start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* actually, no need to search beyond end - search_length position */
|
|
Packit |
b099d7 |
if (end_of_data - search_length >= data->gap_end)
|
|
Packit |
b099d7 |
end_ptr = end_of_data - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
end_ptr = data->gap_start -
|
|
Packit |
b099d7 |
(search_length - (end_of_data - data->gap_end));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase one: search from start back to gap_end */
|
|
Packit |
b099d7 |
/* Set the base for the search */
|
|
Packit |
b099d7 |
if (data->ptr + start > data->gap_start) /* backside of gap */
|
|
Packit |
b099d7 |
ptr = data->ptr + (data->gap_end - data->gap_start) + start;
|
|
Packit |
b099d7 |
else /* we're starting before the gap */
|
|
Packit |
b099d7 |
ptr = data->ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ptr > end_ptr)
|
|
Packit |
b099d7 |
ptr = end_ptr; /* no need search where a match can't be found */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && ptr >= data->gap_end) {
|
|
Packit |
b099d7 |
if (*ptr == *search_string) { /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (ptr[i] != search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = ptr - data->ptr -
|
|
Packit |
b099d7 |
(data->gap_end - data->gap_start);
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
ptr--; /* decrement base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase two: these searches span the gap and are SLOW!
|
|
Packit |
b099d7 |
* Two possibilities: either I've just backed the base back to gap
|
|
Packit |
b099d7 |
* end (and must do searches that span the gap) or start puts
|
|
Packit |
b099d7 |
* the base prior to the gap end. Also, possibility that there
|
|
Packit |
b099d7 |
* isn't enough room after the gap for a complete match
|
|
Packit |
b099d7 |
* (so no need to search it). This phase must be performed as
|
|
Packit |
b099d7 |
* long as data->ptr + start places the base to the right of
|
|
Packit |
b099d7 |
* gap_start - search_length.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Do this as nested for loops; the outer loop decrements the base for
|
|
Packit |
b099d7 |
* the search, the inner loop compares character elements from 0 to
|
|
Packit |
b099d7 |
* length(search_string).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If no match yet and if need to search prior to gap_start... */
|
|
Packit |
b099d7 |
/* Set the base for the search. */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!return_val &&
|
|
Packit |
b099d7 |
(data->ptr + start) > (data->gap_start - search_length)) {
|
|
Packit |
b099d7 |
if (data->ptr < data->gap_start)
|
|
Packit |
b099d7 |
ptr = data->gap_start - 1;
|
|
Packit |
b099d7 |
/* else, we're done... gap_start is at data->ptr and still no match*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (match = True;
|
|
Packit |
b099d7 |
ptr >= data->ptr && (data->gap_start - ptr) +
|
|
Packit |
b099d7 |
(end_of_data - data->gap_end) >= search_length;
|
|
Packit |
b099d7 |
ptr--, match = True) {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*ptr == *search_string) { /* we have a potential winner */
|
|
Packit |
b099d7 |
for (i = 1; i < search_length && match == True; i ++) {
|
|
Packit |
b099d7 |
if (ptr + i >= data->gap_start) {
|
|
Packit |
b099d7 |
tmp_ptr = ptr +(data->gap_end - data->gap_start) + i;
|
|
Packit |
b099d7 |
if (*tmp_ptr != search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (ptr[i] != search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} /* end inner for loop - searching from current base */
|
|
Packit |
b099d7 |
if (match && (i == search_length)) {/* a winner! */
|
|
Packit |
b099d7 |
*position = ptr - data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (return_val) break;
|
|
Packit |
b099d7 |
} /* end outer for - restart search from a new base */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* phase three: search backwards from base == gap_start - search_length
|
|
Packit |
b099d7 |
* through and including base == data->ptr.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!return_val) {
|
|
Packit |
b099d7 |
if (data->ptr + start > data->gap_start - search_length)
|
|
Packit |
b099d7 |
ptr = data->gap_start - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
ptr = data->ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && ptr >= data->ptr) {
|
|
Packit |
b099d7 |
if (*ptr == *search_string) { /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (ptr[i] != search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = ptr - data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
ptr--; /* decrement base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 1 */
|
|
Packit |
b099d7 |
case 2: {
|
|
Packit |
b099d7 |
BITS16 *bits16_ptr, *bits16_search_string, *bits16_gap_start;
|
|
Packit |
b099d7 |
BITS16 *bits16_gap_end, *bits16_end_ptr, *bits16_tmp_ptr;
|
|
Packit |
b099d7 |
BITS16 *bits16_end_of_data;
|
|
Packit |
b099d7 |
bits16_ptr = bits16_search_string = NULL;
|
|
Packit |
b099d7 |
bits16_gap_start = bits16_gap_end = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* search_length is number of characters (!bytes) in search_string */
|
|
Packit |
b099d7 |
bits16_search_string =
|
|
Packit |
b099d7 |
(BITS16 *) XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(search_length + 1) * (int)tw->text.char_size);
|
|
Packit |
b099d7 |
(void) _XmTextBytesToCharacters((char *) bits16_search_string,
|
|
Packit |
b099d7 |
search_string, search_length, True,
|
|
Packit |
b099d7 |
(int)tw->text.char_size);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* setup the variables for the search */
|
|
Packit |
b099d7 |
bits16_gap_start = (BITS16 *) data->gap_start;
|
|
Packit |
b099d7 |
bits16_gap_end = (BITS16 *) data->gap_end;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Make sure you don't search past end of data. End of data is... */
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *)data->ptr;
|
|
Packit |
b099d7 |
bits16_end_of_data = bits16_ptr + data->length +
|
|
Packit |
b099d7 |
(bits16_gap_end - bits16_gap_start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* only need to search up to end - search_length position */
|
|
Packit |
b099d7 |
if (bits16_end_of_data - search_length >= bits16_gap_end)
|
|
Packit |
b099d7 |
bits16_end_ptr = bits16_end_of_data - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
bits16_end_ptr = bits16_gap_start -
|
|
Packit |
b099d7 |
(search_length - (bits16_end_of_data - bits16_gap_end));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase one: search from start back to gap_end */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *)data->ptr;
|
|
Packit |
b099d7 |
if (bits16_ptr + start > bits16_gap_start) /* backside of gap */
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *)data->ptr +
|
|
Packit |
b099d7 |
(bits16_gap_end - bits16_gap_start) + start;
|
|
Packit |
b099d7 |
else /* we're starting before the gap */
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *)data->ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* no need search where a match can't be found */
|
|
Packit |
b099d7 |
if (bits16_ptr > bits16_end_ptr)
|
|
Packit |
b099d7 |
bits16_ptr = bits16_end_ptr;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && bits16_ptr >= bits16_gap_end) {
|
|
Packit |
b099d7 |
if (*bits16_ptr == *bits16_search_string) { /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (bits16_ptr[i] != bits16_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = bits16_ptr - (BITS16 *)data->ptr -
|
|
Packit |
b099d7 |
(bits16_gap_end - bits16_gap_start);
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
bits16_ptr--; /* decrement base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase two: these searches span the gap and are SLOW!
|
|
Packit |
b099d7 |
* Two possibilities: either I've just backed the base back to gap
|
|
Packit |
b099d7 |
* end (and must do searches that span the gap) or start puts
|
|
Packit |
b099d7 |
* the base prior to the gap end. Also, possibility that there
|
|
Packit |
b099d7 |
* isn't enough room after the gap for a complete match
|
|
Packit |
b099d7 |
* (so no need to search it). This phase must be performed as
|
|
Packit |
b099d7 |
* long as data->ptr + start places the base to the right of
|
|
Packit |
b099d7 |
* gap_start - search_length.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Do this as nested for loops; the outer loop decrements the base for
|
|
Packit |
b099d7 |
* the search, the inner loop compares character elements from 0 to
|
|
Packit |
b099d7 |
* length(search_string).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If no match yet and if need to search prior to gap_start... */
|
|
Packit |
b099d7 |
/* Set the base for the search. */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *) data->ptr;
|
|
Packit |
b099d7 |
if (!return_val &&
|
|
Packit |
b099d7 |
(bits16_ptr + start) > (bits16_gap_start - search_length)) {
|
|
Packit |
b099d7 |
if (bits16_ptr < bits16_gap_start)
|
|
Packit |
b099d7 |
bits16_ptr = bits16_gap_start - 1;
|
|
Packit |
b099d7 |
/* else, we're done... gap_start is at data->ptr and still no match*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (match = True;
|
|
Packit |
b099d7 |
bits16_ptr >= (BITS16*)data->ptr &&
|
|
Packit |
b099d7 |
(bits16_gap_start - bits16_ptr) +
|
|
Packit |
b099d7 |
(bits16_end_of_data - bits16_gap_end) >= search_length;
|
|
Packit |
b099d7 |
bits16_ptr--, match = True) {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*bits16_ptr == *bits16_search_string) { /* potential winner */
|
|
Packit |
b099d7 |
for (i = 1; i < search_length && match == True; i ++) {
|
|
Packit |
b099d7 |
if (bits16_ptr + i >= bits16_gap_start) {
|
|
Packit |
b099d7 |
bits16_tmp_ptr = bits16_ptr +
|
|
Packit |
b099d7 |
(bits16_gap_end - bits16_gap_start) + i;
|
|
Packit |
b099d7 |
if (*bits16_tmp_ptr != bits16_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (bits16_ptr[i] != bits16_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} /* end inner for loop - searching from current base */
|
|
Packit |
b099d7 |
if (match && (i == search_length)) {/* a winner! */
|
|
Packit |
b099d7 |
*position = bits16_ptr - (BITS16*)data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (return_val) break;
|
|
Packit |
b099d7 |
} /* end outer for - restart search from a new base */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* phase three: search backwards from base == gap_start - search_length
|
|
Packit |
b099d7 |
* through and including base == data->ptr.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!return_val) {
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *) data->ptr;
|
|
Packit |
b099d7 |
if (bits16_ptr + start > bits16_gap_start - search_length)
|
|
Packit |
b099d7 |
bits16_ptr = bits16_gap_start - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
bits16_ptr = bits16_ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && bits16_ptr >= (BITS16 *)data->ptr) {
|
|
Packit |
b099d7 |
if (*bits16_ptr == *bits16_search_string) {/* potential winner!*/
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (bits16_ptr[i] != bits16_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = bits16_ptr - (BITS16 *)data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
bits16_ptr--; /* decrement base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* clean up before you go */
|
|
Packit |
b099d7 |
if (bits16_search_string != NULL)
|
|
Packit |
b099d7 |
XtFree((char*)bits16_search_string);
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 2 */
|
|
Packit |
b099d7 |
default: {
|
|
Packit |
b099d7 |
wchar_t *wchar_t_ptr, *wchar_t_search_string, *wchar_t_gap_start;
|
|
Packit |
b099d7 |
wchar_t *wchar_t_gap_end, *wchar_t_end_ptr, *wchar_t_tmp_ptr;
|
|
Packit |
b099d7 |
wchar_t *wchar_t_end_of_data;
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_search_string = NULL;
|
|
Packit |
b099d7 |
wchar_t_gap_start = wchar_t_gap_end = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wchar_t_search_string =
|
|
Packit |
b099d7 |
(wchar_t *) XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(search_length + 1) * sizeof(wchar_t));
|
|
Packit |
b099d7 |
(void)_XmTextBytesToCharacters((char *) wchar_t_search_string,
|
|
Packit |
b099d7 |
search_string, search_length, True,
|
|
Packit |
b099d7 |
(int)tw->text.char_size);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* setup the variables for the search of new lines before the gap */
|
|
Packit |
b099d7 |
wchar_t_gap_start = (wchar_t *) data->gap_start;
|
|
Packit |
b099d7 |
wchar_t_gap_end = (wchar_t *) data->gap_end;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Make sure you don't search past end of data. End of data is... */
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *)data->ptr;
|
|
Packit |
b099d7 |
wchar_t_end_of_data = wchar_t_ptr + data->length +
|
|
Packit |
b099d7 |
(wchar_t_gap_end - wchar_t_gap_start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* only need to search up to end - search_length position */
|
|
Packit |
b099d7 |
if (wchar_t_end_of_data - search_length >= wchar_t_gap_end)
|
|
Packit |
b099d7 |
wchar_t_end_ptr = wchar_t_end_of_data - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
wchar_t_end_ptr = wchar_t_gap_start -
|
|
Packit |
b099d7 |
(search_length - (wchar_t_end_of_data - wchar_t_gap_end));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase one: search from start back to gap_end */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *)data->ptr;
|
|
Packit |
b099d7 |
if (wchar_t_ptr + start > wchar_t_gap_start) /* backside of gap */
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *)data->ptr +
|
|
Packit |
b099d7 |
(wchar_t_gap_end - wchar_t_gap_start) + start;
|
|
Packit |
b099d7 |
else /* we're starting before the gap */
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *)data->ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* no need search where a match can't be found */
|
|
Packit |
b099d7 |
if (wchar_t_ptr > wchar_t_end_ptr)
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_end_ptr;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && wchar_t_ptr >= wchar_t_gap_end) {
|
|
Packit |
b099d7 |
if (*wchar_t_ptr == *wchar_t_search_string) { /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (wchar_t_ptr[i] != wchar_t_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = wchar_t_ptr - (wchar_t *)data->ptr -
|
|
Packit |
b099d7 |
(wchar_t_gap_end - wchar_t_gap_start);
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
wchar_t_ptr--; /* decrement base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase two: these searches span the gap and are SLOW!
|
|
Packit |
b099d7 |
* Two possibilities: either I've just backed the base back to gap
|
|
Packit |
b099d7 |
* end (and must do searches that span the gap) or start puts
|
|
Packit |
b099d7 |
* the base prior to the gap end. Also, possibility that there
|
|
Packit |
b099d7 |
* isn't enough room after the gap for a complete match
|
|
Packit |
b099d7 |
* (so no need to search it). This phase must be performed as
|
|
Packit |
b099d7 |
* long as data->ptr + start places the base to the right of
|
|
Packit |
b099d7 |
* gap_start - search_length.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Do this as nested for loops; the outer loop decrements the base for
|
|
Packit |
b099d7 |
* the search, the inner loop compares character elements from 0 to
|
|
Packit |
b099d7 |
* length(search_string).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If no match yet and if need to search prior to gap_start... */
|
|
Packit |
b099d7 |
/* Set the base for the search. */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *) data->ptr;
|
|
Packit |
b099d7 |
if (!return_val &&
|
|
Packit |
b099d7 |
(wchar_t_ptr + start) > (wchar_t_gap_start - search_length)) {
|
|
Packit |
b099d7 |
if (wchar_t_ptr < wchar_t_gap_start)
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_gap_start - 1;
|
|
Packit |
b099d7 |
/*else, we're done... gap_start is at data->ptr and still no match*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (match = True;
|
|
Packit |
b099d7 |
wchar_t_ptr >= (wchar_t*)data->ptr &&
|
|
Packit |
b099d7 |
(wchar_t_gap_start - wchar_t_ptr) +
|
|
Packit |
b099d7 |
(wchar_t_end_of_data - wchar_t_gap_end) >= search_length;
|
|
Packit |
b099d7 |
wchar_t_ptr--, match = True) {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*wchar_t_ptr == *wchar_t_search_string) {/* potential winner */
|
|
Packit |
b099d7 |
for (i = 1; i < search_length && match == True; i ++) {
|
|
Packit |
b099d7 |
if (wchar_t_ptr + i >= wchar_t_gap_start) {
|
|
Packit |
b099d7 |
wchar_t_tmp_ptr = wchar_t_ptr +
|
|
Packit |
b099d7 |
(wchar_t_gap_end - wchar_t_gap_start) + i;
|
|
Packit |
b099d7 |
if (*wchar_t_tmp_ptr != wchar_t_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (wchar_t_ptr[i] != wchar_t_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} /* end inner for loop - searching from current base */
|
|
Packit |
b099d7 |
if (match && (i == search_length)) {/* a winner! */
|
|
Packit |
b099d7 |
*position = wchar_t_ptr - (wchar_t*)data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (return_val) break;
|
|
Packit |
b099d7 |
} /* end outer for - restart search from a new base */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* phase three: search backwards from base == gap_start - search_length
|
|
Packit |
b099d7 |
* through and including base == data->ptr.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!return_val) {
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *) data->ptr;
|
|
Packit |
b099d7 |
if (wchar_t_ptr + start > wchar_t_gap_start - search_length)
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_gap_start - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && wchar_t_ptr >= (wchar_t *)data->ptr) {
|
|
Packit |
b099d7 |
if (*wchar_t_ptr == *wchar_t_search_string) {/* potential winner!*/
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (wchar_t_ptr[i] != wchar_t_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = wchar_t_ptr - (wchar_t *)data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
wchar_t_ptr--; /* decrement base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* clean up before you go */
|
|
Packit |
b099d7 |
if (wchar_t_search_string != NULL)
|
|
Packit |
b099d7 |
XtFree((char*)wchar_t_search_string);
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end default */
|
|
Packit |
b099d7 |
} /* end switch */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return return_val;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmTextFindStringForwards(Widget w,
|
|
Packit |
b099d7 |
XmTextPosition start,
|
|
Packit |
b099d7 |
char* search_string,
|
|
Packit |
b099d7 |
XmTextPosition *position)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
register int i;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
XmSourceData data = tw->text.source->data;
|
|
Packit |
b099d7 |
Boolean return_val = False, match = False;
|
|
Packit |
b099d7 |
int search_length = 0;
|
|
Packit |
b099d7 |
char *ptr, *end_ptr, *tmp_ptr, *end_of_data;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
search_length = _XmTextCountCharacters(search_string,strlen(search_string));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!search_length || !data->length || search_length > data->length)
|
|
Packit |
b099d7 |
return FALSE;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Search can be broken into three phases for fastest search:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* - search from start up to gap_start-strlen(search_string).
|
|
Packit |
b099d7 |
* This is a fast simple compare that doesn't worry about
|
|
Packit |
b099d7 |
* incursions into the gap.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* - search from gap_start-strlen(search_string) until the base
|
|
Packit |
b099d7 |
* of the search is moved across the gap.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* - search from gap_end to data_end - strlen(search_string).
|
|
Packit |
b099d7 |
* This is a fast, simple compare that doesn't worry about
|
|
Packit |
b099d7 |
* incursions into the gap or overrunning end of data.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
switch ((int)tw->text.char_size) {
|
|
Packit |
b099d7 |
case 1: {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Make sure you don't search past end of data. End of data is... */
|
|
Packit |
b099d7 |
end_of_data = data->ptr + data->length +
|
|
Packit |
b099d7 |
(data->gap_end - data->gap_start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* actually, only need to search up to end - search_length position */
|
|
Packit |
b099d7 |
if (end_of_data - search_length >= data->gap_end)
|
|
Packit |
b099d7 |
end_ptr = end_of_data - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
end_ptr = data->gap_start -
|
|
Packit |
b099d7 |
(search_length - (end_of_data - data->gap_end));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase one: search from start to gap_start-strlen(search_string) */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ptr = data->ptr + start;
|
|
Packit |
b099d7 |
while (!return_val && ptr + search_length <= data->gap_start) {
|
|
Packit |
b099d7 |
if (*ptr == *search_string) { /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (ptr[i] != search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = ptr - data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
ptr++; /* advance base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase two: these searches span the gap and are SLOW!
|
|
Packit |
b099d7 |
* Two possibilities: either I'm just short of the gap
|
|
Packit |
b099d7 |
* (and must do searches that span the gap) or start puts
|
|
Packit |
b099d7 |
* the base after gap end. Also, possibility that there
|
|
Packit |
b099d7 |
* isn't enough room after the gap for a complete match
|
|
Packit |
b099d7 |
* (so no need to search it).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Do this as nested for loops; the outer loop advances the base for
|
|
Packit |
b099d7 |
* the search, the inner loop compares character elements from 0 to
|
|
Packit |
b099d7 |
* length(search_string).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* if no match yet and if need to search prior to gap_start... */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!return_val && (data->ptr + start) < data->gap_start) {
|
|
Packit |
b099d7 |
if (data->ptr + start < data->gap_start - search_length)
|
|
Packit |
b099d7 |
ptr = data->gap_start - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
ptr = data->ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (match = True;
|
|
Packit |
b099d7 |
ptr < data->gap_start && (data->gap_start - ptr) +
|
|
Packit |
b099d7 |
(end_of_data - data->gap_end) >= search_length;
|
|
Packit |
b099d7 |
ptr++, match = True) {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*ptr == *search_string) { /* we have a potential winner */
|
|
Packit |
b099d7 |
for (i = 1; i < search_length && match == True; i ++) {
|
|
Packit |
b099d7 |
if (ptr + i >= data->gap_start) {
|
|
Packit |
b099d7 |
tmp_ptr = ptr +(data->gap_end - data->gap_start) + i;
|
|
Packit |
b099d7 |
if (*tmp_ptr != search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (ptr[i] != search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} /* end inner for loop - searching from current base */
|
|
Packit |
b099d7 |
if (match && (i == search_length)) {/* a winner! */
|
|
Packit |
b099d7 |
*position = ptr - data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (return_val) break;
|
|
Packit |
b099d7 |
} /* end outer for - restart search from a new base */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* phase three: search after gap end upto end of data - search_length */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!return_val) {
|
|
Packit |
b099d7 |
if (data->ptr + start < data->gap_start)
|
|
Packit |
b099d7 |
ptr = data->gap_end; /* we've already started - continue at
|
|
Packit |
b099d7 |
* gap end. */
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
ptr = data->ptr + (data->gap_end - data->gap_start) + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && ptr <= end_ptr) {
|
|
Packit |
b099d7 |
if (*ptr == *search_string) { /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (ptr[i] != search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = ptr - data->ptr -
|
|
Packit |
b099d7 |
(data->gap_end - data->gap_start);
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
ptr++; /* advance base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} /* end case 1 */
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
case 2: {
|
|
Packit |
b099d7 |
BITS16 *bits16_ptr, *bits16_search_string, *bits16_gap_start;
|
|
Packit |
b099d7 |
BITS16 *bits16_gap_end, *bits16_end_ptr, *bits16_tmp_ptr;
|
|
Packit |
b099d7 |
BITS16 *bits16_end_of_data;
|
|
Packit |
b099d7 |
bits16_ptr = bits16_search_string = NULL;
|
|
Packit |
b099d7 |
bits16_gap_start = bits16_gap_end = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* search_length is number of characters (!bytes) in search_string */
|
|
Packit |
b099d7 |
bits16_search_string =
|
|
Packit |
b099d7 |
(BITS16 *) XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(search_length + 1) * (int)tw->text.char_size);
|
|
Packit |
b099d7 |
(void) _XmTextBytesToCharacters((char *) bits16_search_string,
|
|
Packit |
b099d7 |
search_string, search_length, True,
|
|
Packit |
b099d7 |
(int)tw->text.char_size);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* setup the variables for the search */
|
|
Packit |
b099d7 |
bits16_gap_start = (BITS16 *) data->gap_start;
|
|
Packit |
b099d7 |
bits16_gap_end = (BITS16 *) data->gap_end;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Make sure you don't search past end of data. End of data is... */
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *)data->ptr;
|
|
Packit |
b099d7 |
bits16_end_of_data = bits16_ptr + data->length +
|
|
Packit |
b099d7 |
(bits16_gap_end - bits16_gap_start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* only need to search up to end - search_length position */
|
|
Packit |
b099d7 |
if (bits16_end_of_data - search_length >= bits16_gap_end)
|
|
Packit |
b099d7 |
bits16_end_ptr = bits16_end_of_data - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
bits16_end_ptr = bits16_gap_start -
|
|
Packit |
b099d7 |
(search_length - (bits16_end_of_data - bits16_gap_end));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase one: search from start to gap start - search_length */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *)data->ptr + start;
|
|
Packit |
b099d7 |
while (!return_val && bits16_ptr + search_length <= bits16_gap_start) {
|
|
Packit |
b099d7 |
if (*bits16_ptr == *bits16_search_string) { /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (bits16_ptr[i] != bits16_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = bits16_ptr - (BITS16 *)data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
bits16_ptr++; /* advance base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase two: these searches span the gap and are SLOW!
|
|
Packit |
b099d7 |
* Two possibilities: either I'm just short of the gap
|
|
Packit |
b099d7 |
* (and must do searches that span the gap) or start puts
|
|
Packit |
b099d7 |
* the base after gap end. Also, possibility that there
|
|
Packit |
b099d7 |
* isn't enough room after the gap for a complete match
|
|
Packit |
b099d7 |
* (so no need to search it).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Do this as nested for loops; the outer loop advances the base for
|
|
Packit |
b099d7 |
* the search, the inner loop compares character elements from 0 to
|
|
Packit |
b099d7 |
* length(search_string).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* if no match yet and if need to search prior to gap_start... */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *) data->ptr;
|
|
Packit |
b099d7 |
if (!return_val && (bits16_ptr + start) < bits16_gap_start) {
|
|
Packit |
b099d7 |
if (bits16_ptr + start < bits16_gap_start - search_length)
|
|
Packit |
b099d7 |
bits16_ptr = bits16_gap_start - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16*)data->ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (match = True;
|
|
Packit |
b099d7 |
bits16_ptr < bits16_gap_start &&
|
|
Packit |
b099d7 |
(bits16_gap_start - bits16_ptr) +
|
|
Packit |
b099d7 |
(bits16_end_of_data - bits16_gap_end) >= search_length;
|
|
Packit |
b099d7 |
bits16_ptr++, match = True) {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*bits16_ptr == *bits16_search_string)
|
|
Packit |
b099d7 |
{ /* have a potential winner*/
|
|
Packit |
b099d7 |
for (i = 1; i < search_length && match == True; i ++) {
|
|
Packit |
b099d7 |
if (bits16_ptr + i >= bits16_gap_start) {
|
|
Packit |
b099d7 |
bits16_tmp_ptr = bits16_ptr +
|
|
Packit |
b099d7 |
(bits16_gap_end - bits16_gap_start) + i;
|
|
Packit |
b099d7 |
if (*bits16_tmp_ptr != bits16_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (bits16_ptr[i] != bits16_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} /* end inner for loop - searching from current base */
|
|
Packit |
b099d7 |
if (match && (i == search_length)) { /* a winner! */
|
|
Packit |
b099d7 |
*position = bits16_ptr - (BITS16*)data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (return_val) break;
|
|
Packit |
b099d7 |
} /* end outer for - restart search from a new base */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* phase three: search after gap end upto end of data - search_length */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!return_val) {
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *) data->ptr;
|
|
Packit |
b099d7 |
if (bits16_ptr + start < bits16_gap_start)
|
|
Packit |
b099d7 |
bits16_ptr = bits16_gap_end; /* we've already started...
|
|
Packit |
b099d7 |
* continue at gap end. */
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16*)data->ptr +
|
|
Packit |
b099d7 |
(bits16_gap_end - bits16_gap_start) + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && bits16_ptr <= bits16_end_ptr) {
|
|
Packit |
b099d7 |
if (*bits16_ptr == *bits16_search_string)
|
|
Packit |
b099d7 |
{ /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i=1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (bits16_ptr[i] != bits16_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = bits16_ptr - (BITS16 *)data->ptr -
|
|
Packit |
b099d7 |
(bits16_gap_end - bits16_gap_start);
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
bits16_ptr++; /* advance base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* clean up before you go */
|
|
Packit |
b099d7 |
if (bits16_search_string != NULL)
|
|
Packit |
b099d7 |
XtFree((char*)bits16_search_string);
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 2 */
|
|
Packit |
b099d7 |
default: {
|
|
Packit |
b099d7 |
wchar_t *wchar_t_ptr, *wchar_t_search_string, *wchar_t_gap_start;
|
|
Packit |
b099d7 |
wchar_t *wchar_t_gap_end, *wchar_t_end_ptr, *wchar_t_tmp_ptr;
|
|
Packit |
b099d7 |
wchar_t *wchar_t_end_of_data;
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_search_string = NULL;
|
|
Packit |
b099d7 |
wchar_t_gap_start = wchar_t_gap_end = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wchar_t_search_string =
|
|
Packit |
b099d7 |
(wchar_t *) XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(search_length + 1) * sizeof(wchar_t));
|
|
Packit |
b099d7 |
(void)_XmTextBytesToCharacters((char *) wchar_t_search_string,
|
|
Packit |
b099d7 |
search_string, search_length, True,
|
|
Packit |
b099d7 |
(int)tw->text.char_size);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* setup the variables for the search of new lines before the gap */
|
|
Packit |
b099d7 |
wchar_t_gap_start = (wchar_t *) data->gap_start;
|
|
Packit |
b099d7 |
wchar_t_gap_end = (wchar_t *) data->gap_end;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *)data->ptr;
|
|
Packit |
b099d7 |
/* Make sure you don't search past end of data. End of data is... */
|
|
Packit |
b099d7 |
wchar_t_end_of_data = wchar_t_ptr + data->length +
|
|
Packit |
b099d7 |
(wchar_t_gap_end - wchar_t_gap_start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* only need to search up to end - search_length position */
|
|
Packit |
b099d7 |
if (wchar_t_end_of_data - search_length >= wchar_t_gap_end)
|
|
Packit |
b099d7 |
wchar_t_end_ptr = wchar_t_end_of_data - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
wchar_t_end_ptr = wchar_t_gap_start -
|
|
Packit |
b099d7 |
(search_length - (wchar_t_end_of_data - wchar_t_gap_end));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase one: search from start to gap start - search_length */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *)data->ptr + start;
|
|
Packit |
b099d7 |
while (!return_val && wchar_t_ptr + search_length <= wchar_t_gap_start) {
|
|
Packit |
b099d7 |
if (*wchar_t_ptr == *wchar_t_search_string) { /* potential winner! */
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (wchar_t_ptr[i] != wchar_t_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = wchar_t_ptr - (wchar_t *)data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
wchar_t_ptr++; /* advance base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Phase two: these searches span the gap and are SLOW!
|
|
Packit |
b099d7 |
* Two possibilities: either I'm just short of the gap
|
|
Packit |
b099d7 |
* (and must do searches that span the gap) or start puts
|
|
Packit |
b099d7 |
* the base after gap end. Also, possibility that there
|
|
Packit |
b099d7 |
* isn't enough room after the gap for a complete match
|
|
Packit |
b099d7 |
* (so no need to search it).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Do this as nested for loops; the outer loop advances the base for
|
|
Packit |
b099d7 |
* the search, the inner loop compares character elements from 0 to
|
|
Packit |
b099d7 |
* length(search_string).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* if no match yet and if need to search prior to gap_start... */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *) data->ptr;
|
|
Packit |
b099d7 |
if (!return_val && (wchar_t_ptr + start) < wchar_t_gap_start) {
|
|
Packit |
b099d7 |
if (wchar_t_ptr + start < wchar_t_gap_start - search_length)
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_gap_start - search_length;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t*)data->ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (match = True;
|
|
Packit |
b099d7 |
wchar_t_ptr < wchar_t_gap_start &&
|
|
Packit |
b099d7 |
(wchar_t_gap_start - wchar_t_ptr) +
|
|
Packit |
b099d7 |
(wchar_t_end_of_data - wchar_t_gap_end) >= search_length;
|
|
Packit |
b099d7 |
wchar_t_ptr++, match = True) {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*wchar_t_ptr == *wchar_t_search_string) {
|
|
Packit |
b099d7 |
/* have a potential winner */
|
|
Packit |
b099d7 |
for (i = 1; i < search_length && match == True; i ++) {
|
|
Packit |
b099d7 |
if (wchar_t_ptr + i >= wchar_t_gap_start) {
|
|
Packit |
b099d7 |
wchar_t_tmp_ptr = wchar_t_ptr +
|
|
Packit |
b099d7 |
(wchar_t_gap_end - wchar_t_gap_start) + i;
|
|
Packit |
b099d7 |
if (*wchar_t_tmp_ptr != wchar_t_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (wchar_t_ptr[i] != wchar_t_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} /* end inner for loop - searching from current base */
|
|
Packit |
b099d7 |
if (match && (i == search_length)) { /* a winner! */
|
|
Packit |
b099d7 |
*position = wchar_t_ptr - (wchar_t*)data->ptr;
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (return_val) break;
|
|
Packit |
b099d7 |
} /* end outer for - restart search from a new base */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* phase three: search after gap end upto end of data - search_length */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!return_val) {
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *) data->ptr;
|
|
Packit |
b099d7 |
if (wchar_t_ptr + start < wchar_t_gap_start)
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_gap_end; /* we've already started...
|
|
Packit |
b099d7 |
* continue at gap end. */
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t*)data->ptr +
|
|
Packit |
b099d7 |
(wchar_t_gap_end - wchar_t_gap_start) + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (!return_val && wchar_t_ptr <= wchar_t_end_ptr) {
|
|
Packit |
b099d7 |
if (*wchar_t_ptr == *wchar_t_search_string) {
|
|
Packit |
b099d7 |
/* potential winner!*/
|
|
Packit |
b099d7 |
for (match = True, i = 1; match && (i < search_length); i++) {
|
|
Packit |
b099d7 |
if (wchar_t_ptr[i] != wchar_t_search_string[i]) {
|
|
Packit |
b099d7 |
match = False;
|
|
Packit |
b099d7 |
i--;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i == search_length) { /* we have a winner! */
|
|
Packit |
b099d7 |
*position = wchar_t_ptr - (wchar_t *)data->ptr -
|
|
Packit |
b099d7 |
(wchar_t_gap_end - wchar_t_gap_start);
|
|
Packit |
b099d7 |
return_val = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
wchar_t_ptr++; /* advance base of search */
|
|
Packit |
b099d7 |
match = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* clean up before you go */
|
|
Packit |
b099d7 |
if (wchar_t_search_string != NULL)
|
|
Packit |
b099d7 |
XtFree((char*)wchar_t_search_string);
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end default */
|
|
Packit |
b099d7 |
} /* end switch */
|
|
Packit |
b099d7 |
return return_val;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmTextFindString(Widget w,
|
|
Packit |
b099d7 |
XmTextPosition start,
|
|
Packit |
b099d7 |
char* search_string,
|
|
Packit |
b099d7 |
XmTextDirection direction,
|
|
Packit |
b099d7 |
XmTextPosition *position)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data;
|
|
Packit |
b099d7 |
Boolean ret_val;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (XmIsTextField(w)) return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
data = ((XmTextWidget)w)->text.source->data;
|
|
Packit |
b099d7 |
if (start > data->length)
|
|
Packit |
b099d7 |
start = data->length;
|
|
Packit |
b099d7 |
else if (start < 0)
|
|
Packit |
b099d7 |
start = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (direction == XmTEXT_BACKWARD)
|
|
Packit |
b099d7 |
ret_val = _XmTextFindStringBackwards(w, start, search_string, position);
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
ret_val = _XmTextFindStringForwards(w, start, search_string, position);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return (ret_val);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmTextFindStringWcs(Widget w,
|
|
Packit |
b099d7 |
XmTextPosition start,
|
|
Packit |
b099d7 |
wchar_t* wc_string,
|
|
Packit |
b099d7 |
XmTextDirection direction,
|
|
Packit |
b099d7 |
XmTextPosition *position)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
wchar_t *tmp_wc;
|
|
Packit |
b099d7 |
char *string;
|
|
Packit |
b099d7 |
int num_chars = 0;
|
|
Packit |
b099d7 |
Boolean return_val = False;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
int wcs_ret_val = 0;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
if (!XmIsTextField(w)) {
|
|
Packit |
b099d7 |
for (num_chars = 0, tmp_wc = wc_string; *tmp_wc != (wchar_t)0L;
|
|
Packit |
b099d7 |
num_chars++) tmp_wc++;
|
|
Packit |
b099d7 |
string = XtMalloc ((unsigned) (num_chars + 1) * (int)tw->text.char_size);
|
|
Packit |
b099d7 |
wcs_ret_val = wcstombs(string, wc_string,
|
|
Packit |
b099d7 |
(num_chars + 1) * (int)tw->text.char_size);
|
|
Packit |
b099d7 |
if (wcs_ret_val >= 0)
|
|
Packit |
b099d7 |
return_val = XmTextFindString(w, start, string, direction, position);
|
|
Packit |
b099d7 |
XtFree(string);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(return_val);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|