- Timestamp:
- Jan 19, 2024, 2:44:41 AM (21 months ago)
- 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. - Location:
- libcfa/src
- Files:
-
- 1 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/Makefile.am
r59c8dff rf988834 48 48 math.trait.hfa \ 49 49 math.hfa \ 50 raii.hfa \ 50 51 time_t.hfa \ 51 52 virtual_dtor.hfa \ -
libcfa/src/collections/array.hfa
r59c8dff rf988834 131 131 132 132 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 141 forall( [N], S & | sized(S), Timmed &, Tbase & | { void ?{}( Timmed & ); } ) 142 static 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 149 forall( [N], S & | sized(S), Timmed &, Tbase & | { void ^?{}( Timmed & ); } ) 150 static 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] ); 142 156 } 143 157 } … … 147 161 // 148 162 149 forall( Te )163 forall( Te * ) 150 164 static inline Te mkar_( tag(Te) ) {} 151 165 -
libcfa/src/collections/string.cfa
r59c8dff rf988834 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Oct 18 21:52:09 202313 // Update Count : 2 0812 // Last Modified On : Sun Jan 14 12:03:47 2024 13 // Update Count : 240 14 14 // 15 15 … … 29 29 // string RAII 30 30 31 32 void ?{}( string & this ) {33 (this.inner) { malloc() };34 ?{}( *this.inner );35 }36 37 31 // 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; 32 static 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 37 void ?{}( string & s ) { 38 (s.inner) { malloc() }; 39 ?{}( *s.inner ); 40 } 41 42 void ?{}( string & s, const string & c ) { 43 (s.inner) { malloc() }; 44 ?{}( *s.inner, *c.inner, COPY_VALUE ); 45 } 46 47 void ?{}( string & s, const string & s2, size_t maxlen) { 48 (s.inner) { malloc() }; 49 ?{}( *s.inner, *s2.inner, COPY_VALUE, maxlen ); 50 } 51 52 53 void ?{}( string & s, string & c ) { 54 ?{}( s, (const string &) c ); 55 } 56 57 void ?{}( string & s, const char c ) { 58 (s.inner) { malloc() }; 59 ?{}( *s.inner, c ); 60 } 61 62 void ?{}( string & s, const char * c ) { 63 (s.inner) { malloc() }; 64 ?{}( *s.inner, c ); 65 } 66 67 void ?{}( string & s, const char * c, size_t size) { 68 (s.inner) { malloc() }; 69 ?{}( *s.inner, c, size ); 70 } 71 72 void ^?{}( string & s ) { 73 ^(*s.inner){}; 74 free( s.inner ); 75 s.inner = 0p; 66 76 } 67 77 … … 69 79 // Alternate construction: request shared edits 70 80 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);81 string_WithSharedEdits ?`shareEdits( string & s ) { 82 string_WithSharedEdits ret = { &s }; 83 return ret; 84 } 85 86 void ?{}( string & s, string_WithSharedEdits src ) { 87 ?{}( s, *src.s->inner, 0, src.s->inner->Handle.lnth); 78 88 } 79 89 … … 81 91 // Assignment 82 92 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; 93 void ?=?( string & s, const char * val ) { 94 (*s.inner) = val; 95 } 96 97 // with and without const on "other" argument helps keep prevent autogen ?=? calls 98 void ?=?(string & s, const string & c) { 99 (*s.inner) = (*c.inner); 100 } 101 string & ?=?(string & s, string & c) { 102 (*s.inner) = (*c.inner); 103 return s; 104 } 105 106 void ?=?( string & s, char val ) { 107 (*s.inner) = val; 108 } 109 110 void assign(string & s, const string & c, size_t n) { 111 assign(*s.inner, *c.inner, n); 112 } 113 void assign(string & s, const char * c, size_t n) { 114 assign(*s.inner, c, n); 98 115 } 99 116 … … 102 119 // Input-Output 103 120 104 ofstream & ?|?( ofstream & out, const string & this ) {105 return out | (* this.inner); // print internal string_res106 } 107 108 void ?|?( ofstream & out, const string & this ) {109 (ofstream &)(out | (* this.inner)); ends( out );121 ofstream & ?|?( ofstream & out, const string & s ) { 122 return out | (*s.inner); // print internal string_res 123 } 124 125 void ?|?( ofstream & out, const string & s ) { 126 (ofstream &)(out | (*s.inner)); ends( out ); 110 127 } 111 128 … … 124 141 } 125 142 126 ifstream & ?|?(ifstream & in, string & this) {127 return in | (* this.inner); // read to internal string_res128 } 129 130 void ?|?( ifstream & in, string & this ) {131 in | (* this.inner);143 ifstream & ?|?(ifstream & in, string & s) { 144 return in | (*s.inner); // read to internal string_res 145 } 146 147 void ?|?( ifstream & in, string & s ) { 148 in | (*s.inner); 132 149 } 133 150 … … 144 161 // Slicing 145 162 146 string ?()( string & this, size_t start, size_t end) {147 string ret = { * this.inner, start, end};163 string ?()( string & s, size_t start, size_t len ) { 164 string ret = { *s.inner, start, len }; 148 165 return ret`shareEdits; 149 166 } 150 167 151 string ?()( string & this, size_t start ) {152 string ret = { * this.inner, start, size( this )};168 string ?()( string & s, size_t start ) { 169 string ret = { *s.inner, start, size( s ) - start }; 153 170 return ret`shareEdits; 154 171 } … … 157 174 // Comparison 158 175 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; }176 int strcmp(const string & s1, const string & s2) { return strcmp(*s1.inner, *s2.inner); } 177 bool ?==?(const string & s1, const string & s2) { return *s1.inner == *s2.inner; } 178 bool ?!=?(const string & s1, const string & s2) { return *s1.inner != *s2.inner; } 179 bool ?>? (const string & s1, const string & s2) { return *s1.inner > *s2.inner; } 180 bool ?>=?(const string & s1, const string & s2) { return *s1.inner >= *s2.inner; } 181 bool ?<=?(const string & s1, const string & s2) { return *s1.inner <= *s2.inner; } 182 bool ?<? (const string & s1, const string & s2) { return *s1.inner < *s2.inner; } 183 184 int strcmp(const string & s1, const char * s2) { return strcmp(*s1.inner, s2 ); } 185 bool ?==?(const string & s1, const char * s2) { return *s1.inner == s2; } 186 bool ?!=?(const string & s1, const char * s2) { return *s1.inner != s2; } 187 bool ?>? (const string & s1, const char * s2) { return *s1.inner > s2; } 188 bool ?>=?(const string & s1, const char * s2) { return *s1.inner >= s2; } 189 bool ?<=?(const string & s1, const char * s2) { return *s1.inner <= s2; } 190 bool ?<? (const string & s1, const char * s2) { return *s1.inner < s2; } 191 192 int strcmp(const char * s1, const string & s2) { return strcmp( s1, *s2.inner); } 193 bool ?==?(const char * s1, const string & s2) { return s1 == *s2.inner; } 194 bool ?!=?(const char * s1, const string & s2) { return s1 != *s2.inner; } 195 bool ?>? (const char * s1, const string & s2) { return s1 > *s2.inner; } 196 bool ?>=?(const char * s1, const string & s2) { return s1 >= *s2.inner; } 197 bool ?<=?(const char * s1, const string & s2) { return s1 <= *s2.inner; } 198 bool ?<? (const char * s1, const string & s2) { return s1 < *s2.inner; } 182 199 183 200 … … 186 203 187 204 size_t size(const string & s) { 188 return size( * 205 return size( *s.inner ); 189 206 } 190 207 … … 192 209 // Concatenation 193 210 194 void ?+=?(string & s, char other) {195 (*s.inner) += other;211 void ?+=?(string & s, char c) { 212 (*s.inner) += c; 196 213 } 197 214 … … 200 217 } 201 218 202 void ?+=?(string & s, const char * other) { 203 (*s.inner) += other; 204 } 205 206 string ?+?(const string & s, char other) { 219 void append(string & s, const string & s2, size_t maxlen) { 220 append( (*s.inner), (*s2.inner), maxlen ); 221 } 222 223 void ?+=?(string & s, const char * c) { 224 (*s.inner) += c; 225 } 226 227 void append(string & s, const char * buffer, size_t bsize) { 228 append( (*s.inner), buffer, bsize ); 229 } 230 231 string ?+?(const string & s, char c) { 207 232 string ret = s; 208 ret += other;233 ret += c; 209 234 return ret; 210 235 } … … 222 247 } 223 248 224 string ?+?(const string & s, const char * other) {249 string ?+?(const string & s, const char * c) { 225 250 string ret = s; 226 ret += other;251 ret += c; 227 252 return ret; 228 253 } … … 231 256 // Repetition 232 257 258 void ?*=?(string & s, size_t factor) { 259 (*s.inner) *= factor; 260 } 261 233 262 string ?*?(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 268 string ?*?(char c, size_t factor) { 269 string ret = c; 270 ret *= factor; 271 return ret; 272 } 273 274 string ?*?(const char * s, size_t factor) { 275 string ret = s; 276 ret *= factor; 277 return ret; 248 278 } 249 279 … … 256 286 257 287 string ?[?](string & s, size_t index) { 258 string ret = { *s.inner, index, index +1 };288 string ret = { *s.inner, index, 1 }; 259 289 return ret`shareEdits; 260 290 } … … 339 369 // charclass, include, exclude 340 370 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;371 void ?{}( charclass & s, const string & chars) { 372 (s.inner) { malloc() }; 373 ?{}( *s.inner, *(const string_res *)chars.inner ); 374 } 375 376 void ?{}( charclass & s, const char * chars ) { 377 (s.inner) { malloc() }; 378 ?{}( *s.inner, chars ); 379 } 380 381 void ?{}( charclass & s, const char * chars, size_t charssize ) { 382 (s.inner) { malloc() }; 383 ?{}( *s.inner, chars, charssize ); 384 } 385 386 void ^?{}( charclass & s ) { 387 ^(*s.inner){}; 388 free( s.inner ); 389 s.inner = 0p; 360 390 } 361 391 -
libcfa/src/collections/string.hfa
r59c8dff rf988834 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S at Sep 2 11:26:28 202313 // Update Count : 5512 // Last Modified On : Sun Jan 14 12:03:46 2024 13 // Update Count : 81 14 14 // 15 15 … … 29 29 // Getters 30 30 size_t size(const string & s); 31 static inline size_t strlen(const string & s) { return size( s ); } 31 32 32 33 // 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 34 void ?{}(string & s); // empty string 37 35 void ?{}(string & s, const string & s2); 36 void ?{}(string & s, const string & s2, size_t maxlen); 38 37 void ?{}(string & s, string & s2); 39 38 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 39 void ?{}(string & s, char); 40 void ?{}(string & s, const char * c); // copy from string literal (NULL-terminated) 41 void ?{}(string & s, const char * c, size_t size); // copy specific length from buffer 42 43 void ?=?(string & s, const char * c); // copy assignment from literal 44 void ?=?(string & s, const string & c); 45 void ?=?(string & s, char c); 46 string & ?=?(string & s, string & c); // surprising ret seems to help avoid calls to autogen 47 void assign(string & s, const string & c, size_t n); 48 void assign(string & s, const char * c, size_t n); 44 49 //string ?=?( string &, string ) = void; 50 51 static inline string & strcpy(string & s, const char * c) { s = c; return s; } 52 static inline string & strncpy(string & s, const char * c, size_t n) { assign( s, c, n); return s; } 53 static inline string & strcpy(string & s, const string & c) { s = c; return s; } 54 static inline string & strncpy(string & s, const string & c, size_t n) { assign(s, c, n); return s; } 55 45 56 void ^?{}(string & s); 46 57 … … 49 60 string * s; 50 61 }; 51 string_WithSharedEdits ?`shareEdits( string & this );52 void ?{}( string & this, string_WithSharedEdits src );62 string_WithSharedEdits ?`shareEdits( string & s ); 63 void ?{}( string & s, string_WithSharedEdits src ); 53 64 54 65 // IO Operator … … 56 67 void ?|?(ofstream & out, const string & s); 57 68 ifstream & ?|?(ifstream & in, string & s); 58 void ?|?( ifstream & in, string & this );69 void ?|?( ifstream & in, string & s ); 59 70 60 71 static inline { … … 81 92 _Istream_Sstr wdi( unsigned int rwd, string & s ) { return (_Istream_Sstr)@{ s, {{0p}, rwd, {.flags.rwd : true}} }; } 82 93 _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}} }; 84 95 } 85 96 _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; 87 98 } 88 99 _Istream_Sstr incl( const char scanset[], string & s ) { return (_Istream_Sstr)@{ s, {{scanset}, -1, {.flags.inex : false}} }; } … … 97 108 98 109 // Concatenation 99 void ?+=?(string & s, char other); // append a character110 void ?+=?(string & s, char c); // append a character 100 111 void ?+=?(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 112 void append(string & s, const string & s2, size_t maxlen); // append-concatenate to first string, up to maxlen 113 void ?+=?(string & s, const char * s2); // append-concatenate NULL-terminated string to first string 114 void append(string & s, const char * buffer, size_t bsize); // append-concatenate given range to first string 115 116 string ?+?(const string & s, char c); // add a character to a copy of the string 103 117 string ?+?(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 118 string ?+?(const char * s1, const char * s2); // copy and concatenate both strings 119 string ?+?(const string & s, const char * c); // copy and concatenate with NULL-terminated string 120 121 static inline string & strcat(string & s, const string & s2) { s += s2; return s; } 122 static inline string & strcat(string & s, const char * c) { s += c; return s; } 123 static inline string & strncat(string & s, const string & s2, size_t maxlen) { append(s, s2, maxlen); return s; } 124 static inline string & strncat(string & s, const char * buffer, size_t bsize) { append(s, buffer, bsize); return s; } 106 125 107 126 // Repetition 108 127 string ?*?(const string & s, size_t factor); 109 string ?*?(char c, size_t size); 110 string ?*?(const char *s, size_t size); 128 void ?*=?(string & s, size_t factor); 129 string ?*?(char c, size_t factor); 130 string ?*?(const char *s, size_t factor); 111 131 112 132 // Character access … … 116 136 117 137 // Comparisons 118 int cmp (const string &, const string &);138 int strcmp (const string &, const string &); 119 139 bool ?==?(const string &, const string &); 120 140 bool ?!=?(const string &, const string &); … … 124 144 bool ?<? (const string &, const string &); 125 145 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 &);146 int strcmp (const string &, const char *); 147 bool ?==?(const string &, const char *); 148 bool ?!=?(const string &, const char *); 149 bool ?>? (const string &, const char *); 150 bool ?>=?(const string &, const char *); 151 bool ?<=?(const string &, const char *); 152 bool ?<? (const string &, const char *); 153 154 int strcmp (const char *, const string &); 155 bool ?==?(const char *, const string &); 156 bool ?!=?(const char *, const string &); 157 bool ?>? (const char *, const string &); 158 bool ?>=?(const char *, const string &); 159 bool ?<=?(const char *, const string &); 160 bool ?<? (const char *, const string &); 141 161 142 162 143 163 // Slicing 144 string ?()( string & this, size_t start, size_t end); // TODO const?145 string ?()( string & this, size_t start);164 string ?()( string & s, size_t start, size_t len ); // TODO const? 165 string ?()( string & s, size_t start); 146 166 147 167 // String search … … 177 197 178 198 179 180 199 struct charclass { 181 200 charclass_res * inner; -
libcfa/src/collections/string_res.cfa
r59c8dff rf988834 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Oct 18 21:54:54 202313 // Update Count : 1512 // Last Modified On : Tue Jan 16 22:19:27 2024 13 // Update Count : 35 14 14 // 15 15 … … 22 22 // Workaround is: EndVbyte = TEMP_ALLOC(char, CurrSize) 23 23 // 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 ) )) 25 25 26 26 #include <assert.h> … … 33 33 34 34 struct 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 39 38 40 int InitSize; // initial number of bytes in the byte-string area41 int CurrSize; // current number of bytes in the byte-string area42 char *StartVbyte; // pointer to the `st byte of the start of the byte-string area43 char *EndVbyte; // pointer to the next byte after the end of the currently used portion of byte-string area44 void *ExtVbyte; // pointer to the next byte after the end of the byte-string area45 46 HandleNode Header; // header node for handle list39 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 47 46 }; // VbyteHeap 48 47 49 48 50 static void compaction( VbyteHeap & ); 51 static void garbage( VbyteHeap &, int ); 49 static void compaction( VbyteHeap & ); // compaction of the byte area 50 static void garbage( VbyteHeap &, int ); // garbage collect the byte area 52 51 static void extend( VbyteHeap &, int ); // extend the size of the byte area 53 52 static void reduce( VbyteHeap &, int ); // reduce the size of the byte area … … 67 66 // Allocate the storage for the variable sized area and intialize the heap variables. 68 67 69 static void ?{}( VbyteHeap & this, size_t Size ) with(this) {70 #ifdef VbyteDebug 71 serr | "enter:VbyteHeap::VbyteHeap, this:" | &this | " Size:" | Size;68 static void ?{}( VbyteHeap & s, size_t Size ) with(s) { 69 #ifdef VbyteDebug 70 serr | "enter:VbyteHeap::VbyteHeap, s:" | &s | " Size:" | Size; 72 71 #endif // VbyteDebug 73 72 NoOfCompactions = NoOfExtensions = NoOfReductions = 0; … … 76 75 ExtVbyte = (void *)( StartVbyte + CurrSize ); 77 76 Header.flink = Header.blink = &Header; 78 Header.ulink = & this;77 Header.ulink = &s; 79 78 #ifdef VbyteDebug 80 79 HeaderPtr = &Header; 81 serr | "exit:VbyteHeap::VbyteHeap, this:" | &this;80 serr | "exit:VbyteHeap::VbyteHeap, s:" | &s; 82 81 #endif // VbyteDebug 83 82 } // VbyteHeap … … 86 85 // Release the dynamically allocated storage for the byte area. 87 86 88 static void ^?{}( VbyteHeap & this ) with(this) {87 static void ^?{}( VbyteHeap & s ) with(s) { 89 88 free( StartVbyte ); 90 89 } // ~VbyteHeap … … 97 96 // creator. 98 97 99 static void ?{}( HandleNode & this ) with(this) {100 #ifdef VbyteDebug 101 serr | "enter:HandleNode::HandleNode, this:" | &this;98 static void ?{}( HandleNode & s ) with(s) { 99 #ifdef VbyteDebug 100 serr | "enter:HandleNode::HandleNode, s:" | &s; 102 101 #endif // VbyteDebug 103 102 s = 0; 104 103 lnth = 0; 105 104 #ifdef VbyteDebug 106 serr | "exit:HandleNode::HandleNode, this:" | &this;105 serr | "exit:HandleNode::HandleNode, s:" | &s; 107 106 #endif // VbyteDebug 108 107 } // HandleNode … … 112 111 // collection. 113 112 114 static void ?{}( HandleNode & this, VbyteHeap & vh ) with(this) {115 #ifdef VbyteDebug 116 serr | "enter:HandleNode::HandleNode, this:" | &this;113 static void ?{}( HandleNode & s, VbyteHeap & vh ) with(s) { 114 #ifdef VbyteDebug 115 serr | "enter:HandleNode::HandleNode, s:" | &s; 117 116 #endif // VbyteDebug 118 117 s = 0; 119 118 lnth = 0; 120 119 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; 124 123 #endif // VbyteDebug 125 124 } // HandleNode … … 129 128 // is the responsibility of the creator to destroy it. 130 129 131 static void ^?{}( HandleNode & this ) with(this) {132 #ifdef VbyteDebug 133 serr | "enter:HandleNode::~HandleNode, this:" | & this;130 static void ^?{}( HandleNode & s ) with(s) { 131 #ifdef VbyteDebug 132 serr | "enter:HandleNode::~HandleNode, s:" | & s; 134 133 { 135 134 serr | nlOff; … … 142 141 } 143 142 #endif // VbyteDebug 144 DeleteNode( this );143 DeleteNode( s ); 145 144 } // ~HandleNode 146 145 … … 151 150 static string_sharectx default_string_sharectx = {NEW_SHARING}; // stable bottom of stack 152 151 153 void ?{}( string_sharectx & this, StringSharectx_Mode mode ) with( this ) {152 void ?{}( string_sharectx & s, StringSharectx_Mode mode ) with( s ) { 154 153 (older){ ambient_string_sharectx }; 155 154 if ( mode == NEW_SHARING ) { … … 159 158 (activeHeap){ 0p }; 160 159 } 161 ambient_string_sharectx = & this;162 } 163 164 void ^?{}( string_sharectx & this ) with( this ) {160 ambient_string_sharectx = & s; 161 } 162 163 void ^?{}( string_sharectx & s ) with( s ) { 165 164 if ( activeHeap ) delete( activeHeap ); 166 165 167 // unlink this from older-list starting from ambient_string_sharectx168 // usually, this==ambient_string_sharectx and the loop runs zero times166 // unlink s from older-list starting from ambient_string_sharectx 167 // usually, s==ambient_string_sharectx and the loop runs zero times 169 168 string_sharectx *& c = ambient_string_sharectx; 170 while ( c != & this ) &c = &c->older; // find this171 c = this.older; // unlink169 while ( c != &s ) &c = &c->older; // find s 170 c = s.older; // unlink 172 171 } 173 172 … … 181 180 182 181 size_t DEBUG_string_bytes_avail_until_gc( VbyteHeap * heap ) { 183 return ((char *)heap->ExtVbyte) - heap->EndVbyte;182 return ((char *)heap->ExtVbyte) - heap->EndVbyte; 184 183 } 185 184 … … 193 192 194 193 // Returns the size of the string in bytes 195 size_t size(const string_res & s) with(s) {194 size_t size(const string_res & s) with(s) { 196 195 return Handle.lnth; 197 196 } 198 197 199 198 // Output operator 200 ofstream & ?|?(ofstream & out, const string_res &s) {199 ofstream & ?|?(ofstream & out, const string_res & s) { 201 200 // CFA string is NOT null terminated, so print exactly lnth characters in a minimum width of 0. 202 201 out | wd( 0, s.Handle.lnth, s.Handle.s ) | nonl; … … 204 203 } 205 204 206 void ?|?(ofstream & out, const string_res &s) {205 void ?|?(ofstream & out, const string_res & s) { 207 206 (ofstream &)(out | s); ends( out ); 208 207 } 209 208 210 209 // Input operator 211 ifstream & ?|?(ifstream &in, string_res &s) { 212 210 ifstream & ?|?(ifstream & in, string_res & s) { 213 211 // Reading into a temp before assigning to s is near zero overhead in typical cases because of sharing. 214 212 // If s is a substring of something larger, simple assignment takes care of that case correctly. … … 231 229 232 230 // 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; 234 232 assert (lenReadable >= 2); 235 233 … … 238 236 *(temp.Handle.ulink->EndVbyte) = '\0'; // pre-assign empty cstring 239 237 in | wdi( lenReadable, temp.Handle.ulink->EndVbyte ); 240 } catch (cstring_length *) {238 } catch (cstring_length *) { 241 239 cont = true; 242 240 } … … 252 250 } 253 251 254 void ?|?( ifstream & in, string_res & this ) {255 (ifstream &)(in | this);252 void ?|?( ifstream & in, string_res & s ) { 253 (ifstream &)(in | s); 256 254 } 257 255 … … 274 272 cont = true; 275 273 } 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 ) { 278 277 *(f.s) = cstr; 279 278 } … … 287 286 cont = true; // continue not allowed 288 287 } finally { 289 if ( ! cf.flags.ignore && 290 cstr[0] != '\0' ) { // something was read 288 if ( ! cf.flags.ignore && cstr[0] != '\0' ) { // something was read 291 289 *(f.s) += cstr; // build string chunk at a time 292 290 } … … 302 300 303 301 // Empty constructor 304 void ?{}(string_res & s) with(s) {302 void ?{}(string_res & s) with(s) { 305 303 if( ambient_string_sharectx->activeHeap ) { 306 304 (Handle){ * ambient_string_sharectx->activeHeap }; … … 317 315 } 318 316 319 static void eagerCopyCtorHelper(string_res & s, const char* rhs, size_t rhslnth) with(s) {317 static void eagerCopyCtorHelper(string_res & s, const char * rhs, size_t rhslnth) with(s) { 320 318 if( ambient_string_sharectx->activeHeap ) { 321 319 (Handle){ * ambient_string_sharectx->activeHeap }; … … 333 331 334 332 // Constructor from a raw buffer and size 335 void ?{}(string_res & s, const char* rhs, size_t rhslnth) with(s) {333 void ?{}(string_res & s, const char * rhs, size_t rhslnth) with(s) { 336 334 eagerCopyCtorHelper(s, rhs, rhslnth); 337 335 } 338 336 339 337 // 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) {338 void ?{}( string_res & s, VbyteHeap & heap, const char * rhs, size_t rhslnth ) with(s) { 341 339 (Handle){ heap }; 342 340 Handle.s = VbyteAlloc(*Handle.ulink, rhslnth); … … 348 346 } 349 347 348 350 349 // General copy constructor 351 void ?{}(string_res &s, const string_res & s2, StrResInitMode mode, size_t start, size_t end ) { 352 350 void ?{}(string_res & s, const string_res & s2, StrResInitMode mode, size_t start, size_t len ) { 351 352 size_t end = start + len; 353 353 verify( start <= end && end <= s2.Handle.lnth ); 354 354 … … 394 394 } 395 395 396 static void assignEditSet(string_res & this, string_res * shareEditSetStartPeer, string_res * shareEditSetEndPeer,396 static void assignEditSet(string_res & s, string_res * shareEditSetStartPeer, string_res * shareEditSetEndPeer, 397 397 char * resultSesStart, 398 398 size_t resultSesLnth, … … 400 400 401 401 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; 405 405 size_t afterLen = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - afterBegin; 406 406 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; 411 411 if (resultPadPosition) 412 MoveThisAfter( this.Handle, *resultPadPosition );412 MoveThisAfter( s.Handle, *resultPadPosition ); 413 413 414 414 // adjust all substring string and handle locations, and check if any substring strings are outside the new base string 415 415 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 ) { 417 417 verify (p->Handle.s >= beforeBegin); 418 418 if ( p->Handle.s >= afterBegin ) { … … 439 439 // take end as end-anchored 440 440 // stretch-shrink p according to the edit 441 p->Handle.lnth += this.Handle.lnth;441 p->Handle.lnth += s.Handle.lnth; 442 442 p->Handle.lnth -= oldLnth; 443 443 } … … 452 452 // p ends during the edit; p does not include the last character replaced 453 453 // set p to empty string at start of edit 454 p->Handle.s = this.Handle.s;454 p->Handle.s = s.Handle.s; 455 455 p->Handle.lnth = 0; 456 456 } else { … … 458 458 // clip start of p to start at end of edit 459 459 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; 461 461 p->Handle.lnth -= charsToClip; 462 462 } … … 467 467 } 468 468 469 // traverse the share-edit set (SES) to recover the range of a base string to which ` this` belongs470 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 470 static 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) { 474 474 if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) { 475 475 shareEditSetStartPeer = editPeer; … … 481 481 } 482 482 483 static string_res & assign_(string_res & this, const char* buffer, size_t bsize, const string_res & valSrc) {483 static string_res & assign_(string_res & s, const char * buffer, size_t bsize, const string_res & valSrc) { 484 484 485 485 string_res * shareEditSetStartPeer; 486 486 string_res * shareEditSetEndPeer; 487 locateInShareEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer );487 locateInShareEditSet( s, shareEditSetStartPeer, shareEditSetEndPeer ); 488 488 489 489 verify( shareEditSetEndPeer->Handle.s >= shareEditSetStartPeer->Handle.s ); 490 490 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 context491 verify( origEditSetLength >= s.Handle.lnth ); 492 493 if ( s.shareEditSet_owns_ulink ) { // assigning to private context 494 494 // ok to overwrite old value within LHS 495 495 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; 498 498 int suffixLen = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - suffixStartOrig; 499 499 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 ) ) { 502 502 // growing: copy from old to new 503 char * dest = VbyteAlloc( * this.Handle.ulink, origEditSetLength + delta );503 char * dest = VbyteAlloc( *s.Handle.ulink, origEditSetLength + delta ); 504 504 char *destCursor = dest; memcpy(destCursor, prefixStartOrig, prefixLen); 505 505 destCursor += prefixLen; memcpy(destCursor, buffer , bsize ); 506 506 destCursor += bsize; memcpy(destCursor, suffixStartOrig, suffixLen); 507 assignEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer,507 assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer, 508 508 dest, 509 509 origEditSetLength + delta, … … 513 513 // room is already allocated in-place: bubble suffix and overwite middle 514 514 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, 518 518 shareEditSetStartPeer->Handle.s, 519 519 origEditSetLength + delta, … … 522 522 523 523 } else if ( // assigning to shared context 524 this.Handle.lnth == origEditSetLength && // overwriting entire run of SES524 s.Handle.lnth == origEditSetLength && // overwriting entire run of SES 525 525 & valSrc && // sourcing from a managed string 526 valSrc.Handle.ulink == this.Handle.ulink ) { // sourcing from same heap526 valSrc.Handle.ulink == s.Handle.ulink ) { // sourcing from same heap 527 527 528 528 // SES's result will only use characters from the source string => reuse source 529 assignEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer,529 assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer, 530 530 valSrc.Handle.s, 531 531 valSrc.Handle.lnth, … … 537 537 538 538 // full string is from start of shareEditSetStartPeer thru end of shareEditSetEndPeer 539 // ` this` occurs in the middle of it, to be replaced539 // `s` occurs in the middle of it, to be replaced 540 540 // build up the new text in `pasting` 541 541 542 542 string_res pasting = { 543 * this.Handle.ulink, // maintain same heap, regardless of context543 * s.Handle.ulink, // maintain same heap, regardless of context 544 544 shareEditSetStartPeer->Handle.s, // start of SES 545 this.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before this545 s.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before s 546 546 append( pasting, 547 buffer, // start of replacement for this548 bsize ); // length of replacement for this547 buffer, // start of replacement for s 548 bsize ); // length of replacement for s 549 549 append( pasting, 550 this.Handle.s + this.Handle.lnth, // start of SES after this550 s.Handle.s + s.Handle.lnth, // start of SES after s 551 551 shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - 552 ( this.Handle.s + this.Handle.lnth) ); // length of SES, after this552 (s.Handle.s + s.Handle.lnth) ); // length of SES, after s 553 553 554 554 // The above string building can trigger compaction. 555 555 // 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, 559 559 pasting.Handle.s, 560 560 pasting.Handle.lnth, … … 562 562 } 563 563 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 567 string_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 571 string_res & assign(string_res & s, const char * buffer, size_t bsize) { 572 return assign_(s, buffer, bsize, *0p); 573 } 574 575 string_res & ?=?(string_res & s, char c) { 576 return assign(s, &c, 1); 573 577 } 574 578 575 579 // 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 ) {580 string_res & ?=?(string_res & s, const string_res & rhs) with( s ) { 581 return assign_(s, rhs.Handle.s, rhs.Handle.lnth, rhs); 582 } 583 584 string_res & ?=?(string_res & s, string_res & rhs) with( s ) { 581 585 const string_res & rhs2 = rhs; 582 return this = rhs2;586 return s = rhs2; 583 587 } 584 588 585 589 586 590 // Destructor 587 void ^?{}(string_res & s) with(s) {591 void ^?{}(string_res & s) with(s) { 588 592 // much delegated to implied ^VbyteSM 589 593 … … 603 607 // With unicode support, this may be different from just the byte at the given 604 608 // offset from the start of the string. 605 char ?[?](const string_res & s, size_t index) with(s) {609 char ?[?](const string_res & s, size_t index) with(s) { 606 610 //TODO: Check if index is valid (no exceptions yet) 607 611 return Handle.s[index]; 608 612 } 609 613 610 void assignAt(const string_res &s, size_t index, char val) { 611 string_res editZone = { s, SHARE_EDITS, index, index+1 }; 614 void 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 }; 612 619 assign(editZone, &val, 1); 613 620 } … … 617 624 // Concatenation 618 625 619 void append(string_res & str1, const char * buffer, size_t bsize) {626 void append(string_res & str1, const char * buffer, size_t bsize) { 620 627 size_t clnth = str1.Handle.lnth + bsize; 621 628 if ( str1.Handle.s + str1.Handle.lnth == buffer ) { // already juxtapose ? … … 635 642 } 636 643 637 void ?+=?(string_res & str1, const string_res &str2) {644 void ?+=?(string_res & str1, const string_res & str2) { 638 645 append( str1, str2.Handle.s, str2.Handle.lnth ); 639 646 } 640 647 641 void ?+=?(string_res &s, char other) { 642 append( s, &other, 1 ); 643 } 644 645 646 647 648 void append(string_res & str1, const string_res & str2, size_t maxlen) { 649 append( str1, str2.Handle.s, min(str2.Handle.lnth, maxlen) ); 650 } 651 652 void ?+=?(string_res & s, char c) { 653 append( s, & c, 1 ); 654 } 655 void ?+=?(string_res & s, const char * c) { 656 append( s, c, strlen(c) ); 657 } 658 659 /////////////////////////////////////////////////////////////////// 660 // Repetition 661 662 void ?*=?(string_res & s, size_t factor) { 663 string_res s2 = { s, COPY_VALUE }; 664 s = ""; 665 for (factor) s += s2; 666 } 648 667 649 668 ////////////////////////////////////////////////////////// 650 669 // Comparisons 651 670 652 int cmp(const string_res &s1, const string_res &s2) {671 int strcmp(const string_res & s1, const string_res & s2) { 653 672 // return 0; 654 673 int ans1 = memcmp(s1.Handle.s, s2.Handle.s, min(s1.Handle.lnth, s2.Handle.lnth)); … … 657 676 } 658 677 659 bool ?==?(const string_res & s1, const string_res &s2) { returncmp(s1, s2) == 0; }660 bool ?!=?(const string_res & s1, const string_res &s2) { returncmp(s1, s2) != 0; }661 bool ?>? (const string_res & s1, const string_res &s2) { returncmp(s1, s2) > 0; }662 bool ?>=?(const string_res & s1, const string_res &s2) { returncmp(s1, s2) >= 0; }663 bool ?<=?(const string_res & s1, const string_res &s2) { returncmp(s1, s2) <= 0; }664 bool ?<? (const string_res & s1, const string_res &s2) { returncmp(s1, s2) < 0; }665 666 int cmp (const string_res &s1, const char* s2) {678 bool ?==?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) == 0; } 679 bool ?!=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) != 0; } 680 bool ?>? (const string_res & s1, const string_res & s2) { return strcmp(s1, s2) > 0; } 681 bool ?>=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) >= 0; } 682 bool ?<=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) <= 0; } 683 bool ?<? (const string_res & s1, const string_res & s2) { return strcmp(s1, s2) < 0; } 684 685 int strcmp (const string_res & s1, const char * s2) { 667 686 string_res s2x = s2; 668 return cmp(s1, s2x);669 } 670 671 bool ?==?(const string_res & s1, const char* s2) { returncmp(s1, s2) == 0; }672 bool ?!=?(const string_res & s1, const char* s2) { returncmp(s1, s2) != 0; }673 bool ?>? (const string_res & s1, const char* s2) { returncmp(s1, s2) > 0; }674 bool ?>=?(const string_res & s1, const char* s2) { returncmp(s1, s2) >= 0; }675 bool ?<=?(const string_res & s1, const char* s2) { returncmp(s1, s2) <= 0; }676 bool ?<? (const string_res & s1, const char* s2) { returncmp(s1, s2) < 0; }677 678 int cmp (const char* s1, const string_res & s2) {687 return strcmp(s1, s2x); 688 } 689 690 bool ?==?(const string_res & s1, const char * s2) { return strcmp(s1, s2) == 0; } 691 bool ?!=?(const string_res & s1, const char * s2) { return strcmp(s1, s2) != 0; } 692 bool ?>? (const string_res & s1, const char * s2) { return strcmp(s1, s2) > 0; } 693 bool ?>=?(const string_res & s1, const char * s2) { return strcmp(s1, s2) >= 0; } 694 bool ?<=?(const string_res & s1, const char * s2) { return strcmp(s1, s2) <= 0; } 695 bool ?<? (const string_res & s1, const char * s2) { return strcmp(s1, s2) < 0; } 696 697 int strcmp (const char * s1, const string_res & s2) { 679 698 string_res s1x = s1; 680 return cmp(s1x, s2);681 } 682 683 bool ?==?(const char * s1, const string_res &s2) { returncmp(s1, s2) == 0; }684 bool ?!=?(const char * s1, const string_res &s2) { returncmp(s1, s2) != 0; }685 bool ?>? (const char * s1, const string_res &s2) { returncmp(s1, s2) > 0; }686 bool ?>=?(const char * s1, const string_res &s2) { returncmp(s1, s2) >= 0; }687 bool ?<=?(const char * s1, const string_res &s2) { returncmp(s1, s2) <= 0; }688 bool ?<? (const char * s1, const string_res &s2) { returncmp(s1, s2) < 0; }699 return strcmp(s1x, s2); 700 } 701 702 bool ?==?(const char * s1, const string_res & s2) { return strcmp(s1, s2) == 0; } 703 bool ?!=?(const char * s1, const string_res & s2) { return strcmp(s1, s2) != 0; } 704 bool ?>? (const char * s1, const string_res & s2) { return strcmp(s1, s2) > 0; } 705 bool ?>=?(const char * s1, const string_res & s2) { return strcmp(s1, s2) >= 0; } 706 bool ?<=?(const char * s1, const string_res & s2) { return strcmp(s1, s2) <= 0; } 707 bool ?<? (const char * s1, const string_res & s2) { return strcmp(s1, s2) < 0; } 689 708 690 709 … … 693 712 // Search 694 713 695 bool contains(const string_res & s, char ch) {714 bool contains(const string_res & s, char ch) { 696 715 for ( i; size(s) ) { 697 716 if (s[i] == ch) return true; … … 700 719 } 701 720 702 int find(const string_res & s, char search) {721 int find(const string_res & s, char search) { 703 722 return findFrom(s, 0, search); 704 723 } 705 724 706 int findFrom(const string_res & s, size_t fromPos, char search) {725 int findFrom(const string_res & s, size_t fromPos, char search) { 707 726 // FIXME: This paricular overload (find of single char) is optimized to use memchr. 708 727 // The general overload (find of string, memchr applying to its first character) and `contains` should be adjusted to match. … … 715 734 } 716 735 717 int find(const string_res & s, const string_res &search) {736 int find(const string_res & s, const string_res & search) { 718 737 return findFrom(s, 0, search); 719 738 } 720 739 721 int findFrom(const string_res & s, size_t fromPos, const string_res &search) {740 int findFrom(const string_res & s, size_t fromPos, const string_res & search) { 722 741 return findFrom(s, fromPos, search.Handle.s, search.Handle.lnth); 723 742 } 724 743 725 int find(const string_res & s, const char* search) {744 int find(const string_res & s, const char * search) { 726 745 return findFrom(s, 0, search); 727 746 } 728 int findFrom(const string_res & s, size_t fromPos, const char* search) {747 int findFrom(const string_res & s, size_t fromPos, const char * search) { 729 748 return findFrom(s, fromPos, search, strlen(search)); 730 749 } 731 750 732 int find(const string_res & s, const char* search, size_t searchsize) {751 int find(const string_res & s, const char * search, size_t searchsize) { 733 752 return findFrom(s, 0, search, searchsize); 734 753 } 735 754 736 int findFrom(const string_res & s, size_t fromPos, const char* search, size_t searchsize) {755 int findFrom(const string_res & s, size_t fromPos, const char * search, size_t searchsize) { 737 756 738 757 /* Remaining implementations essentially ported from Sunjay's work */ … … 771 790 } 772 791 773 bool includes(const string_res & s, const string_res &search) {792 bool includes(const string_res & s, const string_res & search) { 774 793 return includes(s, search.Handle.s, search.Handle.lnth); 775 794 } 776 795 777 bool includes(const string_res & s, const char* search) {796 bool includes(const string_res & s, const char * search) { 778 797 return includes(s, search, strlen(search)); 779 798 } 780 799 781 bool includes(const string_res & s, const char* search, size_t searchsize) {800 bool includes(const string_res & s, const char * search, size_t searchsize) { 782 801 return find(s, search, searchsize) < s.Handle.lnth; 783 802 } 784 803 785 bool startsWith(const string_res & s, const string_res &prefix) {804 bool startsWith(const string_res & s, const string_res & prefix) { 786 805 return startsWith(s, prefix.Handle.s, prefix.Handle.lnth); 787 806 } 788 807 789 bool startsWith(const string_res & s, const char* prefix) {808 bool startsWith(const string_res & s, const char * prefix) { 790 809 return startsWith(s, prefix, strlen(prefix)); 791 810 } 792 811 793 bool startsWith(const string_res & s, const char* prefix, size_t prefixsize) {812 bool startsWith(const string_res & s, const char * prefix, size_t prefixsize) { 794 813 if (s.Handle.lnth < prefixsize) { 795 814 return false; … … 798 817 } 799 818 800 bool endsWith(const string_res & s, const string_res &suffix) {819 bool endsWith(const string_res & s, const string_res & suffix) { 801 820 return endsWith(s, suffix.Handle.s, suffix.Handle.lnth); 802 821 } 803 822 804 bool endsWith(const string_res & s, const char* suffix) {823 bool endsWith(const string_res & s, const char * suffix) { 805 824 return endsWith(s, suffix, strlen(suffix)); 806 825 } 807 826 808 bool endsWith(const string_res & s, const char* suffix, size_t suffixsize) {827 bool endsWith(const string_res & s, const char * suffix, size_t suffixsize) { 809 828 if (s.Handle.lnth < suffixsize) { 810 829 return false; … … 822 841 // charclass, include, exclude 823 842 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 };843 void ?{}( charclass_res & s, const string_res & chars) { 844 (s){ chars.Handle.s, chars.Handle.lnth }; 845 } 846 847 void ?{}( charclass_res & s, const char * chars ) { 848 (s){ chars, strlen(chars) }; 849 } 850 851 void ?{}( charclass_res & s, const char * chars, size_t charssize ) { 852 (s.chars){ chars, charssize }; 834 853 // now sort it ? 835 854 } 836 855 837 void ^?{}( charclass_res & this ) {838 ^( this.chars){};856 void ^?{}( charclass_res & s ) { 857 ^(s.chars){}; 839 858 } 840 859 … … 844 863 } 845 864 846 int exclude(const string_res & s, const charclass_res &mask) {865 int exclude(const string_res & s, const charclass_res & mask) { 847 866 for ( i; size(s) ) { 848 867 if ( test(mask, s[i]) ) return i; … … 851 870 } 852 871 853 int include(const string_res & s, const charclass_res &mask) {872 int include(const string_res & s, const charclass_res & mask) { 854 873 for ( i; size(s) ) { 855 874 if ( ! test(mask, s[i]) ) return i; … … 863 882 // Add a new HandleNode node n after the current HandleNode node. 864 883 865 static void AddThisAfter( HandleNode & this, HandleNode & n ) with(this) {866 #ifdef VbyteDebug 867 serr | "enter:AddThisAfter, this:" | &this | " n:" | &n;884 static void AddThisAfter( HandleNode & s, HandleNode & n ) with(s) { 885 #ifdef VbyteDebug 886 serr | "enter:AddThisAfter, s:" | &s | " n:" | &n; 868 887 #endif // VbyteDebug 869 888 // 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). 870 889 verify( n.ulink != 0p ); 871 verify( this.ulink == n.ulink );890 verify( s.ulink == n.ulink ); 872 891 flink = n.flink; 873 892 blink = &n; 874 n.flink->blink = & this;875 n.flink = & this;893 n.flink->blink = &s; 894 n.flink = &s; 876 895 #ifdef VbyteDebug 877 896 { … … 894 913 // Delete the current HandleNode node. 895 914 896 static void DeleteNode( HandleNode & this ) with(this) {897 #ifdef VbyteDebug 898 serr | "enter:DeleteNode, this:" | &this;915 static void DeleteNode( HandleNode & s ) with(s) { 916 #ifdef VbyteDebug 917 serr | "enter:DeleteNode, s:" | &s; 899 918 #endif // VbyteDebug 900 919 flink->blink = blink; … … 906 925 907 926 908 909 927 // Allocates specified storage for a string from byte-string area. If not enough space remains to perform the 910 928 // allocation, the garbage collection routine is called. 911 929 912 static char * VbyteAlloc( VbyteHeap & this, int size ) with(this) {930 static char * VbyteAlloc( VbyteHeap & s, int size ) with(s) { 913 931 #ifdef VbyteDebug 914 932 serr | "enter:VbyteAlloc, size:" | size; … … 918 936 919 937 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 collector938 if ( NoBytes > ( uintptr_t )ExtVbyte ) { // enough room for new byte-string ? 939 garbage( s, size ); // firer up the garbage collector 922 940 verify( (( uintptr_t )EndVbyte + size) <= ( uintptr_t )ExtVbyte && "garbage run did not free up required space" ); 923 941 } // if … … 939 957 // VbyteAlloc to claim the new space, while doing optimal copying from old to new, then free old. 940 958 941 static char * VbyteTryAdjustLast( VbyteHeap & this, int delta ) with(this) { 942 959 static char * VbyteTryAdjustLast( VbyteHeap & s, int delta ) with(s) { 943 960 if ( ( uintptr_t )EndVbyte + delta <= ( uintptr_t )ExtVbyte ) { 944 961 // room available … … 961 978 // the address in the byte string area. 962 979 963 static void MoveThisAfter( HandleNode & this, const HandleNode & h ) with(this) {964 #ifdef VbyteDebug 965 serr | "enter:MoveThisAfter, this:" | & this | " h:" | & h;980 static void MoveThisAfter( HandleNode & s, const HandleNode & h ) with(s) { 981 #ifdef VbyteDebug 982 serr | "enter:MoveThisAfter, s:" | & s | " h:" | & h; 966 983 #endif // VbyteDebug 967 984 verify( h.ulink != 0p ); 968 verify( this.ulink == h.ulink );985 verify( s.ulink == h.ulink ); 969 986 if ( s < h.s ) { // check argument values 970 987 // serr | "VbyteSM: Error - Cannot move byte string starting at:" | s | " after byte string starting at:" … … 976 993 HandleNode *i; 977 994 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 ); 981 998 } // if 982 999 #ifdef VbyteDebug … … 1058 1075 // the containing string has been moved. Hence, they only require that their string pointers be adjusted. 1059 1076 1060 void compaction(VbyteHeap & this) with(this) {1077 void compaction(VbyteHeap & s) with(s) { 1061 1078 HandleNode *h; 1062 1079 char *obase, *nbase, *limit; … … 1098 1115 // the heap. The heap is then compacted in the existing heap or into the newly allocated heap. 1099 1116 1100 void garbage(VbyteHeap & this, int minreq ) with(this) {1117 void garbage(VbyteHeap & s, int minreq ) with(s) { 1101 1118 #ifdef VbyteDebug 1102 1119 serr | "enter:garbage"; … … 1124 1141 if ( ( double ) AmountFree < ( CurrSize * heap_expansion_freespace_threshold ) || AmountFree < minreq ) { // free space less than threshold or not enough to serve cur request 1125 1142 1126 extend( this, max( CurrSize, minreq ) ); // extend the heap1143 extend( s, max( CurrSize, minreq ) ); // extend the heap 1127 1144 1128 1145 // Peter says, "This needs work before it should be used." … … 1133 1150 1134 1151 } else { 1135 compaction( this); // in-place1152 compaction(s); // in-place 1136 1153 }// if 1137 1154 #ifdef VbyteDebug … … 1159 1176 // area is deleted. 1160 1177 1161 void extend( VbyteHeap & this, int size ) with (this) {1178 void extend( VbyteHeap & s, int size ) with (s) { 1162 1179 #ifdef VbyteDebug 1163 1180 serr | "enter:extend, size:" | size; … … 1171 1188 StartVbyte = EndVbyte = TEMP_ALLOC(char, CurrSize); 1172 1189 ExtVbyte = (void *)( StartVbyte + CurrSize ); 1173 compaction( this); // copy from old heap to new & adjust pointers to new heap1190 compaction(s); // copy from old heap to new & adjust pointers to new heap 1174 1191 free( OldStartVbyte ); // release old heap 1175 1192 #ifdef VbyteDebug -
libcfa/src/collections/string_res.hfa
r59c8dff rf988834 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 12 15:45:47 202313 // Update Count : 2 12 // Last Modified On : Thu Jan 4 11:28:06 2024 13 // Update Count : 27 14 14 // 15 15 … … 70 70 71 71 // Getters 72 size_t size(const string_res & s);72 size_t size(const string_res & s); 73 73 74 74 // Constructors, Assignment Operators, Destructor 75 void ?{}(string_res & s); // empty string76 void ?{}(string_res & s, const char* buffer, size_t bsize); // copy specific length from buffer77 static inline void ?{}(string_res & s, const char* rhs) { // copy from string literal (NULL-terminated)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) 78 78 (s){ rhs, strlen(rhs) }; 79 79 } 80 81 void ?{}(string_res &s, const string_res & s2) = void; 82 void ?{}(string_res &s, string_res & s2) = void; 80 static 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 85 void ?{}(string_res & s, const string_res & s2) = void; 86 void ?{}(string_res & s, string_res & s2) = void; 83 87 84 88 enum 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 ) {89 void ?{}(string_res & s, const string_res & src, StrResInitMode, size_t start, size_t len ); 90 static inline void ?{}(string_res & s, const string_res & src, StrResInitMode mode ) { 87 91 ?{}( s, src, mode, 0, size(src)); 88 92 } 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); 93 static 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 97 string_res & assign(string_res & s, const string_res & src, size_t maxlen); // copy specific length from other string 98 string_res & assign(string_res & s, const char * buffer, size_t bsize); // copy specific length from buffer 99 static inline string_res & ?=?(string_res & s, const char * c) { // copy from string literal (NULL-terminated) 100 return assign(s, c, strlen(c)); 101 } 102 string_res & ?=?(string_res & s, const string_res & c); 103 string_res & ?=?(string_res & s, string_res & c); 104 string_res & ?=?(string_res & s, char c); 105 106 void ^?{}(string_res & s); 99 107 100 108 // 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 );109 ofstream & ?|?(ofstream & out, const string_res & s); 110 void ?|?(ofstream & out, const string_res & s); 111 ifstream & ?|?(ifstream & in, string_res & s); 112 void ?|?( ifstream & in, string_res & s ); 105 113 106 114 struct _Istream_Rstr { … … 113 121 _Istream_Rstr wdi( unsigned int rwd, string_res & s ) { return (_Istream_Rstr)@{ &s, {{0p}, rwd, {.flags.rwd : true}} }; } 114 122 _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}} }; 116 124 } 117 125 _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; 119 127 } 120 128 _Istream_Rstr incl( const char scanset[], string_res & s ) { return (_Istream_Rstr)@{ &s, {{scanset}, -1, {.flags.inex : false}} }; } … … 129 137 130 138 // 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 } 139 void ?+=?(string_res & s, const string_res & s2); 140 void ?+=?(string_res & s, char c); 141 void append(string_res & s, const string_res & s2, size_t maxlen); 142 void ?+=?(string_res & s, const char * c); 143 void append(string_res & s, const char * buffer, size_t bsize); 144 145 static inline string_res & strcat(string_res & s, const string_res & s2) { s += s2; return s; } 146 static inline string_res & strcat(string_res & s, const char * c) { s += c; return s; } 147 static inline string_res & strncat(string_res & s, const string_res & s2, size_t maxlen) { append(s, s2, maxlen); return s; } 148 static inline string_res & strncat(string_res & s, const char * buffer, size_t bsize) { append(s, buffer, bsize); return s; } 149 150 // Repetition 151 void ?*=?(string_res & s, size_t factor); 137 152 138 153 // 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's141 //char codePointAt(const string_res & s, size_t index); // revisit under Unicode154 void assignAt(const string_res & s, size_t index, char val); 155 char ?[?](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 142 157 143 158 // Comparisons 144 int cmp (const string_res &, const string_res &);159 int strcmp (const string_res &, const string_res &); 145 160 bool ?==?(const string_res &, const string_res &); 146 161 bool ?!=?(const string_res &, const string_res &); … … 150 165 bool ?<? (const string_res &, const string_res &); 151 166 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 &);167 int strcmp(const string_res &, const char *); 168 bool ?==?(const string_res &, const char *); 169 bool ?!=?(const string_res &, const char *); 170 bool ?>? (const string_res &, const char *); 171 bool ?>=?(const string_res &, const char *); 172 bool ?<=?(const string_res &, const char *); 173 bool ?<? (const string_res &, const char *); 174 175 int strcmp(const char *, const string_res &); 176 bool ?==?(const char *, const string_res &); 177 bool ?!=?(const char *, const string_res &); 178 bool ?>? (const char *, const string_res &); 179 bool ?>=?(const char *, const string_res &); 180 bool ?<=?(const char *, const string_res &); 181 bool ?<? (const char *, const string_res &); 167 182 168 183 // String search 169 bool contains(const string_res & s, char ch); // single character170 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);184 bool contains(const string_res & s, char ch); // single character 185 186 int find(const string_res & s, char search); 187 int find(const string_res & s, const string_res & search); 188 int find(const string_res & s, const char * search); 189 int find(const string_res & s, const char * search, size_t searchsize); 190 191 int findFrom(const string_res & s, size_t fromPos, char search); 192 int findFrom(const string_res & s, size_t fromPos, const string_res & search); 193 int findFrom(const string_res & s, size_t fromPos, const char * search); 194 int findFrom(const string_res & s, size_t fromPos, const char * search, size_t searchsize); 195 196 bool includes(const string_res & s, const string_res & search); 197 bool includes(const string_res & s, const char * search); 198 bool includes(const string_res & s, const char * search, size_t searchsize); 199 200 bool startsWith(const string_res & s, const string_res & prefix); 201 bool startsWith(const string_res & s, const char * prefix); 202 bool startsWith(const string_res & s, const char * prefix, size_t prefixsize); 203 204 bool endsWith(const string_res & s, const string_res & suffix); 205 bool endsWith(const string_res & s, const char * suffix); 206 bool endsWith(const string_res & s, const char * suffix, size_t suffixsize); 207 208 int include(const string_res & s, const charclass_res & mask); 209 int exclude(const string_res & s, const charclass_res & mask); 195 210 196 211 // 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);212 void padStart(string_res & s, size_t n); 213 void padStart(string_res & s, size_t n, char padding); 214 void padEnd(string_res & s, size_t n); 200 215 void padEnd(string_res &s, size_t n, char padding); 201 216 -
libcfa/src/heap.cfa
r59c8dff rf988834 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Sep 30 17:31:15 202313 // Update Count : 161 712 // Last Modified On : Wed Jan 3 21:30:54 2024 13 // Update Count : 1619 14 14 // 15 15 … … 27 27 #include "bits/align.hfa" // libAlign 28 28 #include "bits/defs.hfa" // likely, unlikely 29 #include "concurrency/kernel/fwd.hfa" // __POLL_PREEMPTION29 #include "concurrency/kernel/fwd.hfa" // disable_interrupts, enable_interrupts 30 30 #include "startup.hfa" // STARTUP_PRIORITY_MEMORY 31 31 #include "math.hfa" // ceiling, min -
libcfa/src/interpose.cfa
r59c8dff rf988834 10 10 // Created On : Wed Mar 29 16:10:31 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 27 21:09:03 202313 // Update Count : 19612 // Last Modified On : Thu Jan 11 18:45:31 2024 13 // Update Count : 218 14 14 // 15 15 … … 18 18 extern "C" { 19 19 #include <dlfcn.h> // dlopen, dlsym 20 //#include <link.h> // dl_iterate_phdr 21 struct dl_phdr_info; 22 int dl_iterate_phdr( int (*)( struct dl_phdr_info *, size_t, void * ), void * ); 20 23 #include <execinfo.h> // backtrace, messages 21 24 } … … 23 26 #include "bits/defs.hfa" 24 27 #include "bits/signal.hfa" // sigHandler_? 28 #include "concurrency/kernel/fwd.hfa" // disable_interrupts, enable_interrupts 25 29 #include "startup.hfa" // STARTUP_PRIORITY_CORE 26 30 #include <assert.h> … … 87 91 void (* exit)( int ) __attribute__(( __noreturn__ )); 88 92 void (* abort)( void ) __attribute__(( __noreturn__ )); 93 int (* dl_iterate_phdr)( int (*)( struct dl_phdr_info *, size_t, void * ), void * ); 89 94 } __cabi_libc; 90 95 … … 102 107 #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" 103 108 INTERPOSE_LIBC( abort, version ); 104 INTERPOSE_LIBC( exit , version ); 109 INTERPOSE_LIBC( exit, version ); 110 INTERPOSE_LIBC( dl_iterate_phdr, version ); 105 111 #pragma GCC diagnostic pop 106 112 … … 150 156 } 151 157 } 158 159 extern "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 152 165 153 166 //============================================================================================= -
libcfa/src/iostream.cfa
r59c8dff rf988834 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Nov 17 13:33:12 202313 // Update Count : 18 5312 // Last Modified On : Wed Jan 3 10:53:13 2024 13 // Update Count : 1898 14 14 // 15 15 … … 984 984 } 985 985 986 istype & ?|?( istype & is, _Istream_Cquoted f ) {986 istype & ?|?( istype & is, _Istream_Cquoted f ) with( f ) { 987 987 char fmtstr[32]; // storage scanset and format codes 988 988 fmtstr[0] = '%'; … … 992 992 bool check = true; 993 993 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 width994 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 997 997 // wd is buffer bytes available (for input chars + null terminator) 998 998 // rwd is count of input chars 999 999 // 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; 1002 1002 pos += sprintf( &fmtstr[pos], "%d", rwd ); 1003 1003 } // if 1004 1004 1005 1005 int len = 0; // may not be set in fmt 1006 if ( ! f.flags.inex ) { // => quoted getline1007 // fprintf( stderr, "quoted\n" );1006 char enddelim; 1007 if ( ! cstr.flags.inex ) { // => quoted getline 1008 1008 args = fmt( is, "%*[ \f\n\r\t\v]" ); // remove leading whitespace 1009 1009 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 1013 1012 if ( len == 0 || eof( is ) ) goto Eof; 1014 1013 } // 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 ); 1020 1018 if ( check && len == rwd && ! eof( is ) ) { // might not fit 1021 1019 char peek; 1022 1020 fmt( is, "%c", &peek ); // check for delimiter 1023 // fprintf( stderr, "peek %d '%c'\n", args, peek );1024 1021 if ( ! eof( is ) ) { 1025 if ( peek != f.delimiter[0]) {1022 if ( peek != enddelim ) { 1026 1023 ungetc( is, peek ); 1027 1024 throwResume ExceptionInst( cstring_length ); … … 1030 1027 } else fmt( is, "%*c" ); // remove delimiter 1031 1028 Eof: ; 1032 if ( rwd > 0 && args == 0 ) f.s[0] = '\0';// read failed => no pattern match => set string to null1029 if ( rwd > 0 && args == 0 ) cstr.s[0] = '\0'; // read failed => no pattern match => set string to null 1033 1030 if ( args == 1 && eof( is ) ) { // data but scan ended at EOF 1034 // fprintf( stderr, "clear\n" );1035 1031 clear( is ); // => reset EOF => detect again on next read 1036 1032 } // if … … 1038 1034 } 1039 1035 1040 istype & ?|?( istype & is, _Istream_Cstr f ) {1036 istype & ?|?( istype & is, _Istream_Cstr f ) with( f ) { 1041 1037 const char * scanset; 1042 1038 size_t nscanset = 0; 1043 if ( f .flags.delimiter ) scanset = f.delimiter; // getline ?1039 if ( flags.delimiter ) scanset = delimiters; // getline ? 1044 1040 else scanset = f.scanset; 1045 1041 if ( scanset ) nscanset = strlen( scanset ); … … 1084 1080 if ( f.flags.delimiter ) { // getline 1085 1081 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] ); 1097 1083 if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1098 1084 else args = fmt( is, fmtstr, f.s, &len ); 1099 // fprintf( stderr, "getline %s %d %d %d\n", fmtstr, args, f.wd, eof( is ) );1100 1085 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 1104 1088 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 ); 1107 1092 throwResume ExceptionInst( cstring_length ); 1108 1093 } // if 1109 1094 } // if 1110 } else fmt( is, "%*c" ); // remove delimiter 1111 X: ; 1095 } else fmt( is, "%*c" ); // remove delimiter 1112 1096 } else { 1113 1097 // incl %[xxx], %*[xxx], %w[xxx], %*w[xxx] -
libcfa/src/iostream.hfa
r59c8dff rf988834 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Nov 15 17:55:31 202313 // Update Count : 59612 // Last Modified On : Wed Jan 3 10:53:18 2024 13 // Update Count : 610 14 14 // 15 15 … … 392 392 union { 393 393 const char * scanset; 394 char delimiter [2];394 char delimiters[3]; // [0] => left, [1] => right 395 395 }; 396 396 int wd; // width … … 412 412 413 413 struct _Istream_Cquoted { 414 char * s; 415 inline _Istream_str_base; 414 _Istream_Cstr cstr; 416 415 }; // _Istream_Cquoted 417 416 … … 419 418 // width must include room for null terminator 420 419 _Istream_Cstr wdi( unsigned int wd, char s[] ) { return (_Istream_Cstr)@{ s, { {0p}, wd, {.all : 0} } }; } 421 // read width does not include null terminator422 420 _Istream_Cstr wdi( unsigned int wd, unsigned int rwd, char s[] ) { 423 421 if ( wd <= rwd ) throw (cstring_length){ &cstring_length_vt }; 424 422 return (_Istream_Cstr)@{ s, { {0p}, rwd, {.flags.rwd : true} } }; 425 423 } 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'; 428 426 return (_Istream_Cquoted &)fmt; 429 427 } 430 428 _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 } 432 431 _Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; } 433 432 _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.