Add packaging files for Tizen
[profile/ivi/yasm.git] / libyasm / genmodule.c
1 /*
2  *
3  * Generate module.c from module.in and Makefile.am or Makefile.
4  *
5  *  Copyright (C) 2004-2007  Peter Johnson
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32
33 #include "compat-queue.h"
34
35 #define OUTPUT  "module.c"
36 #define MAXNAME 128
37 #define MAXLINE 1024
38 #define MAXMODULES 128
39 #define MAXINCLUDES 256
40
41 typedef struct include {
42     STAILQ_ENTRY(include) link;
43     char *filename;
44 } include;
45
46 int
47 main(int argc, char *argv[])
48 {
49     FILE *in, *out;
50     char *str;
51     int i;
52     size_t len;
53     char *strp;
54     char *modules[MAXMODULES];
55     int num_modules = 0;
56     STAILQ_HEAD(includehead, include) includes =
57         STAILQ_HEAD_INITIALIZER(includes);
58     include *inc;
59     int isam = 0;
60     int linecont = 0;
61
62     if (argc != 3) {
63         fprintf(stderr, "Usage: %s <module.in> <Makefile[.am]>\n", argv[0]);
64         return EXIT_FAILURE;
65     }
66
67     str = malloc(MAXLINE);
68
69     /* Starting with initial input Makefile, look for include <file> or
70      * YASM_MODULES += <module>.  Note this currently doesn't handle
71      * a relative starting path.
72      */
73     len = strlen(argv[2]);
74     inc = malloc(sizeof(include));
75     inc->filename = malloc(len+1);
76     strcpy(inc->filename, argv[2]);
77     STAILQ_INSERT_TAIL(&includes, inc, link);
78
79     isam = argv[2][len-2] == 'a' && argv[2][len-1] == 'm';
80
81     while (!STAILQ_EMPTY(&includes)) {
82         inc = STAILQ_FIRST(&includes);
83         STAILQ_REMOVE_HEAD(&includes, link);
84         in = fopen(inc->filename, "rt");
85         if (!in) {
86             fprintf(stderr, "Could not open `%s'.\n", inc->filename);
87             return EXIT_FAILURE;
88         }
89         free(inc->filename);
90         free(inc);
91
92         while (fgets(str, MAXLINE, in)) {
93             /* Strip off any trailing whitespace */
94             len = strlen(str);
95             if (len > 0) {
96                 strp = &str[len-1];
97                 while (len > 0 && isspace(*strp)) {
98                     *strp-- = '\0';
99                     len--;
100                 }
101             }
102
103             strp = str;
104
105             /* Skip whitespace */
106             while (isspace(*strp))
107                 strp++;
108
109             /* Skip comments */
110             if (*strp == '#')
111                 continue;
112
113             /* If line continuation, skip to continue copy */
114             if (linecont)
115                 goto keepgoing;
116
117             /* Check for include if original input is .am file */
118             if (isam && strncmp(strp, "include", 7) == 0 && isspace(strp[7])) {
119                 strp += 7;
120                 while (isspace(*strp))
121                     strp++;
122                 /* Build new include and add to end of list */
123                 inc = malloc(sizeof(include));
124                 inc->filename = malloc(strlen(strp)+1);
125                 strcpy(inc->filename, strp);
126                 STAILQ_INSERT_TAIL(&includes, inc, link);
127                 continue;
128             }
129
130             /* Check for YASM_MODULES = or += */
131             if (strncmp(strp, "YASM_MODULES", 12) != 0)
132                 continue;
133             strp += 12;
134             while (isspace(*strp))
135                 strp++;
136             if (strncmp(strp, "+=", 2) != 0 && *strp != '=')
137                 continue;
138             if (*strp == '+')
139                 strp++;
140             strp++;
141             while (isspace(*strp))
142                 strp++;
143
144 keepgoing:
145             /* Check for continuation */
146             if (len > 0 && str[len-1] == '\\') {
147                 str[len-1] = '\0';
148                 while (isspace(*strp))
149                     *strp-- = '\0';
150                 linecont = 1;
151             } else
152                 linecont = 0;
153
154             while (*strp != '\0') {
155                 /* Copy module name */
156                 modules[num_modules] = malloc(MAXNAME);
157                 len = 0;
158                 while (*strp != '\0' && !isspace(*strp))
159                     modules[num_modules][len++] = *strp++;
160                 modules[num_modules][len] = '\0';
161                 num_modules++;
162
163                 while (isspace(*strp))
164                     strp++;
165             }
166         }
167         fclose(in);
168     }
169
170     out = fopen(OUTPUT, "wt");
171
172     if (!out) {
173         fprintf(stderr, "Could not open `%s'.\n", OUTPUT);
174         return EXIT_FAILURE;
175     }
176
177     fprintf(out, "/* This file auto-generated by genmodule.c"
178                  " - don't edit it */\n\n");
179
180     in = fopen(argv[1], "rt");
181     if (!in) {
182         fprintf(stderr, "Could not open `%s'.\n", argv[1]);
183         fclose(out);
184         remove(OUTPUT);
185         return EXIT_FAILURE;
186     }
187
188     len = 0;
189     while (fgets(str, MAXLINE, in)) {
190         if (strncmp(str, "MODULES_", 8) == 0) {
191             len = 0;
192             strp = str+8;
193             while (*strp != '\0' && *strp != '_') {
194                 len++;
195                 strp++;
196             }
197             *strp = '\0';
198
199             for (i=0; i<num_modules; i++) {
200                 if (strncmp(modules[i], str+8, len) == 0) {
201                     fprintf(out, "    {\"%s\", &yasm_%s_LTX_%s},\n",
202                             modules[i]+len+1, modules[i]+len+1, str+8);
203                 }
204             }
205         } else if (strncmp(str, "EXTERN_LIST", 11) == 0) {
206             for (i=0; i<num_modules; i++) {
207                 strcpy(str, modules[i]);
208                 strp = str;
209                 while (*strp != '\0' && *strp != '_')
210                     strp++;
211                 *strp++ = '\0';
212
213                 fprintf(out, "extern yasm_%s_module yasm_%s_LTX_%s;\n",
214                         str, strp, str);
215             }
216         } else
217             fputs(str, out);
218     }
219
220     fclose(in);
221     fclose(out);
222
223     for (i=0; i<num_modules; i++)
224         free(modules[i]);
225     free(str);
226
227     return EXIT_SUCCESS;
228 }