VirtualBox

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

Last change on this file since 55747 was 55671, checked in by vboxsync, 10 years ago

RTGetOptArgvFromString: Added fFlags parameter for selecting the quoting style.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.3 KB
Line 
1/* $Id: tstRTGetOptArgv.cpp 55671 2015-05-05 16:27:52Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTGetOptArgv*.
4 */
5
6/*
7 * Copyright (C) 2010 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 ",
86 "\t\" asdf \" \\\"xyz \"\t\" \"\n\" \"\\\"\" '\n\r ",
87 NULL,
88 6,
89 {
90 " asdf ",
91 "\"xyz",
92 "\t",
93 "\n",
94 "\"",
95 "\'",
96 NULL, NULL,
97 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
98 },
99 "' asdf ' '\"xyz' '\t' '\n' '\"' ''\"'\"''",
100 "\" asdf \" \"\\\"xyz\" \"\t\" \"\n\" \"\\\"\" '"
101 },
102 {
103 ":0::1::::2:3:4:5:",
104 ":0::1::::2:3:4:5:",
105 ":",
106 6,
107 {
108 "0",
109 "1",
110 "2",
111 "3",
112 "4",
113 "5",
114 NULL, NULL,
115 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
116 },
117 "0 1 2 3 4 5",
118 "0 1 2 3 4 5"
119 },
120 {
121 "0:1;2:3;4:5",
122 "0:1;2:3;4:5",
123 ";;;;;;;;;;;;;;;;;;;;;;:",
124 6,
125 {
126 "0",
127 "1",
128 "2",
129 "3",
130 "4",
131 "5",
132 NULL, NULL,
133 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
134 },
135 "0 1 2 3 4 5",
136 "0 1 2 3 4 5"
137 },
138 {
139 "abcd 'a ' ' b' ' c '",
140 "abcd \"a \" \" b\" \" c \"",
141 NULL,
142 4,
143 {
144 "abcd",
145 "a ",
146 " b",
147 " c ",
148 NULL, NULL, NULL, NULL,
149 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
150 },
151 "abcd 'a ' ' b' ' c '",
152 "abcd \"a \" \" b\" \" c \""
153 },
154 {
155 "'a\n\\b' 'de'\"'\"'fg' h ''\"'\"''",
156 "\"a\n\\b\" de'fg h \"'\" ",
157 NULL,
158 4,
159 {
160 "a\n\\b",
161 "de'fg",
162 "h",
163 "'",
164 NULL, NULL, NULL, NULL,
165 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
166 },
167 "'a\n\\b' 'de'\"'\"'fg' h ''\"'\"''",
168 "\"a\n\\b\" de'fg h '"
169 },
170 {
171 "arg1 \"arg2=\\\"zyx\\\"\" 'arg3=\\\\\\'",
172 "arg1 arg2=\\\"zyx\\\" arg3=\\\\\\",
173 NULL,
174 3,
175 {
176 "arg1",
177 "arg2=\"zyx\"",
178 "arg3=\\\\\\",
179 NULL, NULL, NULL, NULL, NULL,
180 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
181 },
182 "arg1 'arg2=\"zyx\"' 'arg3=\\\\\\'",
183 "arg1 \"arg2=\\\"zyx\\\"\" arg3=\\\\\\"
184 },
185 {
186 " a\\\\\\\\b d\"e f\"g h ij\t",
187 " a\\\\b d\"e f\"g h ij\t",
188 NULL,
189 4,
190 {
191 "a\\\\b",
192 "de fg",
193 "h",
194 "ij",
195 NULL, NULL, NULL, NULL,
196 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
197 },
198 "'a\\\\b' 'de fg' h ij",
199 "a\\\\b \"de fg\" h ij",
200 }
201};
202
203
204
205static void tstCheckNativeMsCrtToArgv(const char *pszCmdLine, int cExpectedArgs, const char * const *papszExpectedArgs)
206{
207#ifdef RT_OS_WINDOWS
208 /*
209 * Resolve APIs.
210 */
211 static void *(__stdcall * s_pfnLocalFree)(void *pvFree);
212 static PRTUTF16 *(__stdcall * s_pfnCommandLineToArgvW)(PCRTUTF16 pwszCmdLine, int *pcArgs);
213 if (!s_pfnCommandLineToArgvW)
214 {
215 *(void **)&s_pfnLocalFree = RTLdrGetSystemSymbol("kernel32.dll", "LocalFree");
216 RTTESTI_CHECK_RETV(s_pfnLocalFree != NULL);
217 *(void **)&s_pfnCommandLineToArgvW = RTLdrGetSystemSymbol("shell32.dll", "CommandLineToArgvW");
218 RTTESTI_CHECK_RETV(s_pfnCommandLineToArgvW != NULL);
219 }
220
221 /*
222 * Calc expected arguments if needed.
223 */
224 if (cExpectedArgs == -1)
225 for (cExpectedArgs = 0; papszExpectedArgs[cExpectedArgs]; cExpectedArgs++)
226 { /* nothing */ }
227
228 /*
229 * Convert input command line to UTF-16 and call native API.
230 */
231 RTUTF16 wszCmdLine[1024];
232 PRTUTF16 pwszCmdLine = &wszCmdLine[1];
233 RTTESTI_CHECK_RC_RETV(RTStrToUtf16Ex(pszCmdLine, RTSTR_MAX, &pwszCmdLine, 1023, NULL), VINF_SUCCESS);
234 wszCmdLine[0] = ' ';
235
236 int cArgs = -2;
237 PRTUTF16 *papwszArgs = s_pfnCommandLineToArgvW(wszCmdLine, &cArgs);
238
239 /*
240 * Check the result.
241 */
242 if (cArgs - 1 != cExpectedArgs)
243 RTTestIFailed("Native returns cArgs=%d, expected %d (cmdline=|%s|)", cArgs - 1, cExpectedArgs, pszCmdLine);
244 int cArgsCheck = RT_MIN(cArgs - 1, cExpectedArgs);
245 for (int i = 0; i < cArgsCheck; i++)
246 {
247 char *pszArg = NULL;
248 RTTESTI_CHECK_RC_RETV(RTUtf16ToUtf8(papwszArgs[i + 1], &pszArg), VINF_SUCCESS);
249 if (strcmp(pszArg, papszExpectedArgs[i]))
250 RTTestIFailed("Native returns argv[%i]='%s', expected '%s' (cmdline=|%s|)",
251 i, pszArg, papszExpectedArgs[i], pszCmdLine);
252 RTStrFree(pszArg);
253 }
254
255 if (papwszArgs)
256 s_pfnLocalFree(papwszArgs);
257#else
258 NOREF(pszCmdLine);
259 NOREF(cExpectedArgs);
260 NOREF(papszExpectedArgs);
261#endif
262}
263
264
265static void tst4(void)
266{
267 /*
268 * Microsoft CRT round-tripping.
269 */
270 RTTestISub("Round-trips / MS_CRT");
271 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)
272 {
273 /* First */
274 char **papszArgs1 = NULL;
275 int cArgs1 = -1;
276 int rc = RTGetOptArgvFromString(&papszArgs1, &cArgs1, g_aTests[i].pszInMsCrt,
277 RTGETOPTARGV_CNV_QUOTE_MS_CRT, g_aTests[i].pszSeparators);
278 if (rc == VINF_SUCCESS)
279 {
280 if (cArgs1 != g_aTests[i].cArgs)
281 RTTestIFailed("g_aTests[%i]: #1=%d, expected %d", i, cArgs1, g_aTests[i].cArgs);
282 for (int iArg = 0; iArg < cArgs1; iArg++)
283 if (strcmp(papszArgs1[iArg], g_aTests[i].apszArgs[iArg]) != 0)
284 RTTestIFailed("g_aTests[%i]/1: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s', '%s'))",
285 i, iArg, papszArgs1[iArg], g_aTests[i].apszArgs[iArg],
286 g_aTests[i].pszInMsCrt, g_aTests[i].pszSeparators);
287 RTTESTI_CHECK_RETV(papszArgs1[cArgs1] == NULL);
288 tstCheckNativeMsCrtToArgv(g_aTests[i].pszInMsCrt, g_aTests[i].cArgs, g_aTests[i].apszArgs);
289
290 /* Second */
291 char *pszArgs2 = NULL;
292 rc = RTGetOptArgvToString(&pszArgs2, papszArgs1, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
293 if (rc == VINF_SUCCESS)
294 {
295 if (strcmp(pszArgs2, g_aTests[i].pszOutMsCrt))
296 RTTestIFailed("g_aTests[%i]/2: '%s', expected '%s'", i, pszArgs2, g_aTests[i].pszOutMsCrt);
297
298 /*
299 * Third
300 */
301 char **papszArgs3 = NULL;
302 int cArgs3 = -1;
303 rc = RTGetOptArgvFromString(&papszArgs3, &cArgs3, pszArgs2, RTGETOPTARGV_CNV_QUOTE_MS_CRT, NULL);
304 if (rc == VINF_SUCCESS)
305 {
306 if (cArgs3 != g_aTests[i].cArgs)
307 RTTestIFailed("g_aTests[%i]/3: %d, expected %d", i, cArgs3, g_aTests[i].cArgs);
308 for (int iArg = 0; iArg < cArgs3; iArg++)
309 if (strcmp(papszArgs3[iArg], g_aTests[i].apszArgs[iArg]) != 0)
310 RTTestIFailed("g_aTests[%i]/3: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s',))",
311 i, iArg, papszArgs3[iArg], g_aTests[i].apszArgs[iArg], pszArgs2);
312 RTTESTI_CHECK_RETV(papszArgs3[cArgs3] == NULL);
313 tstCheckNativeMsCrtToArgv(pszArgs2, g_aTests[i].cArgs, g_aTests[i].apszArgs);
314
315 /*
316 * Fourth
317 */
318 char *pszArgs4 = NULL;
319 rc = RTGetOptArgvToString(&pszArgs4, papszArgs3, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
320 if (rc == VINF_SUCCESS)
321 {
322 if (strcmp(pszArgs4, pszArgs2))
323 RTTestIFailed("g_aTests[%i]/4: '%s' does not match #4='%s'", i, pszArgs2, pszArgs4);
324 RTStrFree(pszArgs4);
325 }
326 else
327 RTTestIFailed("g_aTests[%i]/4: RTGetOptArgvToString() -> %Rrc", i, rc);
328 RTGetOptArgvFree(papszArgs3);
329 }
330 else
331 RTTestIFailed("g_aTests[%i]/3: RTGetOptArgvFromString() -> %Rrc", i, rc);
332 RTStrFree(pszArgs2);
333 }
334 else
335 RTTestIFailed("g_aTests[%i]/2: RTGetOptArgvToString() -> %Rrc", i, rc);
336 RTGetOptArgvFree(papszArgs1);
337 }
338 else
339 RTTestIFailed("g_aTests[%i]/1: RTGetOptArgvFromString(,,'%s', '%s') -> %Rrc",
340 i, g_aTests[i].pszInMsCrt, g_aTests[i].pszSeparators, rc);
341 }
342
343}
344
345
346
347static void tst3(void)
348{
349 /*
350 * Bourne shell round-tripping.
351 */
352 RTTestISub("Round-trips / BOURNE_SH");
353 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)
354 {
355 /* First */
356 char **papszArgs1 = NULL;
357 int cArgs1 = -1;
358 int rc = RTGetOptArgvFromString(&papszArgs1, &cArgs1, g_aTests[i].pszInBourne,
359 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, g_aTests[i].pszSeparators);
360 if (rc == VINF_SUCCESS)
361 {
362 if (cArgs1 != g_aTests[i].cArgs)
363 RTTestIFailed("g_aTests[%i]: #1=%d, expected %d", i, cArgs1, g_aTests[i].cArgs);
364 for (int iArg = 0; iArg < cArgs1; iArg++)
365 if (strcmp(papszArgs1[iArg], g_aTests[i].apszArgs[iArg]) != 0)
366 RTTestIFailed("g_aTests[%i]/1: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s', '%s'))",
367 i, iArg, papszArgs1[iArg], g_aTests[i].apszArgs[iArg],
368 g_aTests[i].pszInBourne, g_aTests[i].pszSeparators);
369 RTTESTI_CHECK_RETV(papszArgs1[cArgs1] == NULL);
370
371 /* Second */
372 char *pszArgs2 = NULL;
373 rc = RTGetOptArgvToString(&pszArgs2, papszArgs1, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
374 if (rc == VINF_SUCCESS)
375 {
376 if (strcmp(pszArgs2, g_aTests[i].pszOutBourneSh))
377 RTTestIFailed("g_aTests[%i]/2: '%s', expected '%s'", i, pszArgs2, g_aTests[i].pszOutBourneSh);
378
379 /*
380 * Third
381 */
382 char **papszArgs3 = NULL;
383 int cArgs3 = -1;
384 rc = RTGetOptArgvFromString(&papszArgs3, &cArgs3, pszArgs2, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL);
385 if (rc == VINF_SUCCESS)
386 {
387 if (cArgs3 != g_aTests[i].cArgs)
388 RTTestIFailed("g_aTests[%i]/3: %d, expected %d", i, cArgs3, g_aTests[i].cArgs);
389 for (int iArg = 0; iArg < cArgs3; iArg++)
390 if (strcmp(papszArgs3[iArg], g_aTests[i].apszArgs[iArg]) != 0)
391 RTTestIFailed("g_aTests[%i]/3: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s',))",
392 i, iArg, papszArgs3[iArg], g_aTests[i].apszArgs[iArg], pszArgs2);
393 RTTESTI_CHECK_RETV(papszArgs3[cArgs3] == NULL);
394
395 /*
396 * Fourth
397 */
398 char *pszArgs4 = NULL;
399 rc = RTGetOptArgvToString(&pszArgs4, papszArgs3, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
400 if (rc == VINF_SUCCESS)
401 {
402 if (strcmp(pszArgs4, pszArgs2))
403 RTTestIFailed("g_aTests[%i]/4: '%s' does not match #4='%s'", i, pszArgs2, pszArgs4);
404 RTStrFree(pszArgs4);
405 }
406 else
407 RTTestIFailed("g_aTests[%i]/4: RTGetOptArgvToString() -> %Rrc", i, rc);
408 RTGetOptArgvFree(papszArgs3);
409 }
410 else
411 RTTestIFailed("g_aTests[%i]/3: RTGetOptArgvFromString() -> %Rrc", i, rc);
412 RTStrFree(pszArgs2);
413 }
414 else
415 RTTestIFailed("g_aTests[%i]/2: RTGetOptArgvToString() -> %Rrc", i, rc);
416 RTGetOptArgvFree(papszArgs1);
417 }
418 else
419 RTTestIFailed("g_aTests[%i]/1: RTGetOptArgvFromString(,,'%s', '%s') -> %Rrc",
420 i, g_aTests[i].pszInBourne, g_aTests[i].pszSeparators, rc);
421 }
422}
423
424
425static void tst2(void)
426{
427 RTTestISub("RTGetOptArgvToString / MS_CRT");
428
429 static const struct
430 {
431 const char * const apszArgs[5];
432 const char *pszCmdLine;
433 } s_aMscCrtTests[] =
434 {
435 {
436 { "abcd", "a ", " b", " c ", NULL },
437 "abcd \"a \" \" b\" \" c \""
438 },
439 {
440 { "a\\\\\\b", "de fg", "h", NULL, NULL },
441 "a\\\\\\b \"de fg\" h"
442 },
443 {
444 { "a\\\"b", "c", "d", "\"", NULL },
445 "\"a\\\\\\\"b\" c d \"\\\"\""
446 },
447 {
448 { "a\\\\b c", "d", "e", " \\", NULL },
449 "\"a\\\\b c\" d e \" \\\\\""
450 },
451 };
452
453 for (size_t i = 0; i < RT_ELEMENTS(s_aMscCrtTests); i++)
454 {
455 char *pszCmdLine = NULL;
456 int rc = RTGetOptArgvToString(&pszCmdLine, s_aMscCrtTests[i].apszArgs, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
457 RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS);
458 if (!strcmp(s_aMscCrtTests[i].pszCmdLine, pszCmdLine))
459 tstCheckNativeMsCrtToArgv(pszCmdLine, -1, s_aMscCrtTests[i].apszArgs);
460 else
461 RTTestIFailed("g_aTest[%i] failed:\n"
462 " got '%s'\n"
463 " expected '%s'\n",
464 i, pszCmdLine, s_aMscCrtTests[i].pszCmdLine);
465 RTStrFree(pszCmdLine);
466 }
467
468 for (size_t i = 0; i < RT_ELEMENTS(g_aTests); i++)
469 {
470 char *pszCmdLine = NULL;
471 int rc = RTGetOptArgvToString(&pszCmdLine, g_aTests[i].apszArgs, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
472 RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS);
473 if (!strcmp(g_aTests[i].pszOutMsCrt, pszCmdLine))
474 tstCheckNativeMsCrtToArgv(pszCmdLine, g_aTests[i].cArgs, g_aTests[i].apszArgs);
475 else
476 RTTestIFailed("g_aTests[%i] failed:\n"
477 " got |%s|\n"
478 " expected |%s|\n",
479 i, pszCmdLine, g_aTests[i].pszOutMsCrt);
480 RTStrFree(pszCmdLine);
481 }
482
483
484
485 RTTestISub("RTGetOptArgvToString / BOURNE_SH");
486
487 for (size_t i = 0; i < RT_ELEMENTS(g_aTests); i++)
488 {
489 char *pszCmdLine = NULL;
490 int rc = RTGetOptArgvToString(&pszCmdLine, g_aTests[i].apszArgs, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
491 RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS);
492 if (strcmp(g_aTests[i].pszOutBourneSh, pszCmdLine))
493 RTTestIFailed("g_aTests[%i] failed:\n"
494 " got |%s|\n"
495 " expected |%s|\n",
496 i, pszCmdLine, g_aTests[i].pszOutBourneSh);
497 RTStrFree(pszCmdLine);
498 }
499}
500
501static void tst1(void)
502{
503 RTTestISub("RTGetOptArgvFromString");
504 char **papszArgs = NULL;
505 int cArgs = -1;
506 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, "", RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL), VINF_SUCCESS);
507 RTTESTI_CHECK_RETV(cArgs == 0);
508 RTTESTI_CHECK_RETV(papszArgs);
509 RTTESTI_CHECK_RETV(!papszArgs[0]);
510 RTGetOptArgvFree(papszArgs);
511
512 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, "0 1 \"\"2'' '3' 4 5 '''''6' 7 8 9 10 11",
513 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL), VINF_SUCCESS);
514 RTTESTI_CHECK_RETV(cArgs == 12);
515 RTTESTI_CHECK_RETV(!strcmp(papszArgs[0], "0"));
516 RTTESTI_CHECK_RETV(!strcmp(papszArgs[1], "1"));
517 RTTESTI_CHECK_RETV(!strcmp(papszArgs[2], "2"));
518 RTTESTI_CHECK_RETV(!strcmp(papszArgs[3], "3"));
519 RTTESTI_CHECK_RETV(!strcmp(papszArgs[4], "4"));
520 RTTESTI_CHECK_RETV(!strcmp(papszArgs[5], "5"));
521 RTTESTI_CHECK_RETV(!strcmp(papszArgs[6], "6"));
522 RTTESTI_CHECK_RETV(!strcmp(papszArgs[7], "7"));
523 RTTESTI_CHECK_RETV(!strcmp(papszArgs[8], "8"));
524 RTTESTI_CHECK_RETV(!strcmp(papszArgs[9], "9"));
525 RTTESTI_CHECK_RETV(!strcmp(papszArgs[10], "10"));
526 RTTESTI_CHECK_RETV(!strcmp(papszArgs[11], "11"));
527 RTTESTI_CHECK_RETV(!papszArgs[12]);
528 RTGetOptArgvFree(papszArgs);
529
530 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, "\t\" asdf \" '\"'xyz \"\t\" '\n' '\"' \"'\"\n\r ",
531 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL), VINF_SUCCESS);
532 RTTESTI_CHECK_RETV(cArgs == 6);
533 RTTESTI_CHECK_RETV(!strcmp(papszArgs[0], " asdf "));
534 RTTESTI_CHECK_RETV(!strcmp(papszArgs[1], "\"xyz"));
535 RTTESTI_CHECK_RETV(!strcmp(papszArgs[2], "\t"));
536 RTTESTI_CHECK_RETV(!strcmp(papszArgs[3], "\n"));
537 RTTESTI_CHECK_RETV(!strcmp(papszArgs[4], "\""));
538 RTTESTI_CHECK_RETV(!strcmp(papszArgs[5], "\'"));
539 RTTESTI_CHECK_RETV(!papszArgs[6]);
540 RTGetOptArgvFree(papszArgs);
541
542 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, ":0::1::::2:3:4:5:",
543 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, ":"), VINF_SUCCESS);
544 RTTESTI_CHECK_RETV(cArgs == 6);
545 RTTESTI_CHECK_RETV(!strcmp(papszArgs[0], "0"));
546 RTTESTI_CHECK_RETV(!strcmp(papszArgs[1], "1"));
547 RTTESTI_CHECK_RETV(!strcmp(papszArgs[2], "2"));
548 RTTESTI_CHECK_RETV(!strcmp(papszArgs[3], "3"));
549 RTTESTI_CHECK_RETV(!strcmp(papszArgs[4], "4"));
550 RTTESTI_CHECK_RETV(!strcmp(papszArgs[5], "5"));
551 RTTESTI_CHECK_RETV(!papszArgs[6]);
552 RTGetOptArgvFree(papszArgs);
553
554 RTTESTI_CHECK_RC_RETV(RTGetOptArgvFromString(&papszArgs, &cArgs, "0:1;2:3;4:5", RTGETOPTARGV_CNV_QUOTE_BOURNE_SH,
555 ";;;;;;;;;;;;;;;;;;;;;;:"), VINF_SUCCESS);
556 RTTESTI_CHECK_RETV(cArgs == 6);
557 RTTESTI_CHECK_RETV(!strcmp(papszArgs[0], "0"));
558 RTTESTI_CHECK_RETV(!strcmp(papszArgs[1], "1"));
559 RTTESTI_CHECK_RETV(!strcmp(papszArgs[2], "2"));
560 RTTESTI_CHECK_RETV(!strcmp(papszArgs[3], "3"));
561 RTTESTI_CHECK_RETV(!strcmp(papszArgs[4], "4"));
562 RTTESTI_CHECK_RETV(!strcmp(papszArgs[5], "5"));
563 RTTESTI_CHECK_RETV(!papszArgs[6]);
564 RTGetOptArgvFree(papszArgs);
565
566 /*
567 * Tests from the list.
568 */
569 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)
570 {
571 papszArgs = NULL;
572 cArgs = -1;
573 int rc = RTGetOptArgvFromString(&papszArgs, &cArgs, g_aTests[i].pszInBourne, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH,
574 g_aTests[i].pszSeparators);
575 if (rc == VINF_SUCCESS)
576 {
577 if (cArgs == g_aTests[i].cArgs)
578 {
579 for (int iArg = 0; iArg < cArgs; iArg++)
580 if (strcmp(papszArgs[iArg], g_aTests[i].apszArgs[iArg]) != 0)
581 RTTestIFailed("g_aTests[%i]: argv[%i] differs: got '%s', expected '%s' (RTGetOptArgvFromString(,,'%s', '%s'))",
582 i, iArg, papszArgs[iArg], g_aTests[i].apszArgs[iArg],
583 g_aTests[i].pszInBourne, g_aTests[i].pszSeparators);
584 RTTESTI_CHECK_RETV(papszArgs[cArgs] == NULL);
585 }
586 else
587 RTTestIFailed("g_aTests[%i]: cArgs=%u, expected %u for RTGetOptArgvFromString(,,'%s', '%s')",
588 i, cArgs, g_aTests[i].cArgs, g_aTests[i].pszInBourne, g_aTests[i].pszSeparators);
589 RTGetOptArgvFree(papszArgs);
590 }
591 else
592 RTTestIFailed("g_aTests[%i]: RTGetOptArgvFromString(,,'%s', '%s') -> %Rrc",
593 i, g_aTests[i].pszInBourne, g_aTests[i].pszSeparators, rc);
594 }
595}
596
597
598int main()
599{
600 /*
601 * Init RT+Test.
602 */
603 RTTEST hTest;
604 int rc = RTTestInitAndCreate("tstRTGetOptArgv", &hTest);
605 if (rc)
606 return rc;
607 RTTestBanner(hTest);
608
609 /*
610 * The test.
611 */
612 tst1();
613 tst2();
614 tst4();
615 tst3();
616
617 /*
618 * Summary.
619 */
620 return RTTestSummaryAndDestroy(hTest);
621}
622
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