]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libiberty/testsuite/test-expandargv.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / libiberty / testsuite / test-expandargv.c
CommitLineData
67d78caa 1/* expandargv test program,
250d07de 2 Copyright (C) 2006-2021 Free Software Foundation, Inc.
67d78caa
DD
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
ae6da67e 43#ifdef HAVE_UNISTD_H
44#include <unistd.h>
45#endif
67d78caa
DD
46
47#ifndef EXIT_SUCCESS
48#define EXIT_SUCCESS 0
49#endif
50
51#ifndef EXIT_FAILURE
52#define EXIT_FAILURE 1
53#endif
54
55static void fatal_error (int, const char *, int) ATTRIBUTE_NORETURN;
56void writeout_test (int, const char *);
57void run_replaces (char *);
58void hook_char_replace (char *, size_t, char, char);
59int run_tests (const char **);
60void erase_test (int);
61
62/* Test input data, argv before, and argv after:
63
64 The \n is an important part of test_data since expandargv
65 may have to work in environments where \n is translated
66 as \r\n. Thus \n is included in the test data for the file.
67
68 We use \b to indicate that the test data is the null character.
69 This is because we use \0 normally to represent the end of the
70 file data, so we need something else for this. */
71
72#define FILENAME_PATTERN "test-expandargv-%d.lst"
73#define ARGV0 "test-expandargv"
74
75const char *test_data[] = {
76 /* Test 0 - Check for expansion with \r\n */
77 "a\r\nb", /* Test 0 data */
78 ARGV0,
79 "@test-expandargv-0.lst",
80 0, /* End of argv[] before expansion */
81 ARGV0,
82 "a",
83 "b",
84 0, /* End of argv[] after expansion */
85
86 /* Test 1 - Check for expansion with \n */
87 "a\nb", /* Test 1 data */
88 ARGV0,
89 "@test-expandargv-1.lst",
90 0,
91 ARGV0,
92 "a",
93 "b",
94 0,
95
96 /* Test 2 - Check for expansion with \0 */
97 "a\bb", /* Test 2 data */
98 ARGV0,
99 "@test-expandargv-2.lst",
100 0,
101 ARGV0,
102 "a",
103 0,
104
105 /* Test 3 - Check for expansion with only \0 */
106 "\b", /* Test 3 data */
107 ARGV0,
108 "@test-expandargv-3.lst",
109 0,
110 ARGV0,
111 0,
112
79e31468
DD
113 /* Test 4 - Check for options beginning with an empty line. */
114 "\na\nb", /* Test 4 data */
115 ARGV0,
116 "@test-expandargv-4.lst",
117 0,
118 ARGV0,
119 "a",
120 "b",
121 0,
122
123 /* Test 5 - Check for options containing an empty argument. */
124 "a\n''\nb", /* Test 5 data */
125 ARGV0,
126 "@test-expandargv-5.lst",
127 0,
128 ARGV0,
129 "a",
130 "",
131 "b",
132 0,
133
134 /* Test 6 - Check for options containing a quoted newline. */
135 "a\n'a\n\nb'\nb", /* Test 6 data */
136 ARGV0,
137 "@test-expandargv-6.lst",
138 0,
139 ARGV0,
140 "a",
141 "a\n\nb",
142 "b",
143 0,
144
67d78caa
DD
145 0 /* Test done marker, don't remove. */
146};
147
148/* Print a fatal error and exit. LINE is the line number where we
149 detected the error, ERRMSG is the error message to print, and ERR
150 is 0 or an errno value to print. */
151
152static void
153fatal_error (int line, const char *errmsg, int err)
154{
155 fprintf (stderr, "test-expandargv:%d: %s", line, errmsg);
156 if (errno != 0)
157 fprintf (stderr, ": %s", xstrerror (err));
158 fprintf (stderr, "\n");
159 exit (EXIT_FAILURE);
160}
161
162/* hook_char_replace:
163 Replace 'replacethis' with 'withthis' */
164
165void
166hook_char_replace (char *string, size_t len, char replacethis, char withthis)
167{
168 int i = 0;
169 for (i = 0; i < len; i++)
170 if (string[i] == replacethis)
171 string[i] = withthis;
172}
173
174/* run_replaces:
175 Hook here all the character for character replaces.
176 Be warned that expanding the string or contracting the string
177 should be handled with care. */
178
179void
180run_replaces (char * string)
181{
182 /* Store original string size */
183 size_t len = strlen (string);
184 hook_char_replace (string, len, '\b', '\0');
185}
186
187/* write_test:
188 Write test datafile */
189
190void
191writeout_test (int test, const char * test_data)
192{
193 char filename[256];
194 FILE *fd;
6b6bd65a 195 size_t len, sys_fwrite;
67d78caa
DD
196 char * parse;
197
198 /* Unique filename per test */
199 sprintf (filename, FILENAME_PATTERN, test);
200 fd = fopen (filename, "w");
201 if (fd == NULL)
202 fatal_error (__LINE__, "Failed to create test file.", errno);
203
204 /* Generate RW copy of data for replaces */
205 len = strlen (test_data);
206 parse = malloc (sizeof (char) * (len + 1));
207 if (parse == NULL)
208 fatal_error (__LINE__, "Failed to malloc parse.", errno);
209
a55c6f41 210 memcpy (parse, test_data, sizeof (char) * (len + 1));
67d78caa
DD
211 /* Run all possible replaces */
212 run_replaces (parse);
213
6b6bd65a
DD
214 sys_fwrite = fwrite (parse, sizeof (char), len, fd);
215 if (sys_fwrite != len)
216 fatal_error (__LINE__, "Failed to write to test file.", errno);
217
67d78caa
DD
218 free (parse);
219 fclose (fd);
220}
221
222/* erase_test:
223 Erase the test file */
224
225void
226erase_test (int test)
227{
228 char filename[256];
229 sprintf (filename, FILENAME_PATTERN, test);
230 if (unlink (filename) != 0)
231 fatal_error (__LINE__, "Failed to erase test file.", errno);
232}
233
234
235/* run_tests:
236 Run expandargv
237 Compare argv before and after.
238 Return number of fails */
239
240int
241run_tests (const char **test_data)
242{
243 int argc_after, argc_before;
244 char ** argv_before, ** argv_after;
245 int i, j, k, fails, failed;
246
247 i = j = fails = 0;
248 /* Loop over all the tests */
249 while (test_data[j])
250 {
251 /* Write test data */
252 writeout_test (i, test_data[j++]);
253 /* Copy argv before */
254 argv_before = dupargv ((char **) &test_data[j]);
255
256 /* Count argc before/after */
257 argc_before = 0;
258 argc_after = 0;
259 while (test_data[j + argc_before])
260 argc_before++;
261 j += argc_before + 1; /* Skip null */
262 while (test_data[j + argc_after])
263 argc_after++;
264
265 /* Copy argv after */
266 argv_after = dupargv ((char **) &test_data[j]);
267
268 /* Run all possible replaces */
269 for (k = 0; k < argc_before; k++)
270 run_replaces (argv_before[k]);
271 for (k = 0; k < argc_after; k++)
272 run_replaces (argv_after[k]);
273
274 /* Run test: Expand arguments */
275 expandargv (&argc_before, &argv_before);
276
277 failed = 0;
278 /* Compare size first */
279 if (argc_before != argc_after)
280 {
281 printf ("FAIL: test-expandargv-%d. Number of arguments don't match.\n", i);
282 failed++;
283 }
284 /* Compare each of the argv's ... */
285 else
286 for (k = 0; k < argc_after; k++)
79e31468 287 if (strcmp (argv_before[k], argv_after[k]) != 0)
67d78caa
DD
288 {
289 printf ("FAIL: test-expandargv-%d. Arguments don't match.\n", i);
290 failed++;
291 }
292
293 if (!failed)
294 printf ("PASS: test-expandargv-%d.\n", i);
295 else
296 fails++;
297
298 freeargv (argv_before);
299 freeargv (argv_after);
300 /* Advance to next test */
301 j += argc_after + 1;
302 /* Erase test file */
303 erase_test (i);
304 i++;
305 }
306 return fails;
307}
308
309/* main:
310 Run tests.
311 Check result and exit with appropriate code. */
312
313int
314main(int argc, char **argv)
315{
316 int fails;
317 /* Repeat for all the tests:
318 - Parse data array and write into file.
319 - Run replace hooks before writing to file.
320 - Parse data array and build argv before/after.
321 - Run replace hooks on argv before/after
322 - Run expandargv.
323 - Compare output of expandargv argv to after argv.
324 - If they compare the same then test passes
325 else the test fails.
326 - Erase test file. */
327
328 fails = run_tests (test_data);
329 if (!fails)
330 exit (EXIT_SUCCESS);
331 else
332 exit (EXIT_FAILURE);
333}
334