Changeset f988834 for libcfa


Ignore:
Timestamp:
Jan 19, 2024, 2:44:41 AM (21 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
ac939461
Parents:
59c8dff (diff), e8b3717 (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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    r59c8dff rf988834  
    4848        math.trait.hfa \
    4949        math.hfa \
     50        raii.hfa \
    5051        time_t.hfa \
    5152        virtual_dtor.hfa \
  • libcfa/src/collections/array.hfa

    r59c8dff rf988834  
    131131
    132132    static inline void __taglen( tag(arpk(N, S, Timmed, Tbase)), tag(N) ) {}
    133 
    134     // workaround #226 (and array relevance thereof demonstrated in mike102/otype-slow-ndims.cfa)
    135     static inline void ?{}( arpk(N, S, Timmed, Tbase) & this ) {
    136         void ?{}( S (&inner)[N] ) {}
    137         ?{}(this.strides);
    138     }
    139     static inline void ^?{}( arpk(N, S, Timmed, Tbase) & this ) {
    140         void ^?{}( S (&inner)[N] ) {}
    141         ^?{}(this.strides);
     133}
     134
     135// RAII pattern has workarounds for
     136//  - Trac 226:  Simplest handling would be, require immediate element to be otype, let autogen
     137//    raii happen.  Performance on even a couple dimensions is unacceptable because of exponential
     138//    thunk creation: ?{}() needs all four otype funcs from next level, so does ^?{}(), so do the
     139//    other two.  This solution offers ?{}() that needs only ?{}(), and similar for ^?{}.
     140
     141forall( [N], S & | sized(S), Timmed &, Tbase & | { void ?{}( Timmed & ); } )
     142static inline void ?{}( arpk(N, S, Timmed, Tbase) & this ) {   
     143    void ?{}( S (&)[N] ) {}
     144    ?{}(this.strides);
     145
     146    for (i; N) ?{}( (Timmed &) this.strides[i] );
     147}
     148
     149forall( [N], S & | sized(S), Timmed &, Tbase & | { void ^?{}( Timmed & ); } )
     150static inline void ^?{}( arpk(N, S, Timmed, Tbase) & this ) {
     151    void ^?{}( S (&)[N] ) {}
     152    ^?{}(this.strides);
     153
     154    for (i; N ) {
     155        ^?{}( (Timmed &) this.strides[N-i-1] );
    142156    }
    143157}
     
    147161//
    148162
    149 forall( Te )
     163forall( Te * )
    150164static inline Te mkar_( tag(Te) ) {}
    151165
  • libcfa/src/collections/string.cfa

    r59c8dff rf988834  
    1010// Created On       : Fri Sep 03 11:00:00 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Oct 18 21:52:09 2023
    13 // Update Count     : 208
     12// Last Modified On : Sun Jan 14 12:03:47 2024
     13// Update Count     : 240
    1414//
    1515
     
    2929// string RAII
    3030
    31 
    32 void ?{}( string & this ) {
    33     (this.inner) { malloc() };
    34     ?{}( *this.inner );
    35 }
    36 
    3731// private (not in header)
    38 static void ?{}( string & this, string_res & src, size_t start, size_t end ) {
    39     (this.inner) { malloc() };
    40     ?{}( *this.inner, src, SHARE_EDITS, start, end );
    41 }
    42 
    43 void ?{}( string & this, const string & other ) {
    44     (this.inner) { malloc() };
    45     ?{}( *this.inner, *other.inner, COPY_VALUE );
    46 }
    47 
    48 void ?{}( string & this, string & other ) {
    49     ?{}( this, (const string &) other );
    50 }
    51 
    52 void ?{}( string & this, const char * val ) {
    53     (this.inner) { malloc() };
    54     ?{}( *this.inner, val );
    55 }
    56 
    57 void ?{}( string & this, const char * buffer, size_t bsize) {
    58     (this.inner) { malloc() };
    59     ?{}( *this.inner, buffer, bsize );
    60 }
    61 
    62 void ^?{}( string & this ) {
    63     ^(*this.inner){};
    64     free( this.inner );
    65     this.inner = 0p;
     32static void ?{}( string & s, string_res & src, size_t start, size_t len ) {
     33    (s.inner) { malloc() };
     34    ?{}( *s.inner, src, SHARE_EDITS, start, len );
     35}
     36
     37void ?{}( string & s ) {
     38    (s.inner) { malloc() };
     39    ?{}( *s.inner );
     40}
     41
     42void ?{}( string & s, const string & c ) {
     43    (s.inner) { malloc() };
     44    ?{}( *s.inner, *c.inner, COPY_VALUE );
     45}
     46
     47void ?{}( string & s, const string & s2, size_t maxlen) {
     48    (s.inner) { malloc() };
     49    ?{}( *s.inner, *s2.inner, COPY_VALUE, maxlen );
     50}
     51
     52
     53void ?{}( string & s, string & c ) {
     54    ?{}( s, (const string &) c );
     55}
     56
     57void ?{}( string & s, const char c ) {
     58    (s.inner) { malloc() };
     59    ?{}( *s.inner, c );
     60}
     61
     62void ?{}( string & s, const char * c ) {
     63    (s.inner) { malloc() };
     64    ?{}( *s.inner, c );
     65}
     66
     67void ?{}( string & s, const char * c, size_t size) {
     68    (s.inner) { malloc() };
     69    ?{}( *s.inner, c, size );
     70}
     71
     72void ^?{}( string & s ) {
     73    ^(*s.inner){};
     74    free( s.inner );
     75    s.inner = 0p;
    6676}
    6777
     
    6979// Alternate construction: request shared edits
    7080
    71 string_WithSharedEdits ?`shareEdits( string & this ) {
    72     string_WithSharedEdits ret = { &this };
    73     return ret;
    74 }
    75 
    76 void ?{}( string & this, string_WithSharedEdits src ) {
    77     ?{}( this, *src.s->inner, 0, src.s->inner->Handle.lnth);
     81string_WithSharedEdits ?`shareEdits( string & s ) {
     82    string_WithSharedEdits ret = { &s };
     83    return ret;
     84}
     85
     86void ?{}( string & s, string_WithSharedEdits src ) {
     87    ?{}( s, *src.s->inner, 0, src.s->inner->Handle.lnth);
    7888}
    7989
     
    8191// Assignment
    8292
    83 void ?=?( string & this, const char * val ) {
    84     (*this.inner) = val;
    85 }
    86 
    87 void ?=?(string & this, const string & other) {
    88     (*this.inner) = (*other.inner);
    89 }
    90 
    91 void ?=?( string & this, char val ) {
    92     (*this.inner) = val;
    93 }
    94 
    95 string & ?=?(string & this, string & other) { //// <---- straw man change
    96     (*this.inner) = (*other.inner);
    97     return this;
     93void ?=?( string & s, const char * val ) {
     94    (*s.inner) = val;
     95}
     96
     97// with and without const on "other" argument helps keep prevent autogen ?=? calls
     98void ?=?(string & s, const string & c) {
     99    (*s.inner) = (*c.inner);
     100}
     101string & ?=?(string & s, string & c) {
     102    (*s.inner) = (*c.inner);
     103    return s;
     104}
     105
     106void ?=?( string & s, char val ) {
     107    (*s.inner) = val;
     108}
     109
     110void assign(string & s, const string & c, size_t n) {
     111    assign(*s.inner, *c.inner, n);
     112}
     113void assign(string & s, const char * c, size_t n) {
     114    assign(*s.inner, c, n);
    98115}
    99116
     
    102119// Input-Output
    103120
    104 ofstream & ?|?( ofstream & out, const string & this ) {
    105     return out | (*this.inner); // print internal string_res
    106 }
    107 
    108 void ?|?( ofstream & out, const string & this ) {
    109     (ofstream &)(out | (*this.inner)); ends( out );
     121ofstream & ?|?( ofstream & out, const string & s ) {
     122    return out | (*s.inner); // print internal string_res
     123}
     124
     125void ?|?( ofstream & out, const string & s ) {
     126    (ofstream &)(out | (*s.inner)); ends( out );
    110127}
    111128
     
    124141}
    125142
    126 ifstream & ?|?(ifstream & in, string & this) {
    127     return in | (*this.inner); // read to internal string_res
    128 }
    129 
    130 void ?|?( ifstream & in, string & this ) {
    131     in | (*this.inner);
     143ifstream & ?|?(ifstream & in, string & s) {
     144    return in | (*s.inner); // read to internal string_res
     145}
     146
     147void ?|?( ifstream & in, string & s ) {
     148    in | (*s.inner);
    132149}
    133150
     
    144161// Slicing
    145162
    146 string ?()( string & this, size_t start, size_t end ) {
    147     string ret = { *this.inner, start, end };
     163string ?()( string & s, size_t start, size_t len ) {
     164    string ret = { *s.inner, start, len };
    148165    return ret`shareEdits;
    149166}
    150167
    151 string ?()( string & this, size_t start ) {
    152     string ret = { *this.inner, start, size( this ) };
     168string ?()( string & s, size_t start ) {
     169    string ret = { *s.inner, start, size( s ) - start };
    153170    return ret`shareEdits;
    154171}
     
    157174// Comparison
    158175
    159 int  cmp (const string &s1, const string &s2) { return cmp(*s1.inner , *s2.inner); }
    160 bool ?==?(const string &s1, const string &s2) { return     *s1.inner == *s2.inner ; }
    161 bool ?!=?(const string &s1, const string &s2) { return     *s1.inner != *s2.inner ; }
    162 bool ?>? (const string &s1, const string &s2) { return     *s1.inner >  *s2.inner ; }
    163 bool ?>=?(const string &s1, const string &s2) { return     *s1.inner >= *s2.inner ; }
    164 bool ?<=?(const string &s1, const string &s2) { return     *s1.inner <= *s2.inner ; }
    165 bool ?<? (const string &s1, const string &s2) { return     *s1.inner <  *s2.inner ; }
    166 
    167 int  cmp (const string &s1, const char*   s2) { return cmp(*s1.inner ,   s2      ); }
    168 bool ?==?(const string &s1, const char*   s2) { return     *s1.inner ==  s2       ; }
    169 bool ?!=?(const string &s1, const char*   s2) { return     *s1.inner !=  s2       ; }
    170 bool ?>? (const string &s1, const char*   s2) { return     *s1.inner >   s2       ; }
    171 bool ?>=?(const string &s1, const char*   s2) { return     *s1.inner >=  s2       ; }
    172 bool ?<=?(const string &s1, const char*   s2) { return     *s1.inner <=  s2       ; }
    173 bool ?<? (const string &s1, const char*   s2) { return     *s1.inner <   s2       ; }
    174 
    175 int  cmp (const char*   s1, const string &s2) { return cmp( s1       , *s2.inner); }
    176 bool ?==?(const char*   s1, const string &s2) { return      s1       == *s2.inner ; }
    177 bool ?!=?(const char*   s1, const string &s2) { return      s1       != *s2.inner ; }
    178 bool ?>? (const char*   s1, const string &s2) { return      s1       >  *s2.inner ; }
    179 bool ?>=?(const char*   s1, const string &s2) { return      s1       >= *s2.inner ; }
    180 bool ?<=?(const char*   s1, const string &s2) { return      s1       <= *s2.inner ; }
    181 bool ?<? (const char*   s1, const string &s2) { return      s1       <  *s2.inner ; }
     176int  strcmp(const string & s1, const string & s2) { return strcmp(*s1.inner, *s2.inner); }
     177bool ?==?(const string & s1, const string & s2) { return *s1.inner == *s2.inner; }
     178bool ?!=?(const string & s1, const string & s2) { return *s1.inner != *s2.inner; }
     179bool ?>? (const string & s1, const string & s2) { return *s1.inner >  *s2.inner; }
     180bool ?>=?(const string & s1, const string & s2) { return *s1.inner >= *s2.inner; }
     181bool ?<=?(const string & s1, const string & s2) { return *s1.inner <= *s2.inner; }
     182bool ?<? (const string & s1, const string & s2) { return *s1.inner <  *s2.inner; }
     183
     184int  strcmp(const string & s1, const char * s2) { return strcmp(*s1.inner, s2 ); }
     185bool ?==?(const string & s1, const char * s2) { return *s1.inner == s2; }
     186bool ?!=?(const string & s1, const char * s2) { return *s1.inner != s2; }
     187bool ?>? (const string & s1, const char * s2) { return *s1.inner >  s2; }
     188bool ?>=?(const string & s1, const char * s2) { return *s1.inner >= s2; }
     189bool ?<=?(const string & s1, const char * s2) { return *s1.inner <= s2; }
     190bool ?<? (const string & s1, const char * s2) { return *s1.inner <  s2; }
     191
     192int  strcmp(const char * s1, const string & s2) { return strcmp( s1, *s2.inner); }
     193bool ?==?(const char * s1, const string & s2) { return s1 == *s2.inner; }
     194bool ?!=?(const char * s1, const string & s2) { return s1 != *s2.inner; }
     195bool ?>? (const char * s1, const string & s2) { return s1 >  *s2.inner; }
     196bool ?>=?(const char * s1, const string & s2) { return s1 >= *s2.inner; }
     197bool ?<=?(const char * s1, const string & s2) { return s1 <= *s2.inner; }
     198bool ?<? (const char * s1, const string & s2) { return s1 <  *s2.inner; }
    182199
    183200
     
    186203
    187204size_t size(const string & s) {
    188     return size( * s.inner );
     205    return size( *s.inner );
    189206}
    190207
     
    192209// Concatenation
    193210
    194 void ?+=?(string & s, char other) {
    195     (*s.inner) += other;
     211void ?+=?(string & s, char c) {
     212    (*s.inner) += c;
    196213}
    197214
     
    200217}
    201218
    202 void ?+=?(string & s, const char * other) {
    203     (*s.inner) += other;
    204 }
    205 
    206 string ?+?(const string & s, char other) {
     219void append(string & s, const string & s2, size_t maxlen) {
     220    append( (*s.inner), (*s2.inner), maxlen );
     221}
     222
     223void ?+=?(string & s, const char * c) {
     224    (*s.inner) += c;
     225}
     226
     227void append(string & s, const char * buffer, size_t bsize) {
     228    append( (*s.inner), buffer, bsize );
     229}
     230
     231string ?+?(const string & s, char c) {
    207232    string ret = s;
    208     ret += other;
     233    ret += c;
    209234    return ret;
    210235}
     
    222247}
    223248
    224 string ?+?(const string & s, const char * other) {
     249string ?+?(const string & s, const char * c) {
    225250    string ret = s;
    226     ret += other;
     251    ret += c;
    227252    return ret;
    228253}
     
    231256// Repetition
    232257
     258void ?*=?(string & s, size_t factor) {
     259    (*s.inner) *= factor;
     260}
     261
    233262string ?*?(const string & s, size_t factor) {
    234     string ret = "";
    235     for (factor) ret += s;
    236     return ret;
    237 }
    238 
    239 string ?*?(char c, size_t size) {
    240     string ret = "";
    241     for ((size_t)size) ret += c;
    242     return ret;
    243 }
    244 
    245 string ?*?(const char *s, size_t factor) {
    246     string ss = s;
    247     return ss * factor;
     263    string ret = s;
     264    ret *= factor;
     265    return ret;
     266}
     267
     268string ?*?(char c, size_t factor) {
     269    string ret = c;
     270    ret *= factor;
     271    return ret;
     272}
     273
     274string ?*?(const char * s, size_t factor) {
     275    string ret = s;
     276    ret *= factor;
     277    return ret;
    248278}
    249279
     
    256286
    257287string ?[?](string & s, size_t index) {
    258     string ret = { *s.inner, index, index + 1 };
     288    string ret = { *s.inner, index, 1 };
    259289    return ret`shareEdits;
    260290}
     
    339369// charclass, include, exclude
    340370
    341 void ?{}( charclass & this, const string & chars) {
    342     (this.inner) { malloc() };
    343     ?{}( *this.inner, *(const string_res *)chars.inner );
    344 }
    345 
    346 void ?{}( charclass & this, const char * chars ) {
    347     (this.inner) { malloc() };
    348     ?{}( *this.inner, chars );
    349 }
    350 
    351 void ?{}( charclass & this, const char * chars, size_t charssize ) {
    352     (this.inner) { malloc() };
    353     ?{}( *this.inner, chars, charssize );
    354 }
    355 
    356 void ^?{}( charclass & this ) {
    357     ^(*this.inner){};
    358     free( this.inner );
    359     this.inner = 0p;
     371void ?{}( charclass & s, const string & chars) {
     372    (s.inner) { malloc() };
     373    ?{}( *s.inner, *(const string_res *)chars.inner );
     374}
     375
     376void ?{}( charclass & s, const char * chars ) {
     377    (s.inner) { malloc() };
     378    ?{}( *s.inner, chars );
     379}
     380
     381void ?{}( charclass & s, const char * chars, size_t charssize ) {
     382    (s.inner) { malloc() };
     383    ?{}( *s.inner, chars, charssize );
     384}
     385
     386void ^?{}( charclass & s ) {
     387    ^(*s.inner){};
     388    free( s.inner );
     389    s.inner = 0p;
    360390}
    361391
  • libcfa/src/collections/string.hfa

    r59c8dff rf988834  
    1010// Created On       : Fri Sep 03 11:00:00 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Sep  2 11:26:28 2023
    13 // Update Count     : 55
     12// Last Modified On : Sun Jan 14 12:03:46 2024
     13// Update Count     : 81
    1414//
    1515
     
    2929// Getters
    3030size_t size(const string & s);
     31static inline size_t strlen(const string & s) { return size( s ); }
    3132
    3233// RAII, assignment
    33 void ?{}(string & this); // empty string
    34 void ?{}(string & s, const char * initial); // copy from string literal (NULL-terminated)
    35 void ?{}(string & s, const char * buffer, size_t bsize); // copy specific length from buffer
    36 
     34void ?{}(string & s); // empty string
    3735void ?{}(string & s, const string & s2);
     36void ?{}(string & s, const string & s2, size_t maxlen);
    3837void ?{}(string & s, string & s2);
    3938
    40 void ?=?(string & s, const char * other); // copy assignment from literal
    41 void ?=?(string & s, const string & other);
    42 void ?=?(string & s, char other);
    43 string & ?=?(string & s, string & other);  // surprising ret seems to help avoid calls to autogen
     39void ?{}(string & s, char);
     40void ?{}(string & s, const char * c); // copy from string literal (NULL-terminated)
     41void ?{}(string & s, const char * c, size_t size); // copy specific length from buffer
     42
     43void ?=?(string & s, const char * c); // copy assignment from literal
     44void ?=?(string & s, const string & c);
     45void ?=?(string & s, char c);
     46string & ?=?(string & s, string & c);  // surprising ret seems to help avoid calls to autogen
     47void assign(string & s, const string & c, size_t n);
     48void assign(string & s, const char * c, size_t n);
    4449//string ?=?( string &, string ) = void;
     50
     51static inline string & strcpy(string & s, const char * c) { s = c; return s; }
     52static inline string & strncpy(string & s, const char * c, size_t n) { assign( s, c, n); return s; }
     53static inline string & strcpy(string & s, const string & c) { s = c; return s; }
     54static inline string & strncpy(string & s, const string & c, size_t n) { assign(s, c, n); return s; }
     55
    4556void ^?{}(string & s);
    4657
     
    4960    string * s;
    5061};
    51 string_WithSharedEdits ?`shareEdits( string & this );
    52 void ?{}( string & this, string_WithSharedEdits src );
     62string_WithSharedEdits ?`shareEdits( string & s );
     63void ?{}( string & s, string_WithSharedEdits src );
    5364
    5465// IO Operator
     
    5667void ?|?(ofstream & out, const string & s);
    5768ifstream & ?|?(ifstream & in, string & s);
    58 void ?|?( ifstream & in, string & this );
     69void ?|?( ifstream & in, string & s );
    5970
    6071static inline {
     
    8192        _Istream_Sstr wdi( unsigned int rwd, string & s ) { return (_Istream_Sstr)@{ s, {{0p}, rwd, {.flags.rwd : true}} }; }
    8293        _Istream_Sstr getline( string & s, const char delimiter = '\n' ) {
    83                 return (_Istream_Sstr)@{ s, {{.delimiter : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} };
     94                return (_Istream_Sstr)@{ s, {{.delimiters : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} };
    8495        }
    8596        _Istream_Sstr & getline( _Istream_Sstr & fmt, const char delimiter = '\n' ) {
    86                 fmt.delimiter[0] = delimiter; fmt.delimiter[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt;
     97                fmt.delimiters[0] = delimiter; fmt.delimiters[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt;
    8798        }
    8899        _Istream_Sstr incl( const char scanset[], string & s ) { return (_Istream_Sstr)@{ s, {{scanset}, -1, {.flags.inex : false}} }; }
     
    97108
    98109// Concatenation
    99 void ?+=?(string & s, char other); // append a character
     110void ?+=?(string & s, char c); // append a character
    100111void ?+=?(string & s, const string & s2); // append-concatenate to first string
    101 void ?+=?(string & s, const char * other); // append-concatenate to first string
    102 string ?+?(const string & s, char other); // add a character to a copy of the string
     112void append(string & s, const string & s2, size_t maxlen);  // append-concatenate to first string, up to maxlen
     113void ?+=?(string & s, const char * s2); // append-concatenate NULL-terminated string to first string
     114void append(string & s, const char * buffer, size_t bsize);  // append-concatenate given range to first string
     115
     116string ?+?(const string & s, char c); // add a character to a copy of the string
    103117string ?+?(const string & s, const string & s2); // copy and concatenate both strings
    104 string ?+?(const char * s1, const char * s2); // concatenate both strings
    105 string ?+?(const string & s, const char * other); // copy and concatenate with NULL-terminated string
     118string ?+?(const char * s1, const char * s2); // copy and concatenate both strings
     119string ?+?(const string & s, const char * c); // copy and concatenate with NULL-terminated string
     120
     121static inline string & strcat(string & s, const string & s2) { s += s2; return s; }
     122static inline string & strcat(string & s, const char * c) { s += c; return s; }
     123static inline string & strncat(string & s, const string & s2, size_t maxlen) { append(s, s2, maxlen); return s; }
     124static inline string & strncat(string & s, const char * buffer, size_t bsize) { append(s, buffer, bsize); return s; }
    106125
    107126// Repetition
    108127string ?*?(const string & s, size_t factor);
    109 string ?*?(char c, size_t size);
    110 string ?*?(const char *s, size_t size);
     128void ?*=?(string & s, size_t factor);
     129string ?*?(char c, size_t factor);
     130string ?*?(const char *s, size_t factor);
    111131
    112132// Character access
     
    116136
    117137// Comparisons
    118 int  cmp (const string &, const string &);
     138int  strcmp (const string &, const string &);
    119139bool ?==?(const string &, const string &);
    120140bool ?!=?(const string &, const string &);
     
    124144bool ?<? (const string &, const string &);
    125145
    126 int  cmp (const string &, const char*);
    127 bool ?==?(const string &, const char*);
    128 bool ?!=?(const string &, const char*);
    129 bool ?>? (const string &, const char*);
    130 bool ?>=?(const string &, const char*);
    131 bool ?<=?(const string &, const char*);
    132 bool ?<? (const string &, const char*);
    133 
    134 int  cmp (const char*, const string &);
    135 bool ?==?(const char*, const string &);
    136 bool ?!=?(const char*, const string &);
    137 bool ?>? (const char*, const string &);
    138 bool ?>=?(const char*, const string &);
    139 bool ?<=?(const char*, const string &);
    140 bool ?<? (const char*, const string &);
     146int  strcmp (const string &, const char *);
     147bool ?==?(const string &, const char *);
     148bool ?!=?(const string &, const char *);
     149bool ?>? (const string &, const char *);
     150bool ?>=?(const string &, const char *);
     151bool ?<=?(const string &, const char *);
     152bool ?<? (const string &, const char *);
     153
     154int  strcmp (const char *, const string &);
     155bool ?==?(const char *, const string &);
     156bool ?!=?(const char *, const string &);
     157bool ?>? (const char *, const string &);
     158bool ?>=?(const char *, const string &);
     159bool ?<=?(const char *, const string &);
     160bool ?<? (const char *, const string &);
    141161
    142162
    143163// Slicing
    144 string ?()( string & this, size_t start, size_t end );  // TODO const?
    145 string ?()( string & this, size_t start);
     164string ?()( string & s, size_t start, size_t len );  // TODO const?
     165string ?()( string & s, size_t start);
    146166
    147167// String search
     
    177197
    178198
    179 
    180199struct charclass {
    181200    charclass_res * inner;
  • libcfa/src/collections/string_res.cfa

    r59c8dff rf988834  
    1010// Created On       : Fri Sep 03 11:00:00 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Oct 18 21:54:54 2023
    13 // Update Count     : 15
     12// Last Modified On : Tue Jan 16 22:19:27 2024
     13// Update Count     : 35
    1414//
    1515
     
    2222// Workaround is:  EndVbyte = TEMP_ALLOC(char, CurrSize)
    2323// Should be:      EndVbyte = alloc(CurrSize)
    24 #define TEMP_ALLOC(T, n) (( T* ) malloc( n * sizeof( T ) ))
     24#define TEMP_ALLOC(T, n) (( T * ) malloc( n * sizeof( T ) ))
    2525
    2626#include <assert.h>
     
    3333
    3434struct VbyteHeap {
    35 
    36     int NoOfCompactions;                                // number of compactions of the byte area
    37     int NoOfExtensions;                                 // number of extensions in the size of the byte area
    38     int NoOfReductions;                                 // number of reductions in the size of the byte area
     35    int NoOfCompactions;                                                // number of compactions of the byte area
     36    int NoOfExtensions;                                                 // number of extensions in the size of the byte area
     37    int NoOfReductions;                                                 // number of reductions in the size of the byte area
    3938   
    40     int InitSize;                                       // initial number of bytes in the byte-string area
    41     int CurrSize;                                       // current number of bytes in the byte-string area
    42     char *StartVbyte;                                   // pointer to the `st byte of the start of the byte-string area
    43     char *EndVbyte;                                     // pointer to the next byte after the end of the currently used portion of byte-string area
    44     void *ExtVbyte;                                     // pointer to the next byte after the end of the byte-string area
    45 
    46     HandleNode Header;                                  // header node for handle list
     39    int InitSize;                                                               // initial number of bytes in the byte-string area
     40    int CurrSize;                                                               // current number of bytes in the byte-string area
     41    char *StartVbyte;                                                   // pointer to the `st byte of the start of the byte-string area
     42    char *EndVbyte;                                                             // pointer to the next byte after the end of the currently used portion of byte-string area
     43    void *ExtVbyte;                                                             // pointer to the next byte after the end of the byte-string area
     44
     45    HandleNode Header;                                                  // header node for handle list
    4746}; // VbyteHeap
    4847
    4948   
    50 static void compaction( VbyteHeap & );                          // compaction of the byte area
    51 static void garbage( VbyteHeap &, int );                                // garbage collect the byte area
     49static void compaction( VbyteHeap & );                  // compaction of the byte area
     50static void garbage( VbyteHeap &, int );                // garbage collect the byte area
    5251static void extend( VbyteHeap &, int );                 // extend the size of the byte area
    5352static void reduce( VbyteHeap &, int );                 // reduce the size of the byte area
     
    6766// Allocate the storage for the variable sized area and intialize the heap variables.
    6867
    69 static void ?{}( VbyteHeap & this, size_t Size ) with(this) {
    70 #ifdef VbyteDebug
    71     serr | "enter:VbyteHeap::VbyteHeap, this:" | &this | " Size:" | Size;
     68static void ?{}( VbyteHeap & s, size_t Size ) with(s) {
     69#ifdef VbyteDebug
     70    serr | "enter:VbyteHeap::VbyteHeap, s:" | &s | " Size:" | Size;
    7271#endif // VbyteDebug
    7372    NoOfCompactions = NoOfExtensions = NoOfReductions = 0;
     
    7675    ExtVbyte = (void *)( StartVbyte + CurrSize );
    7776    Header.flink = Header.blink = &Header;
    78     Header.ulink = & this;
     77    Header.ulink = &s;
    7978#ifdef VbyteDebug
    8079    HeaderPtr = &Header;
    81     serr | "exit:VbyteHeap::VbyteHeap, this:" | &this;
     80    serr | "exit:VbyteHeap::VbyteHeap, s:" | &s;
    8281#endif // VbyteDebug
    8382} // VbyteHeap
     
    8685// Release the dynamically allocated storage for the byte area.
    8786
    88 static void ^?{}( VbyteHeap & this ) with(this) {
     87static void ^?{}( VbyteHeap & s ) with(s) {
    8988    free( StartVbyte );
    9089} // ~VbyteHeap
     
    9796// creator.
    9897
    99 static void ?{}( HandleNode & this ) with(this) {
    100 #ifdef VbyteDebug
    101     serr | "enter:HandleNode::HandleNode, this:" | &this;
     98static void ?{}( HandleNode & s ) with(s) {
     99#ifdef VbyteDebug
     100    serr | "enter:HandleNode::HandleNode, s:" | &s;
    102101#endif // VbyteDebug
    103102    s = 0;
    104103    lnth = 0;
    105104#ifdef VbyteDebug
    106     serr | "exit:HandleNode::HandleNode, this:" | &this;
     105    serr | "exit:HandleNode::HandleNode, s:" | &s;
    107106#endif // VbyteDebug
    108107} // HandleNode
     
    112111// collection.
    113112
    114 static void ?{}( HandleNode & this, VbyteHeap & vh ) with(this) {
    115 #ifdef VbyteDebug
    116     serr | "enter:HandleNode::HandleNode, this:" | &this;
     113static void ?{}( HandleNode & s, VbyteHeap & vh ) with(s) {
     114#ifdef VbyteDebug
     115    serr | "enter:HandleNode::HandleNode, s:" | &s;
    117116#endif // VbyteDebug
    118117    s = 0;
    119118    lnth = 0;
    120119    ulink = &vh;
    121     AddThisAfter( this, *vh.Header.blink );
    122 #ifdef VbyteDebug
    123     serr | "exit:HandleNode::HandleNode, this:" | &this;
     120    AddThisAfter( s, *vh.Header.blink );
     121#ifdef VbyteDebug
     122    serr | "exit:HandleNode::HandleNode, s:" | &s;
    124123#endif // VbyteDebug
    125124} // HandleNode
     
    129128// is the responsibility of the creator to destroy it.
    130129
    131 static void ^?{}( HandleNode & this ) with(this) {
    132 #ifdef VbyteDebug
    133     serr | "enter:HandleNode::~HandleNode, this:" | & this;
     130static void ^?{}( HandleNode & s ) with(s) {
     131#ifdef VbyteDebug
     132    serr | "enter:HandleNode::~HandleNode, s:" | & s;
    134133    {
    135134        serr | nlOff;
     
    142141    }
    143142#endif // VbyteDebug
    144     DeleteNode( this );
     143    DeleteNode( s );
    145144} // ~HandleNode
    146145
     
    151150static string_sharectx default_string_sharectx = {NEW_SHARING}; // stable bottom of stack
    152151
    153 void ?{}( string_sharectx & this, StringSharectx_Mode mode ) with( this ) {
     152void ?{}( string_sharectx & s, StringSharectx_Mode mode ) with( s ) {
    154153    (older){ ambient_string_sharectx };
    155154    if ( mode == NEW_SHARING ) {
     
    159158        (activeHeap){ 0p };
    160159    }
    161     ambient_string_sharectx = & this;
    162 }
    163 
    164 void ^?{}( string_sharectx & this ) with( this ) {
     160    ambient_string_sharectx = & s;
     161}
     162
     163void ^?{}( string_sharectx & s ) with( s ) {
    165164    if ( activeHeap ) delete( activeHeap );
    166165
    167     // unlink this from older-list starting from ambient_string_sharectx
    168     // usually, this==ambient_string_sharectx and the loop runs zero times
     166    // unlink s from older-list starting from ambient_string_sharectx
     167    // usually, s==ambient_string_sharectx and the loop runs zero times
    169168    string_sharectx *& c = ambient_string_sharectx;
    170     while ( c != &this ) &c = &c->older;              // find this
    171     c = this.older;                                   // unlink
     169    while ( c != &s ) &c = &c->older;              // find s
     170    c = s.older;                                   // unlink
    172171}
    173172
     
    181180
    182181size_t DEBUG_string_bytes_avail_until_gc( VbyteHeap * heap ) {
    183     return ((char*)heap->ExtVbyte) - heap->EndVbyte;
     182    return ((char *)heap->ExtVbyte) - heap->EndVbyte;
    184183}
    185184
     
    193192
    194193// Returns the size of the string in bytes
    195 size_t size(const string_res &s) with(s) {
     194size_t size(const string_res & s) with(s) {
    196195    return Handle.lnth;
    197196}
    198197
    199198// Output operator
    200 ofstream & ?|?(ofstream &out, const string_res &s) {
     199ofstream & ?|?(ofstream & out, const string_res & s) {
    201200        // CFA string is NOT null terminated, so print exactly lnth characters in a minimum width of 0.
    202201        out | wd( 0, s.Handle.lnth, s.Handle.s ) | nonl;
     
    204203}
    205204
    206 void ?|?(ofstream &out, const string_res &s) {
     205void ?|?(ofstream & out, const string_res & s) {
    207206        (ofstream &)(out | s); ends( out );
    208207}
    209208
    210209// Input operator
    211 ifstream & ?|?(ifstream &in, string_res &s) {
    212 
     210ifstream & ?|?(ifstream & in, string_res & s) {
    213211    // Reading into a temp before assigning to s is near zero overhead in typical cases because of sharing.
    214212    // If s is a substring of something larger, simple assignment takes care of that case correctly.
     
    231229
    232230        // rest of heap is available to read into
    233         int lenReadable = (char*)temp.Handle.ulink->ExtVbyte - temp.Handle.ulink->EndVbyte;
     231        int lenReadable = (char *)temp.Handle.ulink->ExtVbyte - temp.Handle.ulink->EndVbyte;
    234232        assert (lenReadable >= 2);
    235233
     
    238236                        *(temp.Handle.ulink->EndVbyte) = '\0';   // pre-assign empty cstring
    239237            in | wdi( lenReadable, temp.Handle.ulink->EndVbyte );
    240         } catch (cstring_length*) {
     238        } catch (cstring_length *) {
    241239            cont = true;
    242240        }
     
    252250}
    253251
    254 void ?|?( ifstream & in, string_res & this ) {
    255     (ifstream &)(in | this);
     252void ?|?( ifstream & in, string_res & s ) {
     253    (ifstream &)(in | s);
    256254}
    257255
     
    274272                cont = true;
    275273        } finally {
    276                 if ( ! cf.flags.ignore &&                                               // ok to initialize string
    277                                 cstr[0] != '\0' ) {                                             // something was read
     274                if ( ! cf.flags.ignore                                                  // ok to initialize string
     275//                       &&     cstr[0] != '\0'                                                 // something was read
     276                        ) {
    278277                        *(f.s) = cstr;
    279278                }
     
    287286                        cont = true;                                                            // continue not allowed
    288287                } finally {
    289                         if ( ! cf.flags.ignore &&
    290                                         cstr[0] != '\0' ) {                                     // something was read
     288                        if ( ! cf.flags.ignore && cstr[0] != '\0' ) { // something was read
    291289                                *(f.s) += cstr;                                                 // build string chunk at a time
    292290                        }
     
    302300
    303301// Empty constructor
    304 void ?{}(string_res &s) with(s) {
     302void ?{}(string_res & s) with(s) {
    305303    if( ambient_string_sharectx->activeHeap ) {
    306304        (Handle){ * ambient_string_sharectx->activeHeap };
     
    317315}
    318316
    319 static void eagerCopyCtorHelper(string_res &s, const char* rhs, size_t rhslnth) with(s) {
     317static void eagerCopyCtorHelper(string_res & s, const char * rhs, size_t rhslnth) with(s) {
    320318    if( ambient_string_sharectx->activeHeap ) {
    321319        (Handle){ * ambient_string_sharectx->activeHeap };
     
    333331
    334332// Constructor from a raw buffer and size
    335 void ?{}(string_res &s, const char* rhs, size_t rhslnth) with(s) {
     333void ?{}(string_res & s, const char * rhs, size_t rhslnth) with(s) {
    336334    eagerCopyCtorHelper(s, rhs, rhslnth);
    337335}
    338336
    339337// private ctor (not in header): use specified heap (ignore ambient) and copy chars in
    340 void ?{}( string_res &s, VbyteHeap & heap, const char* rhs, size_t rhslnth ) with(s) {
     338void ?{}( string_res & s, VbyteHeap & heap, const char * rhs, size_t rhslnth ) with(s) {
    341339    (Handle){ heap };
    342340    Handle.s = VbyteAlloc(*Handle.ulink, rhslnth);
     
    348346}
    349347
     348
    350349// General copy constructor
    351 void ?{}(string_res &s, const string_res & s2, StrResInitMode mode, size_t start, size_t end ) {
    352 
     350void ?{}(string_res & s, const string_res & s2, StrResInitMode mode, size_t start, size_t len ) {
     351
     352    size_t end = start + len;
    353353    verify( start <= end && end <= s2.Handle.lnth );
    354354
     
    394394}
    395395
    396 static void assignEditSet(string_res & this, string_res * shareEditSetStartPeer, string_res * shareEditSetEndPeer,
     396static void assignEditSet(string_res & s, string_res * shareEditSetStartPeer, string_res * shareEditSetEndPeer,
    397397    char * resultSesStart,
    398398    size_t resultSesLnth,
     
    400400
    401401    char * beforeBegin = shareEditSetStartPeer->Handle.s;
    402     size_t beforeLen = this.Handle.s - beforeBegin;
    403 
    404     char * afterBegin = this.Handle.s + this.Handle.lnth;
     402    size_t beforeLen = s.Handle.s - beforeBegin;
     403
     404    char * afterBegin = s.Handle.s + s.Handle.lnth;
    405405    size_t afterLen = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - afterBegin;
    406406
    407     size_t oldLnth = this.Handle.lnth;
    408 
    409     this.Handle.s = resultSesStart + beforeLen;
    410     this.Handle.lnth = bsize;
     407    size_t oldLnth = s.Handle.lnth;
     408
     409    s.Handle.s = resultSesStart + beforeLen;
     410    s.Handle.lnth = bsize;
    411411    if (resultPadPosition)
    412         MoveThisAfter( this.Handle, *resultPadPosition );
     412        MoveThisAfter( s.Handle, *resultPadPosition );
    413413
    414414    // adjust all substring string and handle locations, and check if any substring strings are outside the new base string
    415415    char *limit = resultSesStart + resultSesLnth;
    416     for ( string_res * p = this.shareEditSet_next; p != &this; p = p->shareEditSet_next ) {
     416    for ( string_res * p = s.shareEditSet_next; p != &s; p = p->shareEditSet_next ) {
    417417        verify (p->Handle.s >= beforeBegin);
    418418        if ( p->Handle.s >= afterBegin ) {
     
    439439                // take end as end-anchored
    440440                // stretch-shrink p according to the edit
    441                 p->Handle.lnth += this.Handle.lnth;
     441                p->Handle.lnth += s.Handle.lnth;
    442442                p->Handle.lnth -= oldLnth;
    443443            }
     
    452452                // p ends during the edit; p does not include the last character replaced
    453453                // set p to empty string at start of edit
    454                 p->Handle.s = this.Handle.s;
     454                p->Handle.s = s.Handle.s;
    455455                p->Handle.lnth = 0;
    456456            } else {
     
    458458                // clip start of p to start at end of edit
    459459                int charsToClip = afterBegin - p->Handle.s;
    460                 p->Handle.s = this.Handle.s + this.Handle.lnth;
     460                p->Handle.s = s.Handle.s + s.Handle.lnth;
    461461                p->Handle.lnth -= charsToClip;
    462462            }
     
    467467}
    468468
    469 // traverse the share-edit set (SES) to recover the range of a base string to which `this` belongs
    470 static void locateInShareEditSet( string_res &this, string_res *&shareEditSetStartPeer, string_res *&shareEditSetEndPeer ) {
    471     shareEditSetStartPeer = & this;
    472     shareEditSetEndPeer = & this;
    473     for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) {
     469// traverse the share-edit set (SES) to recover the range of a base string to which `s` belongs
     470static void locateInShareEditSet( string_res & s, string_res *& shareEditSetStartPeer, string_res *& shareEditSetEndPeer ) {
     471    shareEditSetStartPeer = & s;
     472    shareEditSetEndPeer = & s;
     473    for (string_res * editPeer = s.shareEditSet_next; editPeer != &s; editPeer = editPeer->shareEditSet_next) {
    474474        if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) {
    475475            shareEditSetStartPeer = editPeer;
     
    481481}
    482482
    483 static string_res & assign_(string_res &this, const char* buffer, size_t bsize, const string_res & valSrc) {
     483static string_res & assign_(string_res & s, const char * buffer, size_t bsize, const string_res & valSrc) {
    484484
    485485    string_res * shareEditSetStartPeer;
    486486    string_res * shareEditSetEndPeer;
    487     locateInShareEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer );
     487    locateInShareEditSet( s, shareEditSetStartPeer, shareEditSetEndPeer );
    488488
    489489    verify( shareEditSetEndPeer->Handle.s >= shareEditSetStartPeer->Handle.s );
    490490    size_t origEditSetLength = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - shareEditSetStartPeer->Handle.s;
    491     verify( origEditSetLength >= this.Handle.lnth );
    492 
    493     if ( this.shareEditSet_owns_ulink ) {                 // assigning to private context
     491    verify( origEditSetLength >= s.Handle.lnth );
     492
     493    if ( s.shareEditSet_owns_ulink ) {                 // assigning to private context
    494494        // ok to overwrite old value within LHS
    495495        char * prefixStartOrig = shareEditSetStartPeer->Handle.s;
    496         int prefixLen = this.Handle.s - prefixStartOrig;
    497         char * suffixStartOrig = this.Handle.s + this.Handle.lnth;
     496        int prefixLen = s.Handle.s - prefixStartOrig;
     497        char * suffixStartOrig = s.Handle.s + s.Handle.lnth;
    498498        int suffixLen = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - suffixStartOrig;
    499499
    500         int delta = bsize - this.Handle.lnth;
    501         if ( char * oldBytes = VbyteTryAdjustLast( *this.Handle.ulink, delta ) ) {
     500        int delta = bsize - s.Handle.lnth;
     501        if ( char * oldBytes = VbyteTryAdjustLast( *s.Handle.ulink, delta ) ) {
    502502            // growing: copy from old to new
    503             char * dest = VbyteAlloc( *this.Handle.ulink, origEditSetLength + delta );
     503            char * dest = VbyteAlloc( *s.Handle.ulink, origEditSetLength + delta );
    504504            char *destCursor = dest;  memcpy(destCursor, prefixStartOrig, prefixLen);
    505505            destCursor += prefixLen;  memcpy(destCursor, buffer         , bsize    );
    506506            destCursor += bsize;      memcpy(destCursor, suffixStartOrig, suffixLen);
    507             assignEditSet(this, shareEditSetStartPeer, shareEditSetEndPeer,
     507            assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer,
    508508                dest,
    509509                origEditSetLength + delta,
     
    513513            // room is already allocated in-place: bubble suffix and overwite middle
    514514            memmove( suffixStartOrig + delta, suffixStartOrig, suffixLen );
    515             memcpy( this.Handle.s, buffer, bsize );
    516 
    517             assignEditSet(this, shareEditSetStartPeer, shareEditSetEndPeer,
     515            memcpy( s.Handle.s, buffer, bsize );
     516
     517            assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer,
    518518                shareEditSetStartPeer->Handle.s,
    519519                origEditSetLength + delta,
     
    522522
    523523    } else if (                                           // assigning to shared context
    524         this.Handle.lnth == origEditSetLength &&          // overwriting entire run of SES
     524        s.Handle.lnth == origEditSetLength &&          // overwriting entire run of SES
    525525        & valSrc &&                                       // sourcing from a managed string
    526         valSrc.Handle.ulink == this.Handle.ulink  ) {     // sourcing from same heap
     526        valSrc.Handle.ulink == s.Handle.ulink  ) {     // sourcing from same heap
    527527
    528528        // SES's result will only use characters from the source string => reuse source
    529         assignEditSet(this, shareEditSetStartPeer, shareEditSetEndPeer,
     529        assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer,
    530530            valSrc.Handle.s,
    531531            valSrc.Handle.lnth,
     
    537537
    538538        // full string is from start of shareEditSetStartPeer thru end of shareEditSetEndPeer
    539         // `this` occurs in the middle of it, to be replaced
     539        // `s` occurs in the middle of it, to be replaced
    540540        // build up the new text in `pasting`
    541541
    542542        string_res pasting = {
    543             * this.Handle.ulink,                               // maintain same heap, regardless of context
     543            * s.Handle.ulink,                               // maintain same heap, regardless of context
    544544            shareEditSetStartPeer->Handle.s,                   // start of SES
    545             this.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before this
     545            s.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before s
    546546        append( pasting,
    547             buffer,                                            // start of replacement for this
    548             bsize );                                           // length of replacement for this
     547            buffer,                                            // start of replacement for s
     548            bsize );                                           // length of replacement for s
    549549        append( pasting,
    550             this.Handle.s + this.Handle.lnth,                  // start of SES after this
     550            s.Handle.s + s.Handle.lnth,                  // start of SES after s
    551551            shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth -
    552             (this.Handle.s + this.Handle.lnth) );              // length of SES, after this
     552            (s.Handle.s + s.Handle.lnth) );              // length of SES, after s
    553553
    554554        // The above string building can trigger compaction.
    555555        // The reference points (that are arguments of the string building) may move during that building.
    556         // From this point on, they are stable.
    557 
    558         assignEditSet(this, shareEditSetStartPeer, shareEditSetEndPeer,
     556        // From s point on, they are stable.
     557
     558        assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer,
    559559            pasting.Handle.s,
    560560            pasting.Handle.lnth,
     
    562562    }
    563563
    564     return this;
    565 }
    566 
    567 string_res & assign(string_res &this, const char* buffer, size_t bsize) {
    568     return assign_(this, buffer, bsize, *0p);
    569 }
    570 
    571 string_res & ?=?(string_res &s, char other) {
    572     return assign(s, &other, 1);
     564    return s;
     565}
     566
     567string_res & assign(string_res & s, const string_res & src, size_t maxlen) {
     568    return assign_(s, src.Handle.s, min(src.Handle.lnth, maxlen), *0p);
     569}
     570
     571string_res & assign(string_res & s, const char * buffer, size_t bsize) {
     572    return assign_(s, buffer, bsize, *0p);
     573}
     574
     575string_res & ?=?(string_res & s, char c) {
     576    return assign(s, &c, 1);
    573577}
    574578
    575579// Copy assignment operator
    576 string_res & ?=?(string_res & this, const string_res & rhs) with( this ) {
    577     return assign_(this, rhs.Handle.s, rhs.Handle.lnth, rhs);
    578 }
    579 
    580 string_res & ?=?(string_res & this, string_res & rhs) with( this ) {
     580string_res & ?=?(string_res & s, const string_res & rhs) with( s ) {
     581    return assign_(s, rhs.Handle.s, rhs.Handle.lnth, rhs);
     582}
     583
     584string_res & ?=?(string_res & s, string_res & rhs) with( s ) {
    581585    const string_res & rhs2 = rhs;
    582     return this = rhs2;
     586    return s = rhs2;
    583587}
    584588
    585589
    586590// Destructor
    587 void ^?{}(string_res &s) with(s) {
     591void ^?{}(string_res & s) with(s) {
    588592    // much delegated to implied ^VbyteSM
    589593
     
    603607// With unicode support, this may be different from just the byte at the given
    604608// offset from the start of the string.
    605 char ?[?](const string_res &s, size_t index) with(s) {
     609char ?[?](const string_res & s, size_t index) with(s) {
    606610    //TODO: Check if index is valid (no exceptions yet)
    607611    return Handle.s[index];
    608612}
    609613
    610 void assignAt(const string_res &s, size_t index, char val) {
    611     string_res editZone = { s, SHARE_EDITS, index, index+1 };
     614void assignAt(const string_res & s, size_t index, char val) {
     615    // caution: not tested (not reachable by string-api-coverage interface)
     616    // equivalent form at string level is `s[index] = val`,
     617    // which uses the overload that returns a length-1 string
     618    string_res editZone = { s, SHARE_EDITS, index, 1 };
    612619    assign(editZone, &val, 1);
    613620}
     
    617624// Concatenation
    618625
    619 void append(string_res &str1, const char * buffer, size_t bsize) {
     626void append(string_res & str1, const char * buffer, size_t bsize) {
    620627    size_t clnth = str1.Handle.lnth + bsize;
    621628    if ( str1.Handle.s + str1.Handle.lnth == buffer ) { // already juxtapose ?
     
    635642}
    636643
    637 void ?+=?(string_res &str1, const string_res &str2) {
     644void ?+=?(string_res & str1, const string_res & str2) {
    638645    append( str1, str2.Handle.s, str2.Handle.lnth );
    639646}
    640647
    641 void ?+=?(string_res &s, char other) {
    642     append( s, &other, 1 );
    643 }
    644 
    645 
    646 
    647 
     648void append(string_res & str1, const string_res & str2, size_t maxlen) {
     649    append( str1, str2.Handle.s, min(str2.Handle.lnth, maxlen) );
     650}
     651
     652void ?+=?(string_res & s, char c) {
     653    append( s, & c, 1 );
     654}
     655void ?+=?(string_res & s, const char * c) {
     656    append( s, c, strlen(c) );
     657}
     658
     659///////////////////////////////////////////////////////////////////
     660// Repetition
     661
     662void ?*=?(string_res & s, size_t factor) {
     663    string_res s2 = { s, COPY_VALUE };
     664    s = "";
     665    for (factor) s += s2;
     666}
    648667
    649668//////////////////////////////////////////////////////////
    650669// Comparisons
    651670
    652 int cmp(const string_res &s1, const string_res &s2) {
     671int strcmp(const string_res & s1, const string_res & s2) {
    653672    // return 0;
    654673    int ans1 = memcmp(s1.Handle.s, s2.Handle.s, min(s1.Handle.lnth, s2.Handle.lnth));
     
    657676}
    658677
    659 bool ?==?(const string_res &s1, const string_res &s2) { return cmp(s1, s2) == 0; }
    660 bool ?!=?(const string_res &s1, const string_res &s2) { return cmp(s1, s2) != 0; }
    661 bool ?>? (const string_res &s1, const string_res &s2) { return cmp(s1, s2) >  0; }
    662 bool ?>=?(const string_res &s1, const string_res &s2) { return cmp(s1, s2) >= 0; }
    663 bool ?<=?(const string_res &s1, const string_res &s2) { return cmp(s1, s2) <= 0; }
    664 bool ?<? (const string_res &s1, const string_res &s2) { return cmp(s1, s2) <  0; }
    665 
    666 int cmp (const string_res &s1, const char* s2) {
     678bool ?==?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) == 0; }
     679bool ?!=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) != 0; }
     680bool ?>? (const string_res & s1, const string_res & s2) { return strcmp(s1, s2) >  0; }
     681bool ?>=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) >= 0; }
     682bool ?<=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) <= 0; }
     683bool ?<? (const string_res & s1, const string_res & s2) { return strcmp(s1, s2) <  0; }
     684
     685int strcmp (const string_res & s1, const char * s2) {
    667686    string_res s2x = s2;
    668     return cmp(s1, s2x);
    669 }
    670 
    671 bool ?==?(const string_res &s1, const char* s2) { return cmp(s1, s2) == 0; }
    672 bool ?!=?(const string_res &s1, const char* s2) { return cmp(s1, s2) != 0; }
    673 bool ?>? (const string_res &s1, const char* s2) { return cmp(s1, s2) >  0; }
    674 bool ?>=?(const string_res &s1, const char* s2) { return cmp(s1, s2) >= 0; }
    675 bool ?<=?(const string_res &s1, const char* s2) { return cmp(s1, s2) <= 0; }
    676 bool ?<? (const string_res &s1, const char* s2) { return cmp(s1, s2) <  0; }
    677 
    678 int cmp (const char* s1, const string_res & s2) {
     687    return strcmp(s1, s2x);
     688}
     689
     690bool ?==?(const string_res & s1, const char * s2) { return strcmp(s1, s2) == 0; }
     691bool ?!=?(const string_res & s1, const char * s2) { return strcmp(s1, s2) != 0; }
     692bool ?>? (const string_res & s1, const char * s2) { return strcmp(s1, s2) >  0; }
     693bool ?>=?(const string_res & s1, const char * s2) { return strcmp(s1, s2) >= 0; }
     694bool ?<=?(const string_res & s1, const char * s2) { return strcmp(s1, s2) <= 0; }
     695bool ?<? (const string_res & s1, const char * s2) { return strcmp(s1, s2) <  0; }
     696
     697int strcmp (const char * s1, const string_res & s2) {
    679698    string_res s1x = s1;
    680     return cmp(s1x, s2);
    681 }
    682 
    683 bool ?==?(const char* s1, const string_res &s2) { return cmp(s1, s2) == 0; }
    684 bool ?!=?(const char* s1, const string_res &s2) { return cmp(s1, s2) != 0; }
    685 bool ?>? (const char* s1, const string_res &s2) { return cmp(s1, s2) >  0; }
    686 bool ?>=?(const char* s1, const string_res &s2) { return cmp(s1, s2) >= 0; }
    687 bool ?<=?(const char* s1, const string_res &s2) { return cmp(s1, s2) <= 0; }
    688 bool ?<? (const char* s1, const string_res &s2) { return cmp(s1, s2) <  0; }
     699    return strcmp(s1x, s2);
     700}
     701
     702bool ?==?(const char * s1, const string_res & s2) { return strcmp(s1, s2) == 0; }
     703bool ?!=?(const char * s1, const string_res & s2) { return strcmp(s1, s2) != 0; }
     704bool ?>? (const char * s1, const string_res & s2) { return strcmp(s1, s2) >  0; }
     705bool ?>=?(const char * s1, const string_res & s2) { return strcmp(s1, s2) >= 0; }
     706bool ?<=?(const char * s1, const string_res & s2) { return strcmp(s1, s2) <= 0; }
     707bool ?<? (const char * s1, const string_res & s2) { return strcmp(s1, s2) <  0; }
    689708
    690709
     
    693712// Search
    694713
    695 bool contains(const string_res &s, char ch) {
     714bool contains(const string_res & s, char ch) {
    696715    for ( i; size(s) ) {
    697716        if (s[i] == ch) return true;
     
    700719}
    701720
    702 int find(const string_res &s, char search) {
     721int find(const string_res & s, char search) {
    703722    return findFrom(s, 0, search);
    704723}
    705724
    706 int findFrom(const string_res &s, size_t fromPos, char search) {
     725int findFrom(const string_res & s, size_t fromPos, char search) {
    707726    // FIXME: This paricular overload (find of single char) is optimized to use memchr.
    708727    // The general overload (find of string, memchr applying to its first character) and `contains` should be adjusted to match.
     
    715734}
    716735
    717 int find(const string_res &s, const string_res &search) {
     736int find(const string_res & s, const string_res & search) {
    718737    return findFrom(s, 0, search);
    719738}
    720739
    721 int findFrom(const string_res &s, size_t fromPos, const string_res &search) {
     740int findFrom(const string_res & s, size_t fromPos, const string_res & search) {
    722741    return findFrom(s, fromPos, search.Handle.s, search.Handle.lnth);
    723742}
    724743
    725 int find(const string_res &s, const char* search) {
     744int find(const string_res & s, const char * search) {
    726745    return findFrom(s, 0, search);
    727746}
    728 int findFrom(const string_res &s, size_t fromPos, const char* search) {
     747int findFrom(const string_res & s, size_t fromPos, const char * search) {
    729748    return findFrom(s, fromPos, search, strlen(search));
    730749}
    731750
    732 int find(const string_res &s, const char* search, size_t searchsize) {
     751int find(const string_res & s, const char * search, size_t searchsize) {
    733752    return findFrom(s, 0, search, searchsize);
    734753}
    735754
    736 int findFrom(const string_res &s, size_t fromPos, const char* search, size_t searchsize) {
     755int findFrom(const string_res & s, size_t fromPos, const char * search, size_t searchsize) {
    737756
    738757    /* Remaining implementations essentially ported from Sunjay's work */
     
    771790}
    772791
    773 bool includes(const string_res &s, const string_res &search) {
     792bool includes(const string_res & s, const string_res & search) {
    774793    return includes(s, search.Handle.s, search.Handle.lnth);
    775794}
    776795
    777 bool includes(const string_res &s, const char* search) {
     796bool includes(const string_res & s, const char * search) {
    778797    return includes(s, search, strlen(search));
    779798}
    780799
    781 bool includes(const string_res &s, const char* search, size_t searchsize) {
     800bool includes(const string_res & s, const char * search, size_t searchsize) {
    782801    return find(s, search, searchsize) < s.Handle.lnth;
    783802}
    784803
    785 bool startsWith(const string_res &s, const string_res &prefix) {
     804bool startsWith(const string_res & s, const string_res & prefix) {
    786805    return startsWith(s, prefix.Handle.s, prefix.Handle.lnth);
    787806}
    788807
    789 bool startsWith(const string_res &s, const char* prefix) {
     808bool startsWith(const string_res & s, const char * prefix) {
    790809    return startsWith(s, prefix, strlen(prefix));
    791810}
    792811
    793 bool startsWith(const string_res &s, const char* prefix, size_t prefixsize) {
     812bool startsWith(const string_res & s, const char * prefix, size_t prefixsize) {
    794813    if (s.Handle.lnth < prefixsize) {
    795814        return false;
     
    798817}
    799818
    800 bool endsWith(const string_res &s, const string_res &suffix) {
     819bool endsWith(const string_res & s, const string_res & suffix) {
    801820    return endsWith(s, suffix.Handle.s, suffix.Handle.lnth);
    802821}
    803822
    804 bool endsWith(const string_res &s, const char* suffix) {
     823bool endsWith(const string_res & s, const char * suffix) {
    805824    return endsWith(s, suffix, strlen(suffix));
    806825}
    807826
    808 bool endsWith(const string_res &s, const char* suffix, size_t suffixsize) {
     827bool endsWith(const string_res & s, const char * suffix, size_t suffixsize) {
    809828    if (s.Handle.lnth < suffixsize) {
    810829        return false;
     
    822841// charclass, include, exclude
    823842
    824 void ?{}( charclass_res & this, const string_res & chars) {
    825     (this){ chars.Handle.s, chars.Handle.lnth };
    826 }
    827 
    828 void ?{}( charclass_res & this, const char * chars ) {
    829     (this){ chars, strlen(chars) };
    830 }
    831 
    832 void ?{}( charclass_res & this, const char * chars, size_t charssize ) {
    833     (this.chars){ chars, charssize };
     843void ?{}( charclass_res & s, const string_res & chars) {
     844    (s){ chars.Handle.s, chars.Handle.lnth };
     845}
     846
     847void ?{}( charclass_res & s, const char * chars ) {
     848    (s){ chars, strlen(chars) };
     849}
     850
     851void ?{}( charclass_res & s, const char * chars, size_t charssize ) {
     852    (s.chars){ chars, charssize };
    834853    // now sort it ?
    835854}
    836855
    837 void ^?{}( charclass_res & this ) {
    838     ^(this.chars){};
     856void ^?{}( charclass_res & s ) {
     857    ^(s.chars){};
    839858}
    840859
     
    844863}
    845864
    846 int exclude(const string_res &s, const charclass_res &mask) {
     865int exclude(const string_res & s, const charclass_res & mask) {
    847866    for ( i; size(s) ) {
    848867        if ( test(mask, s[i]) ) return i;
     
    851870}
    852871
    853 int include(const string_res &s, const charclass_res &mask) {
     872int include(const string_res & s, const charclass_res & mask) {
    854873    for ( i; size(s) ) {
    855874        if ( ! test(mask, s[i]) ) return i;
     
    863882// Add a new HandleNode node n after the current HandleNode node.
    864883
    865 static void AddThisAfter( HandleNode & this, HandleNode & n ) with(this) {
    866 #ifdef VbyteDebug
    867     serr | "enter:AddThisAfter, this:" | &this | " n:" | &n;
     884static void AddThisAfter( HandleNode & s, HandleNode & n ) with(s) {
     885#ifdef VbyteDebug
     886    serr | "enter:AddThisAfter, s:" | &s | " n:" | &n;
    868887#endif // VbyteDebug
    869888    // Performance note: we are on the critical path here. MB has ensured that the verifies don't contribute to runtime (are compiled away, like they're supposed to be).
    870889    verify( n.ulink != 0p );
    871     verify( this.ulink == n.ulink );
     890    verify( s.ulink == n.ulink );
    872891    flink = n.flink;
    873892    blink = &n;
    874     n.flink->blink = &this;
    875     n.flink = &this;
     893    n.flink->blink = &s;
     894    n.flink = &s;
    876895#ifdef VbyteDebug
    877896    {
     
    894913// Delete the current HandleNode node.
    895914
    896 static void DeleteNode( HandleNode & this ) with(this) {
    897 #ifdef VbyteDebug
    898     serr | "enter:DeleteNode, this:" | &this;
     915static void DeleteNode( HandleNode & s ) with(s) {
     916#ifdef VbyteDebug
     917    serr | "enter:DeleteNode, s:" | &s;
    899918#endif // VbyteDebug
    900919    flink->blink = blink;
     
    906925
    907926
    908 
    909927// Allocates specified storage for a string from byte-string area. If not enough space remains to perform the
    910928// allocation, the garbage collection routine is called.
    911929
    912 static char * VbyteAlloc( VbyteHeap & this, int size ) with(this) {
     930static char * VbyteAlloc( VbyteHeap & s, int size ) with(s) {
    913931#ifdef VbyteDebug
    914932    serr | "enter:VbyteAlloc, size:" | size;
     
    918936
    919937    NoBytes = ( uintptr_t )EndVbyte + size;
    920     if ( NoBytes > ( uintptr_t )ExtVbyte ) {            // enough room for new byte-string ?
    921                 garbage( this, size );                                  // firer up the garbage collector
     938    if ( NoBytes > ( uintptr_t )ExtVbyte ) {                    // enough room for new byte-string ?
     939                garbage( s, size );                                                             // firer up the garbage collector
    922940                verify( (( uintptr_t )EndVbyte + size) <= ( uintptr_t )ExtVbyte  && "garbage run did not free up required space" );
    923941    } // if
     
    939957// VbyteAlloc to claim the new space, while doing optimal copying from old to new, then free old.
    940958
    941 static char * VbyteTryAdjustLast( VbyteHeap & this, int delta ) with(this) {
    942 
     959static char * VbyteTryAdjustLast( VbyteHeap & s, int delta ) with(s) {
    943960    if ( ( uintptr_t )EndVbyte + delta <= ( uintptr_t )ExtVbyte ) {
    944961        // room available
     
    961978// the address in the byte string area.
    962979
    963 static void MoveThisAfter( HandleNode & this, const HandleNode  & h ) with(this) {
    964 #ifdef VbyteDebug
    965     serr | "enter:MoveThisAfter, this:" | & this | " h:" | & h;
     980static void MoveThisAfter( HandleNode & s, const HandleNode  & h ) with(s) {
     981#ifdef VbyteDebug
     982    serr | "enter:MoveThisAfter, s:" | & s | " h:" | & h;
    966983#endif // VbyteDebug
    967984    verify( h.ulink != 0p );
    968     verify( this.ulink == h.ulink );
     985    verify( s.ulink == h.ulink );
    969986    if ( s < h.s ) {                                    // check argument values
    970987                // serr | "VbyteSM: Error - Cannot move byte string starting at:" | s | " after byte string starting at:"
     
    976993    HandleNode *i;
    977994    for ( i = h.flink; i->s != 0 && s > ( i->s ); i = i->flink ); // find the position for this node after h
    978     if ( & this != i->blink ) {
    979                 DeleteNode( this );
    980                 AddThisAfter( this, *i->blink );
     995    if ( & s != i->blink ) {
     996                DeleteNode( s );
     997                AddThisAfter( s, *i->blink );
    981998    } // if
    982999#ifdef VbyteDebug
     
    10581075// the containing string has been moved. Hence, they only require that their string pointers be adjusted.
    10591076
    1060 void compaction(VbyteHeap & this) with(this) {
     1077void compaction(VbyteHeap & s) with(s) {
    10611078    HandleNode *h;
    10621079    char *obase, *nbase, *limit;
     
    10981115// the heap.  The heap is then compacted in the existing heap or into the newly allocated heap.
    10991116
    1100 void garbage(VbyteHeap & this, int minreq ) with(this) {
     1117void garbage(VbyteHeap & s, int minreq ) with(s) {
    11011118#ifdef VbyteDebug
    11021119    serr | "enter:garbage";
     
    11241141    if ( ( double ) AmountFree < ( CurrSize * heap_expansion_freespace_threshold ) || AmountFree < minreq ) {   // free space less than threshold or not enough to serve cur request
    11251142
    1126                 extend( this, max( CurrSize, minreq ) );                                // extend the heap
     1143                extend( s, max( CurrSize, minreq ) );                           // extend the heap
    11271144
    11281145                        //  Peter says, "This needs work before it should be used."
     
    11331150
    11341151    } else {
    1135         compaction(this);                                       // in-place
     1152        compaction(s);                                  // in-place
    11361153    }// if
    11371154#ifdef VbyteDebug
     
    11591176// area is deleted.
    11601177
    1161 void extend( VbyteHeap & this, int size ) with (this) {
     1178void extend( VbyteHeap & s, int size ) with (s) {
    11621179#ifdef VbyteDebug
    11631180    serr | "enter:extend, size:" | size;
     
    11711188    StartVbyte = EndVbyte = TEMP_ALLOC(char, CurrSize);
    11721189    ExtVbyte = (void *)( StartVbyte + CurrSize );
    1173     compaction(this);                                   // copy from old heap to new & adjust pointers to new heap
     1190    compaction(s);                                      // copy from old heap to new & adjust pointers to new heap
    11741191    free( OldStartVbyte );                              // release old heap
    11751192#ifdef VbyteDebug
  • libcfa/src/collections/string_res.hfa

    r59c8dff rf988834  
    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:45:47 2023
    13 // Update Count     : 2
     12// Last Modified On : Thu Jan  4 11:28:06 2024
     13// Update Count     : 27
    1414//
    1515
     
    7070
    7171// Getters
    72 size_t size(const string_res &s);
     72size_t size(const string_res & s);
    7373
    7474// Constructors, Assignment Operators, Destructor
    75 void ?{}(string_res &s); // empty string
    76 void ?{}(string_res &s, const char* buffer, size_t bsize); // copy specific length from buffer
    77 static inline void ?{}(string_res &s, const char* rhs) { // copy from string literal (NULL-terminated)
     75void ?{}(string_res & s); // empty string
     76void ?{}(string_res & s, const char * buffer, size_t bsize); // copy specific length from buffer
     77static inline void ?{}(string_res & s, const char * rhs) { // copy from string literal (NULL-terminated)
    7878    (s){ rhs, strlen(rhs) };
    7979}
    80 
    81 void ?{}(string_res &s, const string_res & s2) = void;
    82 void ?{}(string_res &s, string_res & s2) = void;
     80static inline void ?{}(string_res & s, char c ) {
     81    ?{}( s, &c, 1);
     82}
     83
     84// Deleting the copy constructors makes the compiler reject an attempt to call/return by value
     85void ?{}(string_res & s, const string_res & s2) = void;
     86void ?{}(string_res & s, string_res & s2) = void;
    8387
    8488enum StrResInitMode { COPY_VALUE, SHARE_EDITS };
    85 void ?{}(string_res &s, const string_res & src, StrResInitMode, size_t start, size_t end );
    86 static inline void ?{}(string_res &s, const string_res & src, StrResInitMode mode ) {
     89void ?{}(string_res & s, const string_res & src, StrResInitMode, size_t start, size_t len );
     90static inline void ?{}(string_res & s, const string_res & src, StrResInitMode mode ) {
    8791    ?{}( s, src, mode, 0, size(src));
    8892}
    89 
    90 string_res & assign(string_res &s, const char* buffer, size_t bsize); // copy specific length from buffer
    91 static inline string_res & ?=?(string_res &s, const char* other) {  // copy from string literal (NULL-terminated)
    92     return assign(s, other, strlen(other));
    93 }
    94 string_res & ?=?(string_res &s, const string_res &other);
    95 string_res & ?=?(string_res &s, string_res &other);
    96 string_res & ?=?(string_res &s, char other);
    97 
    98 void ^?{}(string_res &s);
     93static inline void ?{}(string_res & s, const string_res & src, StrResInitMode mode, size_t maxlen ) {
     94    ?{}( s, src, mode, 0, (size(src) > maxlen)?maxlen:size(src) );
     95}
     96
     97string_res & assign(string_res & s, const string_res & src, size_t maxlen); // copy specific length from other string
     98string_res & assign(string_res & s, const char * buffer, size_t bsize); // copy specific length from buffer
     99static inline string_res & ?=?(string_res & s, const char * c) {  // copy from string literal (NULL-terminated)
     100    return assign(s, c, strlen(c));
     101}
     102string_res & ?=?(string_res & s, const string_res & c);
     103string_res & ?=?(string_res & s, string_res & c);
     104string_res & ?=?(string_res & s, char c);
     105
     106void ^?{}(string_res & s);
    99107
    100108// IO Operator
    101 ofstream & ?|?(ofstream &out, const string_res &s);
    102 void ?|?(ofstream &out, const string_res &s);
    103 ifstream & ?|?(ifstream &in, string_res &s);
    104 void ?|?( ifstream & in, string_res & this );
     109ofstream & ?|?(ofstream & out, const string_res & s);
     110void ?|?(ofstream & out, const string_res & s);
     111ifstream & ?|?(ifstream & in, string_res & s);
     112void ?|?( ifstream & in, string_res & s );
    105113
    106114struct _Istream_Rstr {
     
    113121        _Istream_Rstr wdi( unsigned int rwd, string_res & s ) { return (_Istream_Rstr)@{ &s, {{0p}, rwd, {.flags.rwd : true}} }; }
    114122        _Istream_Rstr getline( string_res & s, const char delimiter = '\n' ) {
    115                 return (_Istream_Rstr)@{ &s, {{.delimiter : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} };
     123                return (_Istream_Rstr)@{ &s, {{.delimiters : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} };
    116124        }
    117125        _Istream_Rstr & getline( _Istream_Rstr & fmt, const char delimiter = '\n' ) {
    118                 fmt.delimiter[0] = delimiter; fmt.delimiter[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt;
     126                fmt.delimiters[0] = delimiter; fmt.delimiters[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt;
    119127        }
    120128        _Istream_Rstr incl( const char scanset[], string_res & s ) { return (_Istream_Rstr)@{ &s, {{scanset}, -1, {.flags.inex : false}} }; }
     
    129137
    130138// Concatenation
    131 void append(string_res &s, const char* buffer, size_t bsize);
    132 void ?+=?(string_res &s, char other); // append a character
    133 void ?+=?(string_res &s, const string_res &s2); // append-concatenate to first string
    134 static inline void ?+=?(string_res &s, const char* other) {
    135     append( s, other, strlen(other) );
    136 }
     139void ?+=?(string_res & s, const string_res & s2);
     140void ?+=?(string_res & s, char c);
     141void append(string_res & s, const string_res & s2, size_t maxlen);
     142void ?+=?(string_res & s, const char * c);
     143void append(string_res & s, const char * buffer, size_t bsize);
     144
     145static inline string_res & strcat(string_res & s, const string_res & s2) { s += s2; return s; }
     146static inline string_res & strcat(string_res & s, const char * c) { s += c; return s; }
     147static inline string_res & strncat(string_res & s, const string_res & s2, size_t maxlen) { append(s, s2, maxlen); return s; }
     148static inline string_res & strncat(string_res & s, const char * buffer, size_t bsize) { append(s, buffer, bsize); return s; }
     149
     150// Repetition
     151void ?*=?(string_res & s, size_t factor);
    137152
    138153// Character access
    139 void assignAt(const string_res &s, size_t index, char val);
    140 char ?[?](const string_res &s, size_t index); // Mike changed to ret by val from Sunjay's ref, to match Peter's
    141 //char codePointAt(const string_res &s, size_t index); // revisit under Unicode
     154void assignAt(const string_res & s, size_t index, char val);
     155char ?[?](const string_res & s, size_t index); // Mike changed to ret by val from Sunjay's ref, to match Peter's
     156//char codePointAt(const string_res & s, size_t index); // revisit under Unicode
    142157
    143158// Comparisons
    144 int  cmp (const string_res &, const string_res &);
     159int  strcmp (const string_res &, const string_res &);
    145160bool ?==?(const string_res &, const string_res &);
    146161bool ?!=?(const string_res &, const string_res &);
     
    150165bool ?<? (const string_res &, const string_res &);
    151166
    152 int  cmp (const string_res &, const char*);
    153 bool ?==?(const string_res &, const char*);
    154 bool ?!=?(const string_res &, const char*);
    155 bool ?>? (const string_res &, const char*);
    156 bool ?>=?(const string_res &, const char*);
    157 bool ?<=?(const string_res &, const char*);
    158 bool ?<? (const string_res &, const char*);
    159 
    160 int  cmp (const char*, const string_res &);
    161 bool ?==?(const char*, const string_res &);
    162 bool ?!=?(const char*, const string_res &);
    163 bool ?>? (const char*, const string_res &);
    164 bool ?>=?(const char*, const string_res &);
    165 bool ?<=?(const char*, const string_res &);
    166 bool ?<? (const char*, const string_res &);
     167int  strcmp(const string_res &, const char *);
     168bool ?==?(const string_res &, const char *);
     169bool ?!=?(const string_res &, const char *);
     170bool ?>? (const string_res &, const char *);
     171bool ?>=?(const string_res &, const char *);
     172bool ?<=?(const string_res &, const char *);
     173bool ?<? (const string_res &, const char *);
     174
     175int  strcmp(const char *, const string_res &);
     176bool ?==?(const char *, const string_res &);
     177bool ?!=?(const char *, const string_res &);
     178bool ?>? (const char *, const string_res &);
     179bool ?>=?(const char *, const string_res &);
     180bool ?<=?(const char *, const string_res &);
     181bool ?<? (const char *, const string_res &);
    167182
    168183// String search
    169 bool contains(const string_res &s, char ch); // single character
    170 
    171 int find(const string_res &s, char search);
    172 int find(const string_res &s, const string_res &search);
    173 int find(const string_res &s, const char* search);
    174 int find(const string_res &s, const char* search, size_t searchsize);
    175 
    176 int findFrom(const string_res &s, size_t fromPos, char search);
    177 int findFrom(const string_res &s, size_t fromPos, const string_res &search);
    178 int findFrom(const string_res &s, size_t fromPos, const char* search);
    179 int findFrom(const string_res &s, size_t fromPos, const char* search, size_t searchsize);
    180 
    181 bool includes(const string_res &s, const string_res &search);
    182 bool includes(const string_res &s, const char* search);
    183 bool includes(const string_res &s, const char* search, size_t searchsize);
    184 
    185 bool startsWith(const string_res &s, const string_res &prefix);
    186 bool startsWith(const string_res &s, const char* prefix);
    187 bool startsWith(const string_res &s, const char* prefix, size_t prefixsize);
    188 
    189 bool endsWith(const string_res &s, const string_res &suffix);
    190 bool endsWith(const string_res &s, const char* suffix);
    191 bool endsWith(const string_res &s, const char* suffix, size_t suffixsize);
    192 
    193 int include(const string_res &s, const charclass_res &mask);
    194 int exclude(const string_res &s, const charclass_res &mask);
     184bool contains(const string_res & s, char ch); // single character
     185
     186int find(const string_res & s, char search);
     187int find(const string_res & s, const string_res & search);
     188int find(const string_res & s, const char * search);
     189int find(const string_res & s, const char * search, size_t searchsize);
     190
     191int findFrom(const string_res & s, size_t fromPos, char search);
     192int findFrom(const string_res & s, size_t fromPos, const string_res & search);
     193int findFrom(const string_res & s, size_t fromPos, const char * search);
     194int findFrom(const string_res & s, size_t fromPos, const char * search, size_t searchsize);
     195
     196bool includes(const string_res & s, const string_res & search);
     197bool includes(const string_res & s, const char * search);
     198bool includes(const string_res & s, const char * search, size_t searchsize);
     199
     200bool startsWith(const string_res & s, const string_res & prefix);
     201bool startsWith(const string_res & s, const char * prefix);
     202bool startsWith(const string_res & s, const char * prefix, size_t prefixsize);
     203
     204bool endsWith(const string_res & s, const string_res & suffix);
     205bool endsWith(const string_res & s, const char * suffix);
     206bool endsWith(const string_res & s, const char * suffix, size_t suffixsize);
     207
     208int include(const string_res & s, const charclass_res & mask);
     209int exclude(const string_res & s, const charclass_res & mask);
    195210
    196211// Modifiers
    197 void padStart(string_res &s, size_t n);
    198 void padStart(string_res &s, size_t n, char padding);
    199 void padEnd(string_res &s, size_t n);
     212void padStart(string_res & s, size_t n);
     213void padStart(string_res & s, size_t n, char padding);
     214void padEnd(string_res & s, size_t n);
    200215void padEnd(string_res &s, size_t n, char padding);
    201216
  • libcfa/src/heap.cfa

    r59c8dff rf988834  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Sep 30 17:31:15 2023
    13 // Update Count     : 1617
     12// Last Modified On : Wed Jan  3 21:30:54 2024
     13// Update Count     : 1619
    1414//
    1515
     
    2727#include "bits/align.hfa"                                                               // libAlign
    2828#include "bits/defs.hfa"                                                                // likely, unlikely
    29 #include "concurrency/kernel/fwd.hfa"                                   // __POLL_PREEMPTION
     29#include "concurrency/kernel/fwd.hfa"                                   // disable_interrupts, enable_interrupts
    3030#include "startup.hfa"                                                                  // STARTUP_PRIORITY_MEMORY
    3131#include "math.hfa"                                                                             // ceiling, min
  • libcfa/src/interpose.cfa

    r59c8dff rf988834  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar 27 21:09:03 2023
    13 // Update Count     : 196
     12// Last Modified On : Thu Jan 11 18:45:31 2024
     13// Update Count     : 218
    1414//
    1515
     
    1818extern "C" {
    1919#include <dlfcn.h>                                                                              // dlopen, dlsym
     20//#include <link.h>                                                                             // dl_iterate_phdr
     21struct dl_phdr_info;
     22int dl_iterate_phdr( int (*)( struct dl_phdr_info *, size_t, void * ), void * );
    2023#include <execinfo.h>                                                                   // backtrace, messages
    2124}
     
    2326#include "bits/defs.hfa"
    2427#include "bits/signal.hfa"                                                              // sigHandler_?
     28#include "concurrency/kernel/fwd.hfa"                                   // disable_interrupts, enable_interrupts
    2529#include "startup.hfa"                                                                  // STARTUP_PRIORITY_CORE
    2630#include <assert.h>
     
    8791        void (* exit)( int ) __attribute__(( __noreturn__ ));
    8892        void (* abort)( void ) __attribute__(( __noreturn__ ));
     93        int (* dl_iterate_phdr)( int (*)( struct dl_phdr_info *, size_t, void * ), void * );
    8994} __cabi_libc;
    9095
     
    102107                #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
    103108                INTERPOSE_LIBC( abort, version );
    104                 INTERPOSE_LIBC( exit , version );
     109                INTERPOSE_LIBC( exit, version );
     110                INTERPOSE_LIBC( dl_iterate_phdr, version );
    105111                #pragma GCC diagnostic pop
    106112
     
    150156        }
    151157}
     158
     159extern "C" int dl_iterate_phdr( int (* callback)( struct dl_phdr_info *, size_t, void * ), void * data ) {
     160        disable_interrupts();
     161        int ret = __cabi_libc.dl_iterate_phdr( callback, data ); // call real routine
     162        enable_interrupts( false );
     163        return ret;
     164} // dl_iterate_phdr
    152165
    153166//=============================================================================================
  • libcfa/src/iostream.cfa

    r59c8dff rf988834  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 17 13:33:12 2023
    13 // Update Count     : 1853
     12// Last Modified On : Wed Jan  3 10:53:13 2024
     13// Update Count     : 1898
    1414//
    1515
     
    984984        }
    985985
    986         istype & ?|?( istype & is, _Istream_Cquoted f ) {
     986        istype & ?|?( istype & is, _Istream_Cquoted f ) with( f ) {
    987987                char fmtstr[32];                                                                // storage scanset and format codes
    988988                fmtstr[0] = '%';
     
    992992                bool check = true;
    993993
    994                 if ( f.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }
    995                 int rwd = f.wd;
    996                 if ( f.wd != -1 ) {                                                             // => just ignore versus ignore with width
     994                if ( cstr.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }
     995                int rwd = cstr.wd;
     996                if ( cstr.wd != -1 ) {                                          // => just ignore versus ignore with width
    997997                        // wd is buffer bytes available (for input chars + null terminator)
    998998                        // rwd is count of input chars
    999999                        // no maximum width necessary because text ignored => width is read width
    1000                         if ( f.flags.rwd ) check = false;
    1001                         else rwd = f.wd - 1;
     1000                        if ( cstr.flags.rwd ) check = false;
     1001                        else rwd = cstr.wd - 1;
    10021002                        pos += sprintf( &fmtstr[pos], "%d", rwd );
    10031003                } // if
    10041004
    10051005                int len = 0;                                                                    // may not be set in fmt
    1006                 if ( ! f.flags.inex ) {                                                 // => quoted getline
    1007                         // fprintf( stderr, "quoted\n" );
     1006                char enddelim;
     1007                if ( ! cstr.flags.inex ) {                                              // => quoted getline
    10081008                        args = fmt( is, "%*[ \f\n\r\t\v]" );            // remove leading whitespace
    10091009                        if ( eof( is ) ) goto Eof;
    1010 //                      args = fmt( is, (const char *)f.delimiter ); // remove leading quote
    1011                         args = fmt( is, "'%n", &len ); // remove leading quote
    1012                         fprintf( stderr, "quoted %d %d\n", args, len );
     1010                        char rfmt[4] = { cstr.delimiters[0], '%', 'n', '\0' };
     1011                        args = fmt( is, rfmt, &len );                           // remove leading quote
    10131012                        if ( len == 0 || eof( is ) ) goto Eof;
    10141013                } // if
    1015                 sprintf( &fmtstr[pos], "[^%c]%%n", f.delimiter[0] );
    1016                 // fprintf( stderr, "getline %s %d\n", fmtstr, f.wd );
    1017                 if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    1018                 else args = fmt( is, fmtstr, f.s, &len );
    1019                 // fprintf( stderr, "getline %s %d %d %d\n", fmtstr, args, f.wd, eof( is ) );
     1014                enddelim = cstr.delimiters[1] == '\0' ? cstr.delimiters[0] : cstr.delimiters[1];
     1015                sprintf( &fmtstr[pos], "[^%c]%%n", enddelim );
     1016                if ( cstr.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1017                else args = fmt( is, fmtstr, cstr.s, &len );
    10201018                if ( check && len == rwd && ! eof( is ) ) {             // might not fit
    10211019                        char peek;
    10221020                        fmt( is, "%c", &peek );                                         // check for delimiter
    1023                         // fprintf( stderr, "peek %d '%c'\n", args, peek );
    10241021                        if ( ! eof( is ) ) {
    1025                                 if ( peek != f.delimiter[0] ) {
     1022                                if ( peek != enddelim ) {
    10261023                                        ungetc( is, peek );
    10271024                                        throwResume ExceptionInst( cstring_length );
     
    10301027                } else fmt( is, "%*c" );                                                // remove delimiter
    10311028          Eof: ;
    1032                 if ( rwd > 0 && args == 0 ) f.s[0] = '\0';              // read failed => no pattern match => set string to null
     1029                if ( rwd > 0 && args == 0 ) cstr.s[0] = '\0';   // read failed => no pattern match => set string to null
    10331030                if ( args == 1 && eof( is ) ) {                                 // data but scan ended at EOF
    1034                         // fprintf( stderr, "clear\n" );
    10351031                        clear( is );                                                            // => reset EOF => detect again on next read
    10361032                } // if
     
    10381034        }
    10391035
    1040         istype & ?|?( istype & is, _Istream_Cstr f ) {
     1036        istype & ?|?( istype & is, _Istream_Cstr f ) with( f ) {
    10411037                const char * scanset;
    10421038                size_t nscanset = 0;
    1043                 if ( f.flags.delimiter ) scanset = f.delimiter; // getline ?
     1039                if ( flags.delimiter ) scanset = delimiters;    // getline ?
    10441040                else scanset = f.scanset;
    10451041                if ( scanset ) nscanset = strlen( scanset );
     
    10841080                        if ( f.flags.delimiter ) {                                      // getline
    10851081                                int len = 0;                                                    // may not be set in fmt
    1086                                 if ( ! f.flags.inex ) {                                 // => quoted getline
    1087                                         // fprintf( stderr, "quoted\n" );
    1088                                         args = fmt( is, "%*[ \f\n\r\t\v]" ); // remove leading whitespace
    1089                                         if ( eof( is ) ) goto X;
    1090                                         args = fmt( is, "\"" );                         // remove leading quote
    1091                                         if ( eof( is ) ) goto X;
    1092                                 } // if
    1093                                 // fprintf( stderr, "getline\n" );
    1094                                 // sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
    1095                                 sprintf( &fmtstr[pos], "[^%s]%%n", scanset );
    1096                                 // fprintf( stderr, "getline %s %d\n", fmtstr, f.wd );
     1082                                sprintf( &fmtstr[pos], "[^%c]%%n", f.delimiters[0] );
    10971083                                if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
    10981084                                else args = fmt( is, fmtstr, f.s, &len );
    1099                                 // fprintf( stderr, "getline %s %d %d %d\n", fmtstr, args, f.wd, eof( is ) );
    11001085                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
    1101                                         char peek;
    1102                                         fmt( is, "%c", &peek );                         // check for delimiter
    1103                                         // fprintf( stderr, "peek %d '%c'\n", args, peek );
     1086                                        fmtstr[0] = f.delimiters[0]; fmtstr[1] = '%'; fmtstr[2] = 'n'; fmtstr[3] = '\0';
     1087                                        fmt( is, fmtstr, &len );                        // remove delimiter
    11041088                                        if ( ! eof( is ) ) {
    1105                                                 if ( peek != f.delimiter[0] ) {
    1106                                                         ungetc( is, peek );
     1089//                                              if ( peek != f.delimiter[0] ) {
     1090                                                if ( len != 1 ) {
     1091//                                                      ungetc( is, peek );
    11071092                                                        throwResume ExceptionInst( cstring_length );
    11081093                                                } // if
    11091094                                        } // if
    1110                                 } else fmt( is, "%*c" );                        // remove delimiter
    1111                           X: ;
     1095                                } else fmt( is, "%*c" );                                // remove delimiter
    11121096                        } else {
    11131097                                // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
  • libcfa/src/iostream.hfa

    r59c8dff rf988834  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Nov 15 17:55:31 2023
    13 // Update Count     : 596
     12// Last Modified On : Wed Jan  3 10:53:18 2024
     13// Update Count     : 610
    1414//
    1515
     
    392392        union {
    393393                const char * scanset;
    394                 char delimiter[2];
     394                char delimiters[3];                                                             // [0] => left, [1] => right
    395395        };
    396396        int wd;                                                                                         // width
     
    412412
    413413struct _Istream_Cquoted {
    414         char * s;
    415         inline _Istream_str_base;
     414        _Istream_Cstr cstr;
    416415}; // _Istream_Cquoted
    417416
     
    419418        // width must include room for null terminator
    420419        _Istream_Cstr wdi( unsigned int wd, char s[] ) { return (_Istream_Cstr)@{ s, { {0p}, wd, {.all : 0} } }; }
    421         // read width does not include null terminator
    422420        _Istream_Cstr wdi( unsigned int wd, unsigned int rwd, char s[] ) {
    423421                if ( wd <= rwd ) throw (cstring_length){ &cstring_length_vt };
    424422                return (_Istream_Cstr)@{ s, { {0p}, rwd, {.flags.rwd : true} } };
    425423        }
    426         _Istream_Cquoted & quoted( _Istream_Cstr & fmt, const char delimiter = '"' ) {
    427                 fmt.delimiter[0] = delimiter; fmt.delimiter[1] = '\0';
     424        _Istream_Cquoted & quoted( _Istream_Cstr & fmt, const char Ldelimiter = '"', const char Rdelimiter = '\0' ) {
     425                fmt.delimiters[0] = Ldelimiter;  fmt.delimiters[1] = Rdelimiter;  fmt.delimiters[2] = '\0';
    428426                return (_Istream_Cquoted &)fmt;
    429427        }
    430428        _Istream_Cstr & getline( _Istream_Cstr & fmt, const char delimiter = '\n' ) {
    431                 fmt.delimiter[0] = delimiter; fmt.delimiter[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt; }
     429                fmt.delimiters[0] = delimiter; fmt.delimiters[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt;
     430        }
    432431        _Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
    433432        _Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
Note: See TracChangeset for help on using the changeset viewer.