source: tests/collections/string-overwrite.cfa @ 7a780ad

Last change on this file since 7a780ad was e8b3717, checked in by Michael Brooks <mlbrooks@…>, 5 months ago

Modify substring interface from start-end to start-len, and add a missing test.

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