/* * find_pos.c file contains following procedures: * find_string_pos_in_buffer * find_line_pos * textPosToLineColumn * They are used in the asedit program. * * Last changes: 14 April 1994 * */ /* * Copyright 1991 - 1994, Andrzej Stochniol, London, UK * * ASEDIT text editor, both binary and source (hereafter, Software) is * copyrighted by Andrzej Stochniol (hereafter, AS) and ownership remains * with AS. * * AS grants you (hereafter, Licensee) a license to use the Software * for academic, research and internal business purposes only, without a * fee. Licensee may distribute the binary and source code (if released) * to third parties provided that the copyright notice and this statement * appears on all copies and that no charge is associated with such copies. * * Licensee may make derivative works. However, if Licensee distributes * any derivative work based on or derived from the Software, then * Licensee will: * (1) notify AS regarding its distribution of the derivative work, and * (2) clearly notify users that such derivative work is a modified version * and not the original ASEDIT distributed by AS. * * Any Licensee wishing to make commercial use of the Software should * contact AS to negotiate an appropriate license for such commercial use. * Commercial use includes: * (1) integration of all or part of the source code into a product for sale * or license by or on behalf of Licensee to third parties, or * (2) distribution of the binary code or source code to third parties that * need it to utilize a commercial product sold or licensed by or on * behalf of Licensee. * * A. STOCHNIOL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS * SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR * IMPLIED WARRANTY. IN NO EVENT SHALL A. STOCHNIOL BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * By using or copying this Software, Licensee agrees to abide by the * copyright law and all other applicable laws, and the terms of this * license. * AS shall have the right to terminate this license immediately by * written notice upon Licensee's breach of, or non-compliance with, any * of its terms. Licensee may be held legally responsible for any * copyright infringement that is caused or encouraged by Licensee's * failure to abide by the terms of this license. * * * Andrzej Stochniol (A.Stochniol@ic.ac.uk) * 30 Hatch Road * London SW16 4PN * UK */ #include #include #include /* to define toupper function */ #include /* defines Boolean type */ /* find_string_pos_in_buffer returns position of the found string in the character buffer; if the text has not been found (or in case of error) returns negative number; The search is started from startpos and is carried forward when "forward" is True (when "forward" is False the search direction is backward). The search is case sensitive for case_sensitive=True and only whole words are found when whole_words_only=True. The startpos and endpos should contain the range where the string should be searched for. When startpos or endpos is < 0 the default value will be assigned for it inside the procedure (i.e. beginnning or end of the file ); */ #ifdef _NO_PROTO long find_string_pos_in_buffer(searchstring, buf, startpos, endpos, forward, case_sensitive, whole_words_only) char *searchstring; char *buf; long startpos; long endpos; Boolean forward; Boolean case_sensitive; Boolean whole_words_only; #else /* _NO_PROTO */ long find_string_pos_in_buffer(char *searchstring, char *buf, long startpos, long endpos, Boolean forward, Boolean case_sensitive, Boolean whole_words_only) #endif { long pos = -1L; long searchlen = strlen(searchstring); /* length of the search string (should be > 0)*/ long buf_size = (long) strlen(buf); register long i, n; char *s1, *s2; int c1, c2; /* integers used for not case-sensitive search (toupper is defined for integers; we use them to speed the process of search)*/ if(searchlen <= 0L) return(-3L); if(buf_size <= 0L) return(-2L); /* setting the default value for negative startpos and/or endpos */ if(startpos < 0L) { if(forward) startpos = 0L; else startpos = buf_size; } if(endpos < 0L) { if(forward) endpos = buf_size; else endpos = 0L; } /* test (and correct) the search range */ if(endpos > buf_size) endpos=buf_size; if(startpos > buf_size) startpos=buf_size; /* there are two major cases case-sensitive and not (they are split to speed the process of the search */ if(case_sensitive) { if(forward) { /* search forward starting from startpos position */ for( i = startpos; i < endpos; i++) { n = searchlen; s1 = &buf[i]; s2 = searchstring; while (--n >= 0L && *s1++ == *s2++); if(n < 0L) { pos = i; /* additional check for whole words only - check both ends*/ if(whole_words_only) { if((i>0L && (isalnum((unsigned char)buf[i-1]) || buf[i-1] == '_')) || (i+searchlen= endpos; i--) { n = searchlen; s1 = &buf[i]; s2 = searchstring; while (--n >= 0L && *s1++ == *s2++); if(n < 0L) { pos = i; if(whole_words_only) /* as above ... */ { if((i>0L && (isalnum((unsigned char)buf[i-1]) || buf[i-1] == '_')) || (i+searchlen= 0L && c1 == c2) { c1 = toupper((unsigned char) *(++s1)); c2 = toupper((unsigned char) *(++s2)); } if(n < 0L) { pos = i; if(whole_words_only) /* as above ... */ { if((i>0L && (isalnum((unsigned char)buf[i-1]) || buf[i-1] == '_')) || (i+searchlen= endpos; i--) { n = searchlen; s1 = &buf[i]; s2 = searchstring; c1 = toupper((unsigned char)*s1); c2=toupper((unsigned char)*s2); while (--n >= 0L && c1 == c2) { c1 = toupper((unsigned char) *(++s1)); c2 = toupper((unsigned char) *(++s2)); } if(n < 0L) { pos = i; if(whole_words_only) /* as above ... */ { if((i>0L && (isalnum((unsigned char)buf[i-1]) || buf[i-1] == '_')) || (i+searchlen buf_size) return; else { for( i = buf_size; i >= 0L; i--) { if(buf[i] == new_line) (*line)++; /* count the number of skipped lines */ if(i == pos) break; /* we have reached the right position */ } /* go backward untill you find a new_line ... */ for(j=i-1; j>= 0L; j--) { if(buf[j] == new_line) { latest_lf_pos = j; break; } } /* setting the column number - version without taking into account tab characters*/ *column_ntab = *column = pos - latest_lf_pos; /* let's find column with tab characters taken into account ... */ col = 1L; for( i = latest_lf_pos+1L; i