1[[case]] # set/get attribute
2code = '''
3    lfs_format(&lfs, &cfg) => 0;
4    lfs_mount(&lfs, &cfg) => 0;
5    lfs_mkdir(&lfs, "hello") => 0;
6    lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
7    lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
8    lfs_file_close(&lfs, &file);
9    lfs_unmount(&lfs) => 0;
10
11    lfs_mount(&lfs, &cfg) => 0;
12    memset(buffer, 0, sizeof(buffer));
13    lfs_setattr(&lfs, "hello", 'A', "aaaa",   4) => 0;
14    lfs_setattr(&lfs, "hello", 'B', "bbbbbb", 6) => 0;
15    lfs_setattr(&lfs, "hello", 'C', "ccccc",  5) => 0;
16    lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4;
17    lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 6;
18    lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
19    memcmp(buffer,    "aaaa",   4) => 0;
20    memcmp(buffer+4,  "bbbbbb", 6) => 0;
21    memcmp(buffer+10, "ccccc",  5) => 0;
22
23    lfs_setattr(&lfs, "hello", 'B', "", 0) => 0;
24    lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4;
25    lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 0;
26    lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
27    memcmp(buffer,    "aaaa",         4) => 0;
28    memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0;
29    memcmp(buffer+10, "ccccc",        5) => 0;
30
31    lfs_removeattr(&lfs, "hello", 'B') => 0;
32    lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4;
33    lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => LFS_ERR_NOATTR;
34    lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
35    memcmp(buffer,    "aaaa",         4) => 0;
36    memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0;
37    memcmp(buffer+10, "ccccc",        5) => 0;
38
39    lfs_setattr(&lfs, "hello", 'B', "dddddd", 6) => 0;
40    lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4;
41    lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 6;
42    lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
43    memcmp(buffer,    "aaaa",   4) => 0;
44    memcmp(buffer+4,  "dddddd", 6) => 0;
45    memcmp(buffer+10, "ccccc",  5) => 0;
46
47    lfs_setattr(&lfs, "hello", 'B', "eee", 3) => 0;
48    lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4;
49    lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 3;
50    lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
51    memcmp(buffer,    "aaaa",      4) => 0;
52    memcmp(buffer+4,  "eee\0\0\0", 6) => 0;
53    memcmp(buffer+10, "ccccc",     5) => 0;
54
55    lfs_setattr(&lfs, "hello", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC;
56    lfs_setattr(&lfs, "hello", 'B', "fffffffff", 9) => 0;
57    lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4;
58    lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 9;
59    lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
60
61    lfs_unmount(&lfs) => 0;
62
63    lfs_mount(&lfs, &cfg) => 0;
64    memset(buffer, 0, sizeof(buffer));
65    lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4;
66    lfs_getattr(&lfs, "hello", 'B', buffer+4,  9) => 9;
67    lfs_getattr(&lfs, "hello", 'C', buffer+13, 5) => 5;
68    memcmp(buffer,    "aaaa",      4) => 0;
69    memcmp(buffer+4,  "fffffffff", 9) => 0;
70    memcmp(buffer+13, "ccccc",     5) => 0;
71
72    lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0;
73    lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello");
74    memcmp(buffer, "hello", strlen("hello")) => 0;
75    lfs_file_close(&lfs, &file);
76    lfs_unmount(&lfs) => 0;
77'''
78
79[[case]] # set/get root attribute
80code = '''
81    lfs_format(&lfs, &cfg) => 0;
82    lfs_mount(&lfs, &cfg) => 0;
83    lfs_mkdir(&lfs, "hello") => 0;
84    lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
85    lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
86    lfs_file_close(&lfs, &file);
87    lfs_unmount(&lfs) => 0;
88
89    lfs_mount(&lfs, &cfg) => 0;
90    memset(buffer, 0, sizeof(buffer));
91    lfs_setattr(&lfs, "/", 'A', "aaaa",   4) => 0;
92    lfs_setattr(&lfs, "/", 'B', "bbbbbb", 6) => 0;
93    lfs_setattr(&lfs, "/", 'C', "ccccc",  5) => 0;
94    lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4;
95    lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 6;
96    lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
97    memcmp(buffer,    "aaaa",   4) => 0;
98    memcmp(buffer+4,  "bbbbbb", 6) => 0;
99    memcmp(buffer+10, "ccccc",  5) => 0;
100
101    lfs_setattr(&lfs, "/", 'B', "", 0) => 0;
102    lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4;
103    lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 0;
104    lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
105    memcmp(buffer,    "aaaa",         4) => 0;
106    memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0;
107    memcmp(buffer+10, "ccccc",        5) => 0;
108
109    lfs_removeattr(&lfs, "/", 'B') => 0;
110    lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4;
111    lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => LFS_ERR_NOATTR;
112    lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
113    memcmp(buffer,    "aaaa",         4) => 0;
114    memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0;
115    memcmp(buffer+10, "ccccc",        5) => 0;
116
117    lfs_setattr(&lfs, "/", 'B', "dddddd", 6) => 0;
118    lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4;
119    lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 6;
120    lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
121    memcmp(buffer,    "aaaa",   4) => 0;
122    memcmp(buffer+4,  "dddddd", 6) => 0;
123    memcmp(buffer+10, "ccccc",  5) => 0;
124
125    lfs_setattr(&lfs, "/", 'B', "eee", 3) => 0;
126    lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4;
127    lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 3;
128    lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
129    memcmp(buffer,    "aaaa",      4) => 0;
130    memcmp(buffer+4,  "eee\0\0\0", 6) => 0;
131    memcmp(buffer+10, "ccccc",     5) => 0;
132
133    lfs_setattr(&lfs, "/", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC;
134    lfs_setattr(&lfs, "/", 'B', "fffffffff", 9) => 0;
135    lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4;
136    lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 9;
137    lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5;
138    lfs_unmount(&lfs) => 0;
139
140    lfs_mount(&lfs, &cfg) => 0;
141    memset(buffer, 0, sizeof(buffer));
142    lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4;
143    lfs_getattr(&lfs, "/", 'B', buffer+4,  9) => 9;
144    lfs_getattr(&lfs, "/", 'C', buffer+13, 5) => 5;
145    memcmp(buffer,    "aaaa",      4) => 0;
146    memcmp(buffer+4,  "fffffffff", 9) => 0;
147    memcmp(buffer+13, "ccccc",     5) => 0;
148
149    lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0;
150    lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello");
151    memcmp(buffer, "hello", strlen("hello")) => 0;
152    lfs_file_close(&lfs, &file);
153    lfs_unmount(&lfs) => 0;
154'''
155
156[[case]] # set/get file attribute
157code = '''
158    lfs_format(&lfs, &cfg) => 0;
159    lfs_mount(&lfs, &cfg) => 0;
160    lfs_mkdir(&lfs, "hello") => 0;
161    lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
162    lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
163    lfs_file_close(&lfs, &file);
164    lfs_unmount(&lfs) => 0;
165
166    lfs_mount(&lfs, &cfg) => 0;
167    memset(buffer, 0, sizeof(buffer));
168    struct lfs_attr attrs1[] = {
169        {'A', buffer,    4},
170        {'B', buffer+4,  6},
171        {'C', buffer+10, 5},
172    };
173    struct lfs_file_config cfg1 = {.attrs=attrs1, .attr_count=3};
174
175    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
176    memcpy(buffer,    "aaaa",   4);
177    memcpy(buffer+4,  "bbbbbb", 6);
178    memcpy(buffer+10, "ccccc",  5);
179    lfs_file_close(&lfs, &file) => 0;
180    memset(buffer, 0, 15);
181    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
182    lfs_file_close(&lfs, &file) => 0;
183    memcmp(buffer,    "aaaa",   4) => 0;
184    memcmp(buffer+4,  "bbbbbb", 6) => 0;
185    memcmp(buffer+10, "ccccc",  5) => 0;
186
187    attrs1[1].size = 0;
188    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
189    lfs_file_close(&lfs, &file) => 0;
190    memset(buffer, 0, 15);
191    attrs1[1].size = 6;
192    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
193    lfs_file_close(&lfs, &file) => 0;
194    memcmp(buffer,    "aaaa",         4) => 0;
195    memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0;
196    memcmp(buffer+10, "ccccc",        5) => 0;
197
198    attrs1[1].size = 6;
199    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
200    memcpy(buffer+4,  "dddddd", 6);
201    lfs_file_close(&lfs, &file) => 0;
202    memset(buffer, 0, 15);
203    attrs1[1].size = 6;
204    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
205    lfs_file_close(&lfs, &file) => 0;
206    memcmp(buffer,    "aaaa",   4) => 0;
207    memcmp(buffer+4,  "dddddd", 6) => 0;
208    memcmp(buffer+10, "ccccc",  5) => 0;
209
210    attrs1[1].size = 3;
211    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
212    memcpy(buffer+4,  "eee", 3);
213    lfs_file_close(&lfs, &file) => 0;
214    memset(buffer, 0, 15);
215    attrs1[1].size = 6;
216    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
217    lfs_file_close(&lfs, &file) => 0;
218    memcmp(buffer,    "aaaa",      4) => 0;
219    memcmp(buffer+4,  "eee\0\0\0", 6) => 0;
220    memcmp(buffer+10, "ccccc",     5) => 0;
221
222    attrs1[0].size = LFS_ATTR_MAX+1;
223    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1)
224        => LFS_ERR_NOSPC;
225
226    struct lfs_attr attrs2[] = {
227        {'A', buffer,    4},
228        {'B', buffer+4,  9},
229        {'C', buffer+13, 5},
230    };
231    struct lfs_file_config cfg2 = {.attrs=attrs2, .attr_count=3};
232    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDWR, &cfg2) => 0;
233    memcpy(buffer+4,  "fffffffff", 9);
234    lfs_file_close(&lfs, &file) => 0;
235    attrs1[0].size = 4;
236    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
237    lfs_file_close(&lfs, &file) => 0;
238
239    lfs_unmount(&lfs) => 0;
240
241    lfs_mount(&lfs, &cfg) => 0;
242    memset(buffer, 0, sizeof(buffer));
243    struct lfs_attr attrs3[] = {
244        {'A', buffer,    4},
245        {'B', buffer+4,  9},
246        {'C', buffer+13, 5},
247    };
248    struct lfs_file_config cfg3 = {.attrs=attrs3, .attr_count=3};
249
250    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg3) => 0;
251    lfs_file_close(&lfs, &file) => 0;
252    memcmp(buffer,    "aaaa",      4) => 0;
253    memcmp(buffer+4,  "fffffffff", 9) => 0;
254    memcmp(buffer+13, "ccccc",     5) => 0;
255
256    lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0;
257    lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello");
258    memcmp(buffer, "hello", strlen("hello")) => 0;
259    lfs_file_close(&lfs, &file);
260    lfs_unmount(&lfs) => 0;
261'''
262
263[[case]] # deferred file attributes
264code = '''
265    lfs_format(&lfs, &cfg) => 0;
266    lfs_mount(&lfs, &cfg) => 0;
267    lfs_mkdir(&lfs, "hello") => 0;
268    lfs_file_open(&lfs, &file, "hello/hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
269    lfs_file_write(&lfs, &file, "hello", strlen("hello")) => strlen("hello");
270    lfs_file_close(&lfs, &file);
271    lfs_unmount(&lfs) => 0;
272
273    lfs_mount(&lfs, &cfg) => 0;
274    lfs_setattr(&lfs, "hello/hello", 'B', "fffffffff",  9) => 0;
275    lfs_setattr(&lfs, "hello/hello", 'C', "ccccc",      5) => 0;
276
277    memset(buffer, 0, sizeof(buffer));
278    struct lfs_attr attrs1[] = {
279        {'B', "gggg", 4},
280        {'C', "",     0},
281        {'D', "hhhh", 4},
282    };
283    struct lfs_file_config cfg1 = {.attrs=attrs1, .attr_count=3};
284
285    lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
286
287    lfs_getattr(&lfs, "hello/hello", 'B', buffer,    9) => 9;
288    lfs_getattr(&lfs, "hello/hello", 'C', buffer+9,  9) => 5;
289    lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => LFS_ERR_NOATTR;
290    memcmp(buffer,    "fffffffff",          9) => 0;
291    memcmp(buffer+9,  "ccccc\0\0\0\0",      9) => 0;
292    memcmp(buffer+18, "\0\0\0\0\0\0\0\0\0", 9) => 0;
293
294    lfs_file_sync(&lfs, &file) => 0;
295    lfs_getattr(&lfs, "hello/hello", 'B', buffer,    9) => 4;
296    lfs_getattr(&lfs, "hello/hello", 'C', buffer+9,  9) => 0;
297    lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => 4;
298    memcmp(buffer,    "gggg\0\0\0\0\0",     9) => 0;
299    memcmp(buffer+9,  "\0\0\0\0\0\0\0\0\0", 9) => 0;
300    memcmp(buffer+18, "hhhh\0\0\0\0\0",     9) => 0;
301
302    lfs_file_close(&lfs, &file) => 0;
303    lfs_unmount(&lfs) => 0;
304'''
305