source: tests/collections/string-overwrite.cfa@ b200492

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since b200492 was 6cc87c0, checked in by Michael Brooks <mlbrooks@…>, 4 years 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.