diff -udBbr TeXmacs-1.0.0.21-src-orig/src/Basic/Types/string.cc TeXmacs-1.0.0.21-src/src/Basic/Types/string.cc --- TeXmacs-1.0.0.21-src-orig/src/Basic/Types/string.cc Sat Aug 10 08:50:50 2002 +++ TeXmacs-1.0.0.21-src/src/Basic/Types/string.cc Tue Nov 12 23:46:30 2002 @@ -15,6 +15,7 @@ #include #include +#include "list.hh" static inline int round_length (int n) { @@ -320,6 +321,132 @@ return true; } +/************************************************************************************ +* Search & Replace +************************************************************************************/ + +// The function "search" searches for the string in . The index >= at which the +// first match begins is returned. If there are no matches -1 is returned. +// Examples: search ("hello","l")=>2, search("hello","l",3)=>3, search ("hello","ll",3)=>-1 + +int +search (string str, string key, int offset) { + if (offset < 0) offset = 0; + if (N(key) == 0) return -1; + int n= N(str) - N(key) + 1; // we have to keep checking upto index n + + for (int cur = offset; cur < n; cur++) { + if (str[cur]==key[0]) { + bool match = true; + for (int j = 1; j < N(key); j++) { + if (str[cur+j]!=key[j]) { + match = false; + break; + } + } + if (match) return cur; + } + } + return -1; +} + +// The function "search_all" searches for the string in . A list of indices >= at which the +// matches begin is returned. If there are no matches (-1) is returned. Warning! If multiple matches overlapp only +// the first match is returned, see examples. +// Examples: search_all ("aaaa","aa")=>(0,2) +// search_all ("aaa","aa")=>(2) +// search ("aaaaa","aaa")=>(0) + +list +search_all (string str, string key, int offset) { + if (offset < 0) offset = 0; + if (N(key) <= 0) return -1; + int n= N(str) - N(key) + 1; // we have to keep checking upto index n + list matches(-1); // there is no such thing as an empty list, is there? + + for (int cur = offset; cur < n; cur++ ) { + if (str[cur]==key[0]) { + bool match = true; + for (int j = 1; j < N(key); j++) { + if (str[cur+j]!=key[j]) { + match = false; + break; + } + } + if (match) { + matches << cur; + cur += N(key) - 1; // skip till after the end of the key just found. cur is incremented anyway, hence the -1 + } + } + } + if (N(matches)==1) return matches; + else return tail (matches); +} + +// The function "replace" replaces the first occurrence of in with and returns the +// result. + +string +replace (string str, string key, string replace, int offset) { + int match= search (str, key, offset); + if (match != -1) { + string result( N(str) + N(replace) - N (key) ); + int i = 0; int j = 0; + while (j < match) { // copy str->result until match is reached + result[i] = str [j]; + i++; j++; + } + int k = 0; + while (k < N(replace)) { // copy match->result + result[i] = replace [k]; + i++; k++; + } + j += N(key); + while (j < N(str)) { // copy rest of string + result[i] = str [j]; + i++; j++; + } + return result; + } + else { + return copy(str); + } +} + +// The function "replace_all" replaces the all occurrences of in with and returns the +// result. Warning! If multiple matches overlapp only the first overlapping match is replaces, see examples. +// Examples: replace_all("aaaaa","aaa","bb")=>"bbaa" + +string +replace_all (string str, string key, string replace, int offset) { + list matches= search_all(str, key, offset); + if (matches[0] != -1) { + string result( N(str) + N(matches)*(N(replace)-N(key)) ); + int i = 0; int j = 0; + while (N(matches)>0) { // while is something to replace + while (j < matches[0]) { // copy str->result until the next match is reached + result[i] = str [j]; + i++; j++; + } + int k = 0; + while (k < N(replace)) { // copy replace->result until end of replacing string is reached + result[i] = replace [k]; + i++; k++; + } + j += N(key); + matches = tail (matches); + } + while (j < N(str)) { // when the last replacement is done copy the remaining str->result + result[i] = str [j]; + i++; j++; + } + return result; + } + else { + return copy(str); + } +} + /****************************************************************************** * Error messages ******************************************************************************/ diff -udBbr TeXmacs-1.0.0.21-src-orig/src/Basic/Types/string.hh TeXmacs-1.0.0.21-src/src/Basic/Types/string.hh --- TeXmacs-1.0.0.21-src-orig/src/Basic/Types/string.hh Sat Aug 10 08:50:50 2002 +++ TeXmacs-1.0.0.21-src/src/Basic/Types/string.hh Tue Nov 12 22:51:45 2002 @@ -80,6 +80,14 @@ void fatal_error (string message= "unknown", string routine= "unknown", string file= ""); +// forward declaration of class list to avoid including "list.hh" as this leads to circular inclusions +template class list; + +int search (string str, string key, int offset=0); +list search_all (string str, string key, int offset=0); +string replace (string str, string key, string replace, int offset = 0); +string replace_all (string str, string key, string replace, int offset = 0); + void set_info_handler (void (*) (string, string, int)); void set_wait_handler (void (*) (string, string, int)); void set_warning_handler (void (*) (string, string, int));