Fix a memory leak.
[wine] / tools / make_ctests.c
1 /*
2  * Generate a C file containing a list of tests
3  *
4  * Copyright 2002, 2005 Alexandre Julliard
5  * Copyright 2002 Dimitrie O. Paun
6  * Copyright 2005 Royce Mitchell III for the ReactOS Project
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  ****** Keep in sync with tools/winapi/msvcmaker:_generate_testlist_c *****
23  */
24
25 #include "config.h"
26
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 static const char *output_file;
36
37 static void fatal_error( const char *msg, ... )
38 {
39     va_list valist;
40     va_start( valist, msg );
41     fprintf( stderr, "make_ctests: " );
42     vfprintf( stderr, msg, valist );
43     va_end( valist );
44     if (output_file) unlink( output_file );
45     exit(1);
46 }
47
48 static void fatal_perror( const char *msg, ... )
49 {
50     va_list valist;
51     va_start( valist, msg );
52     fprintf( stderr, "make_ctests: " );
53     vfprintf( stderr, msg, valist );
54     perror( " " );
55     va_end( valist );
56     exit(1);
57 }
58
59 static void *xmalloc( size_t size )
60 {
61     void *res = malloc (size ? size : 1);
62     if (!res) fatal_error( "virtual memory exhausted.\n" );
63     return res;
64 }
65
66 static char* basename( const char* filename )
67 {
68     const char *p, *p2;
69     char *out;
70     size_t out_len;
71
72     p = strrchr ( filename, '/' );
73     if ( !p )
74         p = filename;
75     else
76         ++p;
77
78     /* look for backslashes, too... */
79     p2 = strrchr ( p, '\\' );
80     if ( p2 ) p = p2 + 1;
81
82     /* find extension... */
83     p2 = strrchr ( p, '.' );
84     if ( !p2 )
85         p2 = p + strlen(p);
86
87     /* malloc a copy */
88     out_len = p2-p;
89     out = xmalloc ( out_len+1 );
90     memcpy ( out, p, out_len );
91     out[out_len] = '\0';
92     return out;
93 }
94
95 int main( int argc, const char** argv )
96 {
97     int i, count = 0;
98     FILE *out = stdout;
99     char **tests = xmalloc( argc * sizeof(*tests) );
100
101     for (i = 1; i < argc; i++)
102     {
103         if (!strcmp( argv[i], "-o" ) && i < argc-1)
104         {
105             output_file = argv[++i];
106             continue;
107         }
108         tests[count++] = basename( argv[i] );
109     }
110
111     if (output_file)
112     {
113         if (!(out = fopen( output_file, "w" )))
114             fatal_perror( "cannot create %s", output_file );
115     }
116
117     fprintf( out,
118              "/* Automatically generated file; DO NOT EDIT!! */\n"
119              "\n"
120              "#include <windows.h>\n\n"
121              "#define STANDALONE\n"
122              "#include \"wine/test.h\"\n\n" );
123
124     for (i = 0; i < count; i++) fprintf( out, "extern void func_%s(void);\n", tests[i] );
125
126     fprintf( out,
127              "\n"
128              "const struct test winetest_testlist[] =\n"
129              "{\n" );
130
131     for (i = 0; i < count; i++) fprintf( out, "    { \"%s\", func_%s },\n", tests[i], tests[i] );
132
133     fprintf( out,
134              "    { 0, 0 }\n"
135              "};\n" );
136
137     if (output_file && fclose( out ))
138         fatal_perror( "error writing to %s", output_file );
139
140     return 0;
141 }