Changeset 8d96dee for libcfa/src/containers/string_res.cfa
- Timestamp:
- Aug 14, 2023, 1:27:56 PM (2 years ago)
- Branches:
- master
- Children:
- 3543e99
- Parents:
- 89bef959 (diff), d32679d5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/containers/string_res.cfa
r89bef959 r8d96dee 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 29 09:29:06202313 // Update Count : 212 // Last Modified On : Sat Aug 12 15:37:47 2023 13 // Update Count : 10 14 14 // 15 15 … … 17 17 #include "string_sharectx.hfa" 18 18 #include "stdlib.hfa" 19 #include <ctype.h> 19 20 20 21 // Workaround for observed performance penalty from calling CFA's alloc. … … 134 135 serr | nlOff; 135 136 serr | " lnth:" | lnth | " s:" | (void *)s | ",\""; 136 for ( i nt i = 0; i < lnth; i += 1) {137 for ( i; lnth ) { 137 138 serr | s[i]; 138 139 } // for … … 198 199 // Output operator 199 200 ofstream & ?|?(ofstream &out, const string_res &s) { 200 // Store auto-newline state so it can be restored 201 bool anl = getANL$(out); 202 nlOff(out); 203 for (size_t i = 0; i < s.Handle.lnth; i++) { 204 out | s[i]; 205 } 206 out | sepVal; 207 // Re-apply newlines after done, for chaining version 208 if (anl) nlOn(out); 201 // CFA string is NOT null terminated, so print exactly lnth characters in a minimum width of 0. 202 out | wd( 0, s.Handle.lnth, s.Handle.s ) | nonl; 209 203 return out; 210 204 } 211 205 212 206 void ?|?(ofstream &out, const string_res &s) { 213 // Store auto-newline state so it can be restored 214 bool anl = getANL$(out); 215 if( s.Handle.lnth == 0 ) { 216 sout | ""; 217 } else { 218 nlOff(out); 219 for (size_t i = 0; i < s.Handle.lnth; i++) { 220 // Need to re-apply on the last output operator, for whole-statement version 221 if (anl && i == s.Handle.lnth-1) nlOn(out); 222 out | s[i]; 223 } 224 } 225 } 207 (ofstream &)(out | s); ends( out ); 208 } 209 210 // Input operator 211 ifstream & ?|?(ifstream &in, string_res &s) { 212 213 // Reading into a temp before assigning to s is near zero overhead in typical cases because of sharing. 214 // If s is a substring of something larger, simple assignment takes care of that case correctly. 215 // But directly reading a variable amount of text into the middle of a larger context is not practical. 216 string_res temp; 217 218 // Read in chunks. Often, one chunk is enough. Keep the string that accumulates chunks last in the heap, 219 // so available room is rest of heap. When a chunk fills the heap, force growth then take the next chunk. 220 for (;;) { 221 // Append dummy content to temp, forcing expansion when applicable (occurs always on subsequent loops) 222 // length 2 ensures room for at least one real char, plus scanf/pipe-cstr's null terminator 223 temp += "--"; 224 assert( temp.Handle.ulink->EndVbyte == temp.Handle.s + temp.Handle.lnth ); // last in heap 225 226 // reset, to overwrite the appended "--" 227 temp.Handle.lnth -= 2; 228 temp.Handle.ulink->EndVbyte -= 2; 229 230 // rest of heap, less 1 byte for null terminator, is available to read into 231 int lenReadable = (char*)temp.Handle.ulink->ExtVbyte - temp.Handle.ulink->EndVbyte - 1; 232 assert (lenReadable >= 1); 233 234 // get bytes 235 in | wdi( lenReadable, temp.Handle.ulink->EndVbyte ); 236 int lenWasRead = strlen(temp.Handle.ulink->EndVbyte); 237 238 // update metadata 239 temp.Handle.lnth += lenWasRead; 240 temp.Handle.ulink->EndVbyte += lenWasRead; 241 242 if (lenWasRead < lenReadable) break; 243 } 244 245 s = temp; 246 return in; 247 } 248 226 249 227 250 // Empty constructor … … 338 361 // adjust all substring string and handle locations, and check if any substring strings are outside the new base string 339 362 char *limit = resultSesStart + resultSesLnth; 340 for ( string_res * p = this.shareEditSet_next; p != &this; p = p->shareEditSet_next) {363 for ( string_res * p = this.shareEditSet_next; p != &this; p = p->shareEditSet_next ) { 341 364 verify (p->Handle.s >= beforeBegin); 342 365 if ( p->Handle.s >= afterBegin ) { … … 391 414 } 392 415 393 static string_res & assign_(string_res &this, const char* buffer, size_t bsize, const string_res & valSrc) { 394 395 // traverse the incumbent share-edit set (SES) to recover the range of a base string to which `this` belongs 396 string_res * shareEditSetStartPeer = & this; 397 string_res * shareEditSetEndPeer = & this; 416 // traverse the share-edit set (SES) to recover the range of a base string to which `this` belongs 417 static void locateInShareEditSet( string_res &this, string_res *&shareEditSetStartPeer, string_res *&shareEditSetEndPeer ) { 418 shareEditSetStartPeer = & this; 419 shareEditSetEndPeer = & this; 398 420 for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) { 399 421 if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) { … … 404 426 } 405 427 } 428 } 429 430 static string_res & assign_(string_res &this, const char* buffer, size_t bsize, const string_res & valSrc) { 431 432 string_res * shareEditSetStartPeer; 433 string_res * shareEditSetEndPeer; 434 locateInShareEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer ); 406 435 407 436 verify( shareEditSetEndPeer->Handle.s >= shareEditSetStartPeer->Handle.s ); … … 589 618 590 619 bool contains(const string_res &s, char ch) { 591 for ( i; size(s)) {620 for ( i; size(s) ) { 592 621 if (s[i] == ch) return true; 593 622 } … … 643 672 } 644 673 645 for ( size_t i = fromPos; i < s.Handle.lnth; i++) {674 for ( i; fromPos ~ s.Handle.lnth ) { 646 675 size_t remaining = s.Handle.lnth - i; 647 676 // Never going to find the search string if the remaining string is … … 652 681 653 682 bool matched = true; 654 for ( size_t j = 0; j < searchsize; j++) {683 for ( j; searchsize ) { 655 684 if (search[j] != s.Handle.s[i + j]) { 656 685 matched = false; … … 740 769 741 770 int exclude(const string_res &s, const charclass_res &mask) { 742 for ( int i = 0; i < size(s); i++) {771 for ( i; size(s) ) { 743 772 if ( test(mask, s[i]) ) return i; 744 773 } … … 747 776 748 777 int include(const string_res &s, const charclass_res &mask) { 749 for ( int i = 0; i < size(s); i++) {778 for ( i; size(s) ) { 750 779 if ( ! test(mask, s[i]) ) return i; 751 780 } … … 775 804 for ( HandleNode *ni = HeaderPtr->flink; ni != HeaderPtr; ni = ni->flink ) { 776 805 serr | "\tnode:" | ni | " lnth:" | ni->lnth | " s:" | (void *)ni->s | ",\""; 777 for ( i nt i = 0; i < ni->lnth; i += 1) {806 for ( i; ni->lnth ) { 778 807 serr | ni->s[i]; 779 808 } // for … … 881 910 for ( HandleNode *n = HeaderPtr->flink; n != HeaderPtr; n = n->flink ) { 882 911 serr | "\tnode:" | n | " lnth:" | n->lnth | " s:" | (void *)n->s | ",\""; 883 for ( i nt i = 0; i < n->lnth; i += 1) {884 serr | n->s[i];912 for ( i; n->lnth ) { 913 serr | n->s[i]; 885 914 } // for 886 915 serr | "\" flink:" | n->flink | " blink:" | n->blink | nl; … … 960 989 EndVbyte = StartVbyte; 961 990 h = Header.flink; // ignore header node 962 for ( ;;) {991 for () { 963 992 memmove( EndVbyte, h->s, h->lnth ); 964 993 obase = h->s; … … 971 1000 // check if any substrings are allocated within a string 972 1001 973 for ( ;;) {1002 for () { 974 1003 if ( h == &Header ) break; // end of header list ? 975 1004 if ( h->s >= limit ) break; // outside of current string ? … … 1001 1030 serr | nlOff; 1002 1031 serr | "\tnode:" | n | " lnth:" | n->lnth | " s:" | (void *)n->s | ",\""; 1003 for ( i nt i = 0; i < n->lnth; i += 1) {1032 for ( i; n->lnth ) { 1004 1033 serr | n->s[i]; 1005 1034 } // for … … 1036 1065 serr | nlOff; 1037 1066 serr | "\tnode:" | n | " lnth:" | n->lnth | " s:" | (void *)n->s | ",\""; 1038 for ( i nt i = 0; i < n->lnth; i += 1) {1067 for ( i; n->lnth ) { 1039 1068 serr | n->s[i]; 1040 1069 } // for
Note:
See TracChangeset
for help on using the changeset viewer.