merge from gcc
[deliverable/binutils-gdb.git] / libiberty / testsuite / test-expandargv.c
CommitLineData
67d78caa
DD
1/* expandargv test program,
2 Copyright (C) 2006 Free Software Foundation, Inc.
3 Written by Carlos O'Donell <carlos@codesourcery.com>
4
5 This file is part of the libiberty library, which is part of GCC.
6
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.
11
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
19 executable.)
20
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.
25
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.
29*/
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34#include "libiberty.h"
35#include <stdio.h>
36#include <errno.h>
37#ifdef HAVE_STDLIB_H
38#include <stdlib.h>
39#endif
40#ifdef HAVE_STRING_H
41#include <string.h>
42#endif
43
44#ifndef EXIT_SUCCESS
45#define EXIT_SUCCESS 0
46#endif
47
48#ifndef EXIT_FAILURE
49#define EXIT_FAILURE 1
50#endif
51
52static void fatal_error (int, const char *, int) ATTRIBUTE_NORETURN;
53void writeout_test (int, const char *);
54void run_replaces (char *);
55void hook_char_replace (char *, size_t, char, char);
56int run_tests (const char **);
57void erase_test (int);
58
59/* Test input data, argv before, and argv after:
60
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.
64
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. */
68
69#define FILENAME_PATTERN "test-expandargv-%d.lst"
70#define ARGV0 "test-expandargv"
71
72const char *test_data[] = {
73 /* Test 0 - Check for expansion with \r\n */
74 "a\r\nb", /* Test 0 data */
75 ARGV0,
76 "@test-expandargv-0.lst",
77 0, /* End of argv[] before expansion */
78 ARGV0,
79 "a",
80 "b",
81 0, /* End of argv[] after expansion */
82
83 /* Test 1 - Check for expansion with \n */
84 "a\nb", /* Test 1 data */
85 ARGV0,
86 "@test-expandargv-1.lst",
87 0,
88 ARGV0,
89 "a",
90 "b",
91 0,
92
93 /* Test 2 - Check for expansion with \0 */
94 "a\bb", /* Test 2 data */
95 ARGV0,
96 "@test-expandargv-2.lst",
97 0,
98 ARGV0,
99 "a",
100 0,
101
102 /* Test 3 - Check for expansion with only \0 */
103 "\b", /* Test 3 data */
104 ARGV0,
105 "@test-expandargv-3.lst",
106 0,
107 ARGV0,
108 0,
109
79e31468
DD
110 /* Test 4 - Check for options beginning with an empty line. */
111 "\na\nb", /* Test 4 data */
112 ARGV0,
113 "@test-expandargv-4.lst",
114 0,
115 ARGV0,
116 "a",
117 "b",
118 0,
119
120 /* Test 5 - Check for options containing an empty argument. */
121 "a\n''\nb", /* Test 5 data */
122 ARGV0,
123 "@test-expandargv-5.lst",
124 0,
125 ARGV0,
126 "a",
127 "",
128 "b",
129 0,
130
131 /* Test 6 - Check for options containing a quoted newline. */
132 "a\n'a\n\nb'\nb", /* Test 6 data */
133 ARGV0,
134 "@test-expandargv-6.lst",
135 0,
136 ARGV0,
137 "a",
138 "a\n\nb",
139 "b",
140 0,
141
67d78caa
DD
142 0 /* Test done marker, don't remove. */
143};
144
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. */
148
149static void
150fatal_error (int line, const char *errmsg, int err)
151{
152 fprintf (stderr, "test-expandargv:%d: %s", line, errmsg);
153 if (errno != 0)
154 fprintf (stderr, ": %s", xstrerror (err));
155 fprintf (stderr, "\n");
156 exit (EXIT_FAILURE);
157}
158
159/* hook_char_replace:
160 Replace 'replacethis' with 'withthis' */
161
162void
163hook_char_replace (char *string, size_t len, char replacethis, char withthis)
164{
165 int i = 0;
166 for (i = 0; i < len; i++)
167 if (string[i] == replacethis)
168 string[i] = withthis;
169}
170
171/* run_replaces:
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. */
175
176void
177run_replaces (char * string)
178{
179 /* Store original string size */
180 size_t len = strlen (string);
181 hook_char_replace (string, len, '\b', '\0');
182}
183
184/* write_test:
185 Write test datafile */
186
187void
188writeout_test (int test, const char * test_data)
189{
190 char filename[256];
191 FILE *fd;
192 size_t len;
193 char * parse;
194
195 /* Unique filename per test */
196 sprintf (filename, FILENAME_PATTERN, test);
197 fd = fopen (filename, "w");
198 if (fd == NULL)
199 fatal_error (__LINE__, "Failed to create test file.", errno);
200
201 /* Generate RW copy of data for replaces */
202 len = strlen (test_data);
203 parse = malloc (sizeof (char) * (len + 1));
204 if (parse == NULL)
205 fatal_error (__LINE__, "Failed to malloc parse.", errno);
206
207 memcpy (parse, test_data, sizeof (char) * len);
208 /* Run all possible replaces */
209 run_replaces (parse);
210
211 fwrite (parse, len, sizeof (char), fd);
212 free (parse);
213 fclose (fd);
214}
215
216/* erase_test:
217 Erase the test file */
218
219void
220erase_test (int test)
221{
222 char filename[256];
223 sprintf (filename, FILENAME_PATTERN, test);
224 if (unlink (filename) != 0)
225 fatal_error (__LINE__, "Failed to erase test file.", errno);
226}
227
228
229/* run_tests:
230 Run expandargv
231 Compare argv before and after.
232 Return number of fails */
233
234int
235run_tests (const char **test_data)
236{
237 int argc_after, argc_before;
238 char ** argv_before, ** argv_after;
239 int i, j, k, fails, failed;
240
241 i = j = fails = 0;
242 /* Loop over all the tests */
243 while (test_data[j])
244 {
245 /* Write test data */
246 writeout_test (i, test_data[j++]);
247 /* Copy argv before */
248 argv_before = dupargv ((char **) &test_data[j]);
249
250 /* Count argc before/after */
251 argc_before = 0;
252 argc_after = 0;
253 while (test_data[j + argc_before])
254 argc_before++;
255 j += argc_before + 1; /* Skip null */
256 while (test_data[j + argc_after])
257 argc_after++;
258
259 /* Copy argv after */
260 argv_after = dupargv ((char **) &test_data[j]);
261
262 /* Run all possible replaces */
263 for (k = 0; k < argc_before; k++)
264 run_replaces (argv_before[k]);
265 for (k = 0; k < argc_after; k++)
266 run_replaces (argv_after[k]);
267
268 /* Run test: Expand arguments */
269 expandargv (&argc_before, &argv_before);
270
271 failed = 0;
272 /* Compare size first */
273 if (argc_before != argc_after)
274 {
275 printf ("FAIL: test-expandargv-%d. Number of arguments don't match.\n", i);
276 failed++;
277 }
278 /* Compare each of the argv's ... */
279 else
280 for (k = 0; k < argc_after; k++)
79e31468 281 if (strcmp (argv_before[k], argv_after[k]) != 0)
67d78caa
DD
282 {
283 printf ("FAIL: test-expandargv-%d. Arguments don't match.\n", i);
284 failed++;
285 }
286
287 if (!failed)
288 printf ("PASS: test-expandargv-%d.\n", i);
289 else
290 fails++;
291
292 freeargv (argv_before);
293 freeargv (argv_after);
294 /* Advance to next test */
295 j += argc_after + 1;
296 /* Erase test file */
297 erase_test (i);
298 i++;
299 }
300 return fails;
301}
302
303/* main:
304 Run tests.
305 Check result and exit with appropriate code. */
306
307int
308main(int argc, char **argv)
309{
310 int fails;
311 /* Repeat for all the tests:
312 - Parse data array and write into file.
313 - Run replace hooks before writing to file.
314 - Parse data array and build argv before/after.
315 - Run replace hooks on argv before/after
316 - Run expandargv.
317 - Compare output of expandargv argv to after argv.
318 - If they compare the same then test passes
319 else the test fails.
320 - Erase test file. */
321
322 fails = run_tests (test_data);
323 if (!fails)
324 exit (EXIT_SUCCESS);
325 else
326 exit (EXIT_FAILURE);
327}
328
This page took 0.195386 seconds and 4 git commands to generate.