source: tests/collections/string-overwrite.cfa @ 6cc87c0

Last change on this file since 6cc87c0 was 6cc87c0, checked in by Michael Brooks <mlbrooks@…>, 2 months ago

String bug fixes and new tests.

Enabled white-box visibility (DEBUG_ functions) into the string representation for heap-oriented tests.

string-gc/basicFillCompact

  • newly testable, now with the DEBUG_ visibility, but was basically already working

string-gc/fillCompact_withSharedEdits

  • new check for bug fixed here, where an append that triggers a compaction left substrings with dangling pointers

to the old text-pad range; fix is how string_res/assign now sequences growth-pushing operations before grabbing
pointers into the ranges of the old-version

string-overwrite

  • new broad check a few of whose cases are fixed here; fixes are the adjustments to the case priorities and

edge-case classifications in string_res/assign "adjust all substring string and handle locations" section

  • Property mode set to 100644
File size: 9.3 KB
Line 
1#include <containers/string.hfa>
2
3/*
4
5Modify a subrange of a string, while a witness is watching another subrange of the same string.
6
7Cases are the relative positions and overlaps of the modifier vs the witness.
8MS = modifier start
9ME = modifier end
10WS = witness start
11WE = witness end
12
13The dest does:
14  starts with the entire string being, initially, the alphabet; prints this entire alphabet
15  sets up modifier and witness as ranges within it, and prints a visualization of those ranges
16  does the main modification
17  prints the result of the main modification, which is always an unsurprising consequence of the modifier range, but shows little about what happened to the witness, particularly if the witness is/became empty
18  modifies the witness to be "?"
19  prints the result of this second modification, which implies what the witness included after the main modification
20
21Deriving the concrete list of cases....
22
23By definition of a string, MS <= ME and WS <= WE.
24This API's convention has Start positions being inclusive and end positions being exclusive.
25
26With 1 equivalence class:
27MS = ME = WS = WE               1
28
29With 2 equivalence classes:
30   <    =    =
31MS   rest                       2
32WS   rest                       3
33
34   =    <    =
35MS   ME   WS   WE               4
36WS   WE   MS   ME               5
37MS   WS   ME   WE               6
38
39   =    =    <
40        rest   ME               7
41        rest   WE               8
42
43With 3 equivalence classes
44   <    <    =
45MS   ME   WS   WE               9
46     WS   ME   WE               10
47+2                              11, 12
48
49   <    =    <
50MS   WS   ME   WE               13
51          WE   ME               14
52+2                              15, 16
53
54   =    <    <
55MS   WS   WE   ME               17
56     ME   WS   WE               18
57+2                              19, 20
58
59With 4 equivalence classes
60   <    <    <
61MS   ME   WS   WE               21
62     WS   ME   WE               22
63          WE   ME               23
64+3                              24, 25, 26
65
66
67
68*/
69
70
71void showOneReplacement(string & s, int ms, int me, int ws, int we, const char* replaceWith) {
72
73    assert( ms >= 0 && ms <= me && me <= size(s) );
74    assert( ws >= 0 && ws <= we && we <= size(s) );
75
76    string mod = s(ms, me)`shareEdits;
77    string wit = s(ws, we)`shareEdits;
78
79    string modOld = mod;
80    string witOld = wit;
81
82    // s, before the mode
83    sout | s;
84
85    // visualize the pair of ranges
86    sout | nlOff;
87    for ( i; size(s) ) {
88        if( i < ms || i > me ) {
89            sout | ' ';
90        } else if ( i < me ) {
91            sout | '-';
92        } else {
93            assert ( i == me );
94            sout | '!';
95        }
96    } sout | nl;
97    for ( i; size(s) ) {
98        if( i < ws || i > we ) {
99            sout | ' ';
100        } else if ( i < we ) {
101            sout | '-';
102        } else {
103            assert ( i == we );
104            sout | '?';
105        }
106    }
107    sout | nl;
108    sout | nlOn;
109
110    mod = replaceWith;    // main replacement
111    sout | s | "( wit = " | wit | "witlen = " | size(wit) | " )";
112    wit = "?";            // witness-revelaing replacement
113    sout | s;
114}
115
116void runReplaceCases() {
117    char * alphabetTemplate = "abcdefghijklmnopqrstuvwxyz";
118    struct { int ms; int me; int ws; int we; char *replaceWith; char *label; } cases[] = {
119        { 12, 14, 10, 20, "xxxxx", "warmup" },
120//        { 12, 14, 12, 14, "xxxxx", ""       },  // the bug that got me into this test (should be a dup with case 6)
121        { 10, 10, 10, 10, "=====", "1"      },
122        { 10, 10, 10, 10, "=="   , ""       },
123        { 10, 10, 10, 10, "="    , ""       },
124        { 10, 10, 10, 10, ""     , ""       },
125        { 10, 12, 12, 12, "=====", "2"      },
126        { 10, 12, 12, 12, "=="   , ""       },
127        { 10, 12, 12, 12, "="    , ""       },
128        { 10, 12, 12, 12, ""     , ""       },
129        { 12, 12, 10, 12, "=====", "3"      },
130        { 12, 12, 10, 12, "=="   , ""       },
131        { 12, 12, 10, 12, "="    , ""       },
132        { 12, 12, 10, 12, ""     , ""       },
133        { 10, 10, 12, 12, "=====", "4"      },
134        { 10, 10, 12, 12, "=="   , ""       },
135        { 10, 10, 12, 12, "="    , ""       },
136        { 10, 10, 12, 12, ""     , ""       },
137        { 12, 12, 10, 10, "=====", "5"      },
138        { 12, 12, 10, 10, "=="   , ""       },
139        { 12, 12, 10, 10, "="    , ""       },
140        { 12, 12, 10, 10, ""     , ""       },
141        { 10, 12, 10, 12, "=====", "6"      },
142        { 10, 12, 10, 12, "=="   , ""       },
143        { 10, 12, 10, 12, "="    , ""       },
144        { 10, 12, 10, 12, ""     , ""       },
145        { 10, 12, 10, 10, "=====", "7"      },
146        { 10, 12, 10, 10, "=="   , ""       },
147        { 10, 12, 10, 10, "="    , ""       },
148        { 10, 12, 10, 10, ""     , ""       },
149        { 10, 10, 10, 12, "=====", "8"      },
150        { 10, 10, 10, 12, "=="   , ""       },
151        { 10, 10, 10, 12, "="    , ""       },
152        { 10, 10, 10, 12, ""     , ""       },
153        { 10, 12, 14, 14, "=====", "9"      },
154        { 10, 12, 14, 14, "=="   , ""       },
155        { 10, 12, 14, 14, "="    , ""       },
156        { 10, 12, 14, 14, ""     , ""       },
157        { 10, 14, 12, 14, "=====", "10"     },
158        { 10, 14, 12, 14, "=="   , ""       },
159        { 10, 14, 12, 14, "="    , ""       },  // FORMERLY unrunnable bug: tries to print seemingly infinite string
160        { 10, 14, 12, 14, ""     , ""       },  // ditto
161        { 14, 14, 10, 12, "=====", "11"     },
162        { 14, 14, 10, 12, "=="   , ""       },
163        { 14, 14, 10, 12, "="    , ""       },
164        { 14, 14, 10, 12, ""     , ""       },
165        { 12, 14, 10, 14, "=====", "12"     }, // correctness observation:  watching klmn while mn |-> xxx gives klxxx because the mn is inside what I'm watching
166        { 12, 14, 10, 14, "=="   , ""       },
167        { 12, 14, 10, 14, "="    , ""       },
168        { 12, 14, 10, 14, ""     , ""       },
169        { 10, 12, 12, 14, "=====", "13"     },
170        { 10, 12, 12, 14, "=="   , ""       },
171        { 10, 12, 12, 14, "="    , ""       },
172        { 10, 12, 12, 14, ""     , ""       },
173        { 10, 14, 12, 12, "=====", "14"     },
174        { 10, 14, 12, 12, "=="   , ""       },
175        { 10, 14, 12, 12, "="    , ""       },
176        { 10, 14, 12, 12, ""     , ""       },
177        { 12, 14, 10, 12, "=====", "15"     },
178        { 12, 14, 10, 12, "=="   , ""       },
179        { 12, 14, 10, 12, "="    , ""       },
180        { 12, 14, 10, 12, ""     , ""       },
181        { 12, 12, 10, 14, "=====", "16"     },
182        { 12, 12, 10, 14, "=="   , ""       },
183        { 12, 12, 10, 14, "="    , ""       },
184        { 12, 12, 10, 14, ""     , ""       },
185        { 10, 14, 10, 12, "=====", "17"     },
186        { 10, 14, 10, 12, "=="   , ""       },
187        { 10, 14, 10, 12, "="    , ""       },
188        { 10, 14, 10, 12, ""     , ""       },
189        { 10, 10, 12, 14, "=====", "18"     },
190        { 10, 10, 12, 14, "=="   , ""       },
191        { 10, 10, 12, 14, "="    , ""       },
192        { 10, 10, 12, 14, ""     , ""       },
193        { 10, 12, 10, 14, "=====", "19"     },
194        { 10, 12, 10, 14, "=="   , ""       },
195        { 10, 12, 10, 14, "="    , ""       },
196        { 10, 12, 10, 14, ""     , ""       },
197        { 12, 14, 10, 10, "=====", "20"     },
198        { 12, 14, 10, 10, "=="   , ""       },
199        { 12, 14, 10, 10, "="    , ""       },
200        { 12, 14, 10, 10, ""     , ""       },
201        { 10, 12, 14, 16, "=====", "21"     },
202        { 10, 12, 14, 16, "=="   , ""       },
203        { 10, 12, 14, 16, "="    , ""       },
204        { 10, 12, 14, 16, ""     , ""       },
205        { 10, 14, 12, 16, "=====", "22"     },
206        { 10, 14, 12, 16, "=="   , ""       },
207        { 10, 14, 12, 16, "="    , ""       },
208        { 10, 14, 12, 16, ""     , ""       },
209        { 10, 16, 12, 14, "=====", "23"     },
210        { 10, 16, 12, 14, "=="   , ""       },
211        { 10, 16, 12, 14, "="    , ""       },
212        { 10, 16, 12, 14, ""     , ""       },
213        { 14, 16, 10, 12, "=====", "24"     },
214        { 14, 16, 10, 12, "=="   , ""       },
215        { 14, 16, 10, 12, "="    , ""       },
216        { 14, 16, 10, 12, ""     , ""       },
217        { 12, 16, 10, 14, "=====", "25"     },
218        { 12, 16, 10, 14, "=="   , ""       },
219        { 12, 16, 10, 14, "="    , ""       },
220        { 12, 16, 10, 14, ""     , ""       },
221        { 12, 14, 10, 16, "=====", "26"     },
222        { 12, 14, 10, 16, "=="   , ""       },
223        { 12, 14, 10, 16, "="    , ""       },
224        { 12, 14, 10, 16, ""     , ""       },
225/*
226        { , , , , "=====", "NN"     },
227        {  "=="   , ""       },
228        {  "="    , ""       },
229        {  ""     , ""       },
230*/
231    };
232    for ( i; sizeof(cases)/sizeof(cases[0]) ) {
233        sout | "------------------------------------------------------------------------" | cases[i].label;
234        string replaceIn = alphabetTemplate;
235        showOneReplacement( replaceIn, cases[i].ms, cases[i].me, cases[i].ws, cases[i].we, cases[i].replaceWith );
236    }
237}
238
239
240// void f( string & s, string & toEdit ) {
241
242//     sout | s | "|" | toEdit | "|";
243
244//     s(14, 16) = "-";
245//     sout | s | "|" | toEdit | "|";
246// }
247
248int main() {
249    //          0         1         2
250    //          01234567890123456789012345
251    string s = "abcdefghijklmnopqrstuvwxyz";
252
253    s(5,10) = "qqqqq";  // start=5, end=10, len=5
254
255    sout | s;
256
257
258    s(5,5) = "-----";  // start=5, end=5, len=0
259
260    sout | s;
261
262    runReplaceCases();
263}
Note: See TracBrowser for help on using the repository browser.