2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2011 George (Jiri) Lebl
6 * Author: George (Jiri) Lebl
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program 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
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
34 #include "treefuncs.h"
42 char *filename = NULL;
52 extern GList *include_files;
54 extern GHashTable *gtk_doc_hash;
58 static char *outfilebase;
59 static char *outfilehbase;
60 static char *outfilephbase;
61 static char *funcbase;
62 static char *pfuncbase;
63 static char *macrobase;
65 static char *pmacrois;
66 static char *macrotype;
67 static char *pmacrotype;
68 static char *typebase;
69 static char *ptypebase;
71 char *output_dir = NULL;
75 static int signals = 0; /* number of signals */
76 static int set_properties = 0; /* number of named (set) properties */
77 static int get_properties = 0; /* number of named (get) properties */
78 static int overrides = 0; /* number of override methods */
79 static int privates = 0; /* number of private data members */
80 static int protecteds = 0; /* number of protected methods */
81 static int unreftors = 0; /* number of variable unreffing destructors */
82 static int destructors = 0; /* number of variable non-unreffing destructors */
83 static int initializers = 0; /* number of variable initializers */
84 static int glade_widgets = 0; /* number of glade widgets */
85 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
87 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
88 and need the REALLY UGLY HACK to
91 /* the special variable types we need to define */
92 static gboolean special_array[SPECIAL_LAST] = {0};
93 static gboolean any_special = FALSE;
95 static gboolean need_constructor = FALSE;
96 static Method * user_constructor = NULL;
98 static gboolean need_dispose = FALSE;
99 static Method * dispose_handler = NULL;
100 static Method * user_dispose_method = NULL;
102 static gboolean need_finalize = FALSE;
103 static Method * finalize_handler = NULL;
104 static Method * user_finalize_method = NULL;
110 gboolean no_touch = FALSE;
111 gboolean no_touch_headers = FALSE;
112 gboolean for_cpp = FALSE;
113 gboolean no_gnu = FALSE;
114 gboolean exit_on_warn = FALSE;
115 gboolean exit_on_error = TRUE;
116 gboolean got_error = FALSE;
117 gint private_header = PRIVATE_HEADER_ONDEMAND;
118 gboolean no_extern_c = FALSE;
119 gboolean no_write = FALSE;
120 gboolean no_lines = FALSE;
121 gboolean no_self_alias = FALSE;
122 gboolean always_private_struct = FALSE;
125 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
126 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
127 char *m4_commandline = NULL;
128 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
129 #define M4_BASE_FILENAME "gobm4.m4"
130 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
131 #define M4_COMMANDLINE "m4"
133 int method_unique_id = 1;
138 filebase = replace_sep (((Class *)class)->otype, file_sep);
139 gob_strdown (filebase);
141 if (output_dir != NULL &&
142 output_dir[0] != '\0') {
143 fullfilebase = g_build_filename (output_dir, filebase, NULL);
145 fullfilebase = g_strdup (filebase);
148 funcbase = replace_sep (((Class *)class)->otype, '_');
149 gob_strdown (funcbase);
151 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
152 gob_strdown (pfuncbase);
154 macrobase = replace_sep (((Class *)class)->otype, '_');
155 gob_strup (macrobase);
157 macrois = make_pre_macro (((Class *)class)->otype, "IS");
158 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
160 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
161 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
163 typebase = remove_sep (((Class *)class)->otype);
165 ptypebase = remove_sep (((Class *)class)->ptype);
169 get_gtk_doc (const char *id)
176 val = g_hash_table_lookup(gtk_doc_hash, id);
178 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
180 val = g_hash_table_lookup(gtk_doc_hash, id);
182 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
188 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
192 s = get_type(t, postfix_to_stars);
193 out_printf(fp, "%s", s);
199 print_method (FILE *fp,
200 const char *typeprefix,
201 const char *nameprefix,
202 const char *subnameprefix,
203 const char *namepostfix,
204 const char *afterargs,
207 gboolean print_funcattrs,
208 gboolean one_arg_per_line,
209 gboolean no_funcbase,
210 gboolean kill_underscore,
211 gboolean first_unused,
217 out_printf(fp, "%s", typeprefix);
218 print_type(fp, m->mtype, TRUE);
223 out_printf(fp, "%s%s%s%s(",
224 nameprefix, subnameprefix, id, namepostfix);
226 out_printf(fp, "%s%s_%s%s%s(",
227 nameprefix, funcbase, subnameprefix, id,
231 for(li=m->args; li; li=g_list_next(li)) {
232 FuncArg *arg = li->data;
233 const char *unused = "";
236 ! for_cpp && /* g++ has a cow with this */
239 unused = " G_GNUC_UNUSED";
242 print_type(fp, arg->atype, FALSE);
244 out_printf (fp, "___fake___");
246 out_printf(fp, "%s%s%s,%s", arg->name,
247 arg->atype->postfix ?
248 arg->atype->postfix : "",
250 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
252 out_printf(fp, "%s%s%s", arg->name,
253 arg->atype->postfix ?
254 arg->atype->postfix : "",
258 out_printf(fp, ",%s...",
259 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
261 out_printf(fp, "void");
263 /* Slightly icky: sometimes we are called st m->funcattrs
264 hasn't been set, but if so it should be NULL since its been
266 if(print_funcattrs && m->funcattrs != NULL
267 && strlen(m->funcattrs) > 0) {
268 /* To keep the output neat, we trim off the trailing '\n'
269 from the end of funcattrs for a moment. */
270 size_t funcattrs_len = strlen(m->funcattrs);
271 gboolean funcattrs_chomped = FALSE;
272 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
273 m->funcattrs[funcattrs_len - 1] = '\0';
274 funcattrs_chomped = TRUE;
276 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
277 /* Put it back like it was (though it shouldn't matter). */
278 if (funcattrs_chomped) {
279 (m->funcattrs)[funcattrs_len - 1] = '\n';
283 out_printf(fp, "%s)%s", afterargs, postfix);
288 any_method_to_alias(Class *c)
292 for(li=c->nodes;li;li=g_list_next(li)) {
293 Node *node = li->data;
294 if(node->type == METHOD_NODE) {
295 Method *m = (Method *)node;
297 if(m->method == INIT_METHOD ||
298 m->method == CLASS_INIT_METHOD ||
299 m->method == CONSTRUCTOR_METHOD ||
300 m->method == DISPOSE_METHOD ||
301 m->method == FINALIZE_METHOD ||
302 m->method == OVERRIDE_METHOD)
313 make_method_aliases (Class *c)
317 for(li = c->nodes; li != NULL; li = li->next) {
318 Node *node = li->data;
319 if(node->type == METHOD_NODE) {
320 Method *m = (Method *)node;
322 if(m->method == INIT_METHOD ||
323 m->method == CLASS_INIT_METHOD ||
324 m->method == CONSTRUCTOR_METHOD ||
325 m->method == DISPOSE_METHOD ||
326 m->method == FINALIZE_METHOD ||
327 m->method == OVERRIDE_METHOD)
330 out_printf (out, "#define self_%s %s_%s\n",
339 add_bad_hack_to_avoid_unused_warnings(const Class *c)
343 /* if we haven't had any methods, just return */
348 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
350 "/*REALLY BAD HACK\n"
351 " This is to avoid unused warnings if you don't call\n"
352 " some method. I need to find a better way to do\n"
353 " this, not needed in GCC since we use some gcc\n"
354 " extentions to make saner, faster code */\n"
356 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
358 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
359 for(li=c->nodes;li;li=g_list_next(li)) {
360 Node *node = li->data;
361 if(node->type == METHOD_NODE) {
362 Method *m = (Method *)node;
364 if(m->method == INIT_METHOD ||
365 m->method == CLASS_INIT_METHOD ||
366 m->method == CONSTRUCTOR_METHOD ||
367 m->method == DISPOSE_METHOD ||
368 m->method == FINALIZE_METHOD ||
369 m->method == OVERRIDE_METHOD)
372 /* in C++ mode we don't alias new */
373 if(for_cpp && strcmp(m->id, "new")==0)
376 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
379 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
382 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
384 out_printf(out, "}\n\n");
388 put_variable(const Variable *v, FILE *fp)
390 out_printf(fp, "\t");
391 print_type(fp, v->vtype, FALSE);
392 out_printf(fp, "%s%s;", v->id,
394 v->vtype->postfix:"");
395 if(v->scope == PROTECTED_SCOPE)
396 out_printf(fp, " /* protected */");
397 out_printf(fp, "\n");
401 put_vs_method(const Method *m)
403 if(m->method != SIGNAL_LAST_METHOD &&
404 m->method != SIGNAL_FIRST_METHOD &&
405 m->method != VIRTUAL_METHOD)
408 /* if a signal mark it as such */
409 if(m->method != VIRTUAL_METHOD)
410 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
411 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
413 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
414 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
419 put_pub_method(const Method *m)
421 if(m->scope != PUBLIC_SCOPE)
424 out_addline_infile(outh, m->line_no);
425 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
426 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
427 out_addline_outfile(outh);
431 put_signal_macro (const Method *m, gboolean gnu)
433 if(m->method != SIGNAL_LAST_METHOD &&
434 m->method != SIGNAL_FIRST_METHOD)
439 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
440 "g_signal_connect(%s(object),\"%s\","
441 "(GCallback)(func),(data))\n",
442 funcbase, m->id, macrobase, m->id);
445 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
446 "g_signal_connect_after(%s(object),\"%s\","
447 "(GCallback)(func),(data))\n",
448 funcbase, m->id, macrobase, m->id);
451 out_printf (outh, "#define %s_connect_data__%s"
452 "(object,func,data,destroy_data,flags)\t"
453 "g_signal_connect_data(%s(object),\"%s\","
454 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
455 funcbase, m->id, macrobase, m->id);
458 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
460 "%s(__extension__ ({%s *___object = (object); ___object; })),"
462 "(GCallback) __extension__ ({",
463 funcbase, m->id, macrobase, typebase, m->id);
464 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
465 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
466 out_printf (outh, "___%s; }), (data))\n", m->id);
469 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
470 "g_signal_connect_after("
471 "%s(__extension__ ({%s *___object = (object); ___object; })),"
473 "(GCallback) __extension__ ({",
474 funcbase, m->id, macrobase, typebase, m->id);
475 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
476 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
477 out_printf (outh, "___%s; }), (data))\n", m->id);
480 out_printf (outh, "#define %s_connect_data__%s"
481 "(object,func,data,destroy_data,flags)\t"
482 "g_signal_connect_data("
483 "%s(__extension__ ({%s *___object = (object); ___object; })),"
485 "(GCallback) __extension__ ({",
486 funcbase, m->id, macrobase, typebase, m->id);
487 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
488 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
489 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
494 put_signal_macros (const Class *c, gboolean gnu)
501 for (li = c->nodes; li != NULL; li = li->next) {
502 const Node *n = li->data;
503 if (n->type == METHOD_NODE)
504 put_signal_macro ((Method *)n, gnu);
509 put_local_signal_macro (const Method *m)
511 if(m->method != SIGNAL_LAST_METHOD &&
512 m->method != SIGNAL_FIRST_METHOD)
516 out_printf (out, "#define self_connect__%s(object,func,data)\t"
517 "%s_connect__%s((object),(func),(data))\n",
518 m->id, funcbase, m->id);
521 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
522 "%s_connect_after__%s((object),(func),(data))\n",
523 m->id, funcbase, m->id);
526 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
527 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
528 m->id, funcbase, m->id);
532 put_local_signal_macros (const Class *c)
539 for (li = c->nodes; li != NULL; li = li->next) {
540 const Node *n = li->data;
541 if (n->type == METHOD_NODE)
542 put_local_signal_macro ((Method *)n);
548 put_prot_method(const Method *m)
552 if(m->scope != PROTECTED_SCOPE)
555 f = outph ? outph : out;
557 out_addline_infile(f, m->line_no);
558 print_method(f, "", "\t", "", "\t", "", ";\n",
559 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
560 out_addline_outfile(f);
564 put_priv_method_prot(const Method *m)
566 if(m->method == SIGNAL_LAST_METHOD ||
567 m->method == SIGNAL_FIRST_METHOD ||
568 m->method == VIRTUAL_METHOD) {
571 "static ", "___real_", "", " ", "", ";\n",
572 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
574 /* no else, here, it might still have a private prototype, it's not
577 if((m->method == OVERRIDE_METHOD &&
580 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
581 out_addline_infile(out, m->line_no);
582 print_method(out, "static ", s, "", " ", "",
583 no_gnu?";\n":" G_GNUC_UNUSED;\n",
584 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
585 out_addline_outfile(out);
587 } else if(m->scope == PRIVATE_SCOPE ||
588 m->method == INIT_METHOD ||
589 m->method == CLASS_INIT_METHOD ||
590 m->method == CONSTRUCTOR_METHOD ||
591 m->method == DISPOSE_METHOD ||
592 m->method == FINALIZE_METHOD) {
593 out_addline_infile(out, m->line_no);
594 print_method(out, "static ", "", "", " ", "",
595 no_gnu?";\n":" G_GNUC_UNUSED;\n",
596 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
597 out_addline_outfile(out);
602 make_func_arg (const char *typename, gboolean is_class, const char *name)
609 tn = g_strconcat (typename, ":Class", NULL);
611 tn = g_strdup (typename);
613 type = node_new (TYPE_NODE,
617 node = node_new (FUNCARG_NODE,
618 "atype:steal", (Type *)type,
621 return g_list_prepend (NULL, node);
625 make_inits(Class *cl)
627 int got_class_init = FALSE;
628 int got_init = FALSE;
631 for(li=cl->nodes;li;li=g_list_next(li)) {
633 if(n->type == METHOD_NODE) {
634 Method *m = (Method *)n;
635 if(m->method == INIT_METHOD) {
637 error_print(GOB_ERROR, m->line_no, "init defined more then once");
639 } else if(m->method == CLASS_INIT_METHOD) {
641 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
642 got_class_init = TRUE;
646 if(!got_class_init) {
647 Type *type = (Type *)node_new (TYPE_NODE,
650 node = node_new (METHOD_NODE,
652 "method", CLASS_INIT_METHOD,
655 "args:steal", make_func_arg (cl->otype,
658 "unique_id", method_unique_id++,
660 cl->nodes = g_list_prepend(cl->nodes, node);
663 Type *type = (Type *)node_new (TYPE_NODE,
666 node = node_new (METHOD_NODE,
668 "method", INIT_METHOD,
671 "args:steal", make_func_arg (cl->otype,
672 FALSE /* is_class */,
674 "unique_id", method_unique_id++,
676 cl->nodes = g_list_prepend(cl->nodes, node);
681 find_method(const Class *cl, int method, const char *id)
685 for(li=cl->nodes;li;li=g_list_next(li)) {
687 if(n->type == METHOD_NODE) {
688 Method *m = (Method *)n;
689 if (m->method == method
690 && (id == NULL || strcmp(m->id, id)==0))
699 find_constructor(const Class *cl)
701 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
705 find_dispose(const Class *cl)
707 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
708 if (dispose_handler != NULL) {
709 if(strcmp(dispose_handler->otype, "G:Object") != 0)
710 error_print(GOB_ERROR, dispose_handler->line_no,
711 "dispose method override "
712 "of class other then "
714 if(g_list_length(dispose_handler->args) != 1)
715 error_print(GOB_ERROR, dispose_handler->line_no,
716 "dispose method override "
717 "with more then one "
721 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
725 find_finalize(const Class *cl)
727 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
728 if (finalize_handler != NULL) {
729 if(strcmp(finalize_handler->otype, "G:Object") != 0)
730 error_print(GOB_ERROR, finalize_handler->line_no,
731 "finalize method override "
732 "of class other then "
734 if(g_list_length(finalize_handler->args) != 1)
735 error_print(GOB_ERROR, finalize_handler->line_no,
736 "finalize method override "
737 "with more then one "
741 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
745 /* hash of method -> name of signal prototype */
746 static GHashTable *marsh = NULL;
748 /* list of methods with different signal prototypes,
749 we check this list if we can use a signal prototype of a
750 previous signal method, there are only uniques here */
751 static GList *eq_signal_methods = NULL;
753 /* compare a list of strings */
755 is_list_equal(const GList *a, const GList *b)
757 for(;a && b; a=a->next, b=b->next) {
758 if(strcmp(a->data, b->data)!=0) {
762 /* the the lists were different length */
769 find_same_type_signal(const Method *m)
772 for(li=eq_signal_methods;li;li=li->next) {
773 Method *mm = li->data;
774 if(is_list_equal(mm->gtktypes, m->gtktypes))
781 print_signal_marsal_args (const Method *m)
783 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
786 for (i = 0, li = m->gtktypes->next;
788 i++, li = li->next) {
791 if (strcmp (li->data, "UNICHAR") == 0)
792 /* hack because glib is braindamaged */
793 get_func = g_strdup ("g_value_get_uint");
794 else if (strncmp(li->data, "BOXED_", 6) == 0)
795 get_func = g_strdup ("g_value_get_boxed");
797 get_func = g_strdup_printf
798 ("g_value_get_%s", (char *)li->data);
800 gob_strdown (get_func);
801 out_printf (out, ",\n\t\t(%s) "
802 "%s (param_values + %d)",
803 get_cast (li->data, FALSE),
808 out_printf (out, ",\n\t\tdata2);\n");
813 add_signal_prots(Method *m)
819 gboolean ret_none = FALSE;
820 gboolean arglist_none = FALSE;
822 const char *unused = "";
824 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
825 unused = " G_GNUC_UNUSED";
828 if (m->method != SIGNAL_LAST_METHOD &&
829 m->method != SIGNAL_FIRST_METHOD)
833 marsh = g_hash_table_new(NULL, NULL);
835 g_assert (m->gtktypes->next != NULL);
837 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
838 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
840 if (ret_none && arglist_none)
843 /* if we already did a signal prototype just use that */
844 mm = find_same_type_signal (m);
846 s = g_hash_table_lookup (marsh, mm);
847 g_hash_table_insert (marsh, m, s);
854 retcast = get_cast (m->gtktypes->data, FALSE);
856 s = g_strdup_printf("Sig%d", sig++);
858 g_hash_table_insert(marsh, m, s);
859 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
861 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
862 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
863 get_cast(m->gtktypes->data, FALSE), s, typebase);
865 if ( ! arglist_none) {
866 for (li = m->gtktypes->next; li != NULL; li = li->next)
867 out_printf (out, "%s, ", get_cast (li->data, FALSE));
869 out_printf (out, "gpointer);\n");
871 out_printf (out, "\nstatic void\n"
872 "___marshal_%s (GClosure *closure,\n"
873 "\tGValue *return_value%s,\n"
874 "\tguint n_param_values,\n"
875 "\tconst GValue *param_values,\n"
876 "\tgpointer invocation_hint%s,\n"
877 "\tgpointer marshal_data)\n"
884 out_printf (out, "\t%s v_return;\n", retcast);
886 out_printf (out, "\tregister ___%s callback;\n"
887 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
888 "\tregister gpointer data1, data2;\n\n",
891 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
892 arglist_none ? 1 : g_list_length (m->gtktypes));
895 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
896 "\t\tdata1 = closure->data;\n"
897 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
899 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
900 "\t\tdata2 = closure->data;\n"
903 out_printf (out, "\tcallback = (___%s) "
904 "(marshal_data != NULL ? marshal_data : cc->callback);"
908 out_printf (out, "\tcallback ((%s *)data1", typebase);
910 out_printf (out, "\tv_return = callback ((%s *)data1",
914 print_signal_marsal_args (m);
917 /* FIXME: This code is so fucking ugly it hurts */
918 gboolean take_ownership =
919 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
920 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
924 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
925 /* hack because glib is braindamaged */
926 set_func = g_strdup ("g_value_set_uint");
928 set_func = g_strdup_printf ("g_value_set_%s%s",
929 (char *)m->gtktypes->data,
931 "_take_ownership" : "");
932 gob_strdown (set_func);
934 out_printf (out, "\n\t%s (return_value, v_return);\n",
939 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
941 out_printf (out, "\n\treturn_value = NULL;\n");
942 out_printf (out, "\tinvocation_hint = NULL;\n");
945 out_printf (out, "}\n\n");
952 out_printf(out, "\n");
954 out_printf(out, "enum {\n");
955 for(li=c->nodes;li;li=g_list_next(li)) {
957 if(n->type == METHOD_NODE) {
958 Method *m = (Method *)n;
959 if(m->method == SIGNAL_LAST_METHOD ||
960 m->method == SIGNAL_FIRST_METHOD) {
961 char *s = g_strdup(m->id);
963 out_printf(out, "\t%s_SIGNAL,\n", s);
968 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
970 if (set_properties > 0 ||
971 get_properties > 0) {
972 out_printf(out, "enum {\n\tPROP_0");
973 for(li=c->nodes;li;li=g_list_next(li)) {
975 if (n->type == PROPERTY_NODE) {
976 Property *p = (Property *)n;
977 char *s = g_strdup (p->name);
979 out_printf (out, ",\n\tPROP_%s", s);
981 } else if (n->type == ARGUMENT_NODE) {
982 Argument *a = (Argument *)n;
983 char *s = g_strdup(a->name);
985 out_printf(out, ",\n\tPROP_%s", s);
989 out_printf(out, "\n};\n\n");
994 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
996 out_printf(out, "/* pointer to the class of our parent */\n");
997 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
1001 add_interface_methods (Class *c, const char *interface)
1004 gboolean added_line = FALSE;
1006 for (li = c->nodes; li != NULL; li = li->next) {
1008 Method *m = (Method *)n;
1009 if (n->type != METHOD_NODE ||
1010 m->method == OVERRIDE_METHOD ||
1011 m->interface == NULL ||
1012 strcmp (m->interface, interface) != 0)
1015 if (m->line_no > 0) {
1016 out_addline_infile (out, m->line_no);
1018 } else if (m->line_no == 0 &&
1020 out_addline_outfile (out);
1023 out_printf (out, "\tiface->%s = self_%s;\n",
1027 out_addline_outfile (out);
1031 add_interface_inits (Class *c)
1035 if (c->interfaces == NULL)
1038 out_printf(out, "\n");
1040 for (li = c->interfaces; li != NULL; li = li->next) {
1041 const char *interface = li->data;
1043 char *name = replace_sep (interface, '_');
1044 char *type = remove_sep (interface);
1046 /* EEEK! evil, we should have some sort of option
1047 * to force this for arbitrary interfaces, since
1048 * some are Class and some are Iface. Glib is shite
1049 * in consistency. */
1050 if (strcmp (type, "GtkEditable") == 0 ||
1051 strcmp (type, "GTypePlugin") == 0)
1054 /* We'll assume Iface is the standard ending */
1057 out_printf (out, "\nstatic void\n"
1058 "___%s_init (%s%s *iface)\n"
1062 add_interface_methods (c, interface);
1064 out_printf (out, "}\n\n");
1072 add_interface_infos (void)
1075 for (li = ((Class *)class)->interfaces;
1078 char *name = replace_sep (li->data, '_');
1080 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1081 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1091 add_interfaces (void)
1094 for (li = ((Class *)class)->interfaces;
1097 char *name = replace_sep (li->data, '_');
1098 char *type = make_pre_macro (li->data, "TYPE");
1101 "\t\tg_type_add_interface_static (type,\n"
1103 "\t\t\t&%s_info);\n",
1115 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1119 "%s_get_type (void)\n"
1121 "\tstatic GType type = 0;\n\n"
1122 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1123 "\t\tstatic const GTypeInfo info = {\n"
1124 "\t\t\tsizeof (%sClass),\n"
1125 "\t\t\t(GBaseInitFunc) NULL,\n"
1126 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1127 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1128 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1129 "\t\t\tNULL /* class_data */,\n"
1130 "\t\t\tsizeof (%s),\n"
1131 "\t\t\t%d /* n_preallocs */,\n"
1132 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1135 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1137 add_interface_infos ();
1140 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
1141 pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1149 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1151 chunk_size, chunk_size);
1161 add_bonobo_object_get_type (void)
1163 /* char *chunk_size = ((Class*)class)->chunk_size; */
1164 /* _vicious_ spanks seth with a rusty nail
1166 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1167 "gob2 doesn't officially support it yet. It'd be safer "
1168 "and a lot more fun to blow goats.\"\n");
1173 "%s_get_type (void)\n" /* 1 */
1175 "\tstatic GType type = 0;\n\n"
1176 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1177 "\t\tstatic const GTypeInfo info = {\n"
1178 "\t\t\tsizeof (%sClass),\n" /* 2 */
1179 "\t\t\t(GBaseInitFunc) NULL,\n"
1180 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1181 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1182 "\t\t\tNULL, /* class_finalize */\n"
1183 "\t\t\tNULL, /* class_data */\n"
1184 "\t\t\tsizeof (%s),\n" /* 4 */
1185 "\t\t\t0, /* n_preallocs */\n"
1186 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1195 add_interface_infos ();
1198 "\t\ttype = bonobo_type_unique (\n"
1199 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1200 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1201 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1202 "\t\t\t&info, \"%s\");\n", /* 3 */
1203 ((Class*)class)->bonobo_object_class /* 1 */,
1212 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1214 chunk_size, chunk_size);
1223 add_overrides(Class *c, const char *oname,
1224 gboolean did_base_obj)
1230 done = g_hash_table_new (g_str_hash, g_str_equal);
1232 s = g_strdup ("GObject");
1233 g_hash_table_insert (done, s, s);
1235 for (li = c->nodes; li != NULL; li = li->next) {
1238 Method *m = (Method *)n;
1239 if(n->type != METHOD_NODE ||
1240 m->method != OVERRIDE_METHOD)
1243 s = remove_sep(m->otype);
1245 if(g_hash_table_lookup(done, s)) {
1249 g_hash_table_insert(done, s, s);
1251 f = replace_sep(m->otype, '_');
1254 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1259 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1260 g_hash_table_destroy (done);
1264 make_run_signal_flags(Method *m, gboolean last)
1279 gs = g_string_new(NULL);
1282 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1284 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1286 if(m->scope == PUBLIC_SCOPE)
1287 g_string_append(gs, " | G_SIGNAL_ACTION");
1289 for(li = m->flags; li; li = li->next) {
1290 char *flag = li->data;
1292 for(i=0;flags[i];i++) {
1293 if(strcmp(flags[i], flag)==0)
1296 /* if we haven't found it in our list */
1298 error_printf(GOB_WARN, m->line_no,
1299 "Unknown flag '%s' used, "
1300 "perhaps it was misspelled",
1303 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1307 char *ret = gs->str;
1308 g_string_free(gs, FALSE);
1315 add_signals(Class *c)
1319 out_printf(out, "\n");
1320 for(li=c->nodes;li;li=g_list_next(li)) {
1322 char *mar, *sig, *flags;
1323 gboolean is_none, last = FALSE;
1324 Method *m = (Method *)n;
1326 if(n->type != METHOD_NODE ||
1327 (m->method != SIGNAL_FIRST_METHOD &&
1328 m->method != SIGNAL_LAST_METHOD))
1331 if(m->method == SIGNAL_FIRST_METHOD)
1336 if(g_hash_table_lookup(marsh, m))
1337 mar = g_strconcat("___marshal_",
1338 (char *)g_hash_table_lookup(marsh, m),
1341 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1343 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1345 sig = g_strdup (m->id);
1347 flags = make_run_signal_flags (m, last);
1348 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1349 "\t\tg_signal_new (\"%s\",\n"
1350 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1351 "\t\t\t(GSignalFlags)(%s),\n"
1352 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1353 "\t\t\tNULL, NULL,\n"
1355 "\t\t\tG_TYPE_%s, %d",
1358 typebase, m->id, mar,
1359 (char *)m->gtktypes->data,
1360 is_none ? 0 : g_list_length(m->gtktypes->next));
1368 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1369 char *str = l->data;
1370 if (strncmp (str, "BOXED_", 6) == 0)
1371 t = g_strdup (&(str[6]));
1373 t = g_strconcat ("G_TYPE_", str, NULL);
1374 out_printf (out, ",\n\t\t\t%s", t);
1379 out_printf(out, ");\n");
1381 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1384 out_printf(out, "\tif ___GOB_UNLIKELY(");
1385 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1386 out_printf(out, "sizeof(");
1387 print_type(out, m->mtype, FALSE);
1388 out_printf(out, "%s",
1390 m->mtype->postfix : "");
1391 out_printf(out, ") != sizeof(%s) || ",
1392 get_cast(m->gtktypes->data, FALSE));
1395 for(al = m->args->next, gl = m->gtktypes->next;
1396 al != NULL && gl != NULL;
1397 al = al->next, gl = gl->next) {
1398 FuncArg *arg = al->data;
1399 char *gtkarg = gl->data;
1401 out_printf(out, "sizeof(");
1402 print_type(out, arg->atype, FALSE);
1403 out_printf(out, "%s",
1404 arg->atype->postfix ?
1405 arg->atype->postfix : "");
1406 out_printf(out, ") != sizeof(%s) || ",
1407 get_cast(gtkarg, FALSE));
1411 "parent_class == NULL /* avoid warning */");
1413 out_printf(out, ") {\n"
1414 "\t\tg_error(\"%s line %d: Type mismatch "
1415 "of \\\"%s\\\" signal signature\");\n"
1417 filename, m->line_no, m->id);
1424 set_def_handlers(Class *c, const char *oname)
1427 gboolean set_line = FALSE;
1429 out_printf(out, "\n");
1430 for(li = c->nodes; li; li = g_list_next(li)) {
1432 Method *m = (Method *)n;
1434 if(n->type != METHOD_NODE ||
1435 (m->method != SIGNAL_FIRST_METHOD &&
1436 m->method != SIGNAL_LAST_METHOD &&
1437 m->method != VIRTUAL_METHOD &&
1438 m->method != OVERRIDE_METHOD))
1441 if(m->line_no > 0 && m->cbuf) {
1442 out_addline_infile(out, m->line_no);
1444 } else if(set_line) {
1445 out_addline_outfile(out);
1450 if (m->method == OVERRIDE_METHOD) {
1452 s = replace_sep (m->otype, '_');
1456 dispose_handler != NULL &&
1457 strcmp (m->id, "dispose") == 0)
1458 out_printf (out, "\tg_object_class->dispose "
1460 else if (need_finalize &&
1462 strcmp(m->id, "finalize") == 0)
1464 "\tg_object_class->finalize = ___finalize;\n");
1465 else if (m->cbuf != NULL)
1467 "\t%s_class->%s = ___%x_%s_%s;\n",
1468 s, m->id, (guint)m->unique_id,
1471 out_printf(out, "\t%s_class->%s = NULL;\n",
1475 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1479 out_printf(out, "\t%s->%s = NULL;\n",
1484 out_addline_outfile(out);
1488 make_argument (Argument *a)
1493 char *argflags[] = {
1501 flags = g_string_new ("(GParamFlags)(");
1503 if(a->get && a->set)
1504 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1506 g_string_append (flags, "G_PARAM_READABLE");
1508 g_string_append (flags, "G_PARAM_WRITABLE");
1510 g_assert(a->get || a->set);
1512 for (l = a->flags; l != NULL; l = l->next) {
1513 char *flag = l->data;
1515 if(strcmp (flag, "READABLE") == 0 ||
1516 strcmp (flag, "WRITABLE") == 0) {
1517 error_print(GOB_WARN, a->line_no,
1519 "WRITABLE argument flags are "
1520 "set automatically");
1523 for(i = 0; argflags[i]; i++) {
1524 if(strcmp(argflags[i], flag)==0)
1527 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1530 g_string_append (flags, ")");
1532 s = g_strdup(a->name);
1534 if (!strcmp (a->gtktype, "ENUM"))
1535 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1536 "\t\tG_TYPE_ENUM, 0,\n"
1538 a->name, flags->str);
1539 if (!strcmp (a->gtktype, "FLAGS"))
1540 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1541 "\t\tG_TYPE_FLAGS, 0,\n"
1543 a->name, flags->str);
1544 else if (!strcmp (a->gtktype, "OBJECT"))
1545 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1546 "\t\tG_TYPE_OBJECT,\n"
1548 a->name, flags->str);
1549 else if (!strcmp (a->gtktype, "STRING"))
1550 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1553 a->name, flags->str);
1554 else if (!strcmp (a->gtktype, "INT"))
1555 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1556 "\t\tG_MININT, G_MAXINT,\n"
1559 a->name, flags->str);
1560 else if (!strcmp (a->gtktype, "UINT"))
1561 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1562 "\t\t0, G_MAXUINT,\n"
1565 a->name, flags->str);
1566 else if (!strcmp (a->gtktype, "INT"))
1567 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1568 "\t\tG_MININT, G_MAXINT,\n"
1571 a->name, flags->str);
1572 else if (!strcmp (a->gtktype, "CHAR"))
1573 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1577 a->name, flags->str);
1578 else if (!strcmp (a->gtktype, "UCHAR"))
1579 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1583 a->name, flags->str);
1584 else if (!strcmp (a->gtktype, "BOOL") ||
1585 !strcmp (a->gtktype, "BOOLEAN"))
1586 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1589 a->name, flags->str);
1590 else if (!strcmp (a->gtktype, "LONG"))
1591 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1592 "\t\tG_MINLONG, G_MAXLONG,\n"
1595 a->name, flags->str);
1596 else if (!strcmp (a->gtktype, "ULONG"))
1597 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1598 "\t\t0, G_MAXULONG,\n"
1601 a->name, flags->str);
1602 else if (!strcmp (a->gtktype, "INT64"))
1603 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1604 "\t\tG_MININT64, G_MAXINT64,\n"
1607 a->name, flags->str);
1608 else if (!strcmp (a->gtktype, "UINT64"))
1609 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1610 "\t\t0, G_MAXUINT64,\n"
1613 a->name, flags->str);
1614 else if (!strcmp (a->gtktype, "FLOAT"))
1615 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1616 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1619 a->name, flags->str);
1620 else if (!strcmp (a->gtktype, "DOUBLE"))
1621 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1622 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1625 a->name, flags->str);
1626 else if (!strcmp (a->gtktype, "POINTER"))
1627 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1629 a->name, flags->str);
1631 error_printf (GOB_ERROR, a->line_no,
1632 "%s type is not supported for arguments, try using properties",
1635 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1636 "\t\tPROP_%s, param_spec);\n", s);
1640 g_string_free(flags, TRUE);
1643 #define value_for_print(str, alt) (str != NULL ? str : alt)
1646 make_property (Property *p)
1650 if (p->get == NULL && p->set == NULL) {
1651 error_print (GOB_ERROR, p->line_no,
1652 "Property has no getter nor setter");
1656 if (p->flags != NULL)
1657 error_print (GOB_WARN, p->line_no,
1658 "Overridden property, flags ignored");
1659 if (p->nick != NULL)
1660 error_print (GOB_WARN, p->line_no,
1661 "Overridden property, nick ignored");
1662 if (p->blurb != NULL)
1663 error_print (GOB_WARN, p->line_no,
1664 "Overridden property, blurb ignored");
1665 if (p->minimum != NULL)
1666 error_print (GOB_WARN, p->line_no,
1667 "Overridden property, minimum ignored");
1668 if (p->maximum != NULL)
1669 error_print (GOB_WARN, p->line_no,
1670 "Overridden property, maximum ignored");
1671 if (p->default_value != NULL)
1672 error_print (GOB_WARN, p->line_no,
1673 "Overridden property, default_value ignored");
1675 s = g_strdup (p->name);
1677 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1679 "\t\t\"%s\");\n", s, p->name);
1684 char *argflags[] = {
1692 flags = g_string_new ("(GParamFlags)(");
1694 if (p->get != NULL && p->set != NULL)
1695 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1696 else if (p->get != NULL)
1697 g_string_append (flags, "G_PARAM_READABLE");
1699 g_string_append (flags, "G_PARAM_WRITABLE");
1702 for (l = p->flags; l != NULL; l = l->next) {
1703 char *flag = l->data;
1705 if(strcmp (flag, "READABLE") == 0 ||
1706 strcmp (flag, "WRITABLE") == 0) {
1707 error_print(GOB_WARN, p->line_no,
1709 "WRITABLE argument flags are "
1710 "set automatically");
1713 for(i = 0; argflags[i]; i++) {
1714 if(strcmp(argflags[i], flag)==0)
1717 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1720 g_string_append (flags, ")");
1722 if (strcmp (p->gtktype, "CHAR") == 0) {
1723 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1724 "\t\t(\"%s\" /* name */,\n"
1725 "\t\t %s /* nick */,\n"
1726 "\t\t %s /* blurb */,\n"
1727 "\t\t %s /* minimum */,\n"
1728 "\t\t %s /* maximum */,\n"
1729 "\t\t %s /* default_value */,\n"
1732 value_for_print (p->nick, "NULL"),
1733 value_for_print (p->blurb, "NULL"),
1734 value_for_print (p->minimum, "-128"),
1735 value_for_print (p->maximum, "127"),
1736 value_for_print (p->default_value, "0"),
1738 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1739 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1740 "\t\t(\"%s\" /* name */,\n"
1741 "\t\t %s /* nick */,\n"
1742 "\t\t %s /* blurb */,\n"
1743 "\t\t %s /* minimum */,\n"
1744 "\t\t %s /* maximum */,\n"
1745 "\t\t %s /* default_value */,\n"
1748 value_for_print (p->nick, "NULL"),
1749 value_for_print (p->blurb, "NULL"),
1750 value_for_print (p->minimum, "0"),
1751 value_for_print (p->maximum, "0xFF"),
1752 value_for_print (p->default_value, "0"),
1754 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1755 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1756 "\t\t(\"%s\" /* name */,\n"
1757 "\t\t %s /* nick */,\n"
1758 "\t\t %s /* blurb */,\n"
1759 "\t\t %s /* default_value */,\n"
1762 value_for_print (p->nick, "NULL"),
1763 value_for_print (p->blurb, "NULL"),
1764 value_for_print (p->default_value, "FALSE"),
1766 } else if (strcmp (p->gtktype, "INT") == 0) {
1767 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1768 "\t\t(\"%s\" /* name */,\n"
1769 "\t\t %s /* nick */,\n"
1770 "\t\t %s /* blurb */,\n"
1771 "\t\t %s /* minimum */,\n"
1772 "\t\t %s /* maximum */,\n"
1773 "\t\t %s /* default_value */,\n"
1776 value_for_print (p->nick, "NULL"),
1777 value_for_print (p->blurb, "NULL"),
1778 value_for_print (p->minimum, "G_MININT"),
1779 value_for_print (p->maximum, "G_MAXINT"),
1780 value_for_print (p->default_value, "0"),
1782 } else if (strcmp (p->gtktype, "UINT") == 0) {
1783 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1784 "\t\t(\"%s\" /* name */,\n"
1785 "\t\t %s /* nick */,\n"
1786 "\t\t %s /* blurb */,\n"
1787 "\t\t %s /* minimum */,\n"
1788 "\t\t %s /* maximum */,\n"
1789 "\t\t %s /* default_value */,\n"
1792 value_for_print (p->nick, "NULL"),
1793 value_for_print (p->blurb, "NULL"),
1794 value_for_print (p->minimum, "0"),
1795 value_for_print (p->maximum, "G_MAXUINT"),
1796 value_for_print (p->default_value, "0"),
1798 } else if (strcmp (p->gtktype, "LONG") == 0) {
1799 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1800 "\t\t(\"%s\" /* name */,\n"
1801 "\t\t %s /* nick */,\n"
1802 "\t\t %s /* blurb */,\n"
1803 "\t\t %s /* minimum */,\n"
1804 "\t\t %s /* maximum */,\n"
1805 "\t\t %s /* default_value */,\n"
1808 value_for_print (p->nick, "NULL"),
1809 value_for_print (p->blurb, "NULL"),
1810 value_for_print (p->minimum, "G_MINLONG"),
1811 value_for_print (p->maximum, "G_MAXLONG"),
1812 value_for_print (p->default_value, "0"),
1814 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1815 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1816 "\t\t(\"%s\" /* name */,\n"
1817 "\t\t %s /* nick */,\n"
1818 "\t\t %s /* blurb */,\n"
1819 "\t\t %s /* minimum */,\n"
1820 "\t\t %s /* maximum */,\n"
1821 "\t\t %s /* default_value */,\n"
1824 value_for_print (p->nick, "NULL"),
1825 value_for_print (p->blurb, "NULL"),
1826 value_for_print (p->minimum, "0"),
1827 value_for_print (p->maximum, "G_MAXULONG"),
1828 value_for_print (p->default_value, "0"),
1830 } else if (strcmp (p->gtktype, "INT64") == 0) {
1831 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1832 "\t\t(\"%s\" /* name */,\n"
1833 "\t\t %s /* nick */,\n"
1834 "\t\t %s /* blurb */,\n"
1835 "\t\t %s /* minimum */,\n"
1836 "\t\t %s /* maximum */,\n"
1837 "\t\t %s /* default_value */,\n"
1840 value_for_print (p->nick, "NULL"),
1841 value_for_print (p->blurb, "NULL"),
1842 value_for_print (p->minimum, "G_MININT64"),
1843 value_for_print (p->maximum, "G_MAXINT64"),
1844 value_for_print (p->default_value, "0"),
1846 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1847 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1848 "\t\t(\"%s\" /* name */,\n"
1849 "\t\t %s /* nick */,\n"
1850 "\t\t %s /* blurb */,\n"
1851 "\t\t %s /* minimum */,\n"
1852 "\t\t %s /* maximum */,\n"
1853 "\t\t %s /* default_value */,\n"
1856 value_for_print (p->nick, "NULL"),
1857 value_for_print (p->blurb, "NULL"),
1858 value_for_print (p->minimum, "0"),
1859 value_for_print (p->maximum, "G_MAXUINT64"),
1860 value_for_print (p->default_value, "0"),
1862 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1863 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1864 "\t\t(\"%s\" /* name */,\n"
1865 "\t\t %s /* nick */,\n"
1866 "\t\t %s /* blurb */,\n"
1867 "\t\t %s /* default_value */,\n"
1870 value_for_print (p->nick, "NULL"),
1871 value_for_print (p->blurb, "NULL"),
1872 value_for_print (p->default_value, "0"),
1874 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1875 char *type = make_me_type (p->extra_gtktype,
1877 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1878 "\t\t(\"%s\" /* name */,\n"
1879 "\t\t %s /* nick */,\n"
1880 "\t\t %s /* blurb */,\n"
1881 "\t\t %s /* enum_type */,\n"
1882 "\t\t %s /* default_value */,\n"
1885 value_for_print (p->nick, "NULL"),
1886 value_for_print (p->blurb, "NULL"),
1888 value_for_print (p->default_value, "0"),
1891 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1892 char *type = make_me_type (p->extra_gtktype,
1894 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1895 "\t\t(\"%s\" /* name */,\n"
1896 "\t\t %s /* nick */,\n"
1897 "\t\t %s /* blurb */,\n"
1898 "\t\t %s /* flags_type */,\n"
1899 "\t\t %s /* default_value */,\n"
1902 value_for_print (p->nick, "NULL"),
1903 value_for_print (p->blurb, "NULL"),
1905 value_for_print (p->default_value, "0"),
1908 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1909 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1910 "\t\t(\"%s\" /* name */,\n"
1911 "\t\t %s /* nick */,\n"
1912 "\t\t %s /* blurb */,\n"
1913 "\t\t %s /* minimum */,\n"
1914 "\t\t %s /* maximum */,\n"
1915 "\t\t %s /* default_value */,\n"
1918 value_for_print (p->nick, "NULL"),
1919 value_for_print (p->blurb, "NULL"),
1920 value_for_print (p->minimum, "-G_MAXFLOAT"),
1921 value_for_print (p->maximum, "G_MAXFLOAT"),
1922 value_for_print (p->default_value, "0.0"),
1924 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1925 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1926 "\t\t(\"%s\" /* name */,\n"
1927 "\t\t %s /* nick */,\n"
1928 "\t\t %s /* blurb */,\n"
1929 "\t\t %s /* minimum */,\n"
1930 "\t\t %s /* maximum */,\n"
1931 "\t\t %s /* default_value */,\n"
1934 value_for_print (p->nick, "NULL"),
1935 value_for_print (p->blurb, "NULL"),
1936 value_for_print (p->minimum, "-G_MAXDOUBLE"),
1937 value_for_print (p->maximum, "G_MAXDOUBLE"),
1938 value_for_print (p->default_value, "0.0"),
1940 } else if (strcmp (p->gtktype, "STRING") == 0) {
1941 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1942 "\t\t(\"%s\" /* name */,\n"
1943 "\t\t %s /* nick */,\n"
1944 "\t\t %s /* blurb */,\n"
1945 "\t\t %s /* default_value */,\n"
1948 value_for_print (p->nick, "NULL"),
1949 value_for_print (p->blurb, "NULL"),
1950 value_for_print (p->default_value, "NULL"),
1952 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1953 char *type = make_me_type (p->extra_gtktype,
1955 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1956 "\t\t(\"%s\" /* name */,\n"
1957 "\t\t %s /* nick */,\n"
1958 "\t\t %s /* blurb */,\n"
1959 "\t\t %s /* param_type */,\n"
1962 value_for_print (p->nick, "NULL"),
1963 value_for_print (p->blurb, "NULL"),
1967 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1968 char *type = make_me_type (p->extra_gtktype,
1970 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1971 "\t\t(\"%s\" /* name */,\n"
1972 "\t\t %s /* nick */,\n"
1973 "\t\t %s /* blurb */,\n"
1974 "\t\t %s /* boxed_type */,\n"
1977 value_for_print (p->nick, "NULL"),
1978 value_for_print (p->blurb, "NULL"),
1982 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1983 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1984 "\t\t(\"%s\" /* name */,\n"
1985 "\t\t %s /* nick */,\n"
1986 "\t\t %s /* blurb */,\n"
1989 value_for_print (p->nick, "NULL"),
1990 value_for_print (p->blurb, "NULL"),
1992 /* FIXME: VALUE_ARRAY */
1993 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1994 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1995 "\t\t(\"%s\" /* name */,\n"
1996 "\t\t %s /* nick */,\n"
1997 "\t\t %s /* blurb */,\n"
2000 value_for_print (p->nick, "NULL"),
2001 value_for_print (p->blurb, "NULL"),
2003 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2004 char *type = make_me_type (p->extra_gtktype,
2006 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2007 "\t\t(\"%s\" /* name */,\n"
2008 "\t\t %s /* nick */,\n"
2009 "\t\t %s /* blurb */,\n"
2010 "\t\t %s /* object_type */,\n"
2013 value_for_print (p->nick, "NULL"),
2014 value_for_print (p->blurb, "NULL"),
2019 error_printf (GOB_ERROR, p->line_no,
2020 "%s type is not supported by properties",
2024 s = g_strdup (p->name);
2026 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2028 "\t\tparam_spec);\n", s);
2031 g_string_free (flags, TRUE);
2036 make_arguments(Class *c)
2039 if (get_properties > 0)
2040 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2041 if (set_properties > 0)
2042 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2043 out_printf (out, " {\n");
2044 for (li = c->nodes; li != NULL; li = li->next) {
2046 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2047 || n->type == ARGUMENT_NODE) {
2048 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2053 for (li = c->nodes; li != NULL; li = li->next) {
2055 if (n->type == PROPERTY_NODE)
2056 make_property ((Property *)n);
2057 else if (n->type == ARGUMENT_NODE)
2058 make_argument ((Argument *)n);
2060 out_printf(out, " }\n");
2064 print_initializer(Method *m, Variable *v)
2071 if(v->initializer == NULL)
2074 if(v->scope == PRIVATE_SCOPE)
2075 root = g_strconcat(((FuncArg *)m->args->data)->name,
2078 root = g_strdup(((FuncArg *)m->args->data)->name);
2080 if(v->initializer_line > 0)
2081 out_addline_infile(out, v->initializer_line);
2083 if (v->initializer_simple)
2084 out_printf(out, "\t%s->%s = %s;\n",
2085 root, v->id, v->initializer);
2086 else if (strcmp(v->id, "_glade_xml") == 0)
2087 /* This is OK, this v->initializer string is set internally
2088 and it will eat exactly one string! */
2089 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2091 out_printf(out, "%s", v->initializer);
2093 if(v->initializer_line > 0)
2094 out_addline_outfile(out);
2100 print_glade_widget(Method *m, Variable *v)
2105 if(!v->glade_widget)
2108 if(v->scope == PRIVATE_SCOPE)
2109 root = g_strconcat(((FuncArg *)m->args->data)->name,
2112 root = g_strdup(((FuncArg *)m->args->data)->name);
2114 cast = get_type(v->vtype, FALSE);
2115 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2116 root, v->id, cast, root, v->id);
2122 print_destructor (Variable *v)
2126 if(v->destructor == NULL)
2129 if(v->scope == PRIVATE_SCOPE)
2130 root = "self->_priv";
2134 if(v->destructor_simple) {
2135 if(v->destructor_line > 0)
2136 out_addline_infile(out, v->destructor_line);
2139 out_printf(out, "\tif(%s->%s) { "
2140 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2141 "%s->%s = NULL; }\n",
2142 root, v->id, v->destructor, root, v->id,
2145 out_printf(out, "\tif(%s->%s) { "
2146 "%s ((gpointer) %s->%s); "
2147 "%s->%s = NULL; }\n",
2148 root, v->id, v->destructor, root, v->id,
2152 if(v->destructor_line > 0)
2153 out_addline_outfile(out);
2155 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2156 out_printf(out, "#define VAR %s\n", v->id);
2157 out_printf(out, "\t{\n");
2158 if(v->destructor_line > 0)
2159 out_addline_infile(out, v->destructor_line);
2161 out_printf(out, "\t%s}\n", v->destructor);
2163 if(v->destructor_line > 0)
2164 out_addline_outfile(out);
2165 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
2167 out_printf(out, "#undef VAR\n");
2168 out_printf(out, "#undef %s\n", v->id);
2173 add_constructor (Class *c)
2175 out_printf(out, "\nstatic GObject *\n"
2176 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2179 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2182 out_printf(out, "\tGObject *obj_self;\n");
2183 out_printf(out, "\t%s *self;\n", typebase);
2185 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2186 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2188 if (user_constructor->line_no > 0)
2189 out_addline_infile (out, user_constructor->line_no);
2190 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2191 if (user_constructor->line_no > 0)
2192 out_addline_outfile (out);
2194 out_printf(out, "\treturn obj_self;\n");
2195 out_printf(out, "}\n"
2196 "#undef __GOB_FUNCTION__\n\n");
2200 add_dispose (Class *c)
2202 out_printf(out, "\nstatic void\n"
2203 "___dispose (GObject *obj_self)\n"
2206 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2209 if (unreftors > 0 || user_dispose_method != NULL) {
2210 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2212 ! no_gnu ? " G_GNUC_UNUSED" : "",
2216 if (dispose_handler != NULL) {
2217 /* so we get possible bad argument warning */
2218 if (dispose_handler->line_no > 0)
2219 out_addline_infile (out, dispose_handler->line_no);
2220 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2221 (guint)dispose_handler->unique_id, funcbase);
2222 if (dispose_handler->line_no > 0)
2223 out_addline_outfile (out);
2225 if (user_dispose_method != NULL) {
2226 if (user_dispose_method->line_no > 0)
2227 out_addline_infile (out, user_dispose_method->line_no);
2228 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2229 if (user_dispose_method->line_no > 0)
2230 out_addline_outfile (out);
2234 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2235 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2238 if (unreftors > 0) {
2240 for(li = ((Class *)class)->nodes;
2244 Variable *v = (Variable *)n;
2245 if (n->type == VARIABLE_NODE &&
2246 v->scope != CLASS_SCOPE &&
2247 v->destructor_unref)
2248 print_destructor (v);
2252 out_printf(out, "}\n"
2253 "#undef __GOB_FUNCTION__\n\n");
2257 add_finalize (Class *c)
2261 "___finalize(GObject *obj_self)\n"
2264 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2269 user_finalize_method != NULL) {
2270 const char *unused = "";
2272 unused = " G_GNUC_UNUSED";
2273 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2274 typebase, unused, macrobase);
2277 const char *unused = "";
2279 unused = " G_GNUC_UNUSED";
2280 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2284 if(finalize_handler) {
2285 /* so we get possible bad argument warning */
2286 if(finalize_handler->line_no > 0)
2287 out_addline_infile(out, finalize_handler->line_no);
2288 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2289 (guint)finalize_handler->unique_id, funcbase);
2290 if(finalize_handler->line_no > 0)
2291 out_addline_outfile(out);
2293 if (user_finalize_method != NULL) {
2294 if (user_finalize_method->line_no > 0)
2295 out_addline_infile (out, user_finalize_method->line_no);
2296 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2297 if (user_finalize_method->line_no > 0)
2298 out_addline_outfile (out);
2302 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2303 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2306 if (destructors > 0) {
2308 for (li = ((Class *)class)->nodes;
2312 Variable *v = (Variable *)n;
2313 if (n->type == VARIABLE_NODE &&
2314 v->scope != CLASS_SCOPE &&
2315 ! v->destructor_unref)
2316 print_destructor (v);
2320 out_printf(out, "}\n"
2321 "#undef __GOB_FUNCTION__\n\n");
2325 make_bonobo_object_epv (Class *c, const char *classname)
2328 gboolean added_line = FALSE;
2330 for (li = c->nodes; li != NULL; li = li->next) {
2332 Method *m = (Method *)n;
2333 if(n->type != METHOD_NODE ||
2334 m->method == OVERRIDE_METHOD)
2337 if (m->bonobo_object_func) {
2338 if(m->line_no > 0) {
2339 out_addline_infile(out, m->line_no);
2341 } else if (m->line_no == 0 &&
2343 out_addline_outfile(out);
2346 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2347 classname, m->id, m->id);
2351 out_addline_outfile(out);
2357 const char *unused = "";
2361 unused = " G_GNUC_UNUSED";
2363 for(li=c->nodes;li;li=g_list_next(li)) {
2367 if(n->type != METHOD_NODE)
2370 if(m->method == INIT_METHOD) {
2372 out_addline_infile(out, m->line_no);
2373 print_method(out, "static ", "\n", "", " ", "", "\n",
2374 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2376 out_printf(out, "{\n");
2378 out_addline_outfile(out);
2380 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2383 out_printf(out, "\t%s->_priv = "
2384 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2385 ((FuncArg *)m->args->data)->name,
2386 ((FuncArg *)m->args->data)->name,
2389 } else if(always_private_struct) {
2390 out_printf(out, "\t%s->_priv = NULL;\n",
2391 ((FuncArg *)m->args->data)->name);
2393 if(initializers > 0) {
2395 for(li = ((Class *)class)->nodes;
2399 Variable *v = (Variable *)n;
2400 if(n->type != VARIABLE_NODE ||
2401 v->scope == CLASS_SCOPE)
2403 print_initializer(m, v);
2406 if(glade_widgets > 0) {
2408 for(li = ((Class *)class)->nodes;
2412 Variable *v = (Variable *)n;
2413 if(n->type != VARIABLE_NODE ||
2414 v->scope == CLASS_SCOPE)
2416 print_glade_widget(m, v);
2419 } else if(m->method == CLASS_INIT_METHOD) {
2420 gboolean did_base_obj = FALSE;
2423 out_addline_infile(out, m->line_no);
2424 print_method(out, "static ", "\n", "", " ", "", "\n",
2425 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2427 out_printf(out, "{\n");
2429 out_addline_outfile(out);
2431 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2433 if (set_properties > 0 ||
2434 get_properties > 0 ||
2441 "g_object_class%s = "
2442 "(GObjectClass*) %s;\n",
2444 ((FuncArg *)m->args->data)->name);
2445 did_base_obj = TRUE;
2450 ((FuncArg *)m->args->data)->name,
2455 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2456 ((FuncArg *)m->args->data)->name,
2459 if (initializers > 0) {
2461 for(li = ((Class *)class)->nodes;
2465 Variable *v = (Variable *)n;
2466 if(n->type == VARIABLE_NODE &&
2467 v->scope == CLASS_SCOPE)
2468 print_initializer(m, v);
2472 out_printf(out, "\n\tparent_class = ");
2474 out_printf(out, "(%sClass *)", ptypebase);
2475 out_printf(out, "g_type_class_ref (%s);\n",
2481 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2483 /* if there are no handlers for these things, we
2484 * need to set them up here */
2485 if(need_constructor)
2486 out_printf(out, "\tg_object_class->constructor "
2487 "= ___constructor;\n");
2488 if(need_dispose && !dispose_handler)
2489 out_printf(out, "\tg_object_class->dispose "
2491 if(need_finalize && !finalize_handler)
2492 out_printf(out, "\tg_object_class->finalize = "
2495 if(get_properties > 0 || set_properties > 0)
2498 if (c->bonobo_object_class != NULL) {
2499 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2505 out_printf(out, " {\n");
2506 out_addline_infile(out, m->ccode_line);
2507 out_printf(out, "%s\n", m->cbuf);
2508 out_addline_outfile(out);
2509 out_printf(out, " }\n");
2511 out_printf(out, "}\n"
2512 "#undef __GOB_FUNCTION__\n");
2517 add_argument (Argument *a, gboolean is_set)
2521 char *the_type_lower;
2526 line_no = a->set_line;
2529 line_no = a->get_line;
2533 s = g_strdup(a->name);
2535 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2537 the_type_lower = g_strdup (a->gtktype);
2538 gob_strdown (the_type_lower);
2540 /* HACK because there is no g_value_set/get for unichar */
2541 if (strcmp (the_type_lower, "unichar") == 0) {
2542 g_free (the_type_lower);
2543 the_type_lower = g_strdup ("uint");
2548 const char *unused = "";
2550 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2551 unused = " G_GNUC_UNUSED";
2554 if (a->atype != NULL &&
2555 /* gcc -Wbad-function-cast is wanking stupid, moronic
2556 and otherwise evil so we should just use a (gint)
2557 or (guint) cast, not the specific type cast */
2559 (strcmp (a->gtktype, "ENUM") != 0 &&
2560 strcmp (a->gtktype, "FLAGS") != 0)))
2561 cast = get_type (a->atype, TRUE);
2563 cast = g_strdup (get_cast (a->gtktype, FALSE));
2565 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2566 cast, unused, cast, the_type_lower);
2569 } else if ( ! is_set) {
2572 if (a->atype != NULL)
2573 cast = get_type (a->atype, TRUE);
2575 cast = g_strdup (get_cast (a->gtktype, FALSE));
2576 out_printf (out, "\t%s ARG;\n"
2577 "\tmemset (&ARG, 0, sizeof (%s));\n",
2583 out_printf(out, "\t\t{\n");
2585 out_addline_infile (out, line_no);
2586 out_printf (out, "%s\n", cbuf);
2588 out_addline_outfile (out);
2589 out_printf (out, "\t\t}\n");
2591 if (strcmp (a->gtktype, "OBJECT") == 0)
2592 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2595 out_printf (out, "\t\t"
2596 "g_value_set_%s (VAL, ARG);\n",
2599 g_free (the_type_lower);
2602 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2603 out_printf (out, "\t\tif (&ARG) break;\n");
2606 out_printf (out, "\t\tbreak;\n");
2608 out_printf (out, "\t}\n");
2612 add_property (Property *p, gboolean is_set)
2615 char *the_type_lower;
2621 line_no = p->set_line;
2624 line_no = p->get_line;
2629 name_upper = g_strdup (p->name);
2630 gob_strup (name_upper);
2631 the_type_lower = g_strdup (p->gtktype);
2632 gob_strdown (the_type_lower);
2634 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2636 out_printf(out, "\t\t{\n");
2638 out_addline_infile (out, line_no);
2639 out_printf (out, "%s\n", cbuf);
2641 out_addline_outfile (out);
2642 out_printf (out, "\t\t}\n");
2644 g_free (name_upper);
2645 g_free (the_type_lower);
2647 out_printf (out, "\t\tbreak;\n");
2651 add_getset_arg(Class *c, gboolean is_set)
2654 const char *unused = "";
2655 const char *hack_unused = "";
2657 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2658 unused = " G_GNUC_UNUSED";
2660 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2663 out_printf(out, "\nstatic void\n"
2664 "___object_%s_property (GObject *object,\n"
2665 "\tguint property_id,\n"
2666 "\t%sGValue *VAL%s,\n"
2667 "\tGParamSpec *pspec%s)\n"
2668 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2671 "\tself = %s (object);\n\n"
2672 "\tswitch (property_id) {\n",
2673 is_set ? "set" : "get",
2674 is_set ? "const " : "",
2678 is_set ? "set" : "get",
2683 for (li = c->nodes; li != NULL; li = li->next) {
2685 if (n->type == PROPERTY_NODE)
2686 add_property ((Property *)n, is_set);
2687 else if (n->type == ARGUMENT_NODE)
2688 add_argument ((Argument *)n, is_set);
2690 out_printf (out, "\tdefault:\n"
2691 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2692 "#ifndef __PRETTY_FUNCTION__\n"
2693 "# undef G_STRLOC\n"
2694 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2696 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2697 "\t\t%sbreak;\n\t}\n"
2699 "#undef __GOB_FUNCTION__\n", hack_unused);
2703 print_checks (Method *m, FuncArg *fa)
2707 gboolean checked_null = FALSE;
2708 is_void = (strcmp(m->mtype->name, "void")==0 &&
2709 m->mtype->pointer == NULL);
2711 for(li = fa->checks; li != NULL; li = li->next) {
2712 Check *ch = li->data;
2714 /* point to the method prot in .gob for failed checks */
2716 out_addline_infile(out, m->line_no);
2718 out_printf(out, "\tg_return_if_fail (");
2720 out_printf(out, "\tg_return_val_if_fail (");
2721 switch(ch->chtype) {
2723 out_printf(out, "%s != NULL", fa->name);
2724 checked_null = TRUE;
2727 s = make_pre_macro(fa->atype->name, "IS");
2729 out_printf(out, "%s (%s)", s, fa->name);
2731 /* if not check null, null may be valid */
2732 out_printf(out, "!(%s) || %s (%s)", fa->name,
2737 out_printf(out, "%s < %s", fa->name, ch->number);
2740 out_printf(out, "%s > %s", fa->name, ch->number);
2743 out_printf(out, "%s <= %s", fa->name, ch->number);
2746 out_printf(out, "%s >= %s", fa->name, ch->number);
2749 out_printf(out, "%s == %s", fa->name, ch->number);
2752 out_printf(out, "%s != %s", fa->name, ch->number);
2756 out_printf(out, ");\n");
2758 out_printf(out, ", (");
2759 print_type(out, m->mtype, TRUE);
2760 out_printf(out, ")%s);\n",
2761 m->onerror?m->onerror:"0");
2767 print_preconditions(Method *m)
2771 for(li=m->args;li;li=g_list_next(li)) {
2772 FuncArg *fa = li->data;
2774 print_checks(m, fa);
2777 out_addline_outfile(out);
2781 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2783 out_printf(out, "{\n");
2785 out_addline_outfile(out);
2786 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2787 ((Class *)class)->otype,
2790 print_preconditions(m);
2794 (no_gnu || for_cpp) &&
2796 ((FuncArg *)(m->args->data))->name != NULL &&
2797 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2798 out_printf (out, "\tif (&self) { ; }\n");
2801 /* Note: the trailing }'s are on one line, this is so
2802 that we get the no return warning correctly and point to
2803 the correct line in the .gob file, yes this is slightly
2804 ugly in the .c file, but that is not supposed to be
2805 human readable anyway. */
2807 out_printf(out, "{\n");
2809 out_addline_infile(out, m->ccode_line);
2810 out_printf(out, "\t%s}", m->cbuf);
2813 /* Note, there is no \n between the last } and this } so that
2814 * errors/warnings reported on the end of the body get pointed to the
2815 * right line in the .gob source */
2816 out_printf(out, "}\n");
2819 out_addline_outfile(out);
2820 out_printf(out, "#undef __GOB_FUNCTION__\n");
2824 put_signal_args (Method *m)
2830 if (m->args->next == NULL)
2833 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2834 li != NULL && ali != NULL;
2835 li = li->next, ali = ali->next, i++) {
2836 FuncArg *fa = li->data;
2837 char *str = ali->data;
2838 char *cast = g_strdup (get_cast (str, FALSE));
2839 /* FIXME: This code is so fucking ugly it hurts */
2840 gboolean do_static =
2841 (strcmp (str, "STRING") == 0 ||
2842 strcmp (str, "BOXED") == 0 ||
2843 strncmp (str, "BOXED_", 6) == 0);
2848 cast = get_type (fa->atype, TRUE);
2850 /* we should have already proved before that
2851 the we know all the types */
2852 g_assert (cast != NULL);
2854 if (strncmp (str, "BOXED_", 6) == 0)
2855 t = g_strdup (&(str[6]));
2857 t = g_strconcat ("G_TYPE_", str, NULL);
2860 "\t___param_values[%d].g_type = 0;\n"
2861 "\tg_value_init (&___param_values[%d], %s);\n",
2865 if (strcmp (str, "UNICHAR") == 0)
2866 /* hack because glib is braindamaged */
2867 set_func = g_strdup ("g_value_set_uint");
2868 else if (strncmp (str, "BOXED_", 6) == 0)
2869 set_func = g_strdup ("g_value_set_static_boxed");
2871 set_func = g_strdup_printf ("g_value_set%s_%s",
2872 do_static ? "_static" : "",
2874 gob_strdown (set_func);
2876 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2877 set_func, i, cast, fa->name);
2885 clear_signal_args (Method *m)
2890 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2892 if (m->args->next == NULL)
2895 for (li = m->args->next, i = 1;
2897 li = li->next, i++) {
2899 "\tg_value_unset (&___param_values[%d]);\n", i);
2904 get_arg_names_for_macro (Method *m)
2908 GString *gs = g_string_new(NULL);
2910 for(li=m->args;li;li=g_list_next(li)) {
2911 FuncArg *arg = li->data;
2912 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2915 return g_string_free (gs, FALSE);
2919 put_method(Method *m)
2921 char *s, *args, *doc;
2923 is_void = (strcmp(m->mtype->name, "void")==0 &&
2924 m->mtype->pointer == NULL);
2925 out_printf(out, "\n");
2926 if(m->method != OVERRIDE_METHOD) {
2927 doc = get_gtk_doc(m->id);
2929 out_printf(out, "%s", doc);
2934 case REGULAR_METHOD:
2936 out_addline_infile(out, m->line_no);
2937 if(m->scope == PRIVATE_SCOPE)
2938 print_method(out, "static ", "\n", "", " ", "", "\n",
2939 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2940 else /* PUBLIC, PROTECTED */
2941 print_method(out, "", "\n", "", " ", "", "\n",
2942 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2943 print_method_body(m, TRUE, TRUE);
2944 /* the outfile line was added above */
2946 case SIGNAL_FIRST_METHOD:
2947 case SIGNAL_LAST_METHOD:
2949 out_addline_infile(out, m->line_no);
2950 if(m->scope == PRIVATE_SCOPE)
2951 print_method(out, "static ", "\n", "", " ", "", "\n",
2952 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2953 else /* PUBLIC, PROTECTED */
2954 print_method(out, "", "\n", "", " ", "", "\n",
2955 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2956 out_printf (out, "{\n");
2958 out_addline_outfile (out);
2961 "\tGValue ___param_values[%d];\n"
2962 "\tGValue ___return_val;\n\n"
2963 "memset (&___return_val, 0, "
2964 "sizeof (___return_val));\n"
2965 "memset (&___param_values, 0, "
2966 "sizeof (___param_values));\n\n",
2967 g_list_length (m->args));
2969 print_preconditions (m);
2972 "\n\t___param_values[0].g_type = 0;\n"
2973 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2974 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2975 ((FuncArg *)m->args->data)->name,
2976 ((FuncArg *)m->args->data)->name);
2978 put_signal_args (m);
2980 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2981 const char *defret = NULL;
2983 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2984 (char *)m->gtktypes->data);
2986 if (m->defreturn != NULL)
2987 defret = m->defreturn;
2988 else if (m->onerror != NULL)
2989 defret = m->onerror;
2991 if (defret != NULL) {
2993 /* FIXME: This code is so fucking ugly it hurts */
2994 gboolean do_static =
2995 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2996 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2997 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2999 cast = get_type (m->mtype, TRUE);
3001 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3002 /* hack because glib is braindamaged */
3003 set_func = g_strdup ("g_value_set_uint");
3005 set_func = g_strdup_printf ("g_value_set%s_%s",
3006 do_static ? "_static" : "",
3007 (char *)m->gtktypes->data);
3008 gob_strdown (set_func);
3010 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3011 set_func, cast, defret);
3016 out_printf (out, "\n");
3019 s = g_strdup (m->id);
3022 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3023 "\t\tobject_signals[%s_SIGNAL],\n"
3024 "\t\t0 /* detail */,\n"
3025 "\t\t&___return_val);\n", s);
3029 clear_signal_args (m);
3031 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3032 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3034 /* Hack because glib is very very braindead */
3036 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3037 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3038 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3039 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3041 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3042 /* hack because glib is braindamaged */
3043 getfunc = g_strdup ("g_value_get_uint");
3045 getfunc = g_strdup_printf ("g_value_%s_%s",
3046 do_dup ? "dup" : "get",
3047 (char *)m->gtktypes->data);
3048 gob_strdown (getfunc);
3051 cast = get_type (m->mtype, TRUE);
3056 print_type (out, m->mtype, TRUE);
3058 " ___ret = (%s) %s (&___return_val);\n"
3059 "\t\tg_value_unset (&___return_val);\n"
3060 "\t\treturn ___ret;\n"
3067 out_printf(out, "}\n");
3072 out_addline_infile(out, m->line_no);
3073 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3074 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3075 print_method_body(m, FALSE, TRUE);
3076 /* the outfile line was added above */
3078 case VIRTUAL_METHOD:
3080 out_addline_infile(out, m->line_no);
3081 if(m->scope==PRIVATE_SCOPE)
3082 print_method(out, "static ", "\n", "", " ", "", "\n",
3083 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3084 else /* PUBLIC, PROTECTED */
3085 print_method(out, "", "\n", "", " ", "", "\n",
3086 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3087 out_printf(out, "{\n");
3088 out_addline_outfile(out);
3089 out_printf(out, "\t%sClass *klass;\n", typebase);
3090 print_preconditions(m);
3091 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3092 "\tif(klass->%s)\n",
3093 macrobase, ((FuncArg *)m->args->data)->name,
3095 if(strcmp(m->mtype->name, "void") == 0 &&
3096 m->mtype->pointer == NULL) {
3098 out_printf(out, "\t\t(*klass->%s)(%s",
3100 ((FuncArg *)m->args->data)->name);
3101 for(li=m->args->next;li;li=g_list_next(li)) {
3102 FuncArg *fa = li->data;
3103 out_printf(out, ",%s", fa->name);
3105 out_printf(out, ");\n}\n");
3108 out_printf(out, "\t\treturn (*klass->%s)(%s",
3110 ((FuncArg *)m->args->data)->name);
3111 for(li=m->args->next;li;li=g_list_next(li)) {
3112 FuncArg *fa = li->data;
3113 out_printf(out, ",%s", fa->name);
3115 out_printf(out, ");\n"
3118 print_type(out, m->mtype, TRUE);
3120 out_printf(out, ")(%s);\n}\n", m->defreturn);
3122 out_printf(out, ")(%s);\n}\n", m->onerror);
3124 out_printf(out, ")(0);\n}\n");
3130 out_addline_infile(out, m->line_no);
3131 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3132 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3133 print_method_body(m, FALSE, TRUE);
3134 /* the outfile line was added above */
3136 case OVERRIDE_METHOD:
3140 out_addline_infile(out, m->line_no);
3141 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3142 print_method(out, "static ", s, "", " ", "", "\n",
3143 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3145 out_addline_outfile(out);
3146 s = replace_sep(m->otype, '_');
3148 args = get_arg_names_for_macro(m);
3150 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3151 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3152 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3153 args, s, m->id, s, m->id, args);
3155 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3156 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3157 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3159 args, s, m->id, s, m->id, args);
3160 out_printf(out, "(");
3161 print_type(out, m->mtype, TRUE);
3162 out_printf(out, ")%s))\n",
3163 m->onerror?m->onerror:"0");
3167 print_method_body(m, TRUE, TRUE);
3168 /* the outfile line was added above */
3169 out_printf(out, "#undef PARENT_HANDLER\n");
3171 case CONSTRUCTOR_METHOD:
3172 case DISPOSE_METHOD:
3173 case FINALIZE_METHOD:
3175 out_addline_infile(out, m->line_no);
3176 print_method(out, "static ", "\n", "", " ", "", "\n",
3177 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3178 print_method_body(m, TRUE, TRUE);
3179 /* the outfile line was added above */
3188 char *outfile, *outfileh, *outfileph;
3190 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3191 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3193 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3194 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3196 if ((privates > 0 || protecteds > 0 ||
3197 private_header == PRIVATE_HEADER_ALWAYS) &&
3198 private_header != PRIVATE_HEADER_NEVER) {
3199 char sep[2] = {0,0};
3202 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3203 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3205 outfilephbase = NULL;
3211 out = fopen (outfile, "w");
3213 error_printf (GOB_ERROR, 0,
3214 "Cannot open outfile: %s", outfile);
3216 outh = fopen (outfileh, "w");
3218 error_printf (GOB_ERROR, 0,
3219 "Cannot open outfile: %s", outfileh);
3221 if (outfileph != NULL) {
3222 outph = fopen (outfileph, "w");
3223 if (outph == NULL) {
3224 error_printf (GOB_ERROR, 0,
3225 "Cannot open outfile: %s",
3233 put_argument_nongnu_wrappers (Class *c)
3237 if (get_properties < 0 && set_properties < 0)
3240 for (li = c->nodes; li != NULL; li = li->next) {
3242 const char *name, *gtktype;
3248 if (n->type == ARGUMENT_NODE) {
3249 Argument *a = (Argument *)n;
3251 gtktype = a->gtktype;
3253 get = a->get != NULL;
3254 set = a->set != NULL;
3255 } else if (n->type == PROPERTY_NODE) {
3256 Property *p = (Property *)n;
3258 gtktype = p->gtktype;
3260 get = p->get != NULL;
3261 set = p->set != NULL;
3266 aname = g_strdup (name);
3270 cast = get_type (atype, TRUE);
3272 cast = g_strdup (get_cast (gtktype, TRUE));
3276 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3277 "\"%s\",(%s)(arg)\n",
3278 macrobase, aname, name, cast);
3280 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3281 "\"%s\",(%s*)(arg)\n",
3282 macrobase, aname, name, cast);
3285 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3287 macrobase, aname, name);
3289 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3291 macrobase, aname, name);
3299 put_argument_gnu_wrappers(Class *c)
3303 if(get_properties < 0 && set_properties < 0)
3306 for (li = c->nodes; li != NULL; li = li->next) {
3308 const char *name, *gtktype;
3314 if (n->type == ARGUMENT_NODE) {
3315 Argument *a = (Argument *)n;
3317 gtktype = a->gtktype;
3319 get = a->get != NULL;
3320 set = a->set != NULL;
3321 } else if (n->type == PROPERTY_NODE) {
3322 Property *p = (Property *)n;
3324 gtktype = p->gtktype;
3326 get = p->get != NULL;
3327 set = p->set != NULL;
3332 aname = g_strdup (name);
3336 cast = get_type (atype, TRUE);
3338 cast = g_strdup (get_cast (gtktype, TRUE));
3342 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3343 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3344 macrobase, aname, name, cast);
3346 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3347 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3348 macrobase, aname, name, cast);
3351 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3353 macrobase, aname, name);
3355 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3357 macrobase, aname, name);
3365 print_ccode_block(CCode *cc)
3368 switch(cc->cctype) {
3370 /* HT code is printed exactly like normal header
3371 code but is printed before */
3374 out_printf(fp, "\n");
3377 /* AT code is printed exactly like normal 'all'
3378 code but is printed before */
3381 out_printf(outph, "\n");
3382 out_printf(outph, "%s\n", cc->cbuf);
3383 out_addline_infile(outph, cc->line_no);
3384 out_addline_outfile(outph);
3386 out_printf(outh, "\n");
3387 out_printf(outh, "%s\n", cc->cbuf);
3389 out_printf(fp, "\n");
3390 out_addline_infile(fp, cc->line_no);
3396 out_printf(fp, "\n");
3397 out_addline_infile(fp, cc->line_no);
3404 out_printf(fp, "\n");
3405 out_addline_infile(fp, cc->line_no);
3408 out_printf(fp, "%s\n", cc->cbuf);
3409 if(cc->cctype == C_CCODE ||
3410 cc->cctype == AD_CCODE ||
3411 cc->cctype == A_CCODE ||
3412 cc->cctype == AT_CCODE ||
3413 cc->cctype == PH_CCODE)
3414 out_addline_outfile(fp);
3418 print_class_block(Class *c)
3422 gboolean printed_private = FALSE;
3426 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3427 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3431 out_printf(out, "/* utility types we may need */\n");
3432 if(special_array[SPECIAL_2POINTER])
3433 out_printf(out, "typedef struct { "
3434 "gpointer a; gpointer b; "
3435 "} ___twopointertype;\n");
3436 if(special_array[SPECIAL_3POINTER])
3437 out_printf(out, "typedef struct { "
3438 "gpointer a; gpointer b; "
3440 "} ___threepointertype;\n");
3441 if(special_array[SPECIAL_INT_POINTER])
3442 out_printf(out, "typedef struct { "
3443 "gint a; gpointer b; "
3444 "} ___intpointertype;\n");
3445 out_printf(out, "\n");
3448 out_printf(outh, "\n/*\n"
3449 " * Type checking and casting macros\n"
3451 out_printf(outh, "#define %s\t"
3452 "(%s_get_type())\n",
3453 macrotype, funcbase);
3454 out_printf(outh, "#define %s(obj)\t"
3455 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3456 macrobase, funcbase, typebase);
3457 out_printf(outh, "#define %s_CONST(obj)\t"
3458 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3459 macrobase, funcbase, typebase);
3460 out_printf(outh, "#define %s_CLASS(klass)\t"
3461 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3462 macrobase, funcbase, typebase);
3463 out_printf(outh, "#define %s(obj)\t"
3464 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3467 "#define %s_GET_CLASS(obj)\t"
3468 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3469 macrobase, funcbase, typebase);
3471 if ( ! no_self_alias) {
3472 out_printf(out, "/* self casting macros */\n");
3473 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3474 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3475 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3476 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3477 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3479 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3482 out_printf(out, "/* self typedefs */\n");
3483 out_printf(out, "typedef %s Self;\n", typebase);
3484 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3488 always_private_struct) {
3489 out_printf (outh, "\n/* Private structure type */\n");
3490 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3491 typebase, typebase);
3493 out_printf (outh, "/* There are no privates, this "
3494 "structure is thus never defined */\n");
3497 out_printf (outh, "\n/*\n"
3498 " * Main object structure\n"
3500 s = replace_sep (c->otype, '_');
3502 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3503 "#define __TYPEDEF_%s__\n", s, s);
3505 out_printf (outh, "typedef struct _%s %s;\n"
3506 "#endif\n", typebase, typebase);
3507 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3508 typebase, ptypebase);
3509 for (li = c->nodes; li; li=li->next) {
3510 static gboolean printed_public = FALSE;
3512 Variable *v = (Variable *)n;
3513 if(n->type == VARIABLE_NODE &&
3514 v->scope == PUBLIC_SCOPE) {
3515 if( ! printed_public) {
3516 out_printf(outh, "\t/*< public >*/\n");
3517 printed_public = TRUE;
3519 put_variable((Variable *)n, outh);
3522 /* put protecteds always AFTER publics */
3523 for (li = c->nodes; li != NULL; li = li->next) {
3525 Variable *v = (Variable *)n;
3526 if (n->type == VARIABLE_NODE &&
3527 v->scope == PROTECTED_SCOPE) {
3528 if ( ! printed_private) {
3529 out_printf (outh, "\t/*< private >*/\n");
3530 printed_private = TRUE;
3532 put_variable ((Variable *)n, outh);
3536 always_private_struct) {
3537 if ( ! printed_private)
3538 out_printf (outh, "\t/*< private >*/\n");
3539 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3541 out_printf (outh, "};\n");
3546 /* if we are to stick this into the private
3547 header, if not stick it directly into the
3554 out_printf (outfp, "struct _%sPrivate {\n",
3558 for(li=c->nodes; li; li=li->next) {
3560 Variable *v = (Variable *)n;
3561 if(n->type == VARIABLE_NODE &&
3562 v->scope == PRIVATE_SCOPE) {
3563 out_addline_infile(outfp, v->line_no);
3564 put_variable(v, outfp);
3567 out_addline_outfile(outfp);
3569 out_printf(outfp, "};\n");
3572 out_printf(outh, "\n/*\n"
3573 " * Class definition\n"
3575 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3576 typebase, typebase);
3578 "struct _%sClass {\n\t%sClass __parent__;\n",
3579 typebase, ptypebase);
3580 for(li = c->nodes; li != NULL; li = li->next) {
3582 if(n->type == METHOD_NODE)
3583 put_vs_method((Method *)n);
3585 /* If BonoboX type class put down the epv */
3586 if (c->bonobo_object_class != NULL) {
3588 "\t/* Bonobo object epv */\n"
3589 "\tPOA_%s__epv _epv;\n",
3590 c->bonobo_object_class);
3592 /* put class scope variables */
3593 for (li = c->nodes; li != NULL; li = li->next) {
3595 Variable *v = (Variable *)n;
3596 if (n->type == VARIABLE_NODE &&
3597 v->scope == CLASS_SCOPE)
3598 put_variable ((Variable *)n, outh);
3600 out_printf (outh, "};\n\n");
3602 out_printf (out, "/* here are local prototypes */\n");
3603 if (set_properties > 0) {
3604 out_printf (out, "static void ___object_set_property "
3605 "(GObject *object, guint property_id, "
3606 "const GValue *value, GParamSpec *pspec);\n");
3608 if (get_properties > 0) {
3609 out_printf (out, "static void ___object_get_property "
3610 "(GObject *object, guint property_id, "
3611 "GValue *value, GParamSpec *pspec);\n");
3614 out_printf (outh, "\n/*\n"
3615 " * Public methods\n"
3618 if ( ! overrode_get_type) {
3619 out_printf (outh, "GType\t%s_get_type\t(void) G_GNUC_CONST;\n", funcbase);
3622 for(li = c->nodes; li != NULL; li = li->next) {
3624 if(n->type == METHOD_NODE) {
3625 put_pub_method((Method *)n);
3626 put_prot_method((Method *)n);
3627 put_priv_method_prot((Method *)n);
3631 /* this idea is less and less apealing to me */
3633 out_printf (outh, "\n/*\n"
3634 " * Signal connection wrapper macros\n"
3637 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3638 put_signal_macros (c, TRUE);
3639 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3640 put_signal_macros (c, FALSE);
3641 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3643 put_signal_macros (c, FALSE);
3644 out_printf(outh, "\n");
3647 out_printf (out, "\n/*\n"
3648 " * Signal connection wrapper macro shortcuts\n"
3650 put_local_signal_macros (c);
3651 out_printf(outh, "\n");
3654 /* argument wrapping macros */
3655 if(get_properties > 0 || set_properties > 0) {
3656 out_printf(outh, "\n/*\n"
3657 " * Argument wrapping macros\n"
3660 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3661 put_argument_gnu_wrappers(c);
3662 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3663 put_argument_nongnu_wrappers(c);
3664 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3666 put_argument_nongnu_wrappers(c);
3671 for(li = c->nodes; li != NULL; li = li->next) {
3673 if(n->type == METHOD_NODE)
3674 add_signal_prots((Method *)n);
3680 if(any_method_to_alias(c)) {
3681 out_printf (out, "/* Short form macros */\n");
3682 make_method_aliases (c);
3685 add_interface_inits (c);
3687 if ( ! overrode_get_type) {
3688 if (c->bonobo_object_class != NULL)
3689 add_bonobo_object_get_type ();
3694 out_printf (out, "/* a macro for creating a new object of our type */\n");
3696 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3697 typebase, funcbase);
3699 out_printf (out, "/* a function for creating a new object of our type */\n");
3700 out_printf (out, "#include <stdarg.h>\n");
3702 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3703 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3704 "{\n\t%s *ret;\n\tva_list ap;\n"
3705 "\tva_start (ap, first);\n"
3706 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3709 "\treturn ret;\n}\n\n",
3711 no_gnu ? "" : " G_GNUC_UNUSED",
3712 typebase, typebase, typebase, funcbase);
3716 out_printf (out, "/* a function to connect glade callback */\n");
3717 out_printf (out,"static void\n"
3718 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3719 "GObject *object,\n"
3720 "const gchar *signal_name,\n"
3721 "const gchar *signal_data,\n"
3722 "GObject *connect_object,\n"
3724 "gpointer user_data)\n"
3726 "\tstatic GModule * allsymbols = NULL;\n"
3728 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3729 "\tif (allsymbols) {\n"
3730 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3731 "\t\tGCallback func;\n"
3733 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3734 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3735 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3736 "\t\t\t\tg_free(func_name);\n"
3741 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3743 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3744 "\t\tg_free(func_name);\n"
3751 for (li = nodes; li != NULL; li = li->next) {
3752 Node *node = li->data;
3753 if (node->type == CCODE_NODE) {
3754 CCode *cc = (CCode *)node;
3755 if (cc->cctype == AD_CCODE)
3756 print_ccode_block (cc);
3760 if (need_constructor)
3761 add_constructor (c);
3771 if(set_properties > 0) {
3772 add_getset_arg(c, TRUE);
3775 if(get_properties > 0) {
3776 add_getset_arg(c, FALSE);
3779 for(li = c->nodes; li != NULL; li = li->next) {
3781 if(n->type == METHOD_NODE)
3782 put_method((Method *)n);
3785 add_bad_hack_to_avoid_unused_warnings(c);
3789 print_useful_macros(void)
3791 int major = 0, minor = 0, pl = 0;
3794 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3795 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3796 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3797 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3799 /* Useful priv macro thingie */
3800 /* FIXME: this should be done the same way that priv is, as a var,
3802 out_printf (out, "#define selfp (self->_priv)\n\n");
3806 print_more_useful_macros (void)
3809 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3810 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3812 out_printf (out, "#ifdef G_LIKELY\n");
3813 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3814 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3815 out_printf (out, "#else /* ! G_LIKELY */\n");
3816 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3817 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3818 out_printf (out, "#endif /* G_LIKELY */\n");
3823 print_file_comments(void)
3825 out_printf(outh, "/* Generated by GOB (v%s)"
3826 " (do not edit directly) */\n\n", VERSION);
3828 out_printf(outph, "/* Generated by GOB (v%s)"
3829 " (do not edit directly) */\n\n", VERSION);
3830 out_printf(out, "/* Generated by GOB (v%s)"
3831 " (do not edit directly) */\n\n", VERSION);
3833 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3837 print_includes(void)
3839 gboolean found_header;
3842 /* We may need string.h for memset */
3843 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3844 out_printf(out, "#include <string.h> /* memset() */\n\n");
3847 p = g_strconcat(filebase, ".h", NULL);
3848 found_header = TRUE;
3849 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3850 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3851 found_header = FALSE;
3855 /* if we are creating a private header see if it was included */
3857 char sep[2] = {0,0};
3860 p = g_strconcat(filebase, sep, "private.h", NULL);
3861 if( ! g_list_find_custom(include_files, p,
3862 (GCompareFunc)strcmp)) {
3863 out_printf(out, "#include \"%s%cprivate.h\"\n\n",
3867 error_printf(GOB_WARN, 0,
3868 "Implicit private header include "
3870 "\tsource file, while public "
3871 "header is at a custom location, "
3873 "\texplicitly include "
3874 "the private header below the "
3882 print_header_prefixes(void)
3886 p = replace_sep(((Class *)class)->otype, '_');
3888 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3890 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3891 "#define __%s_PRIVATE_H__\n\n"
3892 "#include \"%s.h\"\n\n", p, p, filebase);
3895 if( ! no_extern_c) {
3896 out_printf(outh, "#ifdef __cplusplus\n"
3898 "#endif /* __cplusplus */\n\n");
3900 out_printf(outph, "#ifdef __cplusplus\n"
3902 "#endif /* __cplusplus */\n\n");
3907 print_header_postfixes(void)
3910 out_printf(outh, "\n#ifdef __cplusplus\n"
3912 "#endif /* __cplusplus */\n");
3913 out_printf(outh, "\n#endif\n");
3916 out_printf(outph, "\n#ifdef __cplusplus\n"
3918 "#endif /* __cplusplus */\n");
3919 out_printf(outph, "\n#endif\n");
3928 /* print the AT_CCODE and CT_CCODE blocks */
3929 for(li = nodes; li != NULL; li = li->next) {
3930 Node *node = li->data;
3931 if(node->type == CCODE_NODE) {
3932 CCode *cc = (CCode *)node;
3933 if (cc->cctype == AT_CCODE ||
3934 cc->cctype == CT_CCODE)
3935 print_ccode_block((CCode *)node);
3941 print_header_top(void)
3945 /* mandatory includes */
3946 out_printf (outh, "#include <glib.h>\n");
3947 out_printf (outh, "#include <glib-object.h>\n");
3949 /* print the HT_CCODE blocks */
3950 for (li = nodes; li != NULL; li = li->next) {
3951 Node *node = li->data;
3952 if (node->type == CCODE_NODE) {
3953 CCode *cc = (CCode *)node;
3954 if (cc->cctype == HT_CCODE)
3955 print_ccode_block ((CCode *)node);
3961 print_enum (EnumDef *enode)
3968 funcprefix = replace_sep (enode->etype, '_');
3969 gob_strdown (funcprefix);
3970 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3972 type = remove_sep (enode->etype);
3974 out_printf (outh, "\ntypedef enum {\n");
3976 for (li = enode->values; li != NULL; li = li->next) {
3977 EnumValue *value = li->data;
3979 char *sname = gob_strdown (g_strdup (value->name));
3981 while ((p = strchr (sname, '_')) != NULL)
3984 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3985 if (value->value != NULL)
3986 out_printf (outh, " = %s", value->value);
3987 if (li->next != NULL)
3988 out_printf (outh, ",\n");
3990 out_printf (outh, "\n");
3992 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3993 enode->prefix, value->name,
3994 enode->prefix, value->name,
4000 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4002 out_printf (outh, "} %s;\n", type);
4004 str = make_pre_macro (enode->etype, "TYPE");
4005 out_printf (outh, "#define %s ", str);
4008 out_printf (outh, "%s_get_type()\n", funcprefix);
4009 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4012 "GType\n%s_get_type (void)\n"
4014 "\tstatic GType type = 0;\n"
4015 "\tif ___GOB_UNLIKELY(type == 0)\n"
4016 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4019 funcprefix, type, funcprefix);
4021 g_free (funcprefix);
4026 print_flags (Flags *fnode)
4034 funcprefix = replace_sep (fnode->ftype, '_');
4035 gob_strdown (funcprefix);
4036 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4038 type = remove_sep (fnode->ftype);
4040 out_printf (outh, "\ntypedef enum {\n");
4042 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4043 const char *name = li->data;
4045 char *sname = gob_strdown (g_strdup (name));
4047 while ((p = strchr (sname, '_')) != NULL)
4050 out_printf (outh, "\t%s_%s = 1<<%d",
4051 fnode->prefix, name, i);
4052 if (li->next != NULL)
4053 out_printf (outh, ",\n");
4055 out_printf (outh, "\n");
4057 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4058 fnode->prefix, name,
4059 fnode->prefix, name,
4065 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4067 out_printf (outh, "} %s;\n", type);
4069 str = make_pre_macro (fnode->ftype, "TYPE");
4070 out_printf (outh, "#define %s ", str);
4073 out_printf (outh, "%s_get_type()\n", funcprefix);
4074 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4077 "GType\n%s_get_type (void)\n"
4079 "\tstatic GType type = 0;\n"
4080 "\tif ___GOB_UNLIKELY(type == 0)\n"
4081 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4084 funcprefix, type, funcprefix);
4086 g_free (funcprefix);
4091 print_error (Error *enode)
4098 funcprefix = replace_sep (enode->etype, '_');
4099 gob_strdown (funcprefix);
4100 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4102 type = remove_sep (enode->etype);
4104 out_printf (outh, "\ntypedef enum {\n");
4106 for (li = enode->values; li != NULL; li = li->next) {
4107 const char *name = li->data;
4109 char *sname = gob_strdown (g_strdup (name));
4111 while ((p = strchr (sname, '_')) != NULL)
4114 out_printf (outh, "\t%s_%s", enode->prefix, name);
4115 if (li->next != NULL)
4116 out_printf (outh, ",\n");
4118 out_printf (outh, "\n");
4120 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4121 enode->prefix, name,
4122 enode->prefix, name,
4128 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4130 out_printf (outh, "} %s;\n", type);
4132 str = make_pre_macro (enode->etype, "TYPE");
4133 out_printf (outh, "#define %s ", str);
4136 out_printf (outh, "%s_get_type ()\n", funcprefix);
4137 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4140 "GType\n%s_get_type (void)\n"
4142 "\tstatic GType type = 0;\n"
4143 "\tif ___GOB_UNLIKELY(type == 0)\n"
4144 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4147 funcprefix, type, funcprefix);
4149 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4150 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4152 str = replace_sep (enode->etype, '-');
4156 "GQuark\n%s_quark (void)\n"
4158 "\tstatic GQuark q = 0;\n"
4160 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4167 g_free (funcprefix);
4172 generate_outfiles(void)
4176 print_file_comments();
4182 print_header_prefixes();
4184 print_useful_macros();
4188 print_more_useful_macros ();
4190 for (li = nodes; li != NULL; li = li->next) {
4191 Node *node = li->data;
4192 if (node->type == CCODE_NODE) {
4193 CCode *cc = (CCode *)node;
4194 if (cc->cctype != HT_CCODE &&
4195 cc->cctype != AT_CCODE &&
4196 cc->cctype != AD_CCODE)
4197 print_ccode_block ((CCode *)node);
4198 } else if (node->type == CLASS_NODE) {
4199 print_class_block ((Class *)node);
4200 } else if (node->type == ENUMDEF_NODE) {
4201 print_enum ((EnumDef *)node);
4202 } else if (node->type == FLAGS_NODE) {
4203 print_flags ((Flags *)node);
4204 } else if (node->type == ERROR_NODE) {
4205 print_error ((Error *)node);
4207 g_assert_not_reached();
4211 print_header_postfixes();
4217 fprintf(stderr, "Gob version %s\n\n", VERSION);
4218 fprintf(stderr, "gob [options] file.gob\n\n");
4219 fprintf(stderr, "Options:\n"
4220 "\t--help,-h,-? Display this help\n"
4221 "\t--version Display version\n"
4222 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4223 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4224 "\t--for-cpp Create C++ files\n"
4225 "\t--no-extern-c Never print extern \"C\" into the "
4227 "\t--no-gnu Never use GNU extentions\n"
4228 "\t--no-touch Don't touch output files unless they "
4230 "\t changed (implies --no-touch-headers)\n"
4231 "\t--no-touch-headers Don't touch headers unless they "
4233 "\t--always-private-header Always create a private header "
4235 "\t even if it would be empty\n"
4236 "\t--ondemand-private-header Create private header only when "
4239 "\t--no-private-header Don't create a private header, "
4241 "\t structure and protected "
4242 "prototypes inside c file\n"
4243 "\t--always-private-struct Always create a private pointer "
4245 "\t the object structure\n"
4246 "\t--m4 Preprocess source with m4. "
4247 "Following args will\n"
4248 "\t be passed to m4\n"
4249 "\t--m4-dir Print directory that will be "
4252 "\t--no-write,-n Don't write output files, just "
4254 "\t--no-lines Don't print '#line' to output\n"
4255 "\t--no-self-alias Don't create self type and macro "
4257 "\t--no-kill-underscores Ignored for compatibility\n"
4258 "\t-o,--output-dir The directory where output "
4259 "should be placed\n"
4260 "\t--file-sep[=c] replace default \'-\' file "
4261 "name separator\n\n");
4262 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4266 parse_options(int argc, char *argv[])
4269 int got_file = FALSE;
4270 int no_opts = FALSE;
4271 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4275 for(i = 1 ; i < argc; i++) {
4277 char *new_commandline;
4278 g_assert(m4_commandline!=NULL);
4280 /* check whether this one looks like the filename */
4281 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4283 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4287 /* insert flags before the filename */
4288 new_commandline=g_strconcat(m4_commandline,
4296 /* just an ordinary option */
4298 new_commandline=g_strconcat(m4_commandline,
4303 /* free old commandline */
4304 g_free(m4_commandline);
4305 m4_commandline=new_commandline;
4307 } else if(no_opts ||
4308 argv[i][0] != '-') {
4311 fprintf(stderr, "Specify only one file!\n");
4317 } else if(strcmp(argv[i], "--help")==0) {
4320 } else if(strcmp(argv[i], "--version")==0) {
4321 fprintf(stderr, "Gob version %s\n", VERSION);
4323 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4324 exit_on_warn = TRUE;
4325 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4326 exit_on_warn = FALSE;
4327 } else if(strcmp(argv[i], "--for-cpp")==0) {
4329 } else if(strcmp(argv[i], "--no-touch")==0) {
4331 no_touch_headers = TRUE;
4332 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4333 no_touch_headers = TRUE;
4334 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4335 private_header = PRIVATE_HEADER_ONDEMAND;
4336 } else if(strcmp(argv[i], "--always-private-header")==0) {
4337 private_header = PRIVATE_HEADER_ALWAYS;
4338 } else if(strcmp(argv[i], "--no-private-header")==0) {
4339 private_header = PRIVATE_HEADER_NEVER;
4340 } else if(strcmp(argv[i], "--no-gnu")==0) {
4342 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4344 } else if(strcmp(argv[i], "--no-write")==0) {
4346 } else if(strcmp(argv[i], "--no-lines")==0) {
4348 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4349 no_self_alias = TRUE;
4350 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4352 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4353 always_private_struct = TRUE;
4354 } else if(strcmp(argv[i], "--m4-dir")==0) {
4355 printf("%s\n",M4_INCLUDE_DIR);
4357 } else if(strcmp(argv[i], "--m4")==0) {
4361 m4_commandline=g_strdup(M4_COMMANDLINE);
4362 } else if(strcmp(argv[i], "--m4-clean")==0) {
4366 m4_commandline=g_strdup(M4_COMMANDLINE);
4367 } else if (strcmp (argv[i], "-o") == 0 ||
4368 strcmp (argv[i], "--output-dir") == 0) {
4370 output_dir = g_strdup (argv[i+1]);
4375 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4378 strlen ("--output-dir=")) == 0) {
4379 char *p = strchr (argv[i], '=');
4380 g_assert (p != NULL);
4381 output_dir = g_strdup (p+1);
4382 } else if (strncmp (argv[i], "--file-sep=",
4383 strlen ("--file-sep=")) == 0) {
4384 char *p = strchr (argv[i], '=');
4385 g_assert (p != NULL);
4387 } else if (strncmp (argv[i], "--file-sep",
4388 strlen ("--file-sep")) == 0) {
4390 file_sep = (argv[i+1])[0];
4395 } else if(strcmp(argv[i], "--")==0) {
4396 /*further arguments are files*/
4398 } else if(strncmp(argv[i], "--", 2)==0) {
4399 /*unknown long option*/
4400 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4404 /*by now we know we have a string starting with
4405 - which is a short option string*/
4407 for(p = argv[i] + 1; *p; p++) {
4421 "Unknown option '%c'!\n", *p);
4430 /* if we are using m4, and got no filename, append m4 flags now */
4431 if(!got_file && use_m4 && !use_m4_clean) {
4432 char *new_commandline;
4433 new_commandline=g_strconcat(m4_commandline,
4437 g_free(m4_commandline);
4438 m4_commandline=new_commandline;
4444 compare_and_move (const char *old_filename)
4446 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4448 gboolean equal = FALSE;
4450 old_f = fopen (old_filename, "r");
4453 gboolean error = FALSE;
4455 new_f = fopen (new_filename, "r");
4464 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4465 if (ferror (new_f)) {
4467 error_printf (GOB_ERROR, 0,
4468 "Can't read %s: %s",
4470 g_strerror (errno));
4474 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4476 || feof (new_f) != feof (old_f)
4478 || memcmp (new_buf, old_buf, new_n) != 0)
4487 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4488 new_filename, g_strerror (errno));
4496 if (! equal && unlink (old_filename) != 0) {
4497 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4498 old_filename, g_strerror (errno));
4504 if (unlink (new_filename) != 0)
4505 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4506 new_filename, g_strerror (errno));
4508 if (rename (new_filename, old_filename) != 0)
4509 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4510 new_filename, old_filename,
4511 g_strerror (errno));
4515 g_free (new_filename);
4519 main(int argc, char *argv[])
4521 parse_options(argc, argv);
4524 yyin = popen(m4_commandline, "r");
4526 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4530 } else if(filename) {
4531 yyin = fopen(filename, "r");
4533 fprintf(stderr, "Error: can't open file '%s'\n",
4542 /* This is where parsing is done */
4545 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4547 /* close input file */
4548 if(use_m4) pclose(yyin);
4553 error_print (GOB_ERROR, 0, "no class defined");
4556 exit_on_error = FALSE;
4558 signals = count_signals ((Class *)class);
4559 set_properties = count_set_properties ((Class *)class) +
4560 count_set_arguments ((Class *)class);
4561 get_properties = count_get_properties ((Class *)class) +
4562 count_get_arguments ((Class *)class);
4563 overrides = count_overrides ((Class *)class);
4564 privates = count_privates ((Class *)class);
4565 protecteds = count_protecteds ((Class *)class);
4566 unreftors = count_unreftors ((Class *)class);
4567 destructors = count_destructors ((Class *)class);
4568 initializers = count_initializers ((Class *)class);
4569 glade_widgets = count_glade_widgets ((Class *)class);
4570 overrode_get_type = find_get_type ((Class *)class);
4573 make_inits ((Class *)class);
4575 find_constructor ((Class *)class);
4576 if (user_constructor != NULL)
4577 need_constructor = TRUE;
4579 find_dispose ((Class *)class);
4580 if (unreftors > 0 ||
4581 dispose_handler != NULL ||
4582 user_dispose_method != NULL)
4583 need_dispose = TRUE;
4585 find_finalize ((Class *)class);
4586 if (destructors > 0 ||
4588 user_finalize_method != NULL) {
4589 need_finalize = TRUE;
4592 check_bad_symbols ((Class *)class);
4593 check_duplicate_symbols ((Class *)class);
4594 check_duplicate_overrides ((Class *)class);
4595 check_duplicate_signals_args ((Class *)class);
4596 check_public_new ((Class *)class);
4597 check_vararg ((Class *)class);
4598 check_firstarg ((Class *)class);
4599 check_nonvoidempty ((Class *)class);
4600 check_signal_args ((Class *)class);
4601 check_property_types ((Class *)class);
4602 check_argument_types ((Class *)class);
4603 check_func_arg_checks ((Class *)class);
4604 check_func_attrs ((Class *)class);
4605 check_for_class_destructors ((Class *)class);
4607 exit_on_error = TRUE;
4612 any_special = setup_special_array ((Class *)class, special_array);
4616 generate_outfiles ();
4627 compare_and_move (outfilebase);
4629 compare_and_move (outfilephbase);
4631 if (no_touch_headers)
4632 compare_and_move (outfilehbase);