- File:
-
- 1 edited
-
libcfa/src/containers/string_res.cfa (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/containers/string_res.cfa
rd32679d5 r7d25f44 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 12 15:37:47202313 // Update Count : 1012 // Last Modified On : Thu Jun 29 09:29:06 2023 13 // Update Count : 2 14 14 // 15 15 … … 17 17 #include "string_sharectx.hfa" 18 18 #include "stdlib.hfa" 19 #include <ctype.h>20 19 21 20 // Workaround for observed performance penalty from calling CFA's alloc. … … 135 134 serr | nlOff; 136 135 serr | " lnth:" | lnth | " s:" | (void *)s | ",\""; 137 for ( i ; lnth) {136 for ( int i = 0; i < lnth; i += 1 ) { 138 137 serr | s[i]; 139 138 } // for … … 199 198 // Output operator 200 199 ofstream & ?|?(ofstream &out, const string_res &s) { 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; 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); 203 209 return out; 204 210 } 205 211 206 212 void ?|?(ofstream &out, const string_res &s) { 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 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 } 249 226 250 227 // Empty constructor … … 361 338 // adjust all substring string and handle locations, and check if any substring strings are outside the new base string 362 339 char *limit = resultSesStart + resultSesLnth; 363 for ( string_res * p = this.shareEditSet_next; p != &this; p = p->shareEditSet_next) {340 for (string_res * p = this.shareEditSet_next; p != &this; p = p->shareEditSet_next) { 364 341 verify (p->Handle.s >= beforeBegin); 365 342 if ( p->Handle.s >= afterBegin ) { … … 414 391 } 415 392 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; 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; 420 398 for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) { 421 399 if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) { … … 426 404 } 427 405 } 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 );435 406 436 407 verify( shareEditSetEndPeer->Handle.s >= shareEditSetStartPeer->Handle.s ); … … 618 589 619 590 bool contains(const string_res &s, char ch) { 620 for ( i; size(s)) {591 for (i; size(s)) { 621 592 if (s[i] == ch) return true; 622 593 } … … 672 643 } 673 644 674 for ( i; fromPos ~ s.Handle.lnth) {645 for (size_t i = fromPos; i < s.Handle.lnth; i++) { 675 646 size_t remaining = s.Handle.lnth - i; 676 647 // Never going to find the search string if the remaining string is … … 681 652 682 653 bool matched = true; 683 for ( j; searchsize) {654 for (size_t j = 0; j < searchsize; j++) { 684 655 if (search[j] != s.Handle.s[i + j]) { 685 656 matched = false; … … 769 740 770 741 int exclude(const string_res &s, const charclass_res &mask) { 771 for ( i; size(s)) {742 for (int i = 0; i < size(s); i++) { 772 743 if ( test(mask, s[i]) ) return i; 773 744 } … … 776 747 777 748 int include(const string_res &s, const charclass_res &mask) { 778 for ( i; size(s)) {749 for (int i = 0; i < size(s); i++) { 779 750 if ( ! test(mask, s[i]) ) return i; 780 751 } … … 804 775 for ( HandleNode *ni = HeaderPtr->flink; ni != HeaderPtr; ni = ni->flink ) { 805 776 serr | "\tnode:" | ni | " lnth:" | ni->lnth | " s:" | (void *)ni->s | ",\""; 806 for ( i ; ni->lnth) {777 for ( int i = 0; i < ni->lnth; i += 1 ) { 807 778 serr | ni->s[i]; 808 779 } // for … … 910 881 for ( HandleNode *n = HeaderPtr->flink; n != HeaderPtr; n = n->flink ) { 911 882 serr | "\tnode:" | n | " lnth:" | n->lnth | " s:" | (void *)n->s | ",\""; 912 for ( i ; n->lnth) {913 serr | n->s[i];883 for ( int i = 0; i < n->lnth; i += 1 ) { 884 serr | n->s[i]; 914 885 } // for 915 886 serr | "\" flink:" | n->flink | " blink:" | n->blink | nl; … … 989 960 EndVbyte = StartVbyte; 990 961 h = Header.flink; // ignore header node 991 for ( ) {962 for (;;) { 992 963 memmove( EndVbyte, h->s, h->lnth ); 993 964 obase = h->s; … … 1000 971 // check if any substrings are allocated within a string 1001 972 1002 for ( ) {973 for (;;) { 1003 974 if ( h == &Header ) break; // end of header list ? 1004 975 if ( h->s >= limit ) break; // outside of current string ? … … 1030 1001 serr | nlOff; 1031 1002 serr | "\tnode:" | n | " lnth:" | n->lnth | " s:" | (void *)n->s | ",\""; 1032 for ( i ; n->lnth) {1003 for ( int i = 0; i < n->lnth; i += 1 ) { 1033 1004 serr | n->s[i]; 1034 1005 } // for … … 1065 1036 serr | nlOff; 1066 1037 serr | "\tnode:" | n | " lnth:" | n->lnth | " s:" | (void *)n->s | ",\""; 1067 for ( i ; n->lnth) {1038 for ( int i = 0; i < n->lnth; i += 1 ) { 1068 1039 serr | n->s[i]; 1069 1040 } // for
Note:
See TracChangeset
for help on using the changeset viewer.