2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2004 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_dispose = FALSE;
96 static Method * dispose_handler = NULL;
98 static gboolean need_finalize = FALSE;
99 static Method * finalize_handler = NULL;
105 gboolean no_touch = FALSE;
106 gboolean no_touch_headers = FALSE;
107 gboolean for_cpp = FALSE;
108 gboolean no_gnu = FALSE;
109 gboolean exit_on_warn = FALSE;
110 gboolean exit_on_error = TRUE;
111 gboolean got_error = FALSE;
112 gint private_header = PRIVATE_HEADER_ONDEMAND;
113 gboolean no_extern_c = FALSE;
114 gboolean no_write = FALSE;
115 gboolean no_lines = FALSE;
116 gboolean no_self_alias = FALSE;
117 gboolean always_private_struct = FALSE;
120 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
121 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
122 char *m4_commandline = NULL;
123 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
124 #define M4_BASE_FILENAME "gobm4.m4"
125 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
126 #define M4_COMMANDLINE "m4"
128 int method_unique_id = 1;
133 filebase = replace_sep (((Class *)class)->otype, file_sep);
134 gob_strdown (filebase);
136 if (output_dir != NULL &&
137 output_dir[0] != '\0') {
138 fullfilebase = g_build_filename (output_dir, filebase, NULL);
140 fullfilebase = g_strdup (filebase);
143 funcbase = replace_sep (((Class *)class)->otype, '_');
144 gob_strdown (funcbase);
146 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
147 gob_strdown (pfuncbase);
149 macrobase = replace_sep (((Class *)class)->otype, '_');
150 gob_strup (macrobase);
152 macrois = make_pre_macro (((Class *)class)->otype, "IS");
153 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
155 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
156 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
158 typebase = remove_sep (((Class *)class)->otype);
160 ptypebase = remove_sep (((Class *)class)->ptype);
164 get_gtk_doc (const char *id)
171 val = g_hash_table_lookup(gtk_doc_hash, id);
173 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
175 val = g_hash_table_lookup(gtk_doc_hash, id);
177 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
183 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
187 s = get_type(t, postfix_to_stars);
188 out_printf(fp, "%s", s);
194 print_method (FILE *fp,
195 const char *typeprefix,
196 const char *nameprefix,
197 const char *subnameprefix,
198 const char *namepostfix,
199 const char *afterargs,
202 gboolean one_arg_per_line,
203 gboolean no_funcbase,
204 gboolean kill_underscore,
205 gboolean first_unused,
211 out_printf(fp, "%s", typeprefix);
212 print_type(fp, m->mtype, TRUE);
217 out_printf(fp, "%s%s%s%s(",
218 nameprefix, subnameprefix, id, namepostfix);
220 out_printf(fp, "%s%s_%s%s%s(",
221 nameprefix, funcbase, subnameprefix, id,
225 for(li=m->args; li; li=g_list_next(li)) {
226 FuncArg *arg = li->data;
227 const char *unused = "";
230 ! for_cpp && /* g++ has a cow with this */
233 unused = " G_GNUC_UNUSED";
236 print_type(fp, arg->atype, FALSE);
238 out_printf (fp, "___fake___");
240 out_printf(fp, "%s%s%s,%s", arg->name,
241 arg->atype->postfix ?
242 arg->atype->postfix : "",
244 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
246 out_printf(fp, "%s%s%s", arg->name,
247 arg->atype->postfix ?
248 arg->atype->postfix : "",
252 out_printf(fp, ",%s...",
253 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
255 out_printf(fp, "void");
257 out_printf(fp, "%s)%s", afterargs, postfix);
261 any_method_to_alias(Class *c)
265 for(li=c->nodes;li;li=g_list_next(li)) {
266 Node *node = li->data;
267 if(node->type == METHOD_NODE) {
268 Method *m = (Method *)node;
270 if(m->method == INIT_METHOD ||
271 m->method == CLASS_INIT_METHOD ||
272 m->method == OVERRIDE_METHOD)
283 make_method_aliases (Class *c)
287 for(li = c->nodes; li != NULL; li = li->next) {
288 Node *node = li->data;
289 if(node->type == METHOD_NODE) {
290 Method *m = (Method *)node;
292 if(m->method == INIT_METHOD ||
293 m->method == CLASS_INIT_METHOD ||
294 m->method == OVERRIDE_METHOD)
297 out_printf (out, "#define self_%s %s_%s\n",
306 add_bad_hack_to_avoid_unused_warnings(const Class *c)
310 /* if we haven't had any methods, just return */
315 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
317 "/*REALLY BAD HACK\n"
318 " This is to avoid unused warnings if you don't call\n"
319 " some method. I need to find a better way to do\n"
320 " this, not needed in GCC since we use some gcc\n"
321 " extentions to make saner, faster code */\n"
323 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
325 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
326 for(li=c->nodes;li;li=g_list_next(li)) {
327 Node *node = li->data;
328 if(node->type == METHOD_NODE) {
329 Method *m = (Method *)node;
331 if(m->method == INIT_METHOD ||
332 m->method == CLASS_INIT_METHOD ||
333 m->method == OVERRIDE_METHOD)
336 /* in C++ mode we don't alias new */
337 if(for_cpp && strcmp(m->id, "new")==0)
340 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
343 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
346 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
348 out_printf(out, "}\n\n");
352 put_variable(const Variable *v, FILE *fp)
354 out_printf(fp, "\t");
355 print_type(fp, v->vtype, FALSE);
356 out_printf(fp, "%s%s;", v->id,
358 v->vtype->postfix:"");
359 if(v->scope == PROTECTED_SCOPE)
360 out_printf(fp, " /* protected */");
361 out_printf(fp, "\n");
365 put_vs_method(const Method *m)
367 if(m->method != SIGNAL_LAST_METHOD &&
368 m->method != SIGNAL_FIRST_METHOD &&
369 m->method != VIRTUAL_METHOD)
372 /* if a signal mark it as such */
373 if(m->method != VIRTUAL_METHOD)
374 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
375 m, FALSE, TRUE, TRUE, FALSE, FALSE);
377 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
378 m, FALSE, TRUE, TRUE, FALSE, FALSE);
382 put_pub_method(const Method *m)
384 if(m->scope != PUBLIC_SCOPE)
387 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
388 TRUE, FALSE, TRUE, FALSE, FALSE);
392 put_signal_macro (const Method *m, gboolean gnu)
394 if(m->method != SIGNAL_LAST_METHOD &&
395 m->method != SIGNAL_FIRST_METHOD)
400 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
401 "g_signal_connect(%s(object),\"%s\","
402 "(GCallback)(func),(data))\n",
403 funcbase, m->id, macrobase, m->id);
406 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
407 "g_signal_connect_after(%s(object),\"%s\","
408 "(GCallback)(func),(data))\n",
409 funcbase, m->id, macrobase, m->id);
412 out_printf (outh, "#define %s_connect_data__%s"
413 "(object,func,data,destroy_data,flags)\t"
414 "g_signal_connect_data(%s(object),\"%s\","
415 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
416 funcbase, m->id, macrobase, m->id);
419 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
421 "%s(__extension__ ({%s *___object = (object); ___object; })),"
423 "(GCallback) __extension__ ({",
424 funcbase, m->id, macrobase, typebase, m->id);
425 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
426 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
427 out_printf (outh, "___%s; }), (data))\n", m->id);
430 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
431 "g_signal_connect_after("
432 "%s(__extension__ ({%s *___object = (object); ___object; })),"
434 "(GCallback) __extension__ ({",
435 funcbase, m->id, macrobase, typebase, m->id);
436 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
437 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
438 out_printf (outh, "___%s; }), (data))\n", m->id);
441 out_printf (outh, "#define %s_connect_data__%s"
442 "(object,func,data,destroy_data,flags)\t"
443 "g_signal_connect_data("
444 "%s(__extension__ ({%s *___object = (object); ___object; })),"
446 "(GCallback) __extension__ ({",
447 funcbase, m->id, macrobase, typebase, m->id);
448 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
449 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
450 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
455 put_signal_macros (const Class *c, gboolean gnu)
462 for (li = c->nodes; li != NULL; li = li->next) {
463 const Node *n = li->data;
464 if (n->type == METHOD_NODE)
465 put_signal_macro ((Method *)n, gnu);
470 put_local_signal_macro (const Method *m)
472 if(m->method != SIGNAL_LAST_METHOD &&
473 m->method != SIGNAL_FIRST_METHOD)
477 out_printf (out, "#define self_connect__%s(object,func,data)\t"
478 "%s_connect__%s((object),(func),(data))\n",
479 m->id, funcbase, m->id);
482 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
483 "%s_connect_after__%s((object),(func),(data))\n",
484 m->id, funcbase, m->id);
487 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
488 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
489 m->id, funcbase, m->id);
493 put_local_signal_macros (const Class *c)
500 for (li = c->nodes; li != NULL; li = li->next) {
501 const Node *n = li->data;
502 if (n->type == METHOD_NODE)
503 put_local_signal_macro ((Method *)n);
509 put_prot_method(const Method *m)
511 if(m->scope != PROTECTED_SCOPE)
515 print_method(outph, "", "\t", "", "\t", "", ";\n",
516 m, FALSE, FALSE, TRUE, FALSE, FALSE);
518 print_method(out, "", "\t", "", "\t", "", ";\n",
519 m, FALSE, FALSE, TRUE, FALSE, FALSE);
523 put_priv_method_prot(const Method *m)
525 if(m->method == SIGNAL_LAST_METHOD ||
526 m->method == SIGNAL_FIRST_METHOD ||
527 m->method == VIRTUAL_METHOD) {
530 "static ", "___real_", "", " ", "", ";\n",
531 m, FALSE, FALSE, TRUE, FALSE, FALSE);
533 /* no else, here, it might still have a private prototype, it's not
536 if((m->method == OVERRIDE_METHOD &&
539 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
540 print_method(out, "static ", s, "", " ", "",
541 no_gnu?";\n":" G_GNUC_UNUSED;\n",
542 m, FALSE, FALSE, FALSE, FALSE, FALSE);
544 } else if(m->scope == PRIVATE_SCOPE ||
545 m->method == INIT_METHOD ||
546 m->method == CLASS_INIT_METHOD) {
547 print_method(out, "static ", "", "", " ", "",
548 no_gnu?";\n":" G_GNUC_UNUSED;\n",
549 m, FALSE, FALSE, TRUE, FALSE, FALSE);
554 make_func_arg (const char *typename, gboolean is_class, const char *name)
561 tn = g_strconcat (typename, ":Class", NULL);
563 tn = g_strdup (typename);
565 type = node_new (TYPE_NODE,
569 node = node_new (FUNCARG_NODE,
570 "atype:steal", (Type *)type,
573 return g_list_prepend (NULL, node);
577 make_inits(Class *cl)
579 int got_class_init = FALSE;
580 int got_init = FALSE;
583 for(li=cl->nodes;li;li=g_list_next(li)) {
585 if(n->type == METHOD_NODE) {
586 Method *m = (Method *)n;
587 if(m->method == INIT_METHOD) {
589 error_print(GOB_ERROR, m->line_no, "init defined more then once");
591 } else if(m->method == CLASS_INIT_METHOD) {
593 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
594 got_class_init = TRUE;
598 if(!got_class_init) {
599 Type *type = (Type *)node_new (TYPE_NODE,
602 node = node_new (METHOD_NODE,
604 "method", CLASS_INIT_METHOD,
607 "args:steal", make_func_arg (cl->otype,
610 "unique_id", method_unique_id++,
612 cl->nodes = g_list_prepend(cl->nodes, node);
615 Type *type = (Type *)node_new (TYPE_NODE,
618 node = node_new (METHOD_NODE,
620 "method", INIT_METHOD,
623 "args:steal", make_func_arg (cl->otype,
624 FALSE /* is_class */,
626 "unique_id", method_unique_id++,
628 cl->nodes = g_list_prepend(cl->nodes, node);
633 find_dispose(const Class *cl)
637 dispose_handler = NULL;
638 for(li=cl->nodes;li;li=g_list_next(li)) {
640 if(n->type == METHOD_NODE) {
641 Method *m = (Method *)n;
642 if(m->method == OVERRIDE_METHOD &&
643 strcmp(m->id, "dispose")==0) {
644 if(strcmp(m->otype, "G:Object") != 0) {
645 error_print(GOB_ERROR, m->line_no,
646 "dispose method override "
647 "of class other then "
650 if(g_list_length(m->args) != 1) {
651 error_print(GOB_ERROR, m->line_no,
652 "dispose method override "
653 "with more then one "
664 find_finalize(const Class *cl)
668 finalize_handler = NULL;
669 for(li=cl->nodes;li;li=g_list_next(li)) {
671 if(n->type == METHOD_NODE) {
672 Method *m = (Method *)n;
673 if(m->method == OVERRIDE_METHOD &&
674 strcmp(m->id, "finalize")==0) {
675 if(strcmp(m->otype, "G:Object") != 0) {
676 error_print(GOB_ERROR, m->line_no,
677 "finalize method override "
678 "of class other then "
681 if(g_list_length(m->args) != 1) {
682 error_print(GOB_ERROR, m->line_no,
683 "finalize method override "
684 "with more then one "
687 finalize_handler = m;
695 /* hash of method -> name of signal prototype */
696 static GHashTable *marsh = NULL;
698 /* list of methods with different signal prototypes,
699 we check this list if we can use a signal prototype of a
700 previous signal method, there are only uniques here */
701 static GList *eq_signal_methods = NULL;
703 /* compare a list of strings */
705 is_list_equal(const GList *a, const GList *b)
707 for(;a && b; a=a->next, b=b->next) {
708 if(strcmp(a->data, b->data)!=0) {
712 /* the the lists were different length */
719 find_same_type_signal(const Method *m)
722 for(li=eq_signal_methods;li;li=li->next) {
723 Method *mm = li->data;
724 if(is_list_equal(mm->gtktypes, m->gtktypes))
731 print_signal_marsal_args (const Method *m)
733 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
736 for (i = 0, li = m->gtktypes->next;
738 i++, li = li->next) {
741 if (strcmp (li->data, "UNICHAR") == 0)
742 /* hack because glib is braindamaged */
743 get_func = g_strdup ("g_value_get_uint");
744 else if (strncmp(li->data, "BOXED_", 6) == 0)
745 get_func = g_strdup ("g_value_get_boxed");
747 get_func = g_strdup_printf
748 ("g_value_get_%s", (char *)li->data);
750 gob_strdown (get_func);
751 out_printf (out, ",\n\t\t(%s) "
752 "%s (param_values + %d)",
753 get_cast (li->data, FALSE),
758 out_printf (out, ",\n\t\tdata2);\n");
763 add_signal_prots(Method *m)
769 gboolean ret_none = FALSE;
770 gboolean arglist_none = FALSE;
772 const char *unused = "";
774 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
775 unused = " G_GNUC_UNUSED";
778 if (m->method != SIGNAL_LAST_METHOD &&
779 m->method != SIGNAL_FIRST_METHOD)
783 marsh = g_hash_table_new(NULL, NULL);
785 g_assert (m->gtktypes->next != NULL);
787 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
788 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
790 if (ret_none && arglist_none)
793 /* if we already did a signal prototype just use that */
794 mm = find_same_type_signal (m);
796 s = g_hash_table_lookup (marsh, mm);
797 g_hash_table_insert (marsh, m, s);
804 retcast = get_cast (m->gtktypes->data, FALSE);
806 s = g_strdup_printf("Sig%d", sig++);
808 g_hash_table_insert(marsh, m, s);
809 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
811 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
812 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
813 get_cast(m->gtktypes->data, FALSE), s, typebase);
815 if ( ! arglist_none) {
816 for (li = m->gtktypes->next; li != NULL; li = li->next)
817 out_printf (out, "%s, ", get_cast (li->data, FALSE));
819 out_printf (out, "gpointer);\n");
821 out_printf (out, "\nstatic void\n"
822 "___marshal_%s (GClosure *closure,\n"
823 "\tGValue *return_value%s,\n"
824 "\tguint n_param_values,\n"
825 "\tconst GValue *param_values,\n"
826 "\tgpointer invocation_hint%s,\n"
827 "\tgpointer marshal_data)\n"
834 out_printf (out, "\t%s v_return;\n", retcast);
836 out_printf (out, "\tregister ___%s callback;\n"
837 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
838 "\tregister gpointer data1, data2;\n\n",
841 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
842 arglist_none ? 1 : g_list_length (m->gtktypes));
845 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
846 "\t\tdata1 = closure->data;\n"
847 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
849 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
850 "\t\tdata2 = closure->data;\n"
853 out_printf (out, "\tcallback = (___%s) "
854 "(marshal_data != NULL ? marshal_data : cc->callback);"
858 out_printf (out, "\tcallback ((%s *)data1", typebase);
860 out_printf (out, "\tv_return = callback ((%s *)data1",
864 print_signal_marsal_args (m);
867 /* FIXME: This code is so fucking ugly it hurts */
868 gboolean take_ownership =
869 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
870 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
874 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
875 /* hack because glib is braindamaged */
876 set_func = g_strdup ("g_value_set_uint");
878 set_func = g_strdup_printf ("g_value_set_%s%s",
879 (char *)m->gtktypes->data,
881 "_take_ownership" : "");
882 gob_strdown (set_func);
884 out_printf (out, "\n\t%s (return_value, v_return);\n",
889 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
891 out_printf (out, "\n\treturn_value = NULL;\n");
892 out_printf (out, "\tinvocation_hint = NULL;\n");
895 out_printf (out, "}\n\n");
902 out_printf(out, "\n");
904 out_printf(out, "enum {\n");
905 for(li=c->nodes;li;li=g_list_next(li)) {
907 if(n->type == METHOD_NODE) {
908 Method *m = (Method *)n;
909 if(m->method == SIGNAL_LAST_METHOD ||
910 m->method == SIGNAL_FIRST_METHOD) {
911 char *s = g_strdup(m->id);
913 out_printf(out, "\t%s_SIGNAL,\n", s);
918 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
920 if (set_properties > 0 ||
921 get_properties > 0) {
922 out_printf(out, "enum {\n\tPROP_0");
923 for(li=c->nodes;li;li=g_list_next(li)) {
925 if (n->type == PROPERTY_NODE) {
926 Property *p = (Property *)n;
927 char *s = g_strdup (p->name);
929 out_printf (out, ",\n\tPROP_%s", s);
931 } else if (n->type == ARGUMENT_NODE) {
932 Argument *a = (Argument *)n;
933 char *s = g_strdup(a->name);
935 out_printf(out, ",\n\tPROP_%s", s);
939 out_printf(out, "\n};\n\n");
944 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
946 out_printf(out, "/* pointer to the class of our parent */\n");
947 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
951 add_interface_methods (Class *c, const char *interface)
954 gboolean added_line = FALSE;
956 for (li = c->nodes; li != NULL; li = li->next) {
958 Method *m = (Method *)n;
959 if (n->type != METHOD_NODE ||
960 m->method == OVERRIDE_METHOD ||
961 m->interface == NULL ||
962 strcmp (m->interface, interface) != 0)
965 if (m->line_no > 0) {
966 out_addline_infile (out, m->line_no);
968 } else if (m->line_no == 0 &&
970 out_addline_outfile (out);
973 out_printf (out, "\tiface->%s = self_%s;\n",
977 out_addline_outfile (out);
981 add_interface_inits (Class *c)
985 if (c->interfaces == NULL)
988 out_printf(out, "\n");
990 for (li = c->interfaces; li != NULL; li = li->next) {
991 const char *interface = li->data;
993 char *name = replace_sep (interface, '_');
994 char *type = remove_sep (interface);
996 /* EEEK! evil, we should have some sort of option
997 * to force this for arbitrary interfaces, since
998 * some are Class and some are Iface. Glib is shite
1000 if (strcmp (type, "GtkEditable") == 0 ||
1001 strcmp (type, "GTypePlugin") == 0)
1004 /* We'll assume Iface is the standard ending */
1007 out_printf (out, "\nstatic void\n"
1008 "___%s_init (%s%s *iface)\n"
1012 add_interface_methods (c, interface);
1014 out_printf (out, "}\n\n");
1022 add_interface_infos (void)
1025 for (li = ((Class *)class)->interfaces;
1028 char *name = replace_sep (li->data, '_');
1030 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1031 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1041 add_interfaces (void)
1044 for (li = ((Class *)class)->interfaces;
1047 char *name = replace_sep (li->data, '_');
1048 char *type = make_pre_macro (li->data, "TYPE");
1051 "\t\tg_type_add_interface_static (type,\n"
1053 "\t\t\t&%s_info);\n",
1065 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1069 "%s_get_type (void)\n"
1071 "\tstatic GType type = 0;\n\n"
1072 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1073 "\t\tstatic const GTypeInfo info = {\n"
1074 "\t\t\tsizeof (%sClass),\n"
1075 "\t\t\t(GBaseInitFunc) NULL,\n"
1076 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1077 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1078 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1079 "\t\t\tNULL /* class_data */,\n"
1080 "\t\t\tsizeof (%s),\n"
1081 "\t\t\t%d /* n_preallocs */,\n"
1082 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1085 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1087 add_interface_infos ();
1090 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
1091 pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1099 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1101 chunk_size, chunk_size);
1111 add_bonobo_object_get_type (void)
1113 /* char *chunk_size = ((Class*)class)->chunk_size; */
1114 /* _vicious_ spanks seth with a rusty nail
1116 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1117 "gob2 doesn't officially support it yet. It'd be safer "
1118 "and a lot more fun to blow goats.\"\n");
1123 "%s_get_type (void)\n" /* 1 */
1125 "\tstatic GType type = 0;\n\n"
1126 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1127 "\t\tstatic const GTypeInfo info = {\n"
1128 "\t\t\tsizeof (%sClass),\n" /* 2 */
1129 "\t\t\t(GBaseInitFunc) NULL,\n"
1130 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1131 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1132 "\t\t\tNULL, /* class_finalize */\n"
1133 "\t\t\tNULL, /* class_data */\n"
1134 "\t\t\tsizeof (%s),\n" /* 4 */
1135 "\t\t\t0, /* n_preallocs */\n"
1136 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1145 add_interface_infos ();
1148 "\t\ttype = bonobo_type_unique (\n"
1149 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1150 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1151 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1152 "\t\t\t&info, \"%s\");\n", /* 3 */
1153 ((Class*)class)->bonobo_object_class /* 1 */,
1162 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1164 chunk_size, chunk_size);
1173 add_overrides(Class *c, const char *oname,
1174 gboolean did_base_obj)
1180 done = g_hash_table_new (g_str_hash, g_str_equal);
1182 s = g_strdup ("GObject");
1183 g_hash_table_insert (done, s, s);
1185 for (li = c->nodes; li != NULL; li = li->next) {
1188 Method *m = (Method *)n;
1189 if(n->type != METHOD_NODE ||
1190 m->method != OVERRIDE_METHOD)
1193 s = remove_sep(m->otype);
1195 if(g_hash_table_lookup(done, s)) {
1199 g_hash_table_insert(done, s, s);
1201 f = replace_sep(m->otype, '_');
1204 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1209 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1210 g_hash_table_destroy (done);
1214 make_run_signal_flags(Method *m, gboolean last)
1229 gs = g_string_new(NULL);
1232 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1234 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1236 if(m->scope == PUBLIC_SCOPE)
1237 g_string_append(gs, " | G_SIGNAL_ACTION");
1239 for(li = m->flags; li; li = li->next) {
1240 char *flag = li->data;
1242 for(i=0;flags[i];i++) {
1243 if(strcmp(flags[i], flag)==0)
1246 /* if we haven't found it in our list */
1248 error_printf(GOB_WARN, m->line_no,
1249 "Unknown flag '%s' used, "
1250 "perhaps it was misspelled",
1253 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1257 char *ret = gs->str;
1258 g_string_free(gs, FALSE);
1265 add_signals(Class *c)
1269 out_printf(out, "\n");
1270 for(li=c->nodes;li;li=g_list_next(li)) {
1272 char *mar, *sig, *flags;
1273 gboolean is_none, last = FALSE;
1274 Method *m = (Method *)n;
1276 if(n->type != METHOD_NODE ||
1277 (m->method != SIGNAL_FIRST_METHOD &&
1278 m->method != SIGNAL_LAST_METHOD))
1281 if(m->method == SIGNAL_FIRST_METHOD)
1286 if(g_hash_table_lookup(marsh, m))
1287 mar = g_strconcat("___marshal_",
1288 (char *)g_hash_table_lookup(marsh, m),
1291 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1293 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1295 sig = g_strdup (m->id);
1297 flags = make_run_signal_flags (m, last);
1298 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1299 "\t\tg_signal_new (\"%s\",\n"
1300 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1301 "\t\t\t(GSignalFlags)(%s),\n"
1302 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1303 "\t\t\tNULL, NULL,\n"
1305 "\t\t\tG_TYPE_%s, %d",
1308 typebase, m->id, mar,
1309 (char *)m->gtktypes->data,
1310 is_none ? 0 : g_list_length(m->gtktypes->next));
1318 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1319 char *str = l->data;
1320 if (strncmp (str, "BOXED_", 6) == 0)
1321 t = g_strdup (&(str[6]));
1323 t = g_strconcat ("G_TYPE_", str, NULL);
1324 out_printf (out, ",\n\t\t\t%s", t);
1329 out_printf(out, ");\n");
1331 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1334 out_printf(out, "\tif ___GOB_UNLIKELY(");
1335 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1336 out_printf(out, "sizeof(");
1337 print_type(out, m->mtype, FALSE);
1338 out_printf(out, "%s",
1340 m->mtype->postfix : "");
1341 out_printf(out, ") != sizeof(%s) || ",
1342 get_cast(m->gtktypes->data, FALSE));
1345 for(al = m->args->next, gl = m->gtktypes->next;
1346 al != NULL && gl != NULL;
1347 al = al->next, gl = gl->next) {
1348 FuncArg *arg = al->data;
1349 char *gtkarg = gl->data;
1351 out_printf(out, "sizeof(");
1352 print_type(out, arg->atype, FALSE);
1353 out_printf(out, "%s",
1354 arg->atype->postfix ?
1355 arg->atype->postfix : "");
1356 out_printf(out, ") != sizeof(%s) || ",
1357 get_cast(gtkarg, FALSE));
1361 "parent_class == NULL /* avoid warning */");
1363 out_printf(out, ") {\n"
1364 "\t\tg_error(\"%s line %d: Type mismatch "
1365 "of \\\"%s\\\" signal signature\");\n"
1367 filename, m->line_no, m->id);
1374 set_def_handlers(Class *c, const char *oname)
1377 gboolean set_line = FALSE;
1379 out_printf(out, "\n");
1380 for(li = c->nodes; li; li = g_list_next(li)) {
1382 Method *m = (Method *)n;
1384 if(n->type != METHOD_NODE ||
1385 (m->method != SIGNAL_FIRST_METHOD &&
1386 m->method != SIGNAL_LAST_METHOD &&
1387 m->method != VIRTUAL_METHOD &&
1388 m->method != OVERRIDE_METHOD))
1391 if(m->line_no > 0 && m->cbuf) {
1392 out_addline_infile(out, m->line_no);
1394 } else if(set_line) {
1395 out_addline_outfile(out);
1400 if (m->method == OVERRIDE_METHOD) {
1402 s = replace_sep (m->otype, '_');
1406 dispose_handler != NULL &&
1407 strcmp (m->id, "dispose") == 0)
1408 out_printf (out, "\tg_object_class->dispose "
1410 else if (need_finalize &&
1412 strcmp(m->id, "finalize") == 0)
1414 "\tg_object_class->finalize = ___finalize;\n");
1415 else if (m->cbuf != NULL)
1417 "\t%s_class->%s = ___%x_%s_%s;\n",
1418 s, m->id, (guint)m->unique_id,
1421 out_printf(out, "\t%s_class->%s = NULL;\n",
1425 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1429 out_printf(out, "\t%s->%s = NULL;\n",
1434 out_addline_outfile(out);
1438 make_argument (Argument *a)
1443 char *argflags[] = {
1451 flags = g_string_new ("(GParamFlags)(");
1453 if(a->get && a->set)
1454 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1456 g_string_append (flags, "G_PARAM_READABLE");
1458 g_string_append (flags, "G_PARAM_WRITABLE");
1460 g_assert(a->get || a->set);
1462 for (l = a->flags; l != NULL; l = l->next) {
1463 char *flag = l->data;
1465 if(strcmp (flag, "READABLE") == 0 ||
1466 strcmp (flag, "WRITABLE") == 0) {
1467 error_print(GOB_WARN, a->line_no,
1469 "WRITABLE argument flags are "
1470 "set automatically");
1473 for(i = 0; argflags[i]; i++) {
1474 if(strcmp(argflags[i], flag)==0)
1477 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1480 g_string_append (flags, ")");
1482 s = g_strdup(a->name);
1484 if (!strcmp (a->gtktype, "ENUM"))
1485 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1486 "\t\tG_TYPE_ENUM, 0,\n"
1488 a->name, flags->str);
1489 if (!strcmp (a->gtktype, "FLAGS"))
1490 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1491 "\t\tG_TYPE_FLAGS, 0,\n"
1493 a->name, flags->str);
1494 else if (!strcmp (a->gtktype, "OBJECT"))
1495 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1496 "\t\tG_TYPE_OBJECT,\n"
1498 a->name, flags->str);
1499 else if (!strcmp (a->gtktype, "STRING"))
1500 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1503 a->name, flags->str);
1504 else if (!strcmp (a->gtktype, "INT"))
1505 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1506 "\t\tG_MININT, G_MAXINT,\n"
1509 a->name, flags->str);
1510 else if (!strcmp (a->gtktype, "UINT"))
1511 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1512 "\t\t0, G_MAXUINT,\n"
1515 a->name, flags->str);
1516 else if (!strcmp (a->gtktype, "INT"))
1517 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1518 "\t\tG_MININT, G_MAXINT,\n"
1521 a->name, flags->str);
1522 else if (!strcmp (a->gtktype, "CHAR"))
1523 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1527 a->name, flags->str);
1528 else if (!strcmp (a->gtktype, "UCHAR"))
1529 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1533 a->name, flags->str);
1534 else if (!strcmp (a->gtktype, "BOOL") ||
1535 !strcmp (a->gtktype, "BOOLEAN"))
1536 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1539 a->name, flags->str);
1540 else if (!strcmp (a->gtktype, "LONG"))
1541 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1542 "\t\tG_MINLONG, G_MAXLONG,\n"
1545 a->name, flags->str);
1546 else if (!strcmp (a->gtktype, "ULONG"))
1547 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1548 "\t\t0, G_MAXULONG,\n"
1551 a->name, flags->str);
1552 else if (!strcmp (a->gtktype, "INT64"))
1553 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1554 "\t\tG_MININT64, G_MAXINT64,\n"
1557 a->name, flags->str);
1558 else if (!strcmp (a->gtktype, "UINT64"))
1559 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1560 "\t\t0, G_MAXUINT64,\n"
1563 a->name, flags->str);
1564 else if (!strcmp (a->gtktype, "FLOAT"))
1565 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1566 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1569 a->name, flags->str);
1570 else if (!strcmp (a->gtktype, "DOUBLE"))
1571 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1572 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1575 a->name, flags->str);
1576 else if (!strcmp (a->gtktype, "POINTER"))
1577 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1579 a->name, flags->str);
1581 error_printf (GOB_ERROR, a->line_no,
1582 "%s type is not supported for arguments, try using properties",
1585 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1586 "\t\tPROP_%s, param_spec);\n", s);
1590 g_string_free(flags, TRUE);
1593 #define value_for_print(str, alt) (str != NULL ? str : alt)
1596 make_property (Property *p)
1600 if (p->get == NULL && p->set == NULL) {
1601 error_print (GOB_ERROR, p->line_no,
1602 "Property has no getter nor setter");
1606 if (p->flags != NULL)
1607 error_print (GOB_WARN, p->line_no,
1608 "Overriden property, flags ignored");
1609 if (p->nick != NULL)
1610 error_print (GOB_WARN, p->line_no,
1611 "Overriden property, nick ignored");
1612 if (p->blurb != NULL)
1613 error_print (GOB_WARN, p->line_no,
1614 "Overriden property, blurb ignored");
1615 if (p->minimum != NULL)
1616 error_print (GOB_WARN, p->line_no,
1617 "Overriden property, minimum ignored");
1618 if (p->maximum != NULL)
1619 error_print (GOB_WARN, p->line_no,
1620 "Overriden property, maximum ignored");
1621 if (p->default_value != NULL)
1622 error_print (GOB_WARN, p->line_no,
1623 "Overriden property, default_value ignored");
1625 s = g_strdup (p->name);
1627 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1629 "\t\t\"%s\");\n", s, p->name);
1634 char *argflags[] = {
1642 flags = g_string_new ("(GParamFlags)(");
1644 if (p->get != NULL && p->set != NULL)
1645 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1646 else if (p->get != NULL)
1647 g_string_append (flags, "G_PARAM_READABLE");
1649 g_string_append (flags, "G_PARAM_WRITABLE");
1652 for (l = p->flags; l != NULL; l = l->next) {
1653 char *flag = l->data;
1655 if(strcmp (flag, "READABLE") == 0 ||
1656 strcmp (flag, "WRITABLE") == 0) {
1657 error_print(GOB_WARN, p->line_no,
1659 "WRITABLE argument flags are "
1660 "set automatically");
1663 for(i = 0; argflags[i]; i++) {
1664 if(strcmp(argflags[i], flag)==0)
1667 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1670 g_string_append (flags, ")");
1672 if (strcmp (p->gtktype, "CHAR") == 0) {
1673 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1674 "\t\t(\"%s\" /* name */,\n"
1675 "\t\t %s /* nick */,\n"
1676 "\t\t %s /* blurb */,\n"
1677 "\t\t %s /* minimum */,\n"
1678 "\t\t %s /* maximum */,\n"
1679 "\t\t %s /* default_value */,\n"
1682 value_for_print (p->nick, "NULL"),
1683 value_for_print (p->blurb, "NULL"),
1684 value_for_print (p->minimum, "-128"),
1685 value_for_print (p->maximum, "127"),
1686 value_for_print (p->default_value, "0"),
1688 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1689 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1690 "\t\t(\"%s\" /* name */,\n"
1691 "\t\t %s /* nick */,\n"
1692 "\t\t %s /* blurb */,\n"
1693 "\t\t %s /* minimum */,\n"
1694 "\t\t %s /* maximum */,\n"
1695 "\t\t %s /* default_value */,\n"
1698 value_for_print (p->nick, "NULL"),
1699 value_for_print (p->blurb, "NULL"),
1700 value_for_print (p->minimum, "0"),
1701 value_for_print (p->maximum, "0xFF"),
1702 value_for_print (p->default_value, "0"),
1704 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1705 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1706 "\t\t(\"%s\" /* name */,\n"
1707 "\t\t %s /* nick */,\n"
1708 "\t\t %s /* blurb */,\n"
1709 "\t\t %s /* default_value */,\n"
1712 value_for_print (p->nick, "NULL"),
1713 value_for_print (p->blurb, "NULL"),
1714 value_for_print (p->default_value, "FALSE"),
1716 } else if (strcmp (p->gtktype, "INT") == 0) {
1717 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1718 "\t\t(\"%s\" /* name */,\n"
1719 "\t\t %s /* nick */,\n"
1720 "\t\t %s /* blurb */,\n"
1721 "\t\t %s /* minimum */,\n"
1722 "\t\t %s /* maximum */,\n"
1723 "\t\t %s /* default_value */,\n"
1726 value_for_print (p->nick, "NULL"),
1727 value_for_print (p->blurb, "NULL"),
1728 value_for_print (p->minimum, "G_MININT"),
1729 value_for_print (p->maximum, "G_MAXINT"),
1730 value_for_print (p->default_value, "0"),
1732 } else if (strcmp (p->gtktype, "UINT") == 0) {
1733 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1734 "\t\t(\"%s\" /* name */,\n"
1735 "\t\t %s /* nick */,\n"
1736 "\t\t %s /* blurb */,\n"
1737 "\t\t %s /* minimum */,\n"
1738 "\t\t %s /* maximum */,\n"
1739 "\t\t %s /* default_value */,\n"
1742 value_for_print (p->nick, "NULL"),
1743 value_for_print (p->blurb, "NULL"),
1744 value_for_print (p->minimum, "0"),
1745 value_for_print (p->maximum, "G_MAXUINT"),
1746 value_for_print (p->default_value, "0"),
1748 } else if (strcmp (p->gtktype, "LONG") == 0) {
1749 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1750 "\t\t(\"%s\" /* name */,\n"
1751 "\t\t %s /* nick */,\n"
1752 "\t\t %s /* blurb */,\n"
1753 "\t\t %s /* minimum */,\n"
1754 "\t\t %s /* maximum */,\n"
1755 "\t\t %s /* default_value */,\n"
1758 value_for_print (p->nick, "NULL"),
1759 value_for_print (p->blurb, "NULL"),
1760 value_for_print (p->minimum, "G_MINLONG"),
1761 value_for_print (p->maximum, "G_MAXLONG"),
1762 value_for_print (p->default_value, "0"),
1764 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1765 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1766 "\t\t(\"%s\" /* name */,\n"
1767 "\t\t %s /* nick */,\n"
1768 "\t\t %s /* blurb */,\n"
1769 "\t\t %s /* minimum */,\n"
1770 "\t\t %s /* maximum */,\n"
1771 "\t\t %s /* default_value */,\n"
1774 value_for_print (p->nick, "NULL"),
1775 value_for_print (p->blurb, "NULL"),
1776 value_for_print (p->minimum, "0"),
1777 value_for_print (p->maximum, "G_MAXULONG"),
1778 value_for_print (p->default_value, "0"),
1780 } else if (strcmp (p->gtktype, "INT64") == 0) {
1781 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1782 "\t\t(\"%s\" /* name */,\n"
1783 "\t\t %s /* nick */,\n"
1784 "\t\t %s /* blurb */,\n"
1785 "\t\t %s /* minimum */,\n"
1786 "\t\t %s /* maximum */,\n"
1787 "\t\t %s /* default_value */,\n"
1790 value_for_print (p->nick, "NULL"),
1791 value_for_print (p->blurb, "NULL"),
1792 value_for_print (p->minimum, "G_MININT64"),
1793 value_for_print (p->maximum, "G_MAXINT64"),
1794 value_for_print (p->default_value, "0"),
1796 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1797 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1798 "\t\t(\"%s\" /* name */,\n"
1799 "\t\t %s /* nick */,\n"
1800 "\t\t %s /* blurb */,\n"
1801 "\t\t %s /* minimum */,\n"
1802 "\t\t %s /* maximum */,\n"
1803 "\t\t %s /* default_value */,\n"
1806 value_for_print (p->nick, "NULL"),
1807 value_for_print (p->blurb, "NULL"),
1808 value_for_print (p->minimum, "0"),
1809 value_for_print (p->maximum, "G_MAXUINT64"),
1810 value_for_print (p->default_value, "0"),
1812 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1813 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1814 "\t\t(\"%s\" /* name */,\n"
1815 "\t\t %s /* nick */,\n"
1816 "\t\t %s /* blurb */,\n"
1817 "\t\t %s /* default_value */,\n"
1820 value_for_print (p->nick, "NULL"),
1821 value_for_print (p->blurb, "NULL"),
1822 value_for_print (p->default_value, "0"),
1824 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1825 char *type = make_me_type (p->extra_gtktype,
1827 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1828 "\t\t(\"%s\" /* name */,\n"
1829 "\t\t %s /* nick */,\n"
1830 "\t\t %s /* blurb */,\n"
1831 "\t\t %s /* enum_type */,\n"
1832 "\t\t %s /* default_value */,\n"
1835 value_for_print (p->nick, "NULL"),
1836 value_for_print (p->blurb, "NULL"),
1838 value_for_print (p->default_value, "0"),
1841 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1842 char *type = make_me_type (p->extra_gtktype,
1844 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1845 "\t\t(\"%s\" /* name */,\n"
1846 "\t\t %s /* nick */,\n"
1847 "\t\t %s /* blurb */,\n"
1848 "\t\t %s /* flags_type */,\n"
1849 "\t\t %s /* default_value */,\n"
1852 value_for_print (p->nick, "NULL"),
1853 value_for_print (p->blurb, "NULL"),
1855 value_for_print (p->default_value, "0"),
1858 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1859 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1860 "\t\t(\"%s\" /* name */,\n"
1861 "\t\t %s /* nick */,\n"
1862 "\t\t %s /* blurb */,\n"
1863 "\t\t %s /* minimum */,\n"
1864 "\t\t %s /* maximum */,\n"
1865 "\t\t %s /* default_value */,\n"
1868 value_for_print (p->nick, "NULL"),
1869 value_for_print (p->blurb, "NULL"),
1870 value_for_print (p->minimum, "G_MINFLOAT"),
1871 value_for_print (p->maximum, "G_MAXFLOAT"),
1872 value_for_print (p->default_value, "0.0"),
1874 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1875 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1876 "\t\t(\"%s\" /* name */,\n"
1877 "\t\t %s /* nick */,\n"
1878 "\t\t %s /* blurb */,\n"
1879 "\t\t %s /* minimum */,\n"
1880 "\t\t %s /* maximum */,\n"
1881 "\t\t %s /* default_value */,\n"
1884 value_for_print (p->nick, "NULL"),
1885 value_for_print (p->blurb, "NULL"),
1886 value_for_print (p->minimum, "G_MINDOUBLE"),
1887 value_for_print (p->maximum, "G_MAXDOUBLE"),
1888 value_for_print (p->default_value, "0.0"),
1890 } else if (strcmp (p->gtktype, "STRING") == 0) {
1891 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1892 "\t\t(\"%s\" /* name */,\n"
1893 "\t\t %s /* nick */,\n"
1894 "\t\t %s /* blurb */,\n"
1895 "\t\t %s /* default_value */,\n"
1898 value_for_print (p->nick, "NULL"),
1899 value_for_print (p->blurb, "NULL"),
1900 value_for_print (p->default_value, "NULL"),
1902 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1903 char *type = make_me_type (p->extra_gtktype,
1905 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1906 "\t\t(\"%s\" /* name */,\n"
1907 "\t\t %s /* nick */,\n"
1908 "\t\t %s /* blurb */,\n"
1909 "\t\t %s /* param_type */,\n"
1912 value_for_print (p->nick, "NULL"),
1913 value_for_print (p->blurb, "NULL"),
1917 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1918 char *type = make_me_type (p->extra_gtktype,
1920 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1921 "\t\t(\"%s\" /* name */,\n"
1922 "\t\t %s /* nick */,\n"
1923 "\t\t %s /* blurb */,\n"
1924 "\t\t %s /* boxed_type */,\n"
1927 value_for_print (p->nick, "NULL"),
1928 value_for_print (p->blurb, "NULL"),
1932 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1933 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1934 "\t\t(\"%s\" /* name */,\n"
1935 "\t\t %s /* nick */,\n"
1936 "\t\t %s /* blurb */,\n"
1939 value_for_print (p->nick, "NULL"),
1940 value_for_print (p->blurb, "NULL"),
1942 /* FIXME: VALUE_ARRAY */
1943 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1944 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1945 "\t\t(\"%s\" /* name */,\n"
1946 "\t\t %s /* nick */,\n"
1947 "\t\t %s /* blurb */,\n"
1950 value_for_print (p->nick, "NULL"),
1951 value_for_print (p->blurb, "NULL"),
1953 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
1954 char *type = make_me_type (p->extra_gtktype,
1956 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1957 "\t\t(\"%s\" /* name */,\n"
1958 "\t\t %s /* nick */,\n"
1959 "\t\t %s /* blurb */,\n"
1960 "\t\t %s /* object_type */,\n"
1963 value_for_print (p->nick, "NULL"),
1964 value_for_print (p->blurb, "NULL"),
1969 error_printf (GOB_ERROR, p->line_no,
1970 "%s type is not supported by properties",
1974 s = g_strdup (p->name);
1976 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1978 "\t\tparam_spec);\n", s);
1981 g_string_free (flags, TRUE);
1986 make_arguments(Class *c)
1989 if (get_properties > 0)
1990 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1991 if (set_properties > 0)
1992 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1993 out_printf (out, " {\n");
1994 for (li = c->nodes; li != NULL; li = li->next) {
1996 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
1997 || n->type == ARGUMENT_NODE) {
1998 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2003 for (li = c->nodes; li != NULL; li = li->next) {
2005 if (n->type == PROPERTY_NODE)
2006 make_property ((Property *)n);
2007 else if (n->type == ARGUMENT_NODE)
2008 make_argument ((Argument *)n);
2010 out_printf(out, " }\n");
2014 print_initializer(Method *m, Variable *v)
2021 if(v->initializer == NULL)
2024 if(v->scope == PRIVATE_SCOPE)
2025 root = g_strconcat(((FuncArg *)m->args->data)->name,
2028 root = g_strdup(((FuncArg *)m->args->data)->name);
2030 if(v->initializer_line > 0)
2031 out_addline_infile(out, v->initializer_line);
2033 if (v->initializer_simple)
2034 out_printf(out, "\t%s->%s = %s;\n",
2035 root, v->id, v->initializer);
2036 else if (!strcmp(v->id, "_glade_xml"))
2037 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2039 out_printf(out,v->initializer);
2041 if(v->initializer_line > 0)
2042 out_addline_outfile(out);
2048 print_glade_widget(Method *m, Variable *v)
2053 if(!v->glade_widget)
2056 if(v->scope == PRIVATE_SCOPE)
2057 root = g_strconcat(((FuncArg *)m->args->data)->name,
2060 root = g_strdup(((FuncArg *)m->args->data)->name);
2062 cast = get_type(v->vtype, FALSE);
2063 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2064 root, v->id, cast, root, v->id);
2070 print_destructor (Variable *v)
2074 if(v->destructor == NULL)
2077 if(v->scope == PRIVATE_SCOPE)
2078 root = "self->_priv";
2082 if(v->destructor_simple) {
2083 if(v->destructor_line > 0)
2084 out_addline_infile(out, v->destructor_line);
2087 out_printf(out, "\tif(%s->%s) { "
2088 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2089 "%s->%s = NULL; }\n",
2090 root, v->id, v->destructor, root, v->id,
2093 out_printf(out, "\tif(%s->%s) { "
2094 "%s ((gpointer) %s->%s); "
2095 "%s->%s = NULL; }\n",
2096 root, v->id, v->destructor, root, v->id,
2100 if(v->destructor_line > 0)
2101 out_addline_outfile(out);
2103 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2104 out_printf(out, "#define VAR %s\n", v->id);
2105 out_printf(out, "\t{\n");
2106 if(v->destructor_line > 0)
2107 out_addline_infile(out, v->destructor_line);
2109 out_printf(out, "\t%s}\n", v->destructor);
2111 if(v->destructor_line > 0)
2112 out_addline_outfile(out);
2113 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
2115 out_printf(out, "#undef VAR\n");
2116 out_printf(out, "#undef %s\n", v->id);
2121 add_dispose (Class *c)
2123 out_printf(out, "\nstatic void\n"
2124 "___dispose (GObject *obj_self)\n"
2127 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2130 if (unreftors > 0) {
2131 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2133 ! no_gnu ? " G_GNUC_UNUSED" : "",
2137 if (dispose_handler != NULL) {
2138 /* so we get possible bad argument warning */
2139 if (dispose_handler->line_no > 0)
2140 out_addline_infile (out, dispose_handler->line_no);
2141 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2142 (guint)dispose_handler->unique_id, funcbase);
2143 if (dispose_handler->line_no > 0)
2144 out_addline_outfile (out);
2147 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2148 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2151 if (unreftors > 0) {
2153 for(li = ((Class *)class)->nodes;
2157 Variable *v = (Variable *)n;
2158 if (n->type == VARIABLE_NODE &&
2159 v->scope != CLASS_SCOPE &&
2160 v->destructor_unref)
2161 print_destructor (v);
2165 out_printf(out, "}\n"
2166 "#undef __GOB_FUNCTION__\n\n");
2170 add_finalize (Class *c)
2174 "___finalize(GObject *obj_self)\n"
2177 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2182 const char *unused = "";
2184 unused = " G_GNUC_UNUSED";
2185 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2186 typebase, unused, macrobase);
2189 const char *unused = "";
2191 unused = " G_GNUC_UNUSED";
2192 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2196 if(finalize_handler) {
2197 /* so we get possible bad argument warning */
2198 if(finalize_handler->line_no > 0)
2199 out_addline_infile(out, finalize_handler->line_no);
2200 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2201 (guint)finalize_handler->unique_id, funcbase);
2202 if(finalize_handler->line_no > 0)
2203 out_addline_outfile(out);
2206 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2207 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2210 if (destructors > 0) {
2212 for (li = ((Class *)class)->nodes;
2216 Variable *v = (Variable *)n;
2217 if (n->type == VARIABLE_NODE &&
2218 v->scope != CLASS_SCOPE &&
2219 ! v->destructor_unref)
2220 print_destructor (v);
2224 out_printf(out, "}\n"
2225 "#undef __GOB_FUNCTION__\n\n");
2229 make_bonobo_object_epv (Class *c, const char *classname)
2232 gboolean added_line = FALSE;
2234 for (li = c->nodes; li != NULL; li = li->next) {
2236 Method *m = (Method *)n;
2237 if(n->type != METHOD_NODE ||
2238 m->method == OVERRIDE_METHOD)
2241 if (m->bonobo_object_func) {
2242 if(m->line_no > 0) {
2243 out_addline_infile(out, m->line_no);
2245 } else if (m->line_no == 0 &&
2247 out_addline_outfile(out);
2250 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2251 classname, m->id, m->id);
2255 out_addline_outfile(out);
2261 const char *unused = "";
2265 unused = " G_GNUC_UNUSED";
2267 for(li=c->nodes;li;li=g_list_next(li)) {
2271 if(n->type != METHOD_NODE)
2274 if(m->method == INIT_METHOD) {
2276 out_addline_infile(out, m->line_no);
2277 print_method(out, "static ", "\n", "", " ", "", "\n",
2278 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2280 out_addline_outfile(out);
2281 out_printf(out, "{\n"
2282 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2285 out_printf(out, "\t%s->_priv = "
2286 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2287 ((FuncArg *)m->args->data)->name,
2288 ((FuncArg *)m->args->data)->name,
2291 } else if(always_private_struct) {
2292 out_printf(out, "\t%s->_priv = NULL;\n",
2293 ((FuncArg *)m->args->data)->name);
2295 if(initializers > 0) {
2297 for(li = ((Class *)class)->nodes;
2301 Variable *v = (Variable *)n;
2302 if(n->type != VARIABLE_NODE ||
2303 v->scope == CLASS_SCOPE)
2305 print_initializer(m, v);
2308 if(glade_widgets > 0) {
2310 for(li = ((Class *)class)->nodes;
2314 Variable *v = (Variable *)n;
2315 if(n->type != VARIABLE_NODE ||
2316 v->scope == CLASS_SCOPE)
2318 print_glade_widget(m, v);
2321 } else if(m->method == CLASS_INIT_METHOD) {
2322 gboolean did_base_obj = FALSE;
2325 out_addline_infile(out, m->line_no);
2326 print_method(out, "static ", "\n", "", " ", "", "\n",
2327 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2329 out_addline_outfile(out);
2330 out_printf(out, "{\n"
2331 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2333 if (set_properties > 0 ||
2334 get_properties > 0 ||
2340 "g_object_class%s = "
2341 "(GObjectClass*) %s;\n",
2343 ((FuncArg *)m->args->data)->name);
2344 did_base_obj = TRUE;
2349 ((FuncArg *)m->args->data)->name,
2354 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2355 ((FuncArg *)m->args->data)->name,
2358 if (initializers > 0) {
2360 for(li = ((Class *)class)->nodes;
2364 Variable *v = (Variable *)n;
2365 if(n->type == VARIABLE_NODE &&
2366 v->scope == CLASS_SCOPE)
2367 print_initializer(m, v);
2371 out_printf(out, "\n\tparent_class = ");
2373 out_printf(out, "(%sClass *)", ptypebase);
2374 out_printf(out, "g_type_class_ref (%s);\n",
2380 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2382 /* if there are no handlers for these things, we
2383 * need to set them up here */
2384 if(need_dispose && !dispose_handler)
2385 out_printf(out, "\tg_object_class->dispose "
2387 if(need_finalize && !finalize_handler)
2388 out_printf(out, "\tg_object_class->finalize = "
2391 if(get_properties > 0 || set_properties > 0)
2394 if (c->bonobo_object_class != NULL) {
2395 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2401 out_printf(out, " {\n");
2402 out_addline_infile(out, m->ccode_line);
2403 out_printf(out, "%s\n", m->cbuf);
2404 out_addline_outfile(out);
2405 out_printf(out, " }\n");
2407 out_printf(out, "}\n"
2408 "#undef __GOB_FUNCTION__\n");
2413 add_argument (Argument *a, gboolean is_set)
2417 char *the_type_lower;
2422 line_no = a->set_line;
2425 line_no = a->get_line;
2429 s = g_strdup(a->name);
2431 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2433 the_type_lower = g_strdup (a->gtktype);
2434 gob_strdown (the_type_lower);
2436 /* HACK because there is no g_value_set/get for unichar */
2437 if (strcmp (the_type_lower, "unichar") == 0) {
2438 g_free (the_type_lower);
2439 the_type_lower = g_strdup ("uint");
2444 const char *unused = "";
2446 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2447 unused = " G_GNUC_UNUSED";
2450 if (a->atype != NULL &&
2451 /* gcc -Wbad-function-cast is wanking stupid, moronic
2452 and otherwise evil so we should just use a (gint)
2453 or (guint) cast, not the specific type cast */
2455 (strcmp (a->gtktype, "ENUM") != 0 &&
2456 strcmp (a->gtktype, "FLAGS") != 0)))
2457 cast = get_type (a->atype, TRUE);
2459 cast = g_strdup (get_cast (a->gtktype, FALSE));
2461 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2462 cast, unused, cast, the_type_lower);
2465 } else if ( ! is_set) {
2468 if (a->atype != NULL)
2469 cast = get_type (a->atype, TRUE);
2471 cast = g_strdup (get_cast (a->gtktype, FALSE));
2472 out_printf (out, "\t%s ARG;\n"
2473 "\tmemset (&ARG, 0, sizeof (%s));\n",
2479 out_printf(out, "\t\t{\n");
2481 out_addline_infile (out, line_no);
2482 out_printf (out, "%s\n", cbuf);
2484 out_addline_outfile (out);
2485 out_printf (out, "\t\t}\n");
2487 if (strcmp (a->gtktype, "OBJECT") == 0)
2488 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2491 out_printf (out, "\t\t"
2492 "g_value_set_%s (VAL, ARG);\n",
2495 g_free (the_type_lower);
2498 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2499 out_printf (out, "\t\tif (&ARG) break;\n");
2502 out_printf (out, "\t\tbreak;\n");
2504 out_printf (out, "\t}\n");
2508 add_property (Property *p, gboolean is_set)
2511 char *the_type_lower;
2517 line_no = p->set_line;
2520 line_no = p->get_line;
2525 name_upper = g_strdup (p->name);
2526 gob_strup (name_upper);
2527 the_type_lower = g_strdup (p->gtktype);
2528 gob_strdown (the_type_lower);
2530 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2532 out_printf(out, "\t\t{\n");
2534 out_addline_infile (out, line_no);
2535 out_printf (out, "%s\n", cbuf);
2537 out_addline_outfile (out);
2538 out_printf (out, "\t\t}\n");
2540 g_free (name_upper);
2541 g_free (the_type_lower);
2543 out_printf (out, "\t\tbreak;\n");
2547 add_getset_arg(Class *c, gboolean is_set)
2550 const char *unused = "";
2551 const char *hack_unused = "";
2553 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2554 unused = " G_GNUC_UNUSED";
2556 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2559 out_printf(out, "\nstatic void\n"
2560 "___object_%s_property (GObject *object,\n"
2561 "\tguint property_id,\n"
2562 "\t%sGValue *VAL%s,\n"
2563 "\tGParamSpec *pspec%s)\n"
2564 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2567 "\tself = %s (object);\n\n"
2568 "\tswitch (property_id) {\n",
2569 is_set ? "set" : "get",
2570 is_set ? "const " : "",
2574 is_set ? "set" : "get",
2579 for (li = c->nodes; li != NULL; li = li->next) {
2581 if (n->type == PROPERTY_NODE)
2582 add_property ((Property *)n, is_set);
2583 else if (n->type == ARGUMENT_NODE)
2584 add_argument ((Argument *)n, is_set);
2586 out_printf (out, "\tdefault:\n"
2587 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2588 "#ifndef __PRETTY_FUNCTION__\n"
2589 "# undef G_STRLOC\n"
2590 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2592 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2593 "\t\t%sbreak;\n\t}\n"
2595 "#undef __GOB_FUNCTION__\n", hack_unused);
2599 print_checks (Method *m, FuncArg *fa)
2603 gboolean checked_null = FALSE;
2604 is_void = (strcmp(m->mtype->name, "void")==0 &&
2605 m->mtype->pointer == NULL);
2607 for(li = fa->checks; li != NULL; li = li->next) {
2608 Check *ch = li->data;
2610 /* point to the method prot in .gob for failed checks */
2612 out_addline_infile(out, m->line_no);
2614 out_printf(out, "\tg_return_if_fail (");
2616 out_printf(out, "\tg_return_val_if_fail (");
2617 switch(ch->chtype) {
2619 out_printf(out, "%s != NULL", fa->name);
2620 checked_null = TRUE;
2623 s = make_pre_macro(fa->atype->name, "IS");
2625 out_printf(out, "%s (%s)", s, fa->name);
2627 /* if not check null, null may be valid */
2628 out_printf(out, "!(%s) || %s (%s)", fa->name,
2633 out_printf(out, "%s < %s", fa->name, ch->number);
2636 out_printf(out, "%s > %s", fa->name, ch->number);
2639 out_printf(out, "%s <= %s", fa->name, ch->number);
2642 out_printf(out, "%s >= %s", fa->name, ch->number);
2645 out_printf(out, "%s == %s", fa->name, ch->number);
2648 out_printf(out, "%s != %s", fa->name, ch->number);
2652 out_printf(out, ");\n");
2654 out_printf(out, ", (");
2655 print_type(out, m->mtype, TRUE);
2656 out_printf(out, ")%s);\n",
2657 m->onerror?m->onerror:"0");
2663 print_preconditions(Method *m)
2667 for(li=m->args;li;li=g_list_next(li)) {
2668 FuncArg *fa = li->data;
2670 print_checks(m, fa);
2673 out_addline_outfile(out);
2677 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2680 out_addline_outfile(out);
2681 out_printf(out, "{\n"
2682 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2683 ((Class *)class)->otype,
2686 print_preconditions(m);
2690 (no_gnu || for_cpp) &&
2692 ((FuncArg *)(m->args->data))->name != NULL &&
2693 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2694 out_printf (out, "\tif (&self) { ; }\n");
2697 /* Note: the trailing }'s are on one line, this is so
2698 that we get the no return warning correctly and point to
2699 the correct line in the .gob file, yes this is slightly
2700 ugly in the .c file, but that is not supposed to be
2701 human readable anyway. */
2703 out_printf(out, "{\n");
2705 out_addline_infile(out, m->ccode_line);
2706 out_printf(out, "\t%s}", m->cbuf);
2709 /* Note, there is no \n between the last } and this } so that
2710 * errors/warnings reported on the end of the body get pointed to the
2711 * right line in the .gob source */
2712 out_printf(out, "}\n");
2715 out_addline_outfile(out);
2716 out_printf(out, "#undef __GOB_FUNCTION__\n");
2720 put_signal_args (Method *m)
2726 if (m->args->next == NULL)
2729 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2730 li != NULL && ali != NULL;
2731 li = li->next, ali = ali->next, i++) {
2732 FuncArg *fa = li->data;
2733 char *str = ali->data;
2734 char *cast = g_strdup (get_cast (str, FALSE));
2735 /* FIXME: This code is so fucking ugly it hurts */
2736 gboolean do_static =
2737 (strcmp (str, "STRING") == 0 ||
2738 strcmp (str, "BOXED") == 0 ||
2739 strncmp (str, "BOXED_", 6) == 0);
2744 cast = get_type (fa->atype, TRUE);
2746 /* we should have already proved before that
2747 the we know all the types */
2748 g_assert (cast != NULL);
2750 if (strncmp (str, "BOXED_", 6) == 0)
2751 t = g_strdup (&(str[6]));
2753 t = g_strconcat ("G_TYPE_", str, NULL);
2756 "\t___param_values[%d].g_type = 0;\n"
2757 "\tg_value_init (&___param_values[%d], %s);\n",
2761 if (strcmp (str, "UNICHAR") == 0)
2762 /* hack because glib is braindamaged */
2763 set_func = g_strdup ("g_value_set_uint");
2764 else if (strncmp (str, "BOXED_", 6) == 0)
2765 set_func = g_strdup ("g_value_set_static_boxed");
2767 set_func = g_strdup_printf ("g_value_set%s_%s",
2768 do_static ? "_static" : "",
2770 gob_strdown (set_func);
2772 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2773 set_func, i, cast, fa->name);
2781 clear_signal_args (Method *m)
2786 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2788 if (m->args->next == NULL)
2791 for (li = m->args->next, i = 1;
2793 li = li->next, i++) {
2795 "\tg_value_unset (&___param_values[%d]);\n", i);
2800 get_arg_names_for_macro (Method *m)
2804 GString *gs = g_string_new(NULL);
2806 for(li=m->args;li;li=g_list_next(li)) {
2807 FuncArg *arg = li->data;
2808 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2811 return g_string_free (gs, FALSE);
2815 put_method(Method *m)
2817 char *s, *args, *doc;
2819 is_void = (strcmp(m->mtype->name, "void")==0 &&
2820 m->mtype->pointer == NULL);
2821 out_printf(out, "\n");
2822 if(m->method != OVERRIDE_METHOD) {
2823 doc = get_gtk_doc(m->id);
2825 out_printf(out, "%s", doc);
2830 case REGULAR_METHOD:
2832 out_addline_infile(out, m->line_no);
2833 if(m->scope == PRIVATE_SCOPE)
2834 print_method(out, "static ", "\n", "", " ", "", "\n",
2835 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2836 else /* PUBLIC, PROTECTED */
2837 print_method(out, "", "\n", "", " ", "", "\n",
2838 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2839 print_method_body(m, TRUE, TRUE);
2840 /* the outfile line was added above */
2842 case SIGNAL_FIRST_METHOD:
2843 case SIGNAL_LAST_METHOD:
2845 out_addline_infile(out, m->line_no);
2846 if(m->scope == PRIVATE_SCOPE)
2847 print_method(out, "static ", "\n", "", " ", "", "\n",
2848 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2849 else /* PUBLIC, PROTECTED */
2850 print_method(out, "", "\n", "", " ", "", "\n",
2851 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2852 out_addline_outfile (out);
2854 out_printf (out, "{\n");
2857 "\tGValue ___param_values[%d];\n"
2858 "\tGValue ___return_val;\n\n"
2859 "memset (&___return_val, 0, "
2860 "sizeof (___return_val));\n"
2861 "memset (&___param_values, 0, "
2862 "sizeof (___param_values));\n\n",
2863 g_list_length (m->args));
2865 print_preconditions (m);
2868 "\n\t___param_values[0].g_type = 0;\n"
2869 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2870 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2871 ((FuncArg *)m->args->data)->name,
2872 ((FuncArg *)m->args->data)->name);
2874 put_signal_args (m);
2876 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2877 const char *defret = NULL;
2879 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2880 (char *)m->gtktypes->data);
2882 if (m->defreturn != NULL)
2883 defret = m->defreturn;
2884 else if (m->onerror != NULL)
2885 defret = m->onerror;
2887 if (defret != NULL) {
2889 /* FIXME: This code is so fucking ugly it hurts */
2890 gboolean do_static =
2891 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2892 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2893 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2895 cast = get_type (m->mtype, TRUE);
2897 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2898 /* hack because glib is braindamaged */
2899 set_func = g_strdup ("g_value_set_uint");
2901 set_func = g_strdup_printf ("g_value_set%s_%s",
2902 do_static ? "_static" : "",
2903 (char *)m->gtktypes->data);
2904 gob_strdown (set_func);
2906 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2907 set_func, cast, defret);
2912 out_printf (out, "\n");
2915 s = g_strdup (m->id);
2918 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2919 "\t\tobject_signals[%s_SIGNAL],\n"
2920 "\t\t0 /* detail */,\n"
2921 "\t\t&___return_val);\n", s);
2925 clear_signal_args (m);
2927 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2928 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2930 /* Hack because glib is very very braindead */
2932 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2933 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
2934 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
2935 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
2937 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2938 /* hack because glib is braindamaged */
2939 getfunc = g_strdup ("g_value_get_uint");
2941 getfunc = g_strdup_printf ("g_value_%s_%s",
2942 do_dup ? "dup" : "get",
2943 (char *)m->gtktypes->data);
2944 gob_strdown (getfunc);
2947 cast = get_type (m->mtype, TRUE);
2952 print_type (out, m->mtype, TRUE);
2954 " ___ret = (%s) %s (&___return_val);\n"
2955 "\t\tg_value_unset (&___return_val);\n"
2956 "\t\treturn ___ret;\n"
2963 out_printf(out, "}\n");
2968 out_addline_infile(out, m->line_no);
2969 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2970 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2971 print_method_body(m, FALSE, TRUE);
2972 /* the outfile line was added above */
2974 case VIRTUAL_METHOD:
2976 out_addline_infile(out, m->line_no);
2977 if(m->scope==PRIVATE_SCOPE)
2978 print_method(out, "static ", "\n", "", " ", "", "\n",
2979 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2980 else /* PUBLIC, PROTECTED */
2981 print_method(out, "", "\n", "", " ", "", "\n",
2982 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2983 out_addline_outfile(out);
2984 out_printf(out, "{\n"
2985 "\t%sClass *klass;\n", typebase);
2986 print_preconditions(m);
2987 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2988 "\tif(klass->%s)\n",
2989 macrobase, ((FuncArg *)m->args->data)->name,
2991 if(strcmp(m->mtype->name, "void") == 0 &&
2992 m->mtype->pointer == NULL) {
2994 out_printf(out, "\t\t(*klass->%s)(%s",
2996 ((FuncArg *)m->args->data)->name);
2997 for(li=m->args->next;li;li=g_list_next(li)) {
2998 FuncArg *fa = li->data;
2999 out_printf(out, ",%s", fa->name);
3001 out_printf(out, ");\n}\n");
3004 out_printf(out, "\t\treturn (*klass->%s)(%s",
3006 ((FuncArg *)m->args->data)->name);
3007 for(li=m->args->next;li;li=g_list_next(li)) {
3008 FuncArg *fa = li->data;
3009 out_printf(out, ",%s", fa->name);
3011 out_printf(out, ");\n"
3014 print_type(out, m->mtype, TRUE);
3016 out_printf(out, ")(%s);\n}\n", m->defreturn);
3018 out_printf(out, ")(%s);\n}\n", m->onerror);
3020 out_printf(out, ")(0);\n}\n");
3026 out_addline_infile(out, m->line_no);
3027 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3028 m, FALSE, FALSE, TRUE, TRUE, FALSE);
3029 print_method_body(m, FALSE, TRUE);
3030 /* the outfile line was added above */
3032 case OVERRIDE_METHOD:
3036 out_addline_infile(out, m->line_no);
3037 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3038 print_method(out, "static ", s, "", " ", "", "\n",
3039 m, FALSE, FALSE, FALSE, TRUE, FALSE);
3041 out_addline_outfile(out);
3042 s = replace_sep(m->otype, '_');
3044 args = get_arg_names_for_macro(m);
3046 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3047 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3048 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3049 args, s, m->id, s, m->id, args);
3051 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3052 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3053 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3055 args, s, m->id, s, m->id, args);
3056 out_printf(out, "(");
3057 print_type(out, m->mtype, TRUE);
3058 out_printf(out, ")%s))\n",
3059 m->onerror?m->onerror:"0");
3063 print_method_body(m, TRUE, TRUE);
3064 /* the outfile line was added above */
3065 out_printf(out, "#undef PARENT_HANDLER\n");
3075 char *outfile, *outfileh, *outfileph;
3077 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3078 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3080 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3081 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3083 if ((privates > 0 || protecteds > 0 ||
3084 private_header == PRIVATE_HEADER_ALWAYS) &&
3085 private_header != PRIVATE_HEADER_NEVER) {
3086 char sep[2] = {0,0};
3089 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3090 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3092 outfilephbase = NULL;
3098 out = fopen (outfile, "w");
3100 error_printf (GOB_ERROR, 0,
3101 "Cannot open outfile: %s", outfile);
3103 outh = fopen (outfileh, "w");
3105 error_printf (GOB_ERROR, 0,
3106 "Cannot open outfile: %s", outfileh);
3108 if (outfileph != NULL) {
3109 outph = fopen (outfileph, "w");
3110 if (outph == NULL) {
3111 error_printf (GOB_ERROR, 0,
3112 "Cannot open outfile: %s",
3120 put_argument_nongnu_wrappers (Class *c)
3124 if (get_properties < 0 && set_properties < 0)
3127 for (li = c->nodes; li != NULL; li = li->next) {
3129 const char *name, *gtktype;
3135 if (n->type == ARGUMENT_NODE) {
3136 Argument *a = (Argument *)n;
3138 gtktype = a->gtktype;
3140 get = a->get != NULL;
3141 set = a->set != NULL;
3142 } else if (n->type == PROPERTY_NODE) {
3143 Property *p = (Property *)n;
3145 gtktype = p->gtktype;
3147 get = p->get != NULL;
3148 set = p->set != NULL;
3153 aname = g_strdup (name);
3157 cast = get_type (atype, TRUE);
3159 cast = g_strdup (get_cast (gtktype, TRUE));
3163 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3164 "\"%s\",(%s)(arg)\n",
3165 macrobase, aname, name, cast);
3167 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3168 "\"%s\",(%s*)(arg)\n",
3169 macrobase, aname, name, cast);
3172 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3174 macrobase, aname, name);
3176 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3178 macrobase, aname, name);
3186 put_argument_gnu_wrappers(Class *c)
3190 if(get_properties < 0 && set_properties < 0)
3193 for (li = c->nodes; li != NULL; li = li->next) {
3195 const char *name, *gtktype;
3201 if (n->type == ARGUMENT_NODE) {
3202 Argument *a = (Argument *)n;
3204 gtktype = a->gtktype;
3206 get = a->get != NULL;
3207 set = a->set != NULL;
3208 } else if (n->type == PROPERTY_NODE) {
3209 Property *p = (Property *)n;
3211 gtktype = p->gtktype;
3213 get = p->get != NULL;
3214 set = p->set != NULL;
3219 aname = g_strdup (name);
3223 cast = get_type (atype, TRUE);
3225 cast = g_strdup (get_cast (gtktype, TRUE));
3229 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3230 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3231 macrobase, aname, name, cast);
3233 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3234 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3235 macrobase, aname, name, cast);
3238 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3240 macrobase, aname, name);
3242 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3244 macrobase, aname, name);
3252 print_ccode_block(CCode *cc)
3255 switch(cc->cctype) {
3257 /* HT code is printed exactly like normal header
3258 code but is printed before */
3261 out_printf(fp, "\n");
3264 /* AT code is printed exactly like normal 'all'
3265 code but is printed before */
3268 out_printf(outph, "\n");
3269 out_printf(outph, "%s\n", cc->cbuf);
3270 out_addline_infile(outph, cc->line_no);
3271 out_addline_outfile(outph);
3273 out_printf(outh, "\n");
3274 out_printf(outh, "%s\n", cc->cbuf);
3276 out_printf(fp, "\n");
3277 out_addline_infile(fp, cc->line_no);
3282 out_printf(fp, "\n");
3283 out_addline_infile(fp, cc->line_no);
3290 out_printf(fp, "\n");
3291 out_addline_infile(fp, cc->line_no);
3294 out_printf(fp, "%s\n", cc->cbuf);
3295 if(cc->cctype == C_CCODE ||
3296 cc->cctype == A_CCODE ||
3297 cc->cctype == AT_CCODE ||
3298 cc->cctype == PH_CCODE)
3299 out_addline_outfile(fp);
3303 print_class_block(Class *c)
3307 gboolean printed_private = FALSE;
3311 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3312 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3316 out_printf(out, "/* utility types we may need */\n");
3317 if(special_array[SPECIAL_2POINTER])
3318 out_printf(out, "typedef struct { "
3319 "gpointer a; gpointer b; "
3320 "} ___twopointertype;\n");
3321 if(special_array[SPECIAL_3POINTER])
3322 out_printf(out, "typedef struct { "
3323 "gpointer a; gpointer b; "
3325 "} ___threepointertype;\n");
3326 if(special_array[SPECIAL_INT_POINTER])
3327 out_printf(out, "typedef struct { "
3328 "gint a; gpointer b; "
3329 "} ___intpointertype;\n");
3330 out_printf(out, "\n");
3333 out_printf(outh, "\n/*\n"
3334 " * Type checking and casting macros\n"
3336 out_printf(outh, "#define %s\t"
3337 "(%s_get_type())\n",
3338 macrotype, funcbase);
3339 out_printf(outh, "#define %s(obj)\t"
3340 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3341 macrobase, funcbase, typebase);
3342 out_printf(outh, "#define %s_CONST(obj)\t"
3343 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3344 macrobase, funcbase, typebase);
3345 out_printf(outh, "#define %s_CLASS(klass)\t"
3346 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3347 macrobase, funcbase, typebase);
3348 out_printf(outh, "#define %s(obj)\t"
3349 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3352 "#define %s_GET_CLASS(obj)\t"
3353 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3354 macrobase, funcbase, typebase);
3356 if ( ! no_self_alias) {
3357 out_printf(out, "/* self casting macros */\n");
3358 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3359 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3360 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3361 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3362 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3364 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3367 out_printf(out, "/* self typedefs */\n");
3368 out_printf(out, "typedef %s Self;\n", typebase);
3369 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3373 always_private_struct) {
3374 out_printf (outh, "\n/* Private structure type */\n");
3375 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3376 typebase, typebase);
3378 out_printf (outh, "/* There are no privates, this "
3379 "structure is thus never defined */\n");
3382 out_printf (outh, "\n/*\n"
3383 " * Main object structure\n"
3385 s = replace_sep (c->otype, '_');
3387 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3388 "#define __TYPEDEF_%s__\n", s, s);
3390 out_printf (outh, "typedef struct _%s %s;\n"
3391 "#endif\n", typebase, typebase);
3392 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3393 typebase, ptypebase);
3394 for (li = c->nodes; li; li=li->next) {
3395 static gboolean printed_public = FALSE;
3397 Variable *v = (Variable *)n;
3398 if(n->type == VARIABLE_NODE &&
3399 v->scope == PUBLIC_SCOPE) {
3400 if( ! printed_public) {
3401 out_printf(outh, "\t/*< public >*/\n");
3402 printed_public = TRUE;
3404 put_variable((Variable *)n, outh);
3407 /* put protecteds always AFTER publics */
3408 for (li = c->nodes; li != NULL; li = li->next) {
3410 Variable *v = (Variable *)n;
3411 if (n->type == VARIABLE_NODE &&
3412 v->scope == PROTECTED_SCOPE) {
3413 if ( ! printed_private) {
3414 out_printf (outh, "\t/*< private >*/\n");
3415 printed_private = TRUE;
3417 put_variable ((Variable *)n, outh);
3421 always_private_struct) {
3422 if ( ! printed_private)
3423 out_printf (outh, "\t/*< private >*/\n");
3424 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3426 out_printf (outh, "};\n");
3431 /* if we are to stick this into the private
3432 header, if not stick it directly into the
3439 out_printf (outfp, "struct _%sPrivate {\n",
3443 for(li=c->nodes; li; li=li->next) {
3445 Variable *v = (Variable *)n;
3446 if(n->type == VARIABLE_NODE &&
3447 v->scope == PRIVATE_SCOPE) {
3448 out_addline_infile(outfp, v->line_no);
3449 put_variable(v, outfp);
3452 out_addline_outfile(outfp);
3454 out_printf(outfp, "};\n");
3457 out_printf(outh, "\n/*\n"
3458 " * Class definition\n"
3460 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3461 typebase, typebase);
3463 "struct _%sClass {\n\t%sClass __parent__;\n",
3464 typebase, ptypebase);
3465 for(li = c->nodes; li != NULL; li = li->next) {
3467 if(n->type == METHOD_NODE)
3468 put_vs_method((Method *)n);
3470 /* If BonoboX type class put down the epv */
3471 if (c->bonobo_object_class != NULL) {
3473 "\t/* Bonobo object epv */\n"
3474 "\tPOA_%s__epv _epv;\n",
3475 c->bonobo_object_class);
3477 /* put class scope variables */
3478 for (li = c->nodes; li != NULL; li = li->next) {
3480 Variable *v = (Variable *)n;
3481 if (n->type == VARIABLE_NODE &&
3482 v->scope == CLASS_SCOPE)
3483 put_variable ((Variable *)n, outh);
3485 out_printf (outh, "};\n\n");
3487 out_printf (out, "/* here are local prototypes */\n");
3488 if (set_properties > 0) {
3489 out_printf (out, "static void ___object_set_property "
3490 "(GObject *object, guint property_id, "
3491 "const GValue *value, GParamSpec *pspec);\n");
3493 if (get_properties > 0) {
3494 out_printf (out, "static void ___object_get_property "
3495 "(GObject *object, guint property_id, "
3496 "GValue *value, GParamSpec *pspec);\n");
3499 out_printf (outh, "\n/*\n"
3500 " * Public methods\n"
3503 if ( ! overrode_get_type) {
3504 out_printf (outh, "GType\t%s_get_type\t(void);\n", funcbase);
3507 for(li = c->nodes; li != NULL; li = li->next) {
3509 if(n->type == METHOD_NODE) {
3510 put_pub_method((Method *)n);
3511 put_prot_method((Method *)n);
3512 put_priv_method_prot((Method *)n);
3516 /* this idea is less and less apealing to me */
3518 out_printf (outh, "\n/*\n"
3519 " * Signal connection wrapper macros\n"
3522 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3523 put_signal_macros (c, TRUE);
3524 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3525 put_signal_macros (c, FALSE);
3526 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3528 put_signal_macros (c, FALSE);
3529 out_printf(outh, "\n");
3532 out_printf (out, "\n/*\n"
3533 " * Signal connection wrapper macro shortcuts\n"
3535 put_local_signal_macros (c);
3536 out_printf(outh, "\n");
3539 /* argument wrapping macros */
3540 if(get_properties > 0 || set_properties > 0) {
3541 out_printf(outh, "\n/*\n"
3542 " * Argument wrapping macros\n"
3545 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3546 put_argument_gnu_wrappers(c);
3547 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3548 put_argument_nongnu_wrappers(c);
3549 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3551 put_argument_nongnu_wrappers(c);
3556 for(li = c->nodes; li != NULL; li = li->next) {
3558 if(n->type == METHOD_NODE)
3559 add_signal_prots((Method *)n);
3565 if(any_method_to_alias(c)) {
3566 out_printf (out, "/* Short form macros */\n");
3567 make_method_aliases (c);
3570 add_interface_inits (c);
3572 if ( ! overrode_get_type) {
3573 if (c->bonobo_object_class != NULL)
3574 add_bonobo_object_get_type ();
3579 out_printf (out, "/* a macro for creating a new object of our type */\n");
3581 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3582 typebase, funcbase);
3584 out_printf (out, "/* a function for creating a new object of our type */\n");
3585 out_printf (out, "#include <stdarg.h>\n");
3587 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3588 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3589 "{\n\t%s *ret;\n\tva_list ap;\n"
3590 "\tva_start (ap, first);\n"
3591 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3594 "\treturn ret;\n}\n\n",
3596 no_gnu ? "" : " G_GNUC_UNUSED",
3597 typebase, typebase, typebase, funcbase);
3601 out_printf (out, "/* a function to connect glade callback */\n");
3602 out_printf (out,"static void\n"
3603 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3604 "GObject *object,\n"
3605 "const gchar *signal_name,\n"
3606 "const gchar *signal_data,\n"
3607 "GObject *connect_object,\n"
3609 "gpointer user_data)\n"
3611 "\tstatic GModule * allsymbols = NULL;\n"
3613 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3614 "\tif (allsymbols) {\n"
3615 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3616 "\t\tGCallback func;\n"
3618 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3619 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3620 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3621 "\t\t\t\tg_free(func_name);\n"
3626 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3628 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3629 "\t\tg_free(func_name);\n"
3644 if(set_properties > 0) {
3645 add_getset_arg(c, TRUE);
3648 if(get_properties > 0) {
3649 add_getset_arg(c, FALSE);
3652 for(li = c->nodes; li != NULL; li = li->next) {
3654 if(n->type == METHOD_NODE)
3655 put_method((Method *)n);
3658 add_bad_hack_to_avoid_unused_warnings(c);
3662 print_useful_macros(void)
3664 int major = 0, minor = 0, pl = 0;
3667 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3668 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3669 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3670 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3672 /* Useful priv macro thingie */
3673 /* FIXME: this should be done the same way that priv is, as a var,
3675 out_printf (out, "#define selfp (self->_priv)\n\n");
3679 print_more_useful_macros (void)
3682 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3683 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3685 out_printf (out, "#ifdef G_LIKELY\n");
3686 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3687 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3688 out_printf (out, "#else /* ! G_LIKELY */\n");
3689 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3690 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3691 out_printf (out, "#endif /* G_LIKELY */\n");
3696 print_file_comments(void)
3698 out_printf(outh, "/* Generated by GOB (v%s)"
3699 " (do not edit directly) */\n\n", VERSION);
3701 out_printf(outph, "/* Generated by GOB (v%s)"
3702 " (do not edit directly) */\n\n", VERSION);
3703 out_printf(out, "/* Generated by GOB (v%s)"
3704 " (do not edit directly) */\n\n", VERSION);
3706 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3710 print_includes(void)
3712 gboolean found_header;
3715 /* We may need string.h for memset */
3716 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3717 out_printf(out, "#include <string.h> /* memset() */\n\n");
3720 p = g_strconcat(filebase, ".h", NULL);
3721 found_header = TRUE;
3722 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3723 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3724 found_header = FALSE;
3728 /* if we are creating a private header see if it was included */
3730 char sep[2] = {0,0};
3733 p = g_strconcat(filebase, sep, "private.h", NULL);
3734 if( ! g_list_find_custom(include_files, p,
3735 (GCompareFunc)strcmp)) {
3736 out_printf(out, "#include \"%s%cprivate.h\"\n\n",
3740 error_printf(GOB_WARN, 0,
3741 "Implicit private header include "
3743 "\tsource file, while public "
3744 "header is at a custom location, "
3746 "\texplicitly include "
3747 "the private header below the "
3755 print_header_prefixes(void)
3759 p = replace_sep(((Class *)class)->otype, '_');
3761 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3763 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3764 "#define __%s_PRIVATE_H__\n\n"
3765 "#include \"%s.h\"\n\n", p, p, filebase);
3768 if( ! no_extern_c) {
3769 out_printf(outh, "#ifdef __cplusplus\n"
3771 "#endif /* __cplusplus */\n\n");
3773 out_printf(outph, "#ifdef __cplusplus\n"
3775 "#endif /* __cplusplus */\n\n");
3780 print_header_postfixes(void)
3783 out_printf(outh, "\n#ifdef __cplusplus\n"
3785 "#endif /* __cplusplus */\n");
3786 out_printf(outh, "\n#endif\n");
3789 out_printf(outph, "\n#ifdef __cplusplus\n"
3791 "#endif /* __cplusplus */\n");
3792 out_printf(outph, "\n#endif\n");
3801 /* print the AT_CCODE blocks */
3802 for(li = nodes; li != NULL; li = li->next) {
3803 Node *node = li->data;
3804 if(node->type == CCODE_NODE) {
3805 CCode *cc = (CCode *)node;
3806 if(cc->cctype == AT_CCODE)
3807 print_ccode_block((CCode *)node);
3813 print_header_top(void)
3817 /* mandatory includes */
3818 out_printf (outh, "#include <glib.h>\n");
3819 out_printf (outh, "#include <glib-object.h>\n");
3821 /* print the HT_CCODE blocks */
3822 for (li = nodes; li != NULL; li = li->next) {
3823 Node *node = li->data;
3824 if (node->type == CCODE_NODE) {
3825 CCode *cc = (CCode *)node;
3826 if (cc->cctype == HT_CCODE)
3827 print_ccode_block ((CCode *)node);
3833 print_enum (EnumDef *enode)
3840 funcprefix = replace_sep (enode->etype, '_');
3841 gob_strdown (funcprefix);
3842 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3844 type = remove_sep (enode->etype);
3846 out_printf (outh, "\ntypedef enum {\n");
3848 for (li = enode->values; li != NULL; li = li->next) {
3849 EnumValue *value = li->data;
3851 char *sname = gob_strdown (g_strdup (value->name));
3853 while ((p = strchr (sname, '_')) != NULL)
3856 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3857 if (value->value != NULL)
3858 out_printf (outh, " = %s", value->value);
3859 if (li->next != NULL)
3860 out_printf (outh, ",\n");
3862 out_printf (outh, "\n");
3864 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3865 enode->prefix, value->name,
3866 enode->prefix, value->name,
3872 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3874 out_printf (outh, "} %s;\n", type);
3876 str = make_pre_macro (enode->etype, "TYPE");
3877 out_printf (outh, "#define %s ", str);
3880 out_printf (outh, "%s_get_type()\n", funcprefix);
3881 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3884 "GType\n%s_get_type (void)\n"
3886 "\tstatic GType type = 0;\n"
3887 "\tif ___GOB_UNLIKELY(type == 0)\n"
3888 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3891 funcprefix, type, funcprefix);
3893 g_free (funcprefix);
3898 print_flags (Flags *fnode)
3906 funcprefix = replace_sep (fnode->ftype, '_');
3907 gob_strdown (funcprefix);
3908 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3910 type = remove_sep (fnode->ftype);
3912 out_printf (outh, "\ntypedef enum {\n");
3914 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3915 const char *name = li->data;
3917 char *sname = gob_strdown (g_strdup (name));
3919 while ((p = strchr (sname, '_')) != NULL)
3922 out_printf (outh, "\t%s_%s = 1<<%d",
3923 fnode->prefix, name, i);
3924 if (li->next != NULL)
3925 out_printf (outh, ",\n");
3927 out_printf (outh, "\n");
3929 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3930 fnode->prefix, name,
3931 fnode->prefix, name,
3937 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3939 out_printf (outh, "} %s;\n", type);
3941 str = make_pre_macro (fnode->ftype, "TYPE");
3942 out_printf (outh, "#define %s ", str);
3945 out_printf (outh, "%s_get_type()\n", funcprefix);
3946 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3949 "GType\n%s_get_type (void)\n"
3951 "\tstatic GType type = 0;\n"
3952 "\tif ___GOB_UNLIKELY(type == 0)\n"
3953 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3956 funcprefix, type, funcprefix);
3958 g_free (funcprefix);
3963 print_error (Error *enode)
3970 funcprefix = replace_sep (enode->etype, '_');
3971 gob_strdown (funcprefix);
3972 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3974 type = remove_sep (enode->etype);
3976 out_printf (outh, "\ntypedef enum {\n");
3978 for (li = enode->values; li != NULL; li = li->next) {
3979 const char *name = li->data;
3981 char *sname = gob_strdown (g_strdup (name));
3983 while ((p = strchr (sname, '_')) != NULL)
3986 out_printf (outh, "\t%s_%s", enode->prefix, name);
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, name,
3994 enode->prefix, 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);\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 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4022 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4024 str = replace_sep (enode->etype, '-');
4028 "GQuark\n%s_quark (void)\n"
4030 "\tstatic GQuark q = 0;\n"
4032 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4039 g_free (funcprefix);
4044 generate_outfiles(void)
4048 print_file_comments();
4054 print_header_prefixes();
4056 print_useful_macros();
4060 print_more_useful_macros ();
4062 for (li = nodes; li != NULL; li = li->next) {
4063 Node *node = li->data;
4064 if (node->type == CCODE_NODE) {
4065 CCode *cc = (CCode *)node;
4066 if (cc->cctype != HT_CCODE &&
4067 cc->cctype != AT_CCODE)
4068 print_ccode_block ((CCode *)node);
4069 } else if (node->type == CLASS_NODE) {
4070 print_class_block ((Class *)node);
4071 } else if (node->type == ENUMDEF_NODE) {
4072 print_enum ((EnumDef *)node);
4073 } else if (node->type == FLAGS_NODE) {
4074 print_flags ((Flags *)node);
4075 } else if (node->type == ERROR_NODE) {
4076 print_error ((Error *)node);
4078 g_assert_not_reached();
4082 print_header_postfixes();
4088 fprintf(stderr, "Gob version %s\n\n", VERSION);
4089 fprintf(stderr, "gob [options] file.gob\n\n");
4090 fprintf(stderr, "Options:\n"
4091 "\t--help,-h,-? Display this help\n"
4092 "\t--version Display version\n"
4093 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4094 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4095 "\t--for-cpp Create C++ files\n"
4096 "\t--no-extern-c Never print extern \"C\" into the "
4098 "\t--no-gnu Never use GNU extentions\n"
4099 "\t--no-touch Don't touch output files unless they "
4101 "\t changed (implies --no-touch-headers)\n"
4102 "\t--no-touch-headers Don't touch headers unless they "
4104 "\t--always-private-header Always create a private header "
4106 "\t even if it would be empty\n"
4107 "\t--ondemand-private-header Create private header only when "
4110 "\t--no-private-header Don't create a private header, "
4112 "\t structure and protected "
4113 "prototypes inside c file\n"
4114 "\t--always-private-struct Always create a private pointer "
4116 "\t the object structure\n"
4117 "\t--m4 Preprocess source with m4. "
4118 "Following args will\n"
4119 "\t be passed to m4\n"
4120 "\t--m4-dir Print directory that will be "
4123 "\t--no-write,-n Don't write output files, just "
4125 "\t--no-lines Don't print '#line' to output\n"
4126 "\t--no-self-alias Don't create self type and macro "
4128 "\t--no-kill-underscores Ignored for compatibility\n"
4129 "\t-o,--output-dir The directory where output "
4130 "should be placed\n"
4131 "\t--file-sep[=c] replace default \'-\' file "
4132 "name separator\n");
4136 parse_options(int argc, char *argv[])
4139 int got_file = FALSE;
4140 int no_opts = FALSE;
4141 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4145 for(i = 1 ; i < argc; i++) {
4147 char *new_commandline;
4148 g_assert(m4_commandline!=NULL);
4150 /* check whether this one looks like the filename */
4151 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4153 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4157 /* insert flags before the filename */
4158 new_commandline=g_strconcat(m4_commandline,
4166 /* just an ordinary option */
4168 new_commandline=g_strconcat(m4_commandline,
4173 /* free old commandline */
4174 g_free(m4_commandline);
4175 m4_commandline=new_commandline;
4177 } else if(no_opts ||
4178 argv[i][0] != '-') {
4181 fprintf(stderr, "Specify only one file!\n");
4187 } else if(strcmp(argv[i], "--help")==0) {
4190 } else if(strcmp(argv[i], "--version")==0) {
4191 fprintf(stderr, "Gob version %s\n", VERSION);
4193 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4194 exit_on_warn = TRUE;
4195 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4196 exit_on_warn = FALSE;
4197 } else if(strcmp(argv[i], "--for-cpp")==0) {
4199 } else if(strcmp(argv[i], "--no-touch")==0) {
4201 no_touch_headers = TRUE;
4202 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4203 no_touch_headers = TRUE;
4204 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4205 private_header = PRIVATE_HEADER_ONDEMAND;
4206 } else if(strcmp(argv[i], "--always-private-header")==0) {
4207 private_header = PRIVATE_HEADER_ALWAYS;
4208 } else if(strcmp(argv[i], "--no-private-header")==0) {
4209 private_header = PRIVATE_HEADER_NEVER;
4210 } else if(strcmp(argv[i], "--no-gnu")==0) {
4212 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4214 } else if(strcmp(argv[i], "--no-write")==0) {
4216 } else if(strcmp(argv[i], "--no-lines")==0) {
4218 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4219 no_self_alias = TRUE;
4220 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4222 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4223 always_private_struct = TRUE;
4224 } else if(strcmp(argv[i], "--m4-dir")==0) {
4225 printf("%s\n",M4_INCLUDE_DIR);
4227 } else if(strcmp(argv[i], "--m4")==0) {
4231 m4_commandline=g_strdup(M4_COMMANDLINE);
4232 } else if(strcmp(argv[i], "--m4-clean")==0) {
4236 m4_commandline=g_strdup(M4_COMMANDLINE);
4237 } else if (strcmp (argv[i], "-o") == 0 ||
4238 strcmp (argv[i], "--output-dir") == 0) {
4240 output_dir = g_strdup (argv[i+1]);
4245 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4248 strlen ("--output-dir=")) == 0) {
4249 char *p = strchr (argv[i], '=');
4250 g_assert (p != NULL);
4251 output_dir = g_strdup (p+1);
4252 } else if (strncmp (argv[i], "--file-sep=",
4253 strlen ("--file-sep=")) == 0) {
4254 char *p = strchr (argv[i], '=');
4255 g_assert (p != NULL);
4257 } else if (strncmp (argv[i], "--file-sep",
4258 strlen ("--file-sep")) == 0) {
4260 file_sep = (argv[i+1])[0];
4265 } else if(strcmp(argv[i], "--")==0) {
4266 /*further arguments are files*/
4268 } else if(strncmp(argv[i], "--", 2)==0) {
4269 /*unknown long option*/
4270 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4274 /*by now we know we have a string starting with
4275 - which is a short option string*/
4277 for(p = argv[i] + 1; *p; p++) {
4291 "Unknown option '%c'!\n", *p);
4300 /* if we are using m4, and got no filename, append m4 flags now */
4301 if(!got_file && use_m4 && !use_m4_clean) {
4302 char *new_commandline;
4303 new_commandline=g_strconcat(m4_commandline,
4307 g_free(m4_commandline);
4308 m4_commandline=new_commandline;
4314 compare_and_move (const char *old_filename)
4316 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4318 gboolean equal = FALSE;
4320 old_f = fopen (old_filename, "r");
4323 gboolean error = FALSE;
4325 new_f = fopen (new_filename, "r");
4334 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4335 if (ferror (new_f)) {
4337 error_printf (GOB_ERROR, 0,
4338 "Can't read %s: %s",
4340 g_strerror (errno));
4344 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4346 || feof (new_f) != feof (old_f)
4348 || memcmp (new_buf, old_buf, new_n) != 0)
4357 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4358 new_filename, g_strerror (errno));
4366 if (! equal && unlink (old_filename) != 0) {
4367 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4368 old_filename, g_strerror (errno));
4374 if (unlink (new_filename) != 0)
4375 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4376 new_filename, g_strerror (errno));
4378 if (rename (new_filename, old_filename) != 0)
4379 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4380 new_filename, old_filename,
4381 g_strerror (errno));
4385 g_free (new_filename);
4389 main(int argc, char *argv[])
4391 parse_options(argc, argv);
4394 yyin = popen(m4_commandline, "r");
4396 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4400 } else if(filename) {
4401 yyin = fopen(filename, "r");
4403 fprintf(stderr, "Error: can't open file '%s'\n",
4412 /* This is where parsing is done */
4415 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4417 /* close input file */
4418 if(use_m4) pclose(yyin);
4423 error_print (GOB_ERROR, 0, "no class defined");
4426 exit_on_error = FALSE;
4428 signals = count_signals ((Class *)class);
4429 set_properties = count_set_properties ((Class *)class) +
4430 count_set_arguments ((Class *)class);
4431 get_properties = count_get_properties ((Class *)class) +
4432 count_get_arguments ((Class *)class);
4433 overrides = count_overrides ((Class *)class);
4434 privates = count_privates ((Class *)class);
4435 protecteds = count_protecteds ((Class *)class);
4436 unreftors = count_unreftors ((Class *)class);
4437 destructors = count_destructors ((Class *)class);
4438 initializers = count_initializers ((Class *)class);
4439 glade_widgets = count_glade_widgets ((Class *)class);
4440 overrode_get_type = find_get_type ((Class *)class);
4443 make_inits ((Class *)class);
4445 need_dispose = TRUE;
4446 find_dispose ((Class *)class);
4448 if (destructors > 0 ||
4450 need_finalize = TRUE;
4451 find_finalize ((Class *)class);
4453 check_bad_symbols ((Class *)class);
4454 check_duplicate_symbols ((Class *)class);
4455 check_duplicate_overrides ((Class *)class);
4456 check_duplicate_signals_args ((Class *)class);
4457 check_public_new ((Class *)class);
4458 check_vararg ((Class *)class);
4459 check_firstarg ((Class *)class);
4460 check_nonvoidempty ((Class *)class);
4461 check_signal_args ((Class *)class);
4462 check_property_types ((Class *)class);
4463 check_argument_types ((Class *)class);
4464 check_func_arg_checks ((Class *)class);
4465 check_for_class_destructors ((Class *)class);
4467 exit_on_error = TRUE;
4472 any_special = setup_special_array ((Class *)class, special_array);
4476 generate_outfiles ();
4487 compare_and_move (outfilebase);
4489 compare_and_move (outfilephbase);
4491 if (no_touch_headers)
4492 compare_and_move (outfilehbase);