1 /* GLIB-GenMarshal - Marshaller generator for GObject library
2 * Copyright (C) 2000-2001 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #define G_LOG_DOMAIN "GLib-Genmarshal"
32 #include <sys/types.h>
40 #define PRG_NAME "glib-genmarshal"
41 #define PKG_NAME "GLib"
42 #define PKG_HTTP_HOME "http://www.gtk.org"
45 /* --- typedefs & structures --- */
48 gchar *keyword; /* marhaller list keyword [MY_STRING] */
49 const gchar *sig_name; /* signature name [STRING] */
50 const gchar *ctype; /* C type name [gchar*] */
51 const gchar *getter; /* value getter function [g_value_get_string] */
55 gchar *keyword; /* marhaller list keyword [MY_STRING] */
56 const gchar *sig_name; /* signature name [STRING] */
57 const gchar *ctype; /* C type name [gchar*] */
58 const gchar *setter; /* value setter function [g_value_set_string] */
64 GList *args; /* of type InArgument* */
68 /* --- prototypes --- */
69 static void parse_args (gint *argc_p,
71 static void print_blurb (FILE *bout,
75 /* --- variables --- */
76 static FILE *fout = NULL;
77 static GScannerConfig scanner_config_template =
80 " \t\r" /* "\n" is statement delimiter */
81 ) /* cset_skip_characters */,
86 ) /* cset_identifier_first */,
91 ) /* cset_identifier_nth */,
92 ( "#\n" ) /* cpair_comment_single */,
94 FALSE /* case_sensitive */,
96 TRUE /* skip_comment_multi */,
97 TRUE /* skip_comment_single */,
98 TRUE /* scan_comment_multi */,
99 TRUE /* scan_identifier */,
100 FALSE /* scan_identifier_1char */,
101 FALSE /* scan_identifier_NULL */,
102 TRUE /* scan_symbols */,
103 FALSE /* scan_binary */,
104 TRUE /* scan_octal */,
105 TRUE /* scan_float */,
107 FALSE /* scan_hex_dollar */,
108 TRUE /* scan_string_sq */,
109 TRUE /* scan_string_dq */,
110 TRUE /* numbers_2_int */,
111 FALSE /* int_2_float */,
112 FALSE /* identifier_2_string */,
113 TRUE /* char_2_token */,
114 FALSE /* symbol_2_token */,
115 FALSE /* scope_0_fallback */,
117 static gchar *std_marshaller_prefix = "g_cclosure_marshal";
118 static gchar *marshaller_prefix = "g_cclosure_user_marshal";
119 static GHashTable *marshallers = NULL;
120 static gboolean gen_cheader = FALSE;
121 static gboolean gen_cbody = FALSE;
122 static gboolean skip_ploc = FALSE;
123 static gboolean std_includes = TRUE;
126 /* --- functions --- */
128 put_marshal_value_getters (void)
131 fputs ("#ifdef G_ENABLE_DEBUG\n", fout);
132 fputs ("#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)\n", fout);
133 fputs ("#define g_marshal_value_peek_char(v) g_value_get_char (v)\n", fout);
134 fputs ("#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)\n", fout);
135 fputs ("#define g_marshal_value_peek_int(v) g_value_get_int (v)\n", fout);
136 fputs ("#define g_marshal_value_peek_uint(v) g_value_get_uint (v)\n", fout);
137 fputs ("#define g_marshal_value_peek_long(v) g_value_get_long (v)\n", fout);
138 fputs ("#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)\n", fout);
139 fputs ("#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)\n", fout);
140 fputs ("#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)\n", fout);
141 fputs ("#define g_marshal_value_peek_enum(v) g_value_get_enum (v)\n", fout);
142 fputs ("#define g_marshal_value_peek_flags(v) g_value_get_flags (v)\n", fout);
143 fputs ("#define g_marshal_value_peek_float(v) g_value_get_float (v)\n", fout);
144 fputs ("#define g_marshal_value_peek_double(v) g_value_get_double (v)\n", fout);
145 fputs ("#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)\n", fout);
146 fputs ("#define g_marshal_value_peek_param(v) g_value_get_param (v)\n", fout);
147 fputs ("#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)\n", fout);
148 fputs ("#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)\n", fout);
149 fputs ("#define g_marshal_value_peek_object(v) g_value_get_object (v)\n", fout);
150 fputs ("#else /* !G_ENABLE_DEBUG */\n", fout);
151 fputs ("/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.\n", fout);
152 fputs (" * Do not access GValues directly in your code. Instead, use the\n", fout);
153 fputs (" * g_value_get_*() functions\n", fout);
154 fputs (" */\n", fout);
155 fputs ("#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int\n", fout);
156 fputs ("#define g_marshal_value_peek_char(v) (v)->data[0].v_int\n", fout);
157 fputs ("#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint\n", fout);
158 fputs ("#define g_marshal_value_peek_int(v) (v)->data[0].v_int\n", fout);
159 fputs ("#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint\n", fout);
160 fputs ("#define g_marshal_value_peek_long(v) (v)->data[0].v_long\n", fout);
161 fputs ("#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong\n", fout);
162 fputs ("#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64\n", fout);
163 fputs ("#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64\n", fout);
164 fputs ("#define g_marshal_value_peek_enum(v) (v)->data[0].v_int\n", fout);
165 fputs ("#define g_marshal_value_peek_flags(v) (v)->data[0].v_uint\n", fout);
166 fputs ("#define g_marshal_value_peek_float(v) (v)->data[0].v_float\n", fout);
167 fputs ("#define g_marshal_value_peek_double(v) (v)->data[0].v_double\n", fout);
168 fputs ("#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer\n", fout);
169 fputs ("#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer\n", fout);
170 fputs ("#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer\n", fout);
171 fputs ("#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer\n", fout);
172 fputs ("#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer\n", fout);
173 fputs ("#endif /* !G_ENABLE_DEBUG */\n", fout);
178 complete_in_arg (InArgument *iarg)
180 static const InArgument args[] = {
181 /* keyword sig_name ctype getter */
182 { "VOID", "VOID", "void", NULL, },
183 { "BOOLEAN", "BOOLEAN", "gboolean", "g_marshal_value_peek_boolean", },
184 { "CHAR", "CHAR", "gchar", "g_marshal_value_peek_char", },
185 { "UCHAR", "UCHAR", "guchar", "g_marshal_value_peek_uchar", },
186 { "INT", "INT", "gint", "g_marshal_value_peek_int", },
187 { "UINT", "UINT", "guint", "g_marshal_value_peek_uint", },
188 { "LONG", "LONG", "glong", "g_marshal_value_peek_long", },
189 { "ULONG", "ULONG", "gulong", "g_marshal_value_peek_ulong", },
190 { "INT64", "INT64", "gint64", "g_marshal_value_peek_int64", },
191 { "UINT64", "UINT64", "guint64", "g_marshal_value_peek_uint64", },
192 { "ENUM", "ENUM", "gint", "g_marshal_value_peek_enum", },
193 { "FLAGS", "FLAGS", "guint", "g_marshal_value_peek_flags", },
194 { "FLOAT", "FLOAT", "gfloat", "g_marshal_value_peek_float", },
195 { "DOUBLE", "DOUBLE", "gdouble", "g_marshal_value_peek_double", },
196 { "STRING", "STRING", "gpointer", "g_marshal_value_peek_string", },
197 { "PARAM", "PARAM", "gpointer", "g_marshal_value_peek_param", },
198 { "BOXED", "BOXED", "gpointer", "g_marshal_value_peek_boxed", },
199 { "POINTER", "POINTER", "gpointer", "g_marshal_value_peek_pointer", },
200 { "OBJECT", "OBJECT", "gpointer", "g_marshal_value_peek_object", },
202 { "NONE", "VOID", "void", NULL, },
203 { "BOOL", "BOOLEAN", "gboolean", "g_marshal_value_peek_boolean", },
205 const guint n_args = sizeof (args) / sizeof (args[0]);
208 g_return_val_if_fail (iarg != NULL, FALSE);
210 for (i = 0; i < n_args; i++)
211 if (strcmp (args[i].keyword, iarg->keyword) == 0)
213 iarg->sig_name = args[i].sig_name;
214 iarg->ctype = args[i].ctype;
215 iarg->getter = args[i].getter;
223 complete_out_arg (OutArgument *oarg)
225 static const OutArgument args[] = {
226 /* keyword sig_name ctype setter */
227 { "VOID", "VOID", "void", NULL, },
228 { "BOOLEAN", "BOOLEAN", "gboolean", "g_value_set_boolean", },
229 { "CHAR", "CHAR", "gchar", "g_value_set_char", },
230 { "UCHAR", "UCHAR", "guchar", "g_value_set_uchar", },
231 { "INT", "INT", "gint", "g_value_set_int", },
232 { "UINT", "UINT", "guint", "g_value_set_uint", },
233 { "LONG", "LONG", "glong", "g_value_set_long", },
234 { "ULONG", "ULONG", "gulong", "g_value_set_ulong", },
235 { "INT64", "INT64", "gint64", "g_value_set_int64", },
236 { "UINT64", "UINT64", "guint64", "g_value_set_uint64", },
237 { "ENUM", "ENUM", "gint", "g_value_set_enum", },
238 { "FLAGS", "FLAGS", "guint", "g_value_set_flags", },
239 { "FLOAT", "FLOAT", "gfloat", "g_value_set_float", },
240 { "DOUBLE", "DOUBLE", "gdouble", "g_value_set_double", },
241 { "STRING", "STRING", "gchar*", "g_value_set_string_take_ownership", },
242 { "PARAM", "PARAM", "GParamSpec*", "g_value_set_param_take_ownership", },
243 { "BOXED", "BOXED", "gpointer", "g_value_set_boxed_take_ownership", },
244 { "POINTER", "POINTER", "gpointer", "g_value_set_pointer", },
245 { "OBJECT", "OBJECT", "GObject*", "g_value_set_object_take_ownership", },
247 { "NONE", "VOID", "void", NULL, },
248 { "BOOL", "BOOLEAN", "gboolean", "g_value_set_boolean", },
250 const guint n_args = sizeof (args) / sizeof (args[0]);
253 g_return_val_if_fail (oarg != NULL, FALSE);
255 for (i = 0; i < n_args; i++)
256 if (strcmp (args[i].keyword, oarg->keyword) == 0)
258 oarg->sig_name = args[i].sig_name;
259 oarg->ctype = args[i].ctype;
260 oarg->setter = args[i].setter;
268 pad (const gchar *string)
270 #define PAD_LENGTH 12
271 static gchar *buffer = NULL;
274 g_return_val_if_fail (string != NULL, NULL);
277 buffer = g_new (gchar, PAD_LENGTH + 1);
280 if (strlen (string) >= PAD_LENGTH)
283 buffer = g_strdup_printf ("%s ", string);
284 g_warning ("overfull string (%u bytes) for padspace", (guint) strlen (string));
289 for (i = 0; i < PAD_LENGTH; i++)
291 gboolean done = *string == 0;
293 buffer[i] = done ? ' ' : *string++;
301 indent (guint n_spaces)
303 static gchar *buffer = NULL;
304 static guint blength = 0;
306 if (blength <= n_spaces)
308 blength = n_spaces + 1;
310 buffer = g_new (gchar, blength);
312 memset (buffer, ' ', n_spaces);
313 buffer[n_spaces] = 0;
319 generate_marshal (const gchar *signame,
324 gchar *tmp = g_strconcat (marshaller_prefix, "_", signame, NULL);
325 gboolean have_std_marshaller = FALSE;
327 /* here we have to make sure a marshaller named <marshaller_prefix>_<signame>
328 * exists. we might have put it out already, can revert to a standard marshaller
329 * provided by glib, or need to generate one.
332 if (g_hash_table_lookup (marshallers, tmp))
334 /* done, marshaller already generated */
340 /* need to alias/generate marshaller, register name */
341 g_hash_table_insert (marshallers, tmp, tmp);
344 /* can we revert to a standard marshaller? */
347 tmp = g_strconcat (std_marshaller_prefix, "_", signame, NULL);
348 have_std_marshaller = g_hash_table_lookup (marshallers, tmp) != NULL;
352 if (gen_cheader && have_std_marshaller)
354 fprintf (fout, "#define %s_%s\t%s_%s\n", marshaller_prefix, signame, std_marshaller_prefix, signame);
356 if (gen_cheader && !have_std_marshaller)
358 ind = fprintf (fout, "extern void ");
359 ind += fprintf (fout, "%s_%s (", marshaller_prefix, signame);
360 fprintf (fout, "GClosure *closure,\n");
361 fprintf (fout, "%sGValue *return_value,\n", indent (ind));
362 fprintf (fout, "%sguint n_param_values,\n", indent (ind));
363 fprintf (fout, "%sconst GValue *param_values,\n", indent (ind));
364 fprintf (fout, "%sgpointer invocation_hint,\n", indent (ind));
365 fprintf (fout, "%sgpointer marshal_data);\n", indent (ind));
367 if (gen_cbody && !have_std_marshaller)
369 /* cfile marhsal header */
370 fprintf (fout, "void\n");
371 ind = fprintf (fout, "%s_%s (", marshaller_prefix, signame);
372 fprintf (fout, "GClosure *closure,\n");
373 fprintf (fout, "%sGValue *return_value,\n", indent (ind));
374 fprintf (fout, "%sguint n_param_values,\n", indent (ind));
375 fprintf (fout, "%sconst GValue *param_values,\n", indent (ind));
376 fprintf (fout, "%sgpointer invocation_hint,\n", indent (ind));
377 fprintf (fout, "%sgpointer marshal_data)\n", indent (ind));
378 fprintf (fout, "{\n");
380 /* cfile GMarshalFunc typedef */
381 ind = fprintf (fout, " typedef %s (*GMarshalFunc_%s) (", sig->rarg->ctype, signame);
382 fprintf (fout, "%s data1,\n", pad ("gpointer"));
383 for (a = 1, node = sig->args; node; node = node->next)
385 InArgument *iarg = node->data;
388 fprintf (fout, "%s%s arg_%d,\n", indent (ind), pad (iarg->ctype), a++);
390 fprintf (fout, "%s%s data2);\n", indent (ind), pad ("gpointer"));
392 /* cfile marshal variables */
393 fprintf (fout, " register GMarshalFunc_%s callback;\n", signame);
394 fprintf (fout, " register GCClosure *cc = (GCClosure*) closure;\n");
395 fprintf (fout, " register gpointer data1, data2;\n");
396 if (sig->rarg->setter)
397 fprintf (fout, " %s v_return;\n", sig->rarg->ctype);
399 if (sig->args || sig->rarg->setter)
401 fprintf (fout, "\n");
403 if (sig->rarg->setter)
404 fprintf (fout, " g_return_if_fail (return_value != NULL);\n");
407 for (a = 0, node = sig->args; node; node = node->next)
409 InArgument *iarg = node->data;
414 fprintf (fout, " g_return_if_fail (n_param_values == %u);\n", 1 + a);
418 /* cfile marshal data1, data2 and callback setup */
419 fprintf (fout, "\n");
420 fprintf (fout, " if (G_CCLOSURE_SWAP_DATA (closure))\n {\n");
421 fprintf (fout, " data1 = closure->data;\n");
422 fprintf (fout, " data2 = g_value_peek_pointer (param_values + 0);\n");
423 fprintf (fout, " }\n else\n {\n");
424 fprintf (fout, " data1 = g_value_peek_pointer (param_values + 0);\n");
425 fprintf (fout, " data2 = closure->data;\n");
426 fprintf (fout, " }\n");
427 fprintf (fout, " callback = (GMarshalFunc_%s) (marshal_data ? marshal_data : cc->callback);\n", signame);
429 /* cfile marshal callback action */
430 fprintf (fout, "\n");
431 ind = fprintf (fout, " %s callback (", sig->rarg->setter ? " v_return =" : "");
432 fprintf (fout, "data1,\n");
433 for (a = 1, node = sig->args; node; node = node->next)
435 InArgument *iarg = node->data;
438 fprintf (fout, "%s%s (param_values + %d),\n", indent (ind), iarg->getter, a++);
440 fprintf (fout, "%sdata2);\n", indent (ind));
442 /* cfile marshal return value storage */
443 if (sig->rarg->setter)
445 fprintf (fout, "\n");
446 fprintf (fout, " %s (return_value, v_return);\n", sig->rarg->setter);
449 /* cfile marshal footer */
450 fprintf (fout, "}\n");
455 process_signature (Signature *sig)
457 gchar *pname, *sname, *tmp;
460 /* lookup and complete info on arguments */
461 if (!complete_out_arg (sig->rarg))
463 g_warning ("unknown type: %s", sig->rarg->keyword);
466 for (node = sig->args; node; node = node->next)
468 InArgument *iarg = node->data;
470 if (!complete_in_arg (iarg))
472 g_warning ("unknown type: %s", iarg->keyword);
477 /* construct requested marshaller name and technical marshaller name */
478 pname = g_strconcat (sig->rarg->keyword, "_", NULL);
479 sname = g_strconcat (sig->rarg->sig_name, "_", NULL);
480 for (node = sig->args; node; node = node->next)
482 InArgument *iarg = node->data;
486 sname = g_strconcat (tmp, "_", iarg->sig_name, NULL);
489 pname = g_strconcat (tmp, "_", iarg->keyword, NULL);
493 /* introductionary comment */
494 fprintf (fout, "\n/* %s", sig->rarg->keyword);
495 for (node = sig->args; node; node = node->next)
497 InArgument *iarg = node->data;
499 fprintf (fout, "%c%s", node->prev ? ',' : ':', iarg->keyword);
502 fprintf (fout, " (%s)", sig->ploc);
503 fprintf (fout, " */\n");
505 /* ensure technical marshaller exists (<marshaller_prefix>_<sname>) */
506 generate_marshal (sname, sig);
508 /* put out marshaller alias for requested name if required (<marshaller_prefix>_<pname>) */
509 tmp = g_strconcat (marshaller_prefix, "_", pname, NULL);
510 if (gen_cheader && !g_hash_table_lookup (marshallers, tmp))
512 fprintf (fout, "#define %s_%s\t%s_%s\n", marshaller_prefix, pname, marshaller_prefix, sname);
514 g_hash_table_insert (marshallers, tmp, tmp);
524 new_in_arg (const gchar *pname)
526 InArgument *iarg = g_new0 (InArgument, 1);
528 iarg->keyword = g_strdup (pname);
534 new_out_arg (const gchar *pname)
536 OutArgument *oarg = g_new0 (OutArgument, 1);
538 oarg->keyword = g_strdup (pname);
544 parse_line (GScanner *scanner,
547 /* parse identifier for return value */
548 if (g_scanner_get_next_token (scanner) != G_TOKEN_IDENTIFIER)
549 return G_TOKEN_IDENTIFIER;
550 sig->rarg = new_out_arg (scanner->value.v_identifier);
552 /* keep a note on the location */
553 sig->ploc = g_strdup_printf ("%s:%u", scanner->input_name, scanner->line);
556 if (g_scanner_get_next_token (scanner) != ':')
559 /* parse first argument */
560 if (g_scanner_get_next_token (scanner) != G_TOKEN_IDENTIFIER)
561 return G_TOKEN_IDENTIFIER;
562 sig->args = g_list_append (sig->args, new_in_arg (scanner->value.v_identifier));
564 /* parse rest of argument list */
565 while (g_scanner_peek_next_token (scanner) == ',')
568 g_scanner_get_next_token (scanner);
570 /* parse arg identifier */
571 if (g_scanner_get_next_token (scanner) != G_TOKEN_IDENTIFIER)
572 return G_TOKEN_IDENTIFIER;
573 sig->args = g_list_append (sig->args, new_in_arg (scanner->value.v_identifier));
576 /* expect end of line, done */
577 if (g_scanner_get_next_token (scanner) != '\n')
585 string_key_destroy (gpointer key,
598 const gchar *gobject_marshallers[] = {
599 #include "gmarshal.strings"
602 GSList *slist, *files = NULL;
606 /* parse args and do fast exits */
607 parse_args (&argc, &argv);
609 /* list input files */
610 for (i = 1; i < argc; i++)
611 files = g_slist_prepend (files, argv[i]);
613 files = g_slist_reverse (files);
615 files = g_slist_prepend (files, "/dev/stdin");
617 /* setup auxillary structs */
618 scanner = g_scanner_new (&scanner_config_template);
620 marshallers = g_hash_table_new (g_str_hash, g_str_equal);
622 /* add standard marshallers of the GObject library */
624 for (i = 0; i < sizeof (gobject_marshallers) / sizeof (gobject_marshallers[0]); i++)
626 gchar *tmp = g_strdup (gobject_marshallers[i]);
628 g_hash_table_insert (marshallers, tmp, tmp);
631 /* put out initial heading */
632 fprintf (fout, "\n");
634 if (gen_cheader && std_includes)
636 fprintf (fout, "#ifndef __%s_MARSHAL_H__\n", marshaller_prefix);
637 fprintf (fout, "#define __%s_MARSHAL_H__\n\n", marshaller_prefix);
640 if ((gen_cheader || gen_cbody) && std_includes)
641 fprintf (fout, "#include\t<glib-object.h>\n\n");
644 fprintf (fout, "G_BEGIN_DECLS\n");
646 /* generate necessary preprocessor directives */
648 put_marshal_value_getters ();
650 /* process input files */
651 for (slist = files; slist; slist = slist->next)
653 gchar *file = slist->data;
654 gint fd = open (file, O_RDONLY);
658 g_warning ("failed to open \"%s\": %s", file, g_strerror (errno));
663 /* set file name for error reports */
664 scanner->input_name = file;
666 /* parse & process file */
667 g_scanner_input_file (scanner, fd);
669 /* scanning loop, we parse the input untill it's end is reached,
670 * or our sub routine came across invalid syntax
674 guint expected_token = G_TOKEN_NONE;
676 switch (g_scanner_peek_next_token (scanner))
679 /* eat newline and restart */
680 g_scanner_get_next_token (scanner);
686 /* parse and process signatures */
688 Signature signature = { NULL, NULL, NULL };
691 expected_token = parse_line (scanner, &signature);
693 /* once we got a valid signature, process it */
694 if (expected_token == G_TOKEN_NONE)
695 process_signature (&signature);
697 /* clean up signature contents */
698 g_free (signature.ploc);
700 g_free (signature.rarg->keyword);
701 g_free (signature.rarg);
702 for (node = signature.args; node; node = node->next)
704 InArgument *iarg = node->data;
706 g_free (iarg->keyword);
709 g_list_free (signature.args);
714 /* bail out on errors */
715 if (expected_token != G_TOKEN_NONE)
717 g_scanner_unexp_token (scanner, expected_token, "type name", NULL, NULL, NULL, TRUE);
722 g_scanner_peek_next_token (scanner);
724 while (scanner->next_token != G_TOKEN_EOF);
729 /* put out trailer */
732 fprintf (fout, "\nG_END_DECLS\n");
735 fprintf (fout, "\n#endif /* __%s_MARSHAL_H__ */\n", marshaller_prefix);
737 fprintf (fout, "\n");
740 g_slist_free (files);
741 g_scanner_destroy (scanner);
742 g_hash_table_foreach_remove (marshallers, string_key_destroy, NULL);
743 g_hash_table_destroy (marshallers);
749 parse_args (gint *argc_p,
752 guint argc = *argc_p;
753 gchar **argv = *argv_p;
756 for (i = 1; i < argc; i++)
758 if (strcmp ("--header", argv[i]) == 0)
763 else if (strcmp ("--body", argv[i]) == 0)
768 else if (strcmp ("--skip-source", argv[i]) == 0)
773 else if (strcmp ("--nostdinc", argv[i]) == 0)
775 std_includes = FALSE;
778 else if (strcmp ("--stdinc", argv[i]) == 0)
783 else if ((strcmp ("--prefix", argv[i]) == 0) ||
784 (strncmp ("--prefix=", argv[i], 9) == 0))
786 gchar *equal = argv[i] + 8;
789 marshaller_prefix = g_strdup (equal + 1);
790 else if (i + 1 < argc)
792 marshaller_prefix = g_strdup (argv[i + 1]);
798 else if (strcmp ("-h", argv[i]) == 0 ||
799 strcmp ("--help", argv[i]) == 0)
801 print_blurb (stderr, TRUE);
805 else if (strcmp ("-v", argv[i]) == 0 ||
806 strcmp ("--version", argv[i]) == 0)
808 print_blurb (stderr, FALSE);
812 else if (strcmp (argv[i], "--g-fatal-warnings") == 0)
814 GLogLevelFlags fatal_mask;
816 fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
817 fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
818 g_log_set_always_fatal (fatal_mask);
825 for (i = 1; i < argc; i++)
843 print_blurb (FILE *bout,
848 fprintf (bout, "%s version ", PRG_NAME);
849 fprintf (bout, "%u.%u.%u", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
850 fprintf (bout, "\n");
851 fprintf (bout, "%s comes with ABSOLUTELY NO WARRANTY.\n", PRG_NAME);
852 fprintf (bout, "You may redistribute copies of %s under the terms of\n", PRG_NAME);
853 fprintf (bout, "the GNU General Public License which can be found in the\n");
854 fprintf (bout, "%s source package. Sources, examples and contact\n", PKG_NAME);
855 fprintf (bout, "information are available at %s\n", PKG_HTTP_HOME);
859 fprintf (bout, "Usage: %s [options] [files...]\n", PRG_NAME);
860 fprintf (bout, " --header generate C headers\n");
861 fprintf (bout, " --body generate C code\n");
862 fprintf (bout, " --prefix=string specify marshaller prefix\n");
863 fprintf (bout, " --skip-source skip source location comments\n");
864 fprintf (bout, " --stdinc, --nostdinc include/use standard marshallers\n");
865 fprintf (bout, " -h, --help show this help message\n");
866 fprintf (bout, " -v, --version print version informations\n");
867 fprintf (bout, " --g-fatal-warnings make warnings fatal (abort)\n");