]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/testsuite/test-expandargv.c
Update copyright years.
[thirdparty/gcc.git] / libiberty / testsuite / test-expandargv.c
CommitLineData
974c2c56 1/* expandargv test program,
a945c346 2 Copyright (C) 2006-2024 Free Software Foundation, Inc.
974c2c56
CD
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
89ac0797
GP
43#ifdef HAVE_UNISTD_H
44#include <unistd.h>
45#endif
974c2c56
CD
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
70277b30
DG
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
974c2c56
CD
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;
bd820218 195 size_t len, sys_fwrite;
974c2c56
CD
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
4b9726d4 210 memcpy (parse, test_data, sizeof (char) * (len + 1));
974c2c56
CD
211 /* Run all possible replaces */
212 run_replaces (parse);
213
bd820218
UB
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
974c2c56
CD
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++)
70277b30 287 if (strcmp (argv_before[k], argv_after[k]) != 0)
974c2c56
CD
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