2 * Copyright (C) 2011, The AROS Development Team. All rights reserved.
3 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
5 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
8 #include <string.h> /* for memset() */
10 #include <proto/alib.h>
11 #include <proto/exec.h>
12 #include <proto/dos.h>
14 #include <dos/stdio.h>
15 #include <exec/lists.h>
17 /* For compatibility with AOS, our test reference */
19 static AROS_UFH2(VOID
, _SPutC
,
20 AROS_UFHA(BYTE
, c
, D0
),
21 AROS_UFHA(BYTE
**, ptr
, A3
))
32 VOID
SPrintf( char *target
, const char *format
, ...)
34 RawDoFmt( format
, (APTR
)&(((ULONG
*)&format
)[1]), _SPutC
, &target
);
37 #define SPrintf(target,format,args...) __sprintf(target,format ,##args )
40 #define TEST_START(name) do { \
41 CONST_STRPTR test_name = name ; \
42 struct List expr_list; \
47 #define VERIFY_EQ(retval, expected) \
49 __typeof__(retval) val = retval; \
50 if (val != (expected)) { \
51 struct Node *expr_node = AllocVec(sizeof(struct Node) + 256, MEMF_ANY); \
52 expr_node->ln_Name = (TEXT *)(&expr_node[1]); \
53 SPrintf(expr_node->ln_Name, "%s: %s (%ld) != %ld", mname, #retval , (LONG)(SIPTR)val, (LONG)(SIPTR)expected); \
54 AddTail(&expr_list, expr_node); \
59 #define VERIFY_STREQ(retval, expected) \
61 CONST_STRPTR val = (CONST_STRPTR)(retval); \
62 if (strcmp(val,(expected)) != 0) { \
63 struct Node *expr_node = AllocVec(sizeof(struct Node) + 256, MEMF_ANY); \
64 expr_node->ln_Name = (TEXT *)(&expr_node[1]); \
65 SPrintf(expr_node->ln_Name, "%s: %s (%s) != %s", mname, #retval, val, expected); \
66 AddTail(&expr_list, expr_node); \
72 #define VERIFY_RET(func, ret, reterr) \
75 VERIFY_EQ(func, ret); \
76 VERIFY_EQ(IoErr(), reterr); \
83 Printf("Test %ld: Failed (%s)\n", (LONG)tests, test_name); \
84 while ((node = RemHead(&expr_list)) != NULL) { \
85 Printf("\t%s\n", node->ln_Name); \
91 static inline SIPTR
readargs_buff(CONST_STRPTR format
, IPTR
*args
, CONST_STRPTR input
, struct RDArgs
**retp
)
94 struct RDArgs
*ret
, *in
;
96 in
= AllocDosObject(DOS_RDARGS
, NULL
);
97 in
->RDA_Source
.CS_Buffer
= (APTR
)input
;
98 in
->RDA_Source
.CS_Length
= strlen(input
);
99 in
->RDA_Source
.CS_CurChr
= 0;
102 ret
= ReadArgs(format
, args
, in
);
105 retval
= (ret
!= NULL
) ? RETURN_OK
: IoErr();
110 static inline SIPTR
readargs_file(CONST_STRPTR format
, IPTR
*args
, CONST_STRPTR input
, struct RDArgs
**retp
)
116 CONST_STRPTR tmpfile
= "RAM:readargs.test";
118 oldout
= SelectOutput(Open("NIL:", MODE_NEWFILE
));
120 io
= Open(tmpfile
, MODE_NEWFILE
);
121 Write(io
, input
, strlen(input
));
124 io
= Open(tmpfile
, MODE_OLDFILE
);
129 ret
= ReadArgs(format
, args
, NULL
);
132 retval
= (ret
!= NULL
) ? RETURN_OK
: IoErr();
134 Close(SelectInput(oldin
));
135 Close(SelectOutput(oldout
));
142 #define TEST_READARGS(format, input) \
143 TEST_START(format " '" input "'"); \
145 for (is_buff = 0; is_buff < 2; is_buff++) { \
146 CONST_STRPTR mname = is_buff ? "buff" : "file"; \
147 IPTR args[10] = { (IPTR)"inv1", (IPTR)"inv2", (IPTR)"inv3" }; \
149 struct RDArgs *ret = NULL; \
151 ioerr = readargs_buff(format, (IPTR *)&args[0], Need_Implicit_NL ? input "\n" : input, &ret); \
153 ioerr = readargs_file(format, (IPTR *)&args[0], input, &ret); }
155 #define TEST_ENDARGS() \
156 if (ret) FreeDosObject(DOS_RDARGS, ret); \
160 int main(int argc
, char **argv
)
162 int tests
= 0, tests_failed
= 0;
163 BOOL Need_Implicit_NL
;
165 /* The following behaviour is versus AOS 3.1,
166 * which should be used as the reference for
167 * the AROS implementation
169 Need_Implicit_NL
= FALSE
;
171 /* Verify that the buffer version requires a \n
172 * at the end, and the file version does not.
174 TEST_READARGS("KEYA","val1\n");
175 VERIFY_EQ(ioerr
, RETURN_OK
);
176 VERIFY_STREQ(args
[0], "val1");
179 TEST_READARGS("KEYA","val1");
181 // Succeeds on AROS, fails on AOS.
183 // AOS: VERIFY_EQ(ioerr, ERROR_TOO_MANY_ARGS);
184 // AROS: VERIFY_EQ(ioerr, RETURN_OK);
186 VERIFY_EQ(ioerr
, RETURN_OK
);
187 VERIFY_STREQ(args
[0], "val1");
190 TEST_READARGS("KEYA","?\n\n");
191 VERIFY_EQ(ioerr
, RETURN_OK
);
192 VERIFY_STREQ(args
[0], "inv1");
195 TEST_READARGS("KEYA","?\nval1\n");
196 VERIFY_EQ(ioerr
, RETURN_OK
);
197 VERIFY_STREQ(args
[0], "val1");
200 TEST_READARGS("KEYA","?\nval1");
202 // Succeeds on AROS, fails on AOS.
204 // AOS: VERIFY_EQ(ioerr, ERROR_TOO_MANY_ARGS);
205 // AROS: VERIFY_EQ(ioerr, RETURN_OK);
207 VERIFY_EQ(ioerr
, RETURN_OK
);
208 VERIFY_STREQ(args
[0], "val1");
211 TEST_READARGS("KEYA","keya val1\n");
212 VERIFY_EQ(ioerr
, RETURN_OK
);
213 VERIFY_STREQ(args
[0], "val1");
216 TEST_READARGS("KEYA","keya val1");
218 // Succeeds on AROS, fails on AOS.
220 // AOS: VERIFY_EQ(ioerr, ERROR_TOO_MANY_ARGS);
221 // AROS: VERIFY_EQ(ioerr, RETURN_OK);
223 VERIFY_EQ(ioerr
, RETURN_OK
);
224 VERIFY_STREQ(args
[0], "val1");
227 TEST_READARGS("KEYA,KEYB","val1 keyb ");
228 VERIFY_EQ(ioerr
, ERROR_KEY_NEEDS_ARG
);
229 // Acceptable difference:
230 // AOS: VERIFY_STREQ(args[0], "val1");
231 // AROS: VERIFY_STREQ(args[0], "inv1");
232 VERIFY_STREQ(args
[1], "inv2");
235 TEST_READARGS("KEYA,KEYB","val1 keyb ");
236 VERIFY_EQ(ioerr
, ERROR_KEY_NEEDS_ARG
);
237 // Acceptable difference:
238 // AOS: VERIFY_STREQ(args[0], "val1");
239 // AROS: VERIFY_STREQ(args[0], "inv1");
240 VERIFY_STREQ(args
[1], "inv2");
243 Need_Implicit_NL
= TRUE
;
245 /* Verify that \n is treated as part of the key name,
246 * and is not ignored at the end of the ReadArgs template
248 TEST_READARGS("KEYA\n","keya val1");
249 VERIFY_EQ(ioerr
, ERROR_TOO_MANY_ARGS
);
252 TEST_READARGS("KEYA","keya=val1");
253 VERIFY_EQ(ioerr
, RETURN_OK
);
254 VERIFY_STREQ(args
[0], "val1");
257 TEST_READARGS("KEYA,KEYB","val1 val2");
258 VERIFY_EQ(ioerr
, RETURN_OK
);
259 VERIFY_STREQ(args
[0], "val1");
260 VERIFY_STREQ(args
[1], "val2");
263 TEST_READARGS("KEYA,KEYB","keya=val1 keyb=val2");
264 VERIFY_EQ(ioerr
, RETURN_OK
);
265 VERIFY_STREQ(args
[0], "val1");
266 VERIFY_STREQ(args
[1], "val2");
269 TEST_READARGS("KEYA,KEYB","keya val1 keyb val2");
270 VERIFY_EQ(ioerr
, RETURN_OK
);
271 VERIFY_STREQ(args
[0], "val1");
272 VERIFY_STREQ(args
[1], "val2");
275 TEST_READARGS("KEYA,KEYB","keya val1 val2");
276 VERIFY_EQ(ioerr
, RETURN_OK
);
277 VERIFY_STREQ(args
[0], "val1");
278 VERIFY_STREQ(args
[1], "val2");
281 TEST_READARGS("KEYA,KEYB","keyb val2 val1");
282 VERIFY_EQ(ioerr
, RETURN_OK
);
283 VERIFY_STREQ(args
[0], "val1");
284 VERIFY_STREQ(args
[1], "val2");
287 TEST_READARGS("KEYA,KEYB","keyb val2 keya val1");
288 VERIFY_EQ(ioerr
, RETURN_OK
);
289 VERIFY_STREQ(args
[0], "val1");
290 VERIFY_STREQ(args
[1], "val2");
293 TEST_READARGS("KEYA,KEYB/F","val1 val2 val3");
294 VERIFY_EQ(ioerr
, RETURN_OK
);
295 VERIFY_STREQ(args
[0], "val1");
296 VERIFY_STREQ(args
[1], "val2 val3");
299 TEST_READARGS("KEYA,KEYB/F","val1 val2 val3=val4 \"val5\" keya=val6");
300 VERIFY_EQ(ioerr
, RETURN_OK
);
301 VERIFY_STREQ(args
[0], "val1");
302 VERIFY_STREQ(args
[1], "val2 val3=val4 \"val5\" keya=val6");
305 TEST_READARGS("KEYA,KEYB/F","val1 val2 val3\n");
306 VERIFY_EQ(ioerr
, RETURN_OK
);
307 VERIFY_STREQ(args
[0], "val1");
308 VERIFY_STREQ(args
[1], "val2 val3");
311 TEST_READARGS("KEYA,KEYB/F,KEYC","val1 keyc val4 val2 val3\n");
312 VERIFY_EQ(ioerr
, RETURN_OK
);
313 VERIFY_STREQ(args
[0], "val1");
314 VERIFY_STREQ(args
[1], "val2 val3");
315 VERIFY_STREQ(args
[2], "val4");
318 TEST_READARGS("KEYA,KEYB/M","val1 val2 val3");
319 VERIFY_EQ(ioerr
, RETURN_OK
);
320 VERIFY_STREQ(args
[0], "val1");
321 VERIFY_STREQ(((CONST_STRPTR
*)args
[1])[0], "val2");
322 VERIFY_STREQ(((CONST_STRPTR
*)args
[1])[1], "val3");
323 VERIFY_EQ(((CONST_STRPTR
*)args
[1])[2], NULL
);
326 TEST_READARGS("KEYA,KEYB/M","keyb=val1 keya=val2 keyb=val3");
327 VERIFY_EQ(ioerr
, RETURN_OK
);
328 VERIFY_STREQ(args
[0], "val2");
329 VERIFY_STREQ(((CONST_STRPTR
*)args
[1])[0], "val1");
330 VERIFY_STREQ(((CONST_STRPTR
*)args
[1])[1], "val3");
331 VERIFY_EQ(((CONST_STRPTR
*)args
[1])[2], NULL
);
334 TEST_READARGS("KEYA,KEYB/M,KEYC","keyb=val1 keya=val2 val3 val4");
335 VERIFY_EQ(ioerr
, RETURN_OK
);
336 VERIFY_STREQ(args
[0], "val2");
337 VERIFY_STREQ(((CONST_STRPTR
*)args
[1])[0], "val1");
338 VERIFY_STREQ(((CONST_STRPTR
*)args
[1])[1], "val3");
339 VERIFY_STREQ(((CONST_STRPTR
*)args
[1])[2], "val4");
340 VERIFY_EQ(((CONST_STRPTR
*)args
[1])[3], NULL
);
343 TEST_READARGS("KEYA/S,KEYB,KEYC","keyb=val1 keya val3");
344 VERIFY_EQ(ioerr
, RETURN_OK
);
345 VERIFY_EQ(args
[0], DOSTRUE
);
346 VERIFY_STREQ(args
[1],"val1");
347 VERIFY_STREQ(args
[2],"val3");
350 TEST_READARGS("KEYA/K,KEYB,KEYC","val1 keya val2 val3");
351 VERIFY_EQ(ioerr
, RETURN_OK
);
352 VERIFY_STREQ(args
[0],"val2");
353 VERIFY_STREQ(args
[1],"val1");
354 VERIFY_STREQ(args
[2],"val3");
357 TEST_READARGS("KEYA/S,KEYB/F","keya \"val1 val2\"");
358 VERIFY_EQ(ioerr
, RETURN_OK
);
359 VERIFY_EQ(args
[0],DOSTRUE
);
360 VERIFY_STREQ(args
[1],"val1 val2");
363 TEST_READARGS("KEYA/S,KEYB/F","\"val1 val2\"");
364 VERIFY_EQ(ioerr
, RETURN_OK
);
365 VERIFY_STREQ(args
[0],"inv1");
366 VERIFY_STREQ(args
[1],"val1 val2");
369 TEST_READARGS("KEYA/S,KEYB/F","\"val1\" val2");
370 VERIFY_EQ(ioerr
, RETURN_OK
);
371 VERIFY_STREQ(args
[0],"inv1");
372 VERIFY_STREQ(args
[1],"val1 val2");
375 TEST_READARGS("KEYA/S,KEYB/F","val1 \"val2\"");
376 VERIFY_EQ(ioerr
, RETURN_OK
);
377 VERIFY_STREQ(args
[0],"inv1");
378 VERIFY_STREQ(args
[1],"val1 \"val2\"");
381 TEST_READARGS("KEYA/S,KEYB/F","\"va\"l1 \"val2");
382 VERIFY_EQ(ioerr
, RETURN_OK
);
383 VERIFY_STREQ(args
[0],"inv1");
384 VERIFY_STREQ(args
[1],"val1 \"val2");
387 TEST_READARGS("KEYA/S,KEYB/F","\"va\"l1 \"val2\"");
388 VERIFY_EQ(ioerr
, RETURN_OK
);
389 VERIFY_STREQ(args
[0],"inv1");
390 VERIFY_STREQ(args
[1],"val1 \"val2\"");
393 if (tests_failed
== 0)
394 Printf("All %ld test passed\n", (LONG
)tests
);
396 Printf("%ld of %ld tests failed\n", (LONG
)tests_failed
, (LONG
)tests
);