OSDN Git Service

libiberty/
[pf3gnuchains/gcc-fork.git] / libiberty / testsuite / test-expandargv.c
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
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);
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
72 const 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
110   0 /* Test done marker, don't remove. */
111 };
112
113 /* Print a fatal error and exit.  LINE is the line number where we
114    detected the error, ERRMSG is the error message to print, and ERR
115    is 0 or an errno value to print.  */
116
117 static void
118 fatal_error (int line, const char *errmsg, int err)
119 {
120   fprintf (stderr, "test-expandargv:%d: %s", line, errmsg);
121   if (errno != 0)
122     fprintf (stderr, ": %s", xstrerror (err));
123   fprintf (stderr, "\n");
124   exit (EXIT_FAILURE);
125 }
126
127 /* hook_char_replace:
128      Replace 'replacethis' with 'withthis' */
129
130 void
131 hook_char_replace (char *string, size_t len, char replacethis, char withthis)
132 {
133   int i = 0;
134   for (i = 0; i < len; i++)
135     if (string[i] == replacethis)
136       string[i] = withthis;
137 }
138
139 /* run_replaces:
140      Hook here all the character for character replaces.
141      Be warned that expanding the string or contracting the string
142      should be handled with care. */
143
144 void
145 run_replaces (char * string)
146 {
147   /* Store original string size */
148   size_t len = strlen (string);
149   hook_char_replace (string, len, '\b', '\0');
150 }
151
152 /* write_test:
153    Write test datafile */
154
155 void
156 writeout_test (int test, const char * test_data)
157 {
158   char filename[256];
159   FILE *fd;
160   size_t len;
161   char * parse;
162
163   /* Unique filename per test */
164   sprintf (filename, FILENAME_PATTERN, test);
165   fd = fopen (filename, "w");
166   if (fd == NULL)
167     fatal_error (__LINE__, "Failed to create test file.", errno);
168
169   /* Generate RW copy of data for replaces */
170   len = strlen (test_data);
171   parse = malloc (sizeof (char) * (len + 1));
172   if (parse == NULL)
173     fatal_error (__LINE__, "Failed to malloc parse.", errno);
174       
175   memcpy (parse, test_data, sizeof (char) * len);
176   /* Run all possible replaces */
177   run_replaces (parse);
178
179   fwrite (parse, len, sizeof (char), fd);
180   free (parse);
181   fclose (fd);
182 }
183
184 /* erase_test:
185      Erase the test file */
186
187 void 
188 erase_test (int test)
189 {
190   char filename[256]; 
191   sprintf (filename, FILENAME_PATTERN, test);
192   if (unlink (filename) != 0)
193     fatal_error (__LINE__, "Failed to erase test file.", errno);
194 }
195
196
197 /* run_tests:
198     Run expandargv
199     Compare argv before and after.
200     Return number of fails */
201
202 int
203 run_tests (const char **test_data)
204 {
205   int argc_after, argc_before;
206   char ** argv_before, ** argv_after;
207   int i, j, k, fails, failed;
208
209   i = j = fails = 0;
210   /* Loop over all the tests */
211   while (test_data[j])
212     {
213       /* Write test data */
214       writeout_test (i, test_data[j++]);
215       /* Copy argv before */
216       argv_before = dupargv ((char **) &test_data[j]);
217
218       /* Count argc before/after */
219       argc_before = 0;
220       argc_after = 0;
221       while (test_data[j + argc_before])
222         argc_before++;
223       j += argc_before + 1; /* Skip null */
224       while (test_data[j + argc_after])
225         argc_after++;
226
227       /* Copy argv after */
228       argv_after = dupargv ((char **) &test_data[j]);
229
230       /* Run all possible replaces */
231       for (k = 0; k < argc_before; k++)
232         run_replaces (argv_before[k]);
233       for (k = 0; k < argc_after; k++)
234         run_replaces (argv_after[k]);
235
236       /* Run test: Expand arguments */
237       expandargv (&argc_before, &argv_before);
238
239       failed = 0;
240       /* Compare size first */
241       if (argc_before != argc_after)
242         {
243           printf ("FAIL: test-expandargv-%d. Number of arguments don't match.\n", i);
244           failed++;
245         }
246       /* Compare each of the argv's ... */
247       else
248         for (k = 0; k < argc_after; k++)
249           if (strncmp (argv_before[k], argv_after[k], strlen(argv_after[k])) != 0)
250             {
251               printf ("FAIL: test-expandargv-%d. Arguments don't match.\n", i);
252               failed++;
253             }
254
255       if (!failed)
256         printf ("PASS: test-expandargv-%d.\n", i);
257       else
258         fails++;
259
260       freeargv (argv_before);
261       freeargv (argv_after);
262       /* Advance to next test */
263       j += argc_after + 1;
264       /* Erase test file */
265       erase_test (i);
266       i++;
267     }
268   return fails;
269 }
270
271 /* main:
272     Run tests. 
273     Check result and exit with appropriate code. */
274
275 int 
276 main(int argc, char **argv)
277 {
278   int fails;
279   /* Repeat for all the tests:
280      - Parse data array and write into file.
281        - Run replace hooks before writing to file.
282      - Parse data array and build argv before/after.
283        - Run replace hooks on argv before/after
284      - Run expandargv.
285      - Compare output of expandargv argv to after argv.
286        - If they compare the same then test passes
287          else the test fails. 
288      - Erase test file. */
289
290   fails = run_tests (test_data);
291   if (!fails)
292     exit (EXIT_SUCCESS);
293   else
294     exit (EXIT_FAILURE);
295 }
296