Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/containers/string_res.cfa

    rd32679d5 r7d25f44  
    1010// Created On       : Fri Sep 03 11:00:00 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug 12 15:37:47 2023
    13 // Update Count     : 10
     12// Last Modified On : Thu Jun 29 09:29:06 2023
     13// Update Count     : 2
    1414//
    1515
     
    1717#include "string_sharectx.hfa"
    1818#include "stdlib.hfa"
    19 #include <ctype.h>
    2019
    2120// Workaround for observed performance penalty from calling CFA's alloc.
     
    135134        serr | nlOff;
    136135        serr | " lnth:" | lnth | " s:" | (void *)s | ",\"";
    137         for ( i; lnth ) {
     136        for ( int i = 0; i < lnth; i += 1 ) {
    138137            serr | s[i];
    139138        } // for
     
    199198// Output operator
    200199ofstream & ?|?(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);
    203209    return out;
    204210}
    205211
    206212void ?|?(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}
    249226
    250227// Empty constructor
     
    361338    // adjust all substring string and handle locations, and check if any substring strings are outside the new base string
    362339    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) {
    364341        verify (p->Handle.s >= beforeBegin);
    365342        if ( p->Handle.s >= afterBegin ) {
     
    414391}
    415392
    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;
     393static 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;
    420398    for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) {
    421399        if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) {
     
    426404        }
    427405    }
    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 );
    435406
    436407    verify( shareEditSetEndPeer->Handle.s >= shareEditSetStartPeer->Handle.s );
     
    618589
    619590bool contains(const string_res &s, char ch) {
    620     for ( i; size(s) ) {
     591    for (i; size(s)) {
    621592        if (s[i] == ch) return true;
    622593    }
     
    672643    }
    673644
    674     for ( i; fromPos ~ s.Handle.lnth ) {
     645    for (size_t i = fromPos; i < s.Handle.lnth; i++) {
    675646        size_t remaining = s.Handle.lnth - i;
    676647        // Never going to find the search string if the remaining string is
     
    681652
    682653        bool matched = true;
    683         for ( j; searchsize ) {
     654        for (size_t j = 0; j < searchsize; j++) {
    684655            if (search[j] != s.Handle.s[i + j]) {
    685656                matched = false;
     
    769740
    770741int exclude(const string_res &s, const charclass_res &mask) {
    771     for ( i; size(s) ) {
     742    for (int i = 0; i < size(s); i++) {
    772743        if ( test(mask, s[i]) ) return i;
    773744    }
     
    776747
    777748int include(const string_res &s, const charclass_res &mask) {
    778     for ( i; size(s) ) {
     749    for (int i = 0; i < size(s); i++) {
    779750        if ( ! test(mask, s[i]) ) return i;
    780751    }
     
    804775                for ( HandleNode *ni = HeaderPtr->flink; ni != HeaderPtr; ni = ni->flink ) {
    805776                        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 ) {
    807778                                serr | ni->s[i];
    808779                        } // for
     
    910881        for ( HandleNode *n = HeaderPtr->flink; n != HeaderPtr; n = n->flink ) {
    911882            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];
    914885            } // for
    915886            serr | "\" flink:" | n->flink | " blink:" | n->blink | nl;
     
    989960    EndVbyte = StartVbyte;
    990961    h = Header.flink;                                   // ignore header node
    991     for () {
     962    for (;;) {
    992963                memmove( EndVbyte, h->s, h->lnth );
    993964                obase = h->s;
     
    1000971                // check if any substrings are allocated within a string
    1001972               
    1002                 for () {
     973                for (;;) {
    1003974                        if ( h == &Header ) break;                      // end of header list ?
    1004975                        if ( h->s >= limit ) break;                     // outside of current string ?
     
    10301001                        serr | nlOff;
    10311002                        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 ) {
    10331004                                serr | n->s[i];
    10341005                        } // for
     
    10651036                        serr | nlOff;
    10661037                        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 ) {
    10681039                                serr | n->s[i];
    10691040                        } // for
Note: See TracChangeset for help on using the changeset viewer.