]> rtime.felk.cvut.cz Git - frescor/forb.git/blob - forb-idl/forb-idl-main.c
Added mutex to protect request send from multiple threads
[frescor/forb.git] / forb-idl / forb-idl-main.c
1 /**************************************************************************
2
3     forb-idl-main.c (Driver program for the IDL parser & backend)
4
5     Copyright (C) 1999 Elliot Lee
6
7     This program 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     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21     $Id: forb-idl-main.c 2060 2008-05-19 21:11:07Z tml $
22
23 ***************************************************************************/
24
25 #include "config.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <glib.h>
31 #include <libIDL/IDL.h>
32 #include <glib/goption.h>
33 #include <glib/gi18n.h>
34 #include "forb_config.h"
35
36 #include "forb-idl2.h"
37
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41
42 /* FIXME: this program doesn't seem to support i18n? */
43 #ifndef GETTEXT_PACKAGE
44 #define GETTEXT_PACKAGE NULL
45 #endif
46
47 /* Settings made from the command line (prefaced with cl_) */
48 static gboolean cl_disable_stubs = FALSE,
49   cl_disable_skels = FALSE,
50   cl_disable_common = FALSE,
51   cl_disable_headers = FALSE;
52   /* cl_enable_skeleton_impl = FALSE */
53 static int cl_idlwarnlevel = 2;
54 static int cl_debuglevel = 0;
55 static int cl_is_pidl = 0;
56 static int cl_disable_idata = 0;
57 /* static int cl_enable_imodule = 0; */
58 /* static int cl_add_imodule = 0; */
59 static gboolean cl_disable_defs_skels = FALSE;
60 static gboolean cl_showcpperrors = FALSE;
61 static char *cl_output_lang = "c";
62 static char *cl_include = NULL;
63 static char *cl_header_guard_prefix = "";
64 static char *cl_backend_dir = NULL;
65 static gboolean cl_onlytop = TRUE;
66 static char *cl_deps_file = NULL;
67 static char *cl_output_directory = "";
68 static char **idl_files = NULL;
69
70 #define BASE_CPP_ARGS "-D__FORB_IDL__ "
71 static GString *cl_cpp_args;
72
73 /* Callbacks for goption */
74
75 static gboolean
76 cl_libIDL_version_callback (const char *option_name,
77                             const char *value,
78                             gpointer data,
79                             GError **error)
80 {
81   g_print("libIDL %s (CORBA %s)\n",
82           IDL_get_libver_string(),
83           IDL_get_IDLver_string());
84   exit(0);
85 }
86
87 static gboolean
88 cl_cpp_define_callback (const char *option_name,
89                         const char *value,
90                         gpointer data,
91                         GError **error)
92 {
93   g_string_append_printf (cl_cpp_args, "-D%s ", value);
94   return TRUE;
95 }
96
97 static gboolean
98 cl_cpp_include_callback (const char *option_name,
99                          const char *value,
100                          gpointer data,
101                          GError **error)
102 {
103   g_string_append_printf (cl_cpp_args, "-I%s ", value);
104   return TRUE;
105 }
106
107 static gboolean
108 cl_version_callback (const char *option_name,
109                      const char *value,
110                      gpointer data,
111                      GError **error)
112 {
113   g_print ("forb-idl-2 %s - serial %d\n",
114            VERSION, FORB_CONFIG_SERIAL);
115   exit(0);
116 }
117
118 /* static gboolean */
119 /* cl_c_output_formatter_callback (const char *option_name, */
120 /*                              const char *value, */
121 /*                              gpointer data, */
122 /*                              GError **error) */
123 /* { */
124 /*   g_warning ("Do not use the 'c-output-formatter' option. It is ignored and will soon go away."); */
125 /*   return TRUE; */
126 /* } */
127
128 static const GOptionEntry cl_libIDL_goptions[] = {
129   { "libIDL-version", 0, 0, G_OPTION_ARG_CALLBACK, cl_libIDL_version_callback, N_("Show version of libIDL used"), NULL },
130   { NULL }
131 };
132
133 static const GOptionEntry cl_cpp_goptions[] = {
134   { "define", 'D', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, cl_cpp_define_callback, N_("Define value in preprocessor"), N_("DEFINE") },
135   { "include", 'I', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, cl_cpp_include_callback, N_("Add search path for include files"), N_("DIR") },
136   { NULL }
137 };
138
139 static const GOptionEntry goptions[] = {
140   { "version", 'v', 0, G_OPTION_ARG_CALLBACK, cl_version_callback, N_("Output compiler version and serial"), NULL },
141   { "lang", 'l', 0, G_OPTION_ARG_STRING, &cl_output_lang, N_("Output language (default is C)"), N_("LANG") },
142   { "debug", 'd', 0, G_OPTION_ARG_INT, &cl_debuglevel, N_("Debug level (0 to 4)"), N_("LEVEL") },
143   { "idlwarnlevel", 0, 0, G_OPTION_ARG_INT, &cl_idlwarnlevel, N_("IDL warning level (0 to 4, default is 2)"), N_("LEVEL") },
144   { "showcpperrors", 0, 0, G_OPTION_ARG_NONE, &cl_showcpperrors, N_("Show CPP errors"), NULL },
145   { "nostubs", 0, 0, G_OPTION_ARG_NONE, &cl_disable_stubs, N_("Don't output stubs"), NULL },
146   { "noskels", 0, 0, G_OPTION_ARG_NONE, &cl_disable_skels, N_("Don't output skels"), NULL },
147   { "nocommon", 0, 0, G_OPTION_ARG_NONE, &cl_disable_common, N_("Don't output common"), NULL },
148   { "noheaders", 0, 0, G_OPTION_ARG_NONE, &cl_disable_headers, N_("Don't output headers"), NULL },
149   { "include", 0, 0, G_OPTION_ARG_STRING, &cl_include, N_("Put #include <FILE> to the generated header (for native types)"), N_("FILE") },
150 /*   { "noidata", 0, 0, G_OPTION_ARG_NONE, &cl_disable_idata, N_("Don't generate Interface type data"), NULL }, */
151 /*   { "imodule", 'i', 0, G_OPTION_ARG_NONE, &cl_enable_imodule, N_("Output only an imodule file"), NULL }, */
152 /*   { "add-imodule", 0, 0, G_OPTION_ARG_NONE, &cl_add_imodule, N_("Output an imodule file"), NULL }, */
153 /*   { "skeleton-impl", 0, 0, G_OPTION_ARG_NONE, &cl_enable_skeleton_impl, N_("Output skeleton implementation"), NULL }, */
154   { "backenddir", 0, 0, G_OPTION_ARG_FILENAME, &cl_backend_dir, N_("Override IDL backend library directory"), N_("DIR") },
155 /*   { "c-output-formatter", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, &cl_c_output_formatter_callback, "DEPRECATED and IGNORED", "PROGRAM" }, */
156   { "onlytop", 0, 0, G_OPTION_ARG_NONE, &cl_onlytop, N_("Inhibit includes"), NULL },
157   { "pidl", 0, 0, G_OPTION_ARG_NONE, &cl_is_pidl, N_("Treat as Pseudo IDL"), NULL },
158   { "nodefskels", 0, 0, G_OPTION_ARG_NONE, &cl_disable_defs_skels, N_("Don't output defs for skels in header"), NULL },
159   { "deps", 0, 0,  G_OPTION_ARG_FILENAME, &cl_deps_file, N_("Generate dependency info suitable for inclusion in Makefile"), N_("FILENAME") },
160   { "headerguardprefix", 0, 0, G_OPTION_ARG_STRING, &cl_header_guard_prefix, N_("Prefix for #ifdef header guards. Sometimes useful to avoid conflicts."), N_("PREFIX") },
161   { "output-dir", 0, 0, G_OPTION_ARG_FILENAME, &cl_output_directory, N_("Where to put generated files. This directory must exist."), N_("DIR") },
162   { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &idl_files, NULL, N_("<IDL files>") },
163   { NULL }
164 };
165
166 /********** main routines **********/
167 int main(int argc, char *argv[])
168 {
169   GOptionContext *context;
170   GOptionGroup *group;
171   GError *error = NULL;
172   OIDL_Run_Info rinfo;
173   GPtrArray *args;
174   int retval = 0;
175   gboolean result;
176   gpointer freeme;
177   guint i;
178
179   /* Argument parsing, etc. */
180   cl_cpp_args = g_string_new("-D__FORB_IDL__ ");
181
182   /* GOption cannot parse single-letter options without space
183    * between option and argument (-I../dir) or single-dash options.
184    * So fix those up before parsing, to retain command line compatibility
185    * with previous popt based versions of forb-idl-2
186    */
187   args = g_ptr_array_sized_new (2 * argc);
188   g_ptr_array_add (args, g_strdup (argv[0]));
189
190   for (i = 1; i < argc; ++i) {
191     if (argv[i][0] == '-' &&
192         (argv[i][1] == 'D' || argv[i][1] == 'I') &&
193         argv[i][2] != '\0') {
194       g_ptr_array_add (args, g_strndup (argv[i], 2));
195       g_ptr_array_add (args, g_strdup (argv[i] + 2));
196     } else if (strcmp (argv[i], "-define") == 0 ||
197                strcmp (argv[i], "-include") == 0) {
198       g_ptr_array_add (args, g_strdup_printf ("-%s", argv[i]));
199     } else {
200       g_ptr_array_add (args, g_strdup (argv[i]));
201     }
202   }
203
204   /* Parsing will modify the array; memdup it beforehand
205    * so we can free it correctly
206    */
207   argc = args->len;
208   argv = freeme = g_memdup (args->pdata, argc * sizeof (gpointer));
209   g_ptr_array_add (args, NULL); /* so we can use g_strfreev */
210
211   /* Now parse the options */
212   context = g_option_context_new ("");
213   g_option_context_add_main_entries (context, goptions, GETTEXT_PACKAGE);
214
215   group = g_option_group_new ("libIDL", N_("libIDL options"), N_("Show libIDL options"), NULL, NULL);
216   g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
217   g_option_group_add_entries (group, cl_libIDL_goptions);
218   g_option_context_add_group (context, group);
219
220   group = g_option_group_new ("cpp", N_("Preprocessor options"), N_("Show preprocessor options"), NULL, NULL);
221   g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
222   g_option_group_add_entries (group, cl_cpp_goptions);
223   g_option_context_add_group (context, group);
224
225   result = g_option_context_parse (context, &argc, &argv, &error);
226  
227   g_option_context_free (context);
228   g_strfreev ((char **) g_ptr_array_free (args, FALSE));
229   g_free (freeme);
230
231   if (!result) {
232     g_print ("forb-idl-2: %s\n", error->message);
233     g_error_free (error);
234     exit (1);
235   }
236
237   if (!idl_files) {
238     g_print ("No input files given!\n");
239     exit (1);
240   }
241
242   /* Prep our run info for the backend */
243   rinfo.cpp_args = cl_cpp_args->str;
244   rinfo.debug_level = cl_debuglevel;
245   rinfo.idl_warn_level = cl_idlwarnlevel;
246   rinfo.show_cpp_errors = cl_showcpperrors;
247   rinfo.is_pidl = cl_is_pidl;
248   rinfo.do_skel_defs = !cl_disable_defs_skels;
249   rinfo.enabled_passes =
250      (cl_disable_stubs?0:OUTPUT_STUBS)
251     |(cl_disable_skels?0:OUTPUT_SKELS)
252     |(cl_disable_common?0:OUTPUT_COMMON)
253     |(cl_disable_headers?0:OUTPUT_HEADERS)
254 /*     |(cl_enable_skeleton_impl?OUTPUT_SKELIMPL:0) */
255 /*     |(cl_add_imodule?OUTPUT_IMODULE:0) */
256     |(cl_deps_file != NULL?OUTPUT_DEPS:0)
257     ;
258
259   rinfo.deps_file = cl_deps_file;
260
261 /*   if (cl_enable_imodule) /\* clobber *\/ */
262 /*     rinfo.enabled_passes = */
263 /*       OUTPUT_COMMON | OUTPUT_HEADERS | OUTPUT_IMODULE; */
264
265   rinfo.output_language = cl_output_lang;
266   rinfo.header_guard_prefix = cl_header_guard_prefix;
267   rinfo.include = cl_include;
268   rinfo.output_directory = cl_output_directory;
269   rinfo.backend_directory = cl_backend_dir;
270   rinfo.onlytop = cl_onlytop;
271   rinfo.idata = !cl_disable_idata;
272
273   if (cl_debuglevel) {
274   printf ("forb-idl-2 " VERSION " compiling\n");
275   printf (" %s mode, %s preprocessor errors, passes: %s%s%s%s%s%s\n\n",
276           rinfo.is_pidl ? "pidl" : "",
277           rinfo.show_cpp_errors ? "show" : "hide",
278           rinfo.enabled_passes&OUTPUT_STUBS ? "stubs " : "",
279           rinfo.enabled_passes&OUTPUT_SKELS ? "skels " : "",
280           rinfo.enabled_passes&OUTPUT_COMMON ? "common " : "",
281           rinfo.enabled_passes&OUTPUT_HEADERS ? "headers " : "",
282           rinfo.enabled_passes&OUTPUT_SKELIMPL ? "skel_impl " : "",
283           rinfo.enabled_passes&OUTPUT_IMODULE ? "imodule" : "");
284   }
285   
286   /* Do it */
287   for (i = 0; idl_files[i]; ++i) {
288     if (cl_debuglevel) g_print ("Processing file %s\n", idl_files[i]);
289     rinfo.input_filename = idl_files[i];
290     if (!forb_idl_to_backend(idl_files[i], &rinfo)) {
291       g_warning("%s compilation failed", idl_files[i]);
292       retval = 1;
293     }
294   }
295
296   exit (retval);
297 }