VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTGetOptArgv.cpp@ 57023

Last change on this file since 57023 was 56290, checked in by vboxsync, 10 years ago

IPRT: Updated (C) year.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.9 KB
Line 
1/* $Id: tstRTGetOptArgv.cpp 56290 2015-06-09 14:01:31Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTGetOptArgv*.
4 */
5
6/*
7 * Copyright (C) 2010-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <iprt/path.h>
31
32#include <iprt/err.h>
33#include <iprt/param.h>
34#include <iprt/getopt.h>
35#include <iprt/ldr.h>
36#include <iprt/string.h>
37#include <iprt/test.h>
38
39
40/*******************************************************************************
41* Global Variables *
42*******************************************************************************/
43static const struct
44{
45 /** The input string, bourne shell. */
46 const char *pszInBourne;
47 /** The input string, MS CRT. */
48 const char *pszInMsCrt;
49 /** Separators, NULL if default. */
50 const char *pszSeparators;
51 /** The number of arguments. */
52 int cArgs;
53 /** Expected argument vector. */
54 const char *apszArgs[16];
55 /** Expected quoted string, bourne shell. */
56 const char *pszOutBourneSh;
57 /** Expected quoted string, MS CRT. */
58 const char *pszOutMsCrt;
59} g_aTests[] =
60{
61 {
62 "0 1 \"\"2'' '3' 4 5 '''''6' 7 8 9 10 11",
63 "0 1 \"\"2 3 4 5 \"6\" 7 8 \"\"9\"\" 10 11",
64 NULL,
65 12,
66 {
67 "0",
68 "1",
69 "2",
70 "3",
71 "4",
72 "5",
73 "6",
74 "7",
75 "8",
76 "9",
77 "10",
78 "11",
79 NULL, NULL, NULL, NULL,
80 },
81 "0 1 2 3 4 5 6 7 8 9 10 11",
82 "0 1 2 3 4 5 6 7 8 9 10 11"
83 },
84 {
85 "\t\" asdf \" '\"'xyz \"\t\" '\n' '\"' \"'\"\n\r \\\"xyz",
86 /* Note! Two things here to make CommandLineArgW happy. First, it doesn't use IFS including newline/return, so
87 we skip that bit of the test. Second, it uses pre-2008 doubledouble quoting rules, unlike the CRT and IPRT
88 which uses the post-2008 rules. We work around that by putting that test last.
89 See http://www.daviddeley.com/autohotkey/parameters/parameters.htm */
90 "\t\" asdf \" \\\"xyz \"\t\" \"\n\" \"\\\"\" ' \"\"\"xyz\"",
91 NULL,
92 7,
93 {
94 " asdf ",
95 "\"xyz",
96 "\t",
97 "\n",
98 "\"",
99 "\'",
100 "\"xyz",
101 NULL,
102 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
103 },
104 "' asdf ' '\"xyz' '\t' '\n' '\"' ''\"'\"'' '\"xyz'",
105 "\" asdf \" \"\\\"xyz\" \"\t\" \"\n\" \"\\\"\" ' \"\\\"xyz\""
106 },
107 {
108 ":0::1::::2:3:4:5:",
109 ":0::1::::2:3:4:5:",
110 ":",
111 6,
112 {
113 "0",
114 "1",
115 "2",
116 "3",
117 "4",
118 "5",
119 NULL, NULL,
120 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
121 },
122 "0 1 2 3 4 5",
123 "0 1 2 3 4 5"
124 },
125 {
126 "0:1;2:3;4:5",
127 "0:1;2:3;4:5",
128 ";;;;;;;;;;;;;;;;;;;;;;:",
129 6,
130 {
131 "0",
132 "1",
133 "2",
134 "3",
135 "4",
136 "5",
137 NULL, NULL,
138 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
139 },
140 "0 1 2 3 4 5",
141 "0 1 2 3 4 5"
142 },
143 {
144 "abcd 'a ' ' b' ' c '",
145 "abcd \"a \" \" b\" \" c \"",
146 NULL,
147 4,
148 {
149 "abcd",
150 "a ",
151 " b",
152 " c ",
153 NULL, NULL, NULL, NULL,
154 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
155 },
156 "abcd 'a ' ' b' ' c '",
157 "abcd \"a \" \" b\" \" c \""
158 },
159 {
160 "'a\n\\b' 'de'\"'\"'fg' h ''\"'\"''",
161 "\"a\n\\b\" de'fg h \"'\" ",
162 NULL,
163 4,
164 {
165 "a\n\\b",
166 "de'fg",
167 "h",
168 "'",
169 NULL, NULL, NULL, NULL,
170 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
171 },
172 "'a\n\\b' 'de'\"'\"'fg' h ''\"'\"''",
173 "\"a\n\\b\" de'fg h '"
174 },
175 {
176 "arg1 \"arg2=\\\"zyx\\\"\" 'arg3=\\\\\\'",
177 "arg1 arg2=\\\"zyx\\\" arg3=\\\\\\",
178 NULL,
179 3,
180 {
181 "arg1",
182 "arg2=\"zyx\"",
183 "arg3=\\\\\\",
184 NULL, NULL, NULL, NULL, NULL,
185 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
186 },
187 "arg1 'arg2=\"zyx\"' 'arg3=\\\\\\'",
188 "arg1 \"arg2=\\\"zyx\\\"\" arg3=\\\\\\"
189 },
190 {
191 " a\\\\\\\\b d\"e f\"g h ij\t",
192 " a\\\\b d\"e f\"g h ij\t",
193 NULL,
194 4,
195 {
196 "a\\\\b",
197 "de fg",
198 "h",
199 "ij",
200 NULL, NULL, NULL, NULL,
201 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
202 },
203 "'a\\\\b' 'de fg' h ij",
204 "a\\\\b \"de fg\" h ij",
205 }
206};
207
208
209
210static void tstCheckNativeMsCrtToArgv(const char *pszCmdLine, int cExpectedArgs, const char * const *papszExpectedArgs)
211{
212#ifdef RT_OS_WINDOWS
213 /*
214 * Resolve APIs.
215 */
216 static void *(__stdcall * s_pfnLocalFree)(void *pvFree);
217 static PRTUTF16 *(__stdcall * s_pfnCommandLineToArgvW)(PCRTUTF16 pwszCmdLine, int *pcArgs);
218 if (!s_pfnCommandLineToArgvW)
219 {
220 *(void **)&s_pfnLocalFree = RTLdrGetSystemSymbol("kernel32.dll", "LocalFree");
221 RTTESTI_CHECK_RETV(s_pfnLocalFree != NULL);
222 *(void **)&s_pfnCommandLineToArgvW = RTLdrGetSystemSymbol("shell32.dll", "CommandLineToArgvW");
223 RTTESTI_CHECK_RETV(s_pfnCommandLineToArgvW != NULL);
224 }
225
226 /*
227 * Calc expected arguments if needed.
228 */
229 if (cExpectedArgs == -1)
230 for (cExpectedArgs = 0; papszExpectedArgs[cExpectedArgs]; cExpectedArgs++)
231 { /* nothing */ }
232
233 /*
234 * Convert input command line to UTF-16 and call native API.
235 */
236 RTUTF16 wszCmdLine[1024];
237 PRTUTF16 pwszCmdLine = &wszCmdLine[1];
238 RTTESTI_CHECK_RC_RETV(RTStrToUtf16Ex(pszCmdLine, RTSTR_MAX, &pwszCmdLine, 1023, NULL), VINF_SUCCESS);
239 wszCmdLine[0] = ' ';
240
241 int cArgs = -2;
242 PRTUTF16 *papwszArgs = s_pfnCommandLineToArgvW(wszCmdLine, &cArgs);
243
244 /*
245 * Check the result.
246 */
247 if (cArgs - 1 != cExpectedArgs)
248 RTTestIFailed("Native returns cArgs=%d, expected %d (cmdline=|%s|)", cArgs - 1, cExpectedArgs, pszCmdLine);
249 int cArgsCheck = RT_MIN(cArgs - 1, cExpectedArgs);
250 for (int i = 0; i < cArgsCheck; i++)
251 {
252 char *pszArg = NULL;
253 RTTESTI_CHECK_RC_RETV(RTUtf16ToUtf8(papwszArgs[i + 1], &pszArg), VINF_SUCCESS);
254 if (strcmp(pszArg, papszExpectedArgs[i]))
255 RTTestIFailed("Native returns argv[%i]='%s', expected '%s' (cmdline=|%s|)",
256 i, pszArg, papszExpectedArgs[i], pszCmdLine);
257 RTStrFree(pszArg);
258 }
259
260 if (papwszArgs)
261 s_pfnLocalFree(papwszArgs);
262#else
263 NOREF(pszCmdLine);
264 NOREF(cExpectedArgs);
265 NOREF(papszExpectedArgs);
266#endif
267}
268
269
270static void tst4(void)
271{
272 /*
273 * Microsoft CRT round-tripping.
274 */
275 RTTestISub("Round-trips / MS_CRT");
276 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)
277 {
278 /* First */
279 char **papszArgs1 = NULL;
280 int cArgs1 = -1;
281 int rc = RTGetOptArgvFromString(&papszArgs1, &cArgs1, g_aTests[i].pszInMsCrt,
282 RTGETOPTARGV_CNV_QUOTE_MS_CRT, g_aTests[i].pszSeparators);
283 if (rc == VINF_SUCCESS)
284 {
285 if (cArgs1 != g_aTests[i].cArgs)
286 RTTestIFailed("g_aTests[%i]: #1=%d, expected %d", i, cArgs1, g_aTests[i].cArgs);
287 for (int iArg = 0; iArg < cArgs1; iArg++)
288 if (strcmp(papszArgs1[iArg], g_aTests[i].apszArgs[iArg]) != 0)
289 RTTestIFailed("g_aTests[%i]/1: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s', '%s'))",
290 i, iArg, papszArgs1[iArg], g_aTests[i].apszArgs[iArg],
291 g_aTests[i].pszInMsCrt, g_aTests[i].pszSeparators);
292 RTTESTI_CHECK_RETV(papszArgs1[cArgs1] == NULL);
293 if (g_aTests[i].pszSeparators == NULL)
294 tstCheckNativeMsCrtToArgv(g_aTests[i].pszInMsCrt, g_aTests[i].cArgs, g_aTests[i].apszArgs);
295
296 /* Second */
297 char *pszArgs2 = NULL;
298 rc = RTGetOptArgvToString(&pszArgs2, papszArgs1, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
299 if (rc == VINF_SUCCESS)
300 {
301 if (strcmp(pszArgs2, g_aTests[i].pszOutMsCrt))
302 RTTestIFailed("g_aTests[%i]/2: '%s', expected '%s'", i, pszArgs2, g_aTests[i].pszOutMsCrt);
303
304 /*
305 * Third
306 */
307 char **papszArgs3 = NULL;
308 int cArgs3 = -1;
309 rc = RTGetOptArgvFromString(&papszArgs3, &cArgs3, pszArgs2, RTGETOPTARGV_CNV_QUOTE_MS_CRT, NULL);
310 if (rc == VINF_SUCCESS)
311 {
312 if (cArgs3 != g_aTests[i].cArgs)
313 RTTestIFailed("g_aTests[%i]/3: %d, expected %d", i, cArgs3, g_aTests[i].cArgs);
314 for (int iArg = 0; iArg < cArgs3; iArg++)
315 if (strcmp(papszArgs3[iArg], g_aTests[i].apszArgs[iArg]) != 0)
316 RTTestIFailed("g_aTests[%i]/3: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s',))",
317 i, iArg, papszArgs3[iArg], g_aTests[i].apszArgs[iArg], pszArgs2);
318 RTTESTI_CHECK_RETV(papszArgs3[cArgs3] == NULL);
319 if (g_aTests[i].pszSeparators == NULL)
320 tstCheckNativeMsCrtToArgv(pszArgs2, g_aTests[i].cArgs, g_aTests[i].apszArgs);
321
322 /*
323 * Fourth
324 */
325 char *pszArgs4 = NULL;
326 rc = RTGetOptArgvToString(&pszArgs4, papszArgs3, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
327 if (rc == VINF_SUCCESS)
328 {
329 if (strcmp(pszArgs4, pszArgs2))
330 RTTestIFailed("g_aTests[%i]/4: '%s' does not match #4='%s'", i, pszArgs2, pszArgs4);
331 RTStrFree(pszArgs4);
332 }
333 else
334 RTTestIFailed("g_aTests[%i]/4: RTGetOptArgvToString() -> %Rrc", i, rc);
335 RTGetOptArgvFree(papszArgs3);
336 }
337 else
338 RTTestIFailed("g_aTests[%i]/3: RTGetOptArgvFromString() -> %Rrc", i, rc);
339 RTStrFree(pszArgs2);
340 }
341 else
342 RTTestIFailed("g_aTests[%i]/2: RTGetOptArgvToString() -> %Rrc", i, rc);
343 RTGetOptArgvFree(papszArgs1);
344 }
345 else
346 RTTestIFailed("g_aTests[%i]/1: RTGetOptArgvFromString(,,'%s', '%s') -> %Rrc",
347 i, g_aTests[i].pszInMsCrt, g_aTests[i].pszSeparators, rc);
348 }
349
350}
351
352
353
354static void tst3(void)
355{
356 /*
357 * Bourne shell round-tripping.
358 */
359 RTTestISub("Round-trips / BOURNE_SH");
360 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)
361 {
362 /* First */
363 char **papszArgs1 = NULL;
364 int cArgs1 = -1;
365 int rc = RTGetOptArgvFromString(&papszArgs1, &cArgs1, g_aTests[i].pszInBourne,
366 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, g_aTests[i].pszSeparators);
367 if (rc == VINF_SUCCESS)
368 {
369 if (cArgs1 != g_aTests[i].cArgs)
370 RTTestIFailed("g_aTests[%i]: #1=%d, expected %d", i, cArgs1, g_aTests[i].cArgs);
371 for (int iArg = 0; iArg < cArgs1; iArg++)
372 if (strcmp(papszArgs1[iArg], g_aTests[i].apszArgs[iArg]) != 0)
373 RTTestIFailed("g_aTests[%i]/1: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s', '%s'))",
374 i, iArg, papszArgs1[iArg], g_aTests[i].apszArgs[iArg],
375 g_aTests[i].pszInBourne, g_aTests[i].pszSeparators);
376 RTTESTI_CHECK_RETV(papszArgs1[cArgs1] == NULL);
377
378 /* Second */
379 char *pszArgs2 = NULL;
380 rc = RTGetOptArgvToString(&pszArgs2, papszArgs1, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
381 if (rc == VINF_SUCCESS)
382 {
383 if (strcmp(pszArgs2, g_aTests[i].pszOutBourneSh))
384 RTTestIFailed("g_aTests[%i]/2: '%s', expected '%s'", i, pszArgs2, g_aTests[i].pszOutBourneSh);
385
386 /*
387 * Third
388 */
389 char **papszArgs3 = NULL;
390 int cArgs3 = -1;
391 rc = RTGetOptArgvFromString(&papszArgs3, &cArgs3, pszArgs2, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL);
392 if (rc == VINF_SUCCESS)
393 {
394 if (cArgs3 != g_aTests[i].cArgs)
395 RTTestIFailed("g_aTests[%i]/3: %d, expected %d", i, cArgs3, g_aTests[i].cArgs);
396 for (int iArg = 0; iArg < cArgs3; iArg++)
397 if (strcmp(papszArgs3[iArg], g_aTests[i].apszArgs[iArg]) != 0)
398 RTTestIFailed("g_aTests[%i]/3: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s',))",
399 i, iArg, papszArgs3[iArg], g_aTests[i].apszArgs[iArg], pszArgs2);
400 RTTESTI_CHECK_RETV(papszArgs3[cArgs3] == NULL);
401
402 /*
403 * Fourth
404 */
405 char *pszArgs4 = NULL;
406 rc = RTGetOptArgvToString(&pszArgs4, papszArgs3, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
407 if (rc == VINF_SUCCESS)
408 {
409 if (strcmp(pszArgs4, pszArgs2))
410 RTTestIFailed("g_aTests[%i]/4: '%s' does not match #4='%s'", i, pszArgs2, pszArgs4);
411 RTStrFree(pszArgs4);
412 }
413 else
414 RTTestIFailed("g_aTests[%i]/4: RTGetOptArgvToString() -> %Rrc", i, rc);
415 RTGetOptArgvFree(papszArgs3);
416 }
417 else
418 RTTestIFailed("g_aTests[%i]/3: RTGetOptArgvFromString() -> %Rrc", i, rc);
419 RTStrFree(pszArgs2);
420 }
421 else
422 RTTestIFailed("g_aTests[%i]/2: RTGetOptArgvToString() -> %Rrc", i, rc);
423 RTGetOptArgvFree(papszArgs1);
424 }
425 else
426 RTTestIFailed("g_aTests[%i]/1: RTGetOptArgvFromString(,,'%s', '%s') -> %Rrc",
427 i, g_aTests[i].pszInBourne, g_aTests[i].pszSeparators, rc);
428 }
429}
430
431
432static void tst2(void)
433{
434 RTTestISub("RTGetOptArgvToString / MS_CRT");
435
436 static const struct
437 {
438 const char * const apszArgs[5];
439 const char *pszCmdLine;
440 } s_aMscCrtTests[] =
441 {
442 {
443 { "abcd", "a ", " b", " c ", NULL },
444 "abcd \"a \" \" b\" \" c \""
445 },
446 {
447 { "a\\\\\\b", "de fg", "h", NULL, NULL },
448 "a\\\\\\b \"de fg\" h"
449 },
450 {
451 { "a\\\"b", "c", "d", "\"", NULL },
452 "\"a\\\\\\\"b\" c d \"\\\"\""
453 },
454 {
455 { "a\\\\b c", "d", "e", " \\", NULL },
456 "\"a\\\\b c\" d e \" \\\\\""
457 },
458 };
459
460 for (size_t i = 0; i < RT_ELEMENTS(s_aMscCrtTests); i++)
461 {
462 char *pszCmdLine = NULL;
463 int rc = RTGetOptArgvToString(&pszCmdLine, s_aMscCrtTests[i].apszArgs, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
464 RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS);
465 if (!strcmp(s_aMscCrtTests[i].pszCmdLine, pszCmdLine))
466 tstCheckNativeMsCrtToArgv(pszCmdLine, -1, s_aMscCrtTests[i].apszArgs);
467 else
468 RTTestIFailed("g_aTest[%i] failed:\n"
469 " got '%s'\n"
470 " expected '%s'\n",
471 i, pszCmdLine, s_aMscCrtTests[i].pszCmdLine);
472 RTStrFree(pszCmdLine);
473 }
474
475 for (size_t i = 0; i < RT_ELEMENTS(g_aTests); i++)
476 {
477 char *pszCmdLine = NULL;
478 int rc = RTGetOptArgvToString(&pszCmdLine, g_aTests[i].apszArgs, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
479 RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS);
480 if (!strcmp(g_aTests[i].pszOutMsCrt, pszCmdLine))
481 tstCheckNativeMsCrtToArgv(pszCmdLine, g_aTests[i].cArgs, g_aTests[i].apszArgs);
482 else
483 RTTestIFailed("g_aTests[%i] failed:\n"
484 " got |%s|\n"
485 " expected |%s|\n",
486 i, pszCmdLine, g_aTests[i].pszOutMsCrt);
487 RTStrFree(pszCmdLine);
488 }
489
490
491
492 RTTestISub("RTGetOptArgvToString / BOURNE_SH");
493
494 for (size_t i = 0; i < RT_ELEMENTS(g_aTests); i++)
495 {
496 char *pszCmdLine = NULL;
497 int rc = RTGetOptArgvToString(&pszCmdLine, g_aTests[i].apszArgs, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
498 RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS);
499 if (strcmp(g_aTests[i].pszOutBourneSh, pszCmdLine))
500 RTTestIFailed("g_aTests[%i] failed:\n"
501 " got |%s|\n"
502 " expected |%s|\n",
503 i, pszCmdLine, g_aTests[i].pszOutBourneSh);
504 RTStrFree(pszCmdLine);
505 }
506}
507
508static void tst1(void)
509{
510 RTTestISub("RTGetOptArgvFromString");
511 char **papszArgs = NULL;
512 int cArgs = -1;
513 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, "", RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL), VINF_SUCCESS);
514 RTTESTI_CHECK_RETV(cArgs == 0);
515 RTTESTI_CHECK_RETV(papszArgs);
516 RTTESTI_CHECK_RETV(!papszArgs[0]);
517 RTGetOptArgvFree(papszArgs);
518
519 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, "0 1 \"\"2'' '3' 4 5 '''''6' 7 8 9 10 11",
520 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL), VINF_SUCCESS);
521 RTTESTI_CHECK_RETV(cArgs == 12);
522 RTTESTI_CHECK_RETV(!strcmp(papszArgs[0], "0"));
523 RTTESTI_CHECK_RETV(!strcmp(papszArgs[1], "1"));
524 RTTESTI_CHECK_RETV(!strcmp(papszArgs[2], "2"));
525 RTTESTI_CHECK_RETV(!strcmp(papszArgs[3], "3"));
526 RTTESTI_CHECK_RETV(!strcmp(papszArgs[4], "4"));
527 RTTESTI_CHECK_RETV(!strcmp(papszArgs[5], "5"));
528 RTTESTI_CHECK_RETV(!strcmp(papszArgs[6], "6"));
529 RTTESTI_CHECK_RETV(!strcmp(papszArgs[7], "7"));
530 RTTESTI_CHECK_RETV(!strcmp(papszArgs[8], "8"));
531 RTTESTI_CHECK_RETV(!strcmp(papszArgs[9], "9"));
532 RTTESTI_CHECK_RETV(!strcmp(papszArgs[10], "10"));
533 RTTESTI_CHECK_RETV(!strcmp(papszArgs[11], "11"));
534 RTTESTI_CHECK_RETV(!papszArgs[12]);
535 RTGetOptArgvFree(papszArgs);
536
537 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, "\t\" asdf \" '\"'xyz \"\t\" '\n' '\"' \"'\"\n\r ",
538 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL), VINF_SUCCESS);
539 RTTESTI_CHECK_RETV(cArgs == 6);
540 RTTESTI_CHECK_RETV(!strcmp(papszArgs[0], " asdf "));
541 RTTESTI_CHECK_RETV(!strcmp(papszArgs[1], "\"xyz"));
542 RTTESTI_CHECK_RETV(!strcmp(papszArgs[2], "\t"));
543 RTTESTI_CHECK_RETV(!strcmp(papszArgs[3], "\n"));
544 RTTESTI_CHECK_RETV(!strcmp(papszArgs[4], "\""));
545 RTTESTI_CHECK_RETV(!strcmp(papszArgs[5], "\'"));
546 RTTESTI_CHECK_RETV(!papszArgs[6]);
547 RTGetOptArgvFree(papszArgs);
548
549 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, ":0::1::::2:3:4:5:",
550 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, ":"), VINF_SUCCESS);
551 RTTESTI_CHECK_RETV(cArgs == 6);
552 RTTESTI_CHECK_RETV(!strcmp(papszArgs[0], "0"));
553 RTTESTI_CHECK_RETV(!strcmp(papszArgs[1], "1"));
554 RTTESTI_CHECK_RETV(!strcmp(papszArgs[2], "2"));
555 RTTESTI_CHECK_RETV(!strcmp(papszArgs[3], "3"));
556 RTTESTI_CHECK_RETV(!strcmp(papszArgs[4], "4"));
557 RTTESTI_CHECK_RETV(!strcmp(papszArgs[5], "5"));
558 RTTESTI_CHECK_RETV(!papszArgs[6]);
559 RTGetOptArgvFree(papszArgs);
560
561 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, "0:1;2:3;4:5", RTGETOPTARGV_CNV_QUOTE_BOURNE_SH,
562 ";;;;;;;;;;;;;;;;;;;;;;:"), VINF_SUCCESS);
563 RTTESTI_CHECK_RETV(cArgs == 6);
564 RTTESTI_CHECK_RETV(!strcmp(papszArgs[0], "0"));
565 RTTESTI_CHECK_RETV(!strcmp(papszArgs[1], "1"));
566 RTTESTI_CHECK_RETV(!strcmp(papszArgs[2], "2"));
567 RTTESTI_CHECK_RETV(!strcmp(papszArgs[3], "3"));
568 RTTESTI_CHECK_RETV(!strcmp(papszArgs[4], "4"));
569 RTTESTI_CHECK_RETV(!strcmp(papszArgs[5], "5"));
570 RTTESTI_CHECK_RETV(!papszArgs[6]);
571 RTGetOptArgvFree(papszArgs);
572
573 /*
574 * Tests from the list.
575 */
576 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)
577 {
578 papszArgs = NULL;
579 cArgs = -1;
580 int rc = RTGetOptArgvFromString(&papszArgs, &cArgs, g_aTests[i].pszInBourne, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH,
581 g_aTests[i].pszSeparators);
582 if (rc == VINF_SUCCESS)
583 {
584 if (cArgs == g_aTests[i].cArgs)
585 {
586 for (int iArg = 0; iArg < cArgs; iArg++)
587 if (strcmp(papszArgs[iArg], g_aTests[i].apszArgs[iArg]) != 0)
588 RTTestIFailed("g_aTests[%i]: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s', '%s'))",
589 i, iArg, papszArgs[iArg], g_aTests[i].apszArgs[iArg],
590 g_aTests[i].pszInBourne, g_aTests[i].pszSeparators);
591 RTTESTI_CHECK_RETV(papszArgs[cArgs] == NULL);
592 }
593 else
594 RTTestIFailed("g_aTests[%i]: cArgs=%u, expected %u for RTGetOptArgvFromString(,,'%s', '%s')",
595 i, cArgs, g_aTests[i].cArgs, g_aTests[i].pszInBourne, g_aTests[i].pszSeparators);
596 RTGetOptArgvFree(papszArgs);
597 }
598 else
599 RTTestIFailed("g_aTests[%i]: RTGetOptArgvFromString(,,'%s', '%s') -> %Rrc",
600 i, g_aTests[i].pszInBourne, g_aTests[i].pszSeparators, rc);
601 }
602}
603
604
605int main()
606{
607 /*
608 * Init RT+Test.
609 */
610 RTTEST hTest;
611 int rc = RTTestInitAndCreate("tstRTGetOptArgv", &hTest);
612 if (rc)
613 return rc;
614 RTTestBanner(hTest);
615
616 /*
617 * The test.
618 */
619 tst1();
620 tst2();
621 tst4();
622 tst3();
623
624 /*
625 * Summary.
626 */
627 return RTTestSummaryAndDestroy(hTest);
628}
629
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette