1 /* expandargv test program,
2 Copyright (C) 2006 Free Software Foundation, Inc.
3 Written by Carlos O'Donell <carlos@codesourcery.com>
5 This file is part of the libiberty library, which is part of GCC.
7 This file is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combined
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
34 #include "libiberty.h"
45 #define EXIT_SUCCESS 0
49 #define EXIT_FAILURE 1
52 static void fatal_error (int, const char *, int) ATTRIBUTE_NORETURN;
53 void writeout_test (int, const char *);
54 void run_replaces (char *);
55 void hook_char_replace (char *, size_t, char, char);
56 int run_tests (const char **);
57 void erase_test (int);
59 /* Test input data, argv before, and argv after:
61 The \n is an important part of test_data since expandargv
62 may have to work in environments where \n is translated
63 as \r\n. Thus \n is included in the test data for the file.
65 We use \b to indicate that the test data is the null character.
66 This is because we use \0 normally to represent the end of the
67 file data, so we need something else for this. */
69 #define FILENAME_PATTERN "test-expandargv-%d.lst"
70 #define ARGV0 "test-expandargv"
72 const char *test_data[] = {
73 /* Test 0 - Check for expansion with \r\n */
74 "a\r\nb", /* Test 0 data */
76 "@test-expandargv-0.lst",
77 0, /* End of argv[] before expansion */
81 0, /* End of argv[] after expansion */
83 /* Test 1 - Check for expansion with \n */
84 "a\nb", /* Test 1 data */
86 "@test-expandargv-1.lst",
93 /* Test 2 - Check for expansion with \0 */
94 "a\bb", /* Test 2 data */
96 "@test-expandargv-2.lst",
102 /* Test 3 - Check for expansion with only \0 */
103 "\b", /* Test 3 data */
105 "@test-expandargv-3.lst",
110 /* Test 4 - Check for options beginning with an empty line. */
111 "\na\nb", /* Test 4 data */
113 "@test-expandargv-4.lst",
120 /* Test 5 - Check for options containing an empty argument. */
121 "a\n''\nb", /* Test 5 data */
123 "@test-expandargv-5.lst",
131 /* Test 6 - Check for options containing a quoted newline. */
132 "a\n'a\n\nb'\nb", /* Test 6 data */
134 "@test-expandargv-6.lst",
142 0 /* Test done marker, don't remove. */
145 /* Print a fatal error and exit. LINE is the line number where we
146 detected the error, ERRMSG is the error message to print, and ERR
147 is 0 or an errno value to print. */
150 fatal_error (int line, const char *errmsg, int err)
152 fprintf (stderr, "test-expandargv:%d: %s", line, errmsg);
154 fprintf (stderr, ": %s", xstrerror (err));
155 fprintf (stderr, "\n");
159 /* hook_char_replace:
160 Replace 'replacethis' with 'withthis' */
163 hook_char_replace (char *string, size_t len, char replacethis, char withthis)
166 for (i = 0; i < len; i++)
167 if (string[i] == replacethis)
168 string[i] = withthis;
172 Hook here all the character for character replaces.
173 Be warned that expanding the string or contracting the string
174 should be handled with care. */
177 run_replaces (char * string)
179 /* Store original string size */
180 size_t len = strlen (string);
181 hook_char_replace (string, len, '\b', '\0');
185 Write test datafile */
188 writeout_test (int test, const char * test_data)
192 size_t len, sys_fwrite;
195 /* Unique filename per test */
196 sprintf (filename, FILENAME_PATTERN, test);
197 fd = fopen (filename, "w");
199 fatal_error (__LINE__, "Failed to create test file.", errno);
201 /* Generate RW copy of data for replaces */
202 len = strlen (test_data);
203 parse = malloc (sizeof (char) * (len + 1));
205 fatal_error (__LINE__, "Failed to malloc parse.", errno);
207 memcpy (parse, test_data, sizeof (char) * (len + 1));
208 /* Run all possible replaces */
209 run_replaces (parse);
211 sys_fwrite = fwrite (parse, sizeof (char), len, fd);
212 if (sys_fwrite != len)
213 fatal_error (__LINE__, "Failed to write to test file.", errno);
220 Erase the test file */
223 erase_test (int test)
226 sprintf (filename, FILENAME_PATTERN, test);
227 if (unlink (filename) != 0)
228 fatal_error (__LINE__, "Failed to erase test file.", errno);
234 Compare argv before and after.
235 Return number of fails */
238 run_tests (const char **test_data)
240 int argc_after, argc_before;
241 char ** argv_before, ** argv_after;
242 int i, j, k, fails, failed;
245 /* Loop over all the tests */
248 /* Write test data */
249 writeout_test (i, test_data[j++]);
250 /* Copy argv before */
251 argv_before = dupargv ((char **) &test_data[j]);
253 /* Count argc before/after */
256 while (test_data[j + argc_before])
258 j += argc_before + 1; /* Skip null */
259 while (test_data[j + argc_after])
262 /* Copy argv after */
263 argv_after = dupargv ((char **) &test_data[j]);
265 /* Run all possible replaces */
266 for (k = 0; k < argc_before; k++)
267 run_replaces (argv_before[k]);
268 for (k = 0; k < argc_after; k++)
269 run_replaces (argv_after[k]);
271 /* Run test: Expand arguments */
272 expandargv (&argc_before, &argv_before);
275 /* Compare size first */
276 if (argc_before != argc_after)
278 printf ("FAIL: test-expandargv-%d. Number of arguments don't match.\n", i);
281 /* Compare each of the argv's ... */
283 for (k = 0; k < argc_after; k++)
284 if (strcmp (argv_before[k], argv_after[k]) != 0)
286 printf ("FAIL: test-expandargv-%d. Arguments don't match.\n", i);
291 printf ("PASS: test-expandargv-%d.\n", i);
295 freeargv (argv_before);
296 freeargv (argv_after);
297 /* Advance to next test */
299 /* Erase test file */
308 Check result and exit with appropriate code. */
311 main(int argc, char **argv)
314 /* Repeat for all the tests:
315 - Parse data array and write into file.
316 - Run replace hooks before writing to file.
317 - Parse data array and build argv before/after.
318 - Run replace hooks on argv before/after
320 - Compare output of expandargv argv to after argv.
321 - If they compare the same then test passes
323 - Erase test file. */
325 fails = run_tests (test_data);