2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2004 George 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,
33 #include "treefuncs.h"
41 char *filename = NULL;
51 extern GList *include_files;
53 extern GHashTable *gtk_doc_hash;
57 static char *funcbase;
58 static char *pfuncbase;
59 static char *macrobase;
61 static char *pmacrois;
62 static char *macrotype;
63 static char *pmacrotype;
64 static char *typebase;
65 static char *ptypebase;
67 char *output_dir = NULL;
69 static int signals = 0; /* number of signals */
70 static int set_properties = 0; /* number of named (set) properties */
71 static int get_properties = 0; /* number of named (get) properties */
72 static int overrides = 0; /* number of override methods */
73 static int privates = 0; /* number of private data members */
74 static int protecteds = 0; /* number of protected methods */
75 static int unreftors = 0; /* number of variable unreffing destructors */
76 static int destructors = 0; /* number of variable non-unreffing destructors */
77 static int initializers = 0; /* number of variable initializers */
78 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
80 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
81 and need the REALLY UGLY HACK to
84 /* the special variable types we need to define */
85 static gboolean special_array[SPECIAL_LAST] = {0};
86 static gboolean any_special = FALSE;
88 static gboolean need_dispose = FALSE;
89 static Method * dispose_handler = NULL;
91 static gboolean need_finalize = FALSE;
92 static Method * finalize_handler = NULL;
99 gboolean no_touch_headers = FALSE;
100 gboolean for_cpp = FALSE;
101 gboolean no_gnu = FALSE;
102 gboolean exit_on_warn = FALSE;
103 gboolean exit_on_error = TRUE;
104 gboolean got_error = FALSE;
105 gint private_header = PRIVATE_HEADER_ONDEMAND;
106 gboolean no_extern_c = FALSE;
107 gboolean no_write = FALSE;
108 gboolean no_lines = FALSE;
109 gboolean no_self_alias = FALSE;
110 gboolean always_private_struct = FALSE;
112 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
113 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
114 char *m4_commandline = NULL;
115 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
116 #define M4_BASE_FILENAME "gobm4.m4"
117 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
118 #define M4_COMMANDLINE "m4"
120 int method_unique_id = 1;
125 filebase = replace_sep (((Class *)class)->otype, '-');
126 gob_strdown (filebase);
128 if (output_dir != NULL &&
129 output_dir[0] != '\0') {
130 fullfilebase = g_build_filename (output_dir, filebase, NULL);
132 fullfilebase = g_strdup (filebase);
135 funcbase = replace_sep (((Class *)class)->otype, '_');
136 gob_strdown (funcbase);
138 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
139 gob_strdown (pfuncbase);
141 macrobase = replace_sep (((Class *)class)->otype, '_');
142 gob_strup (macrobase);
144 macrois = make_pre_macro (((Class *)class)->otype, "IS");
145 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
147 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
148 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
150 typebase = remove_sep (((Class *)class)->otype);
152 ptypebase = remove_sep (((Class *)class)->ptype);
156 get_gtk_doc (const char *id)
163 val = g_hash_table_lookup(gtk_doc_hash, id);
165 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
167 val = g_hash_table_lookup(gtk_doc_hash, id);
169 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
175 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
179 s = get_type(t, postfix_to_stars);
180 out_printf(fp, "%s", s);
186 print_method (FILE *fp,
187 const char *typeprefix,
188 const char *nameprefix,
189 const char *subnameprefix,
190 const char *namepostfix,
191 const char *afterargs,
194 gboolean one_arg_per_line,
195 gboolean no_funcbase,
196 gboolean kill_underscore)
201 out_printf(fp, "%s", typeprefix);
202 print_type(fp, m->mtype, TRUE);
207 out_printf(fp, "%s%s%s%s(",
208 nameprefix, subnameprefix, id, namepostfix);
210 out_printf(fp, "%s%s_%s%s%s(",
211 nameprefix, funcbase, subnameprefix, id,
215 for(li=m->args; li; li=g_list_next(li)) {
216 FuncArg *arg = li->data;
217 print_type(fp, arg->atype, FALSE);
219 out_printf(fp, "%s%s,%s", arg->name,
220 arg->atype->postfix ?
221 arg->atype->postfix : "",
222 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
224 out_printf(fp, "%s%s", arg->name,
225 arg->atype->postfix ?
226 arg->atype->postfix : "");
229 out_printf(fp, ",%s...",
230 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
232 out_printf(fp, "void");
234 out_printf(fp, "%s)%s", afterargs, postfix);
238 any_method_to_alias(Class *c)
242 for(li=c->nodes;li;li=g_list_next(li)) {
243 Node *node = li->data;
244 if(node->type == METHOD_NODE) {
245 Method *m = (Method *)node;
247 if(m->method == INIT_METHOD ||
248 m->method == CLASS_INIT_METHOD ||
249 m->method == OVERRIDE_METHOD)
259 /* just the vararg macros, we use the same func pointers for these as in non-gnu */
261 make_method_gnu_aliases(Class *c)
265 for(li = c->nodes; li != NULL; li = li->next) {
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)
276 out_printf(out, "#define self_%s(args...) "
277 "%s_%s(args)\n", m->id,
280 out_printf(out, "#define self_%s() "
288 make_method_nongnu_aliases(Class *c)
292 gboolean local_made_aliases = FALSE;
294 for(li=c->nodes; li; li=g_list_next(li)) {
295 Node *node = li->data;
296 if(node->type == METHOD_NODE) {
297 Method *m = (Method *)node;
299 if(m->method == INIT_METHOD ||
300 m->method == CLASS_INIT_METHOD ||
301 m->method == OVERRIDE_METHOD)
304 if( ! local_made_aliases)
305 out_printf(out, "\n/* Short form pointers */\n");
307 print_method(out, "static ", "(* const self_", "", ") ",
309 m, FALSE, TRUE, FALSE);
310 out_printf(out, " = %s_%s;\n", funcbase,
313 local_made_aliases = TRUE;
316 if(local_made_aliases) {
317 out_printf(out, "\n");
323 add_bad_hack_to_avoid_unused_warnings(const Class *c)
327 /* if we haven't had any methods, just return */
332 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
334 "/*REALLY BAD HACK\n"
335 " This is to avoid unused warnings if you don't call\n"
336 " some method. I need to find a better way to do\n"
337 " this, not needed in GCC since we use some gcc\n"
338 " extentions to make saner, faster code */\n"
340 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
342 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
343 for(li=c->nodes;li;li=g_list_next(li)) {
344 Node *node = li->data;
345 if(node->type == METHOD_NODE) {
346 Method *m = (Method *)node;
348 if(m->method == INIT_METHOD ||
349 m->method == CLASS_INIT_METHOD ||
350 m->method == OVERRIDE_METHOD)
353 /* in C++ mode we don't alias new */
354 if(for_cpp && strcmp(m->id, "new")==0)
357 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
360 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
363 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
365 out_printf(out, "}\n\n");
369 put_variable(const Variable *v, FILE *fp)
371 out_printf(fp, "\t");
372 print_type(fp, v->vtype, FALSE);
373 out_printf(fp, "%s%s;", v->id,
375 v->vtype->postfix:"");
376 if(v->scope == PROTECTED_SCOPE)
377 out_printf(fp, " /* protected */");
378 out_printf(fp, "\n");
382 put_vs_method(const Method *m)
384 if(m->method != SIGNAL_LAST_METHOD &&
385 m->method != SIGNAL_FIRST_METHOD &&
386 m->method != VIRTUAL_METHOD)
389 /* if a signal mark it as such */
390 if(m->method != VIRTUAL_METHOD)
391 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
392 m, FALSE, TRUE, TRUE);
394 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
395 m, FALSE, TRUE, TRUE);
399 put_pub_method(const Method *m)
401 if(m->scope != PUBLIC_SCOPE)
404 print_method(outh, "", "\t", "", "\t", "", ";\n", m, TRUE, FALSE, TRUE);
408 put_signal_macro (const Method *m, gboolean gnu)
410 if(m->method != SIGNAL_LAST_METHOD &&
411 m->method != SIGNAL_FIRST_METHOD)
416 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
417 "g_signal_connect(%s(object),\"%s\","
418 "(GCallback)(func),(data))\n",
419 funcbase, m->id, macrobase, m->id);
422 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
423 "g_signal_connect_after(%s(object),\"%s\","
424 "(GCallback)(func),(data))\n",
425 funcbase, m->id, macrobase, m->id);
428 out_printf (outh, "#define %s_connect_data__%s"
429 "(object,func,data,destroy_data,flags)\t"
430 "g_signal_connect_data(%s(object),\"%s\","
431 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
432 funcbase, m->id, macrobase, m->id);
435 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
437 "%s(({%s *___object = (object); ___object; })),"
440 funcbase, m->id, macrobase, typebase, m->id);
441 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
442 " = (func); ", m, FALSE, TRUE, TRUE);
443 out_printf (outh, "___%s; }), (data))\n", m->id);
446 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
447 "g_signal_connect_after("
448 "%s(({%s *___object = (object); ___object; })),"
451 funcbase, m->id, macrobase, typebase, m->id);
452 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
453 " = (func); ", m, FALSE, TRUE, TRUE);
454 out_printf (outh, "___%s; }), (data))\n", m->id);
457 out_printf (outh, "#define %s_connect_data__%s"
458 "(object,func,data,destroy_data,flags)\t"
459 "g_signal_connect_data("
460 "%s(({%s *___object = (object); ___object; })),"
463 funcbase, m->id, macrobase, typebase, m->id);
464 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
465 " = (func); ", m, FALSE, TRUE, TRUE);
466 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
471 put_signal_macros (const Class *c, gboolean gnu)
478 for (li = c->nodes; li != NULL; li = li->next) {
479 const Node *n = li->data;
480 if (n->type == METHOD_NODE)
481 put_signal_macro ((Method *)n, gnu);
486 put_local_signal_macro (const Method *m)
488 if(m->method != SIGNAL_LAST_METHOD &&
489 m->method != SIGNAL_FIRST_METHOD)
493 out_printf (out, "#define self_connect__%s(object,func,data)\t"
494 "%s_connect__%s((object),(func),(data))\n",
495 m->id, funcbase, m->id);
498 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
499 "%s_connect_after__%s((object),(func),(data))\n",
500 m->id, funcbase, m->id);
503 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
504 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
505 m->id, funcbase, m->id);
509 put_local_signal_macros (const Class *c)
516 for (li = c->nodes; li != NULL; li = li->next) {
517 const Node *n = li->data;
518 if (n->type == METHOD_NODE)
519 put_local_signal_macro ((Method *)n);
525 put_prot_method(const Method *m)
527 if(m->scope != PROTECTED_SCOPE)
531 print_method(outph, "", "\t", "", "\t", "", ";\n",
532 m, FALSE, FALSE, TRUE);
534 print_method(out, "", "\t", "", "\t", "", ";\n",
535 m, FALSE, FALSE, TRUE);
539 put_priv_method_prot(const Method *m)
541 if(m->method == SIGNAL_LAST_METHOD ||
542 m->method == SIGNAL_FIRST_METHOD ||
543 m->method == VIRTUAL_METHOD) {
546 "static ", "___real_", "", " ", "", ";\n",
547 m, FALSE, FALSE, TRUE);
549 /* no else, here, it might still have a private prototype, it's not
552 if((m->method == OVERRIDE_METHOD &&
555 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
556 print_method(out, "static ", s, "", " ", "",
557 no_gnu?";\n":" G_GNUC_UNUSED;\n",
558 m, FALSE, FALSE, FALSE);
560 } else if(m->scope == PRIVATE_SCOPE ||
561 m->method == INIT_METHOD ||
562 m->method == CLASS_INIT_METHOD) {
563 print_method(out, "static ", "", "", " ", "",
564 no_gnu?";\n":" G_GNUC_UNUSED;\n",
565 m, FALSE, FALSE, TRUE);
570 make_func_arg (const char *typename, gboolean is_class, const char *name)
577 tn = g_strconcat (typename, ":Class", NULL);
579 tn = g_strdup (typename);
581 type = node_new (TYPE_NODE,
585 node = node_new (FUNCARG_NODE,
586 "atype:steal", (Type *)type,
589 return g_list_prepend (NULL, node);
593 make_inits(Class *cl)
595 int got_class_init = FALSE;
596 int got_init = FALSE;
599 for(li=cl->nodes;li;li=g_list_next(li)) {
601 if(n->type == METHOD_NODE) {
602 Method *m = (Method *)n;
603 if(m->method == INIT_METHOD) {
605 error_print(GOB_ERROR, m->line_no, "init defined more then once");
607 } else if(m->method == CLASS_INIT_METHOD) {
609 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
610 got_class_init = TRUE;
614 if(!got_class_init) {
615 Type *type = (Type *)node_new (TYPE_NODE,
618 node = node_new (METHOD_NODE,
620 "method", CLASS_INIT_METHOD,
623 "args:steal", make_func_arg (cl->otype,
626 "unique_id", method_unique_id++,
628 cl->nodes = g_list_prepend(cl->nodes, node);
631 Type *type = (Type *)node_new (TYPE_NODE,
634 node = node_new (METHOD_NODE,
636 "method", INIT_METHOD,
639 "args:steal", make_func_arg (cl->otype,
640 FALSE /* is_class */,
642 "unique_id", method_unique_id++,
644 cl->nodes = g_list_prepend(cl->nodes, node);
649 find_dispose(const Class *cl)
653 dispose_handler = NULL;
654 for(li=cl->nodes;li;li=g_list_next(li)) {
656 if(n->type == METHOD_NODE) {
657 Method *m = (Method *)n;
658 if(m->method == OVERRIDE_METHOD &&
659 strcmp(m->id, "dispose")==0) {
660 if(strcmp(m->otype, "G:Object") != 0) {
661 error_print(GOB_ERROR, m->line_no,
662 "dispose method override "
663 "of class other then "
666 if(g_list_length(m->args) != 1) {
667 error_print(GOB_ERROR, m->line_no,
668 "dispose method override "
669 "with more then one "
680 find_finalize(const Class *cl)
684 finalize_handler = NULL;
685 for(li=cl->nodes;li;li=g_list_next(li)) {
687 if(n->type == METHOD_NODE) {
688 Method *m = (Method *)n;
689 if(m->method == OVERRIDE_METHOD &&
690 strcmp(m->id, "finalize")==0) {
691 if(strcmp(m->otype, "G:Object") != 0) {
692 error_print(GOB_ERROR, m->line_no,
693 "finalize method override "
694 "of class other then "
697 if(g_list_length(m->args) != 1) {
698 error_print(GOB_ERROR, m->line_no,
699 "finalize method override "
700 "with more then one "
703 finalize_handler = m;
711 /* hash of method -> name of signal prototype */
712 static GHashTable *marsh = NULL;
714 /* list of methods with different signal prototypes,
715 we check this list if we can use a signal prototype of a
716 previous signal method, there are only uniques here */
717 static GList *eq_signal_methods = NULL;
719 /* compare a list of strings */
721 is_list_equal(const GList *a, const GList *b)
723 for(;a && b; a=a->next, b=b->next) {
724 if(strcmp(a->data, b->data)!=0) {
728 /* the the lists were different length */
735 find_same_type_signal(const Method *m)
738 for(li=eq_signal_methods;li;li=li->next) {
739 Method *mm = li->data;
740 if(is_list_equal(mm->gtktypes, m->gtktypes))
747 print_signal_marsal_args (const Method *m)
749 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
752 for (i = 0, li = m->gtktypes->next;
754 i++, li = li->next) {
757 if (strcmp (li->data, "UNICHAR") == 0)
758 /* hack because glib is braindamaged */
759 get_func = g_strdup ("g_value_get_uint");
761 get_func = g_strdup_printf
762 ("g_value_get_%s", (char *)li->data);
764 gob_strdown (get_func);
765 out_printf (out, ",\n\t\t(%s) "
766 "%s (param_values + %d)",
767 get_cast (li->data, FALSE),
772 out_printf (out, ",\n\t\tdata2);\n");
777 add_signal_prots(Method *m)
783 gboolean ret_none = FALSE;
784 gboolean arglist_none = FALSE;
787 if (m->method != SIGNAL_LAST_METHOD &&
788 m->method != SIGNAL_FIRST_METHOD)
792 marsh = g_hash_table_new(NULL, NULL);
794 g_assert (m->gtktypes->next != NULL);
796 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
797 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
799 if (ret_none && arglist_none)
802 /* if we already did a signal prototype just use that */
803 mm = find_same_type_signal (m);
805 s = g_hash_table_lookup (marsh, mm);
806 g_hash_table_insert (marsh, m, s);
813 retcast = get_cast (m->gtktypes->data, FALSE);
815 s = g_strdup_printf("Sig%d", sig++);
817 g_hash_table_insert(marsh, m, s);
818 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
820 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
821 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
822 get_cast(m->gtktypes->data, FALSE), s, typebase);
824 if ( ! arglist_none) {
825 for (li = m->gtktypes->next; li != NULL; li = li->next)
826 out_printf (out, "%s, ", get_cast (li->data, FALSE));
828 out_printf (out, "gpointer);\n");
830 out_printf (out, "\nstatic void\n"
831 "___marshal_%s (GClosure *closure,\n"
832 "\tGValue *return_value,\n"
833 "\tguint n_param_values,\n"
834 "\tconst GValue *param_values,\n"
835 "\tgpointer invocation_hint,\n"
836 "\tgpointer marshal_data)\n"
840 out_printf (out, "\t%s v_return;\n", retcast);
842 out_printf (out, "\tregister ___%s callback;\n"
843 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
844 "\tregister gpointer data1, data2;\n\n",
847 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
848 arglist_none ? 1 : g_list_length (m->gtktypes));
851 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
852 "\t\tdata1 = closure->data;\n"
853 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
855 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
856 "\t\tdata2 = closure->data;\n"
859 out_printf (out, "\tcallback = (___%s) "
860 "(marshal_data != NULL ? marshal_data : cc->callback);"
864 out_printf (out, "\tcallback ((%s *)data1", typebase);
866 out_printf (out, "\tv_return = callback ((%s *)data1",
870 print_signal_marsal_args (m);
873 /* FIXME: This code is so fucking ugly it hurts */
874 gboolean take_ownership =
875 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
876 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
880 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
881 /* hack because glib is braindamaged */
882 set_func = g_strdup ("g_value_set_uint");
884 set_func = g_strdup_printf ("g_value_set_%s%s",
885 (char *)m->gtktypes->data,
887 "_take_ownership" : "");
888 gob_strdown (set_func);
890 out_printf (out, "\n\t%s (return_value, v_return);\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\t0 /* n_preallocs */,\n"
1082 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1084 funcbase, typebase, funcbase, typebase, funcbase);
1086 add_interface_infos ();
1089 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)0);\n",
1090 pmacrotype, typebase);
1098 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1100 chunk_size, chunk_size);
1110 add_bonobo_object_get_type (void)
1112 /* char *chunk_size = ((Class*)class)->chunk_size; */
1113 /* _vicious_ spanks seth with a rusty nail
1115 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1116 "gob2 doesn't officially support it yet. It'd be safer "
1117 "and a lot more fun to blow goats.\"\n");
1122 "%s_get_type (void)\n" /* 1 */
1124 "\tstatic GType type = 0;\n\n"
1125 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1126 "\t\tstatic const GTypeInfo info = {\n"
1127 "\t\t\tsizeof (%sClass),\n" /* 2 */
1128 "\t\t\t(GBaseInitFunc) NULL,\n"
1129 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1130 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1131 "\t\t\tNULL, /* class_finalize */\n"
1132 "\t\t\tNULL, /* class_data */\n"
1133 "\t\t\tsizeof (%s),\n" /* 4 */
1134 "\t\t\t0, /* n_preallocs */\n"
1135 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1144 add_interface_infos ();
1147 "\t\ttype = bonobo_type_unique (\n"
1148 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1149 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1150 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1151 "\t\t\t&info, \"%s\");\n", /* 3 */
1152 ((Class*)class)->bonobo_object_class /* 1 */,
1161 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1163 chunk_size, chunk_size);
1172 add_overrides(Class *c, const char *oname,
1173 gboolean did_base_obj)
1179 done = g_hash_table_new (g_str_hash, g_str_equal);
1181 s = g_strdup ("GObject");
1182 g_hash_table_insert (done, s, s);
1184 for (li = c->nodes; li != NULL; li = li->next) {
1187 Method *m = (Method *)n;
1188 if(n->type != METHOD_NODE ||
1189 m->method != OVERRIDE_METHOD)
1192 s = remove_sep(m->otype);
1194 if(g_hash_table_lookup(done, s)) {
1198 g_hash_table_insert(done, s, s);
1200 f = replace_sep(m->otype, '_');
1203 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1208 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1209 g_hash_table_destroy (done);
1213 make_run_signal_flags(Method *m, gboolean last)
1228 gs = g_string_new(NULL);
1231 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1233 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1235 if(m->scope == PUBLIC_SCOPE)
1236 g_string_append(gs, " | G_SIGNAL_ACTION");
1238 for(li = m->flags; li; li = li->next) {
1239 char *flag = li->data;
1241 for(i=0;flags[i];i++) {
1242 if(strcmp(flags[i], flag)==0)
1245 /* if we haven't found it in our list */
1247 error_printf(GOB_WARN, m->line_no,
1248 "Unknown flag '%s' used, "
1249 "perhaps it was misspelled",
1252 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1256 char *ret = gs->str;
1257 g_string_free(gs, FALSE);
1264 add_signals(Class *c)
1268 out_printf(out, "\n");
1269 for(li=c->nodes;li;li=g_list_next(li)) {
1271 char *mar, *sig, *flags;
1272 gboolean is_none, last = FALSE;
1273 Method *m = (Method *)n;
1275 if(n->type != METHOD_NODE ||
1276 (m->method != SIGNAL_FIRST_METHOD &&
1277 m->method != SIGNAL_LAST_METHOD))
1280 if(m->method == SIGNAL_FIRST_METHOD)
1285 if(g_hash_table_lookup(marsh, m))
1286 mar = g_strconcat("___marshal_",
1287 (char *)g_hash_table_lookup(marsh, m),
1290 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1292 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1294 sig = g_strdup (m->id);
1296 flags = make_run_signal_flags (m, last);
1297 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1298 "\t\tg_signal_new (\"%s\",\n"
1299 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1300 "\t\t\t(GSignalFlags)(%s),\n"
1301 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1302 "\t\t\tNULL, NULL,\n"
1304 "\t\t\tG_TYPE_%s, %d",
1307 typebase, m->id, mar,
1308 (char *)m->gtktypes->data,
1309 is_none ? 0 : g_list_length(m->gtktypes->next));
1316 for(l = m->gtktypes->next; l != NULL; l = l->next)
1317 out_printf(out, ",\n\t\t\tG_TYPE_%s",
1321 out_printf(out, ");\n");
1323 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1326 const char *sep = "";
1327 out_printf(out, "\tif ___GOB_UNLIKELY(");
1328 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1329 out_printf(out, "%s sizeof(", sep);
1330 print_type(out, m->mtype, FALSE);
1331 out_printf(out, "%s",
1333 m->mtype->postfix : "");
1334 out_printf(out, ") != sizeof(%s)",
1335 get_cast(m->gtktypes->data, FALSE));
1340 for(al = m->args->next, gl = m->gtktypes->next;
1341 al != NULL && gl != NULL;
1342 al = al->next, gl = gl->next) {
1343 FuncArg *arg = al->data;
1344 char *gtkarg = gl->data;
1346 out_printf(out, "%ssizeof(", sep);
1347 print_type(out, arg->atype, FALSE);
1348 out_printf(out, "%s",
1349 arg->atype->postfix ?
1350 arg->atype->postfix : "");
1351 out_printf(out, ") != sizeof(%s)",
1352 get_cast(gtkarg, FALSE));
1356 out_printf(out, ") {\n"
1357 "\t\tg_error(\"%s line %d: Type mismatch "
1358 "of \\\"%s\\\" signal signature\");\n"
1360 filename, m->line_no, m->id);
1367 set_def_handlers(Class *c, const char *oname)
1370 gboolean set_line = FALSE;
1372 out_printf(out, "\n");
1373 for(li = c->nodes; li; li = g_list_next(li)) {
1375 Method *m = (Method *)n;
1377 if(n->type != METHOD_NODE ||
1378 (m->method != SIGNAL_FIRST_METHOD &&
1379 m->method != SIGNAL_LAST_METHOD &&
1380 m->method != VIRTUAL_METHOD &&
1381 m->method != OVERRIDE_METHOD))
1384 if(m->line_no > 0 && m->cbuf) {
1385 out_addline_infile(out, m->line_no);
1387 } else if(set_line) {
1388 out_addline_outfile(out);
1393 if (m->method == OVERRIDE_METHOD) {
1395 s = replace_sep (m->otype, '_');
1399 dispose_handler != NULL &&
1400 strcmp (m->id, "dispose") == 0)
1401 out_printf (out, "\tg_object_class->dispose "
1403 else if (need_finalize &&
1405 strcmp(m->id, "finalize") == 0)
1407 "\tg_object_class->finalize = ___finalize;\n");
1408 else if (m->cbuf != NULL)
1410 "\t%s_class->%s = ___%x_%s_%s;\n",
1411 s, m->id, (guint)m->unique_id,
1414 out_printf(out, "\t%s_class->%s = NULL;\n",
1418 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1422 out_printf(out, "\t%s->%s = NULL;\n",
1427 out_addline_outfile(out);
1431 make_argument (Argument *a)
1436 char *argflags[] = {
1444 flags = g_string_new ("(GParamFlags)(");
1446 if(a->get && a->set)
1447 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1449 g_string_append (flags, "G_PARAM_READABLE");
1451 g_string_append (flags, "G_PARAM_WRITABLE");
1453 g_assert(a->get || a->set);
1455 for (l = a->flags; l != NULL; l = l->next) {
1456 char *flag = l->data;
1458 if(strcmp (flag, "READABLE") == 0 ||
1459 strcmp (flag, "WRITABLE") == 0) {
1460 error_print(GOB_WARN, a->line_no,
1462 "WRITABLE argument flags are "
1463 "set automatically");
1466 for(i = 0; argflags[i]; i++) {
1467 if(strcmp(argflags[i], flag)==0)
1470 /* if we haven't found it in our list */
1471 if( ! argflags[i]) {
1472 error_printf(GOB_WARN, a->line_no,
1473 "Unknown flag '%s' used, "
1474 "perhaps it was misspelled", flag);
1476 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1479 g_string_append (flags, ")");
1481 s = g_strdup(a->name);
1483 if (!strcmp (a->gtktype, "ENUM"))
1484 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1485 "\t\tG_TYPE_ENUM, 0,\n"
1487 a->name, flags->str);
1488 if (!strcmp (a->gtktype, "FLAGS"))
1489 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1490 "\t\tG_TYPE_FLAGS, 0,\n"
1492 a->name, flags->str);
1493 else if (!strcmp (a->gtktype, "OBJECT"))
1494 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1495 "\t\tG_TYPE_OBJECT,\n"
1497 a->name, flags->str);
1498 else if (!strcmp (a->gtktype, "STRING"))
1499 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1502 a->name, flags->str);
1503 else if (!strcmp (a->gtktype, "INT"))
1504 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1505 "\t\tG_MININT, G_MAXINT,\n"
1508 a->name, flags->str);
1509 else if (!strcmp (a->gtktype, "UINT"))
1510 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1511 "\t\t0, G_MAXUINT,\n"
1514 a->name, flags->str);
1515 else if (!strcmp (a->gtktype, "INT"))
1516 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1517 "\t\tG_MININT, G_MAXINT,\n"
1520 a->name, flags->str);
1521 else if (!strcmp (a->gtktype, "CHAR"))
1522 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1526 a->name, flags->str);
1527 else if (!strcmp (a->gtktype, "UCHAR"))
1528 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1532 a->name, flags->str);
1533 else if (!strcmp (a->gtktype, "BOOL") ||
1534 !strcmp (a->gtktype, "BOOLEAN"))
1535 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1538 a->name, flags->str);
1539 else if (!strcmp (a->gtktype, "LONG"))
1540 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1541 "\t\tG_MINLONG, G_MAXLONG,\n"
1544 a->name, flags->str);
1545 else if (!strcmp (a->gtktype, "ULONG"))
1546 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1547 "\t\t0, G_MAXULONG,\n"
1550 a->name, flags->str);
1551 else if (!strcmp (a->gtktype, "INT64"))
1552 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1553 "\t\tG_MININT64, G_MAXINT64,\n"
1556 a->name, flags->str);
1557 else if (!strcmp (a->gtktype, "UINT64"))
1558 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1559 "\t\t0, G_MAXUINT64,\n"
1562 a->name, flags->str);
1563 else if (!strcmp (a->gtktype, "FLOAT"))
1564 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1565 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1568 a->name, flags->str);
1569 else if (!strcmp (a->gtktype, "DOUBLE"))
1570 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1571 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1574 a->name, flags->str);
1575 else if (!strcmp (a->gtktype, "POINTER"))
1576 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1578 a->name, flags->str);
1580 error_printf (GOB_ERROR, a->line_no,
1581 "%s type is not supported for arguments, try using properties",
1584 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1585 "\t\tPROP_%s, param_spec);\n", s);
1589 g_string_free(flags, TRUE);
1592 #define value_for_print(str, alt) (str != NULL ? str : alt)
1595 make_property (Property *p)
1600 char *argflags[] = {
1608 flags = g_string_new ("(GParamFlags)(");
1610 if (p->get != NULL && p->set != NULL)
1611 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1612 else if (p->get != NULL)
1613 g_string_append (flags, "G_PARAM_READABLE");
1615 g_string_append (flags, "G_PARAM_WRITABLE");
1617 if (p->get == NULL && p->set == NULL) {
1618 error_print (GOB_ERROR, p->line_no,
1619 "Property has no getter nor setter");
1622 for (l = p->flags; l != NULL; l = l->next) {
1623 char *flag = l->data;
1625 if(strcmp (flag, "READABLE") == 0 ||
1626 strcmp (flag, "WRITABLE") == 0) {
1627 error_print(GOB_WARN, p->line_no,
1629 "WRITABLE argument flags are "
1630 "set automatically");
1633 for(i = 0; argflags[i]; i++) {
1634 if(strcmp(argflags[i], flag)==0)
1637 /* if we haven't found it in our list */
1638 if( ! argflags[i]) {
1639 error_printf(GOB_WARN, p->line_no,
1640 "Unknown flag '%s' used, "
1641 "perhaps it was misspelled", flag);
1643 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1646 g_string_append (flags, ")");
1648 if (strcmp (p->gtktype, "CHAR") == 0) {
1649 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1650 "\t\t(\"%s\" /* name */,\n"
1651 "\t\t %s /* nick */,\n"
1652 "\t\t %s /* blurb */,\n"
1653 "\t\t %s /* minimum */,\n"
1654 "\t\t %s /* maximum */,\n"
1655 "\t\t %s /* default_value */,\n"
1658 value_for_print (p->nick, "NULL"),
1659 value_for_print (p->blurb, "NULL"),
1660 value_for_print (p->minimum, "-128"),
1661 value_for_print (p->maximum, "127"),
1662 value_for_print (p->default_value, "0"),
1664 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1665 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1666 "\t\t(\"%s\" /* name */,\n"
1667 "\t\t %s /* nick */,\n"
1668 "\t\t %s /* blurb */,\n"
1669 "\t\t %s /* minimum */,\n"
1670 "\t\t %s /* maximum */,\n"
1671 "\t\t %s /* default_value */,\n"
1674 value_for_print (p->nick, "NULL"),
1675 value_for_print (p->blurb, "NULL"),
1676 value_for_print (p->minimum, "0"),
1677 value_for_print (p->maximum, "0xFF"),
1678 value_for_print (p->default_value, "0"),
1680 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1681 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1682 "\t\t(\"%s\" /* name */,\n"
1683 "\t\t %s /* nick */,\n"
1684 "\t\t %s /* blurb */,\n"
1685 "\t\t %s /* default_value */,\n"
1688 value_for_print (p->nick, "NULL"),
1689 value_for_print (p->blurb, "NULL"),
1690 value_for_print (p->default_value, "FALSE"),
1692 } else if (strcmp (p->gtktype, "INT") == 0) {
1693 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1694 "\t\t(\"%s\" /* name */,\n"
1695 "\t\t %s /* nick */,\n"
1696 "\t\t %s /* blurb */,\n"
1697 "\t\t %s /* minimum */,\n"
1698 "\t\t %s /* maximum */,\n"
1699 "\t\t %s /* default_value */,\n"
1702 value_for_print (p->nick, "NULL"),
1703 value_for_print (p->blurb, "NULL"),
1704 value_for_print (p->minimum, "G_MININT"),
1705 value_for_print (p->maximum, "G_MAXINT"),
1706 value_for_print (p->default_value, "0"),
1708 } else if (strcmp (p->gtktype, "UINT") == 0) {
1709 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1710 "\t\t(\"%s\" /* name */,\n"
1711 "\t\t %s /* nick */,\n"
1712 "\t\t %s /* blurb */,\n"
1713 "\t\t %s /* minimum */,\n"
1714 "\t\t %s /* maximum */,\n"
1715 "\t\t %s /* default_value */,\n"
1718 value_for_print (p->nick, "NULL"),
1719 value_for_print (p->blurb, "NULL"),
1720 value_for_print (p->minimum, "0"),
1721 value_for_print (p->maximum, "G_MAXUINT"),
1722 value_for_print (p->default_value, "0"),
1724 } else if (strcmp (p->gtktype, "LONG") == 0) {
1725 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1726 "\t\t(\"%s\" /* name */,\n"
1727 "\t\t %s /* nick */,\n"
1728 "\t\t %s /* blurb */,\n"
1729 "\t\t %s /* minimum */,\n"
1730 "\t\t %s /* maximum */,\n"
1731 "\t\t %s /* default_value */,\n"
1734 value_for_print (p->nick, "NULL"),
1735 value_for_print (p->blurb, "NULL"),
1736 value_for_print (p->minimum, "G_MINLONG"),
1737 value_for_print (p->maximum, "G_MAXLONG"),
1738 value_for_print (p->default_value, "0"),
1740 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1741 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1742 "\t\t(\"%s\" /* name */,\n"
1743 "\t\t %s /* nick */,\n"
1744 "\t\t %s /* blurb */,\n"
1745 "\t\t %s /* minimum */,\n"
1746 "\t\t %s /* maximum */,\n"
1747 "\t\t %s /* default_value */,\n"
1750 value_for_print (p->nick, "NULL"),
1751 value_for_print (p->blurb, "NULL"),
1752 value_for_print (p->minimum, "0"),
1753 value_for_print (p->maximum, "G_MAXULONG"),
1754 value_for_print (p->default_value, "0"),
1756 } else if (strcmp (p->gtktype, "INT64") == 0) {
1757 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1758 "\t\t(\"%s\" /* name */,\n"
1759 "\t\t %s /* nick */,\n"
1760 "\t\t %s /* blurb */,\n"
1761 "\t\t %s /* minimum */,\n"
1762 "\t\t %s /* maximum */,\n"
1763 "\t\t %s /* default_value */,\n"
1766 value_for_print (p->nick, "NULL"),
1767 value_for_print (p->blurb, "NULL"),
1768 value_for_print (p->minimum, "G_MININT64"),
1769 value_for_print (p->maximum, "G_MAXINT64"),
1770 value_for_print (p->default_value, "0"),
1772 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1773 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1774 "\t\t(\"%s\" /* name */,\n"
1775 "\t\t %s /* nick */,\n"
1776 "\t\t %s /* blurb */,\n"
1777 "\t\t %s /* minimum */,\n"
1778 "\t\t %s /* maximum */,\n"
1779 "\t\t %s /* default_value */,\n"
1782 value_for_print (p->nick, "NULL"),
1783 value_for_print (p->blurb, "NULL"),
1784 value_for_print (p->minimum, "0"),
1785 value_for_print (p->maximum, "G_MAXUINT64"),
1786 value_for_print (p->default_value, "0"),
1788 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1789 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1790 "\t\t(\"%s\" /* name */,\n"
1791 "\t\t %s /* nick */,\n"
1792 "\t\t %s /* blurb */,\n"
1793 "\t\t %s /* default_value */,\n"
1796 value_for_print (p->nick, "NULL"),
1797 value_for_print (p->blurb, "NULL"),
1798 value_for_print (p->default_value, "0"),
1800 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1801 char *type = make_me_type (p->extra_gtktype,
1803 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1804 "\t\t(\"%s\" /* name */,\n"
1805 "\t\t %s /* nick */,\n"
1806 "\t\t %s /* blurb */,\n"
1807 "\t\t %s /* enum_type */,\n"
1808 "\t\t %s /* default_value */,\n"
1811 value_for_print (p->nick, "NULL"),
1812 value_for_print (p->blurb, "NULL"),
1814 value_for_print (p->default_value, "0"),
1817 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1818 char *type = make_me_type (p->extra_gtktype,
1820 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1821 "\t\t(\"%s\" /* name */,\n"
1822 "\t\t %s /* nick */,\n"
1823 "\t\t %s /* blurb */,\n"
1824 "\t\t %s /* flags_type */,\n"
1825 "\t\t %s /* default_value */,\n"
1828 value_for_print (p->nick, "NULL"),
1829 value_for_print (p->blurb, "NULL"),
1831 value_for_print (p->default_value, "0"),
1834 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1835 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1836 "\t\t(\"%s\" /* name */,\n"
1837 "\t\t %s /* nick */,\n"
1838 "\t\t %s /* blurb */,\n"
1839 "\t\t %s /* minimum */,\n"
1840 "\t\t %s /* maximum */,\n"
1841 "\t\t %s /* default_value */,\n"
1844 value_for_print (p->nick, "NULL"),
1845 value_for_print (p->blurb, "NULL"),
1846 value_for_print (p->minimum, "G_MINFLOAT"),
1847 value_for_print (p->maximum, "G_MAXFLOAT"),
1848 value_for_print (p->default_value, "0.0"),
1850 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1851 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1852 "\t\t(\"%s\" /* name */,\n"
1853 "\t\t %s /* nick */,\n"
1854 "\t\t %s /* blurb */,\n"
1855 "\t\t %s /* minimum */,\n"
1856 "\t\t %s /* maximum */,\n"
1857 "\t\t %s /* default_value */,\n"
1860 value_for_print (p->nick, "NULL"),
1861 value_for_print (p->blurb, "NULL"),
1862 value_for_print (p->minimum, "G_MINDOUBLE"),
1863 value_for_print (p->maximum, "G_MAXDOUBLE"),
1864 value_for_print (p->default_value, "0.0"),
1866 } else if (strcmp (p->gtktype, "STRING") == 0) {
1867 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1868 "\t\t(\"%s\" /* name */,\n"
1869 "\t\t %s /* nick */,\n"
1870 "\t\t %s /* blurb */,\n"
1871 "\t\t %s /* default_value */,\n"
1874 value_for_print (p->nick, "NULL"),
1875 value_for_print (p->blurb, "NULL"),
1876 value_for_print (p->default_value, "NULL"),
1878 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1879 char *type = make_me_type (p->extra_gtktype,
1881 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1882 "\t\t(\"%s\" /* name */,\n"
1883 "\t\t %s /* nick */,\n"
1884 "\t\t %s /* blurb */,\n"
1885 "\t\t %s /* param_type */,\n"
1888 value_for_print (p->nick, "NULL"),
1889 value_for_print (p->blurb, "NULL"),
1893 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1894 char *type = make_me_type (p->extra_gtktype,
1896 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1897 "\t\t(\"%s\" /* name */,\n"
1898 "\t\t %s /* nick */,\n"
1899 "\t\t %s /* blurb */,\n"
1900 "\t\t %s /* boxed_type */,\n"
1903 value_for_print (p->nick, "NULL"),
1904 value_for_print (p->blurb, "NULL"),
1908 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1909 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1910 "\t\t(\"%s\" /* name */,\n"
1911 "\t\t %s /* nick */,\n"
1912 "\t\t %s /* blurb */,\n"
1915 value_for_print (p->nick, "NULL"),
1916 value_for_print (p->blurb, "NULL"),
1918 /* FIXME: VALUE_ARRAY */
1919 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1920 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1921 "\t\t(\"%s\" /* name */,\n"
1922 "\t\t %s /* nick */,\n"
1923 "\t\t %s /* blurb */,\n"
1926 value_for_print (p->nick, "NULL"),
1927 value_for_print (p->blurb, "NULL"),
1929 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
1930 char *type = make_me_type (p->extra_gtktype,
1932 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1933 "\t\t(\"%s\" /* name */,\n"
1934 "\t\t %s /* nick */,\n"
1935 "\t\t %s /* blurb */,\n"
1936 "\t\t %s /* object_type */,\n"
1939 value_for_print (p->nick, "NULL"),
1940 value_for_print (p->blurb, "NULL"),
1945 error_printf (GOB_ERROR, p->line_no,
1946 "%s type is not supported by properties",
1950 s = g_strdup (p->name);
1952 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1954 "\t\tparam_spec);\n", s);
1957 g_string_free (flags, TRUE);
1961 make_arguments(Class *c)
1964 if (get_properties > 0)
1965 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1966 if (set_properties > 0)
1967 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1968 out_printf (out, " {\n"
1969 "\tGParamSpec *param_spec;\n\n");
1971 for (li = c->nodes; li != NULL; li = li->next) {
1973 if (n->type == PROPERTY_NODE)
1974 make_property ((Property *)n);
1975 else if (n->type == ARGUMENT_NODE)
1976 make_argument ((Argument *)n);
1978 out_printf(out, " }\n");
1982 print_initializer(Method *m, Variable *v)
1986 if(v->initializer == NULL)
1989 if(v->scope == PRIVATE_SCOPE)
1990 root = g_strconcat(((FuncArg *)m->args->data)->name,
1993 root = g_strdup(((FuncArg *)m->args->data)->name);
1995 if(v->initializer_line > 0)
1996 out_addline_infile(out, v->initializer_line);
1998 out_printf(out, "\t%s->%s = %s;\n",
1999 root, v->id, v->initializer);
2001 if(v->initializer_line > 0)
2002 out_addline_outfile(out);
2008 print_destructor (Variable *v)
2012 if(v->destructor == NULL)
2015 if(v->scope == PRIVATE_SCOPE)
2016 root = "self->_priv";
2020 if(v->destructor_simple) {
2021 if(v->destructor_line > 0)
2022 out_addline_infile(out, v->destructor_line);
2024 out_printf(out, "\tif(%s->%s) { "
2025 "((*(void (*)(void *))%s)) (%s->%s); "
2026 "%s->%s = NULL; }\n",
2027 root, v->id, v->destructor, root, v->id,
2030 if(v->destructor_line > 0)
2031 out_addline_outfile(out);
2033 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2034 out_printf(out, "#define VAR %s\n", v->id);
2035 out_printf(out, "\t{\n");
2036 if(v->destructor_line > 0)
2037 out_addline_infile(out, v->destructor_line);
2039 out_printf(out, "\t%s}\n", v->destructor);
2041 if(v->destructor_line > 0)
2042 out_addline_outfile(out);
2043 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
2045 out_printf(out, "#undef VAR\n");
2046 out_printf(out, "#undef %s\n", v->id);
2051 add_dispose (Class *c)
2053 out_printf(out, "\nstatic void\n"
2054 "___dispose (GObject *obj_self)\n"
2057 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2060 if (unreftors > 0) {
2061 out_printf (out, "\t%s *self = %s (obj_self);\n",
2062 typebase, macrobase);
2065 if (dispose_handler != NULL) {
2066 /* so we get possible bad argument warning */
2067 if (dispose_handler->line_no > 0)
2068 out_addline_infile (out, dispose_handler->line_no);
2069 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2070 (guint)dispose_handler->unique_id, funcbase);
2071 if (dispose_handler->line_no > 0)
2072 out_addline_outfile (out);
2075 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2076 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2079 if (unreftors > 0) {
2081 for(li = ((Class *)class)->nodes;
2085 Variable *v = (Variable *)n;
2086 if (n->type == VARIABLE_NODE &&
2087 v->scope != CLASS_SCOPE &&
2088 v->destructor_unref)
2089 print_destructor (v);
2093 out_printf (out, "\treturn;\n");
2095 out_printf(out, "\tself = NULL;\n");
2096 out_printf(out, "}\n"
2097 "#undef __GOB_FUNCTION__\n\n");
2101 add_finalize (Class *c)
2105 "___finalize(GObject *obj_self)\n"
2108 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2113 out_printf(out, "\t%s *self = %s (obj_self);\n",
2114 typebase, macrobase);
2117 out_printf(out, "\tgpointer priv = self->_priv;\n");
2120 if(finalize_handler) {
2121 /* so we get possible bad argument warning */
2122 if(finalize_handler->line_no > 0)
2123 out_addline_infile(out, finalize_handler->line_no);
2124 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2125 (guint)finalize_handler->unique_id, funcbase);
2126 if(finalize_handler->line_no > 0)
2127 out_addline_outfile(out);
2130 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2131 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2134 if (destructors > 0) {
2136 for (li = ((Class *)class)->nodes;
2140 Variable *v = (Variable *)n;
2141 if (n->type == VARIABLE_NODE &&
2142 v->scope != CLASS_SCOPE &&
2143 ! v->destructor_unref)
2144 print_destructor (v);
2149 out_printf(out, "\tg_free (priv);\n");
2151 out_printf (out, "\treturn;\n");
2152 if (destructors > 0 ||
2154 out_printf (out, "\tself = NULL;\n");
2156 out_printf(out, "}\n"
2157 "#undef __GOB_FUNCTION__\n\n");
2161 make_bonobo_object_epv (Class *c, const char *classname)
2164 gboolean added_line = FALSE;
2166 for (li = c->nodes; li != NULL; li = li->next) {
2168 Method *m = (Method *)n;
2169 if(n->type != METHOD_NODE ||
2170 m->method == OVERRIDE_METHOD)
2173 if (m->bonobo_object_func) {
2174 if(m->line_no > 0) {
2175 out_addline_infile(out, m->line_no);
2177 } else if (m->line_no == 0 &&
2179 out_addline_outfile(out);
2182 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2183 classname, m->id, m->id);
2187 out_addline_outfile(out);
2194 for(li=c->nodes;li;li=g_list_next(li)) {
2198 gboolean add_unused_class = FALSE;
2200 if(n->type != METHOD_NODE)
2203 if(m->method == INIT_METHOD) {
2205 out_addline_infile(out, m->line_no);
2206 print_method(out, "static ", "\n", "", " ", "", "\n",
2207 m, FALSE, FALSE, TRUE);
2209 out_addline_outfile(out);
2210 out_printf(out, "{\n"
2211 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2214 out_printf(out, "\t%s->_priv = "
2215 "g_new0 (%sPrivate, 1);\n",
2216 ((FuncArg *)m->args->data)->name,
2218 } else if(always_private_struct) {
2219 out_printf(out, "\t%s->_priv = NULL;\n",
2220 ((FuncArg *)m->args->data)->name);
2222 if(initializers > 0) {
2224 for(li = ((Class *)class)->nodes;
2228 Variable *v = (Variable *)n;
2229 if(n->type != VARIABLE_NODE ||
2230 v->scope == CLASS_SCOPE)
2232 print_initializer(m, v);
2235 } else if(m->method == CLASS_INIT_METHOD) {
2236 gboolean did_base_obj = FALSE;
2239 out_addline_infile(out, m->line_no);
2240 print_method(out, "static ", "\n", "", " ", "", "\n",
2241 m, FALSE, FALSE, TRUE);
2243 out_addline_outfile(out);
2244 out_printf(out, "{\n"
2245 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2247 if (set_properties > 0 ||
2248 get_properties > 0 ||
2255 "(GObjectClass*) %s;\n",
2256 ((FuncArg *)m->args->data)->name);
2257 add_unused_class = TRUE;
2258 did_base_obj = TRUE;
2263 ((FuncArg *)m->args->data)->name,
2266 if (initializers > 0) {
2268 for(li = ((Class *)class)->nodes;
2272 Variable *v = (Variable *)n;
2273 if(n->type == VARIABLE_NODE &&
2274 v->scope == CLASS_SCOPE)
2275 print_initializer(m, v);
2279 out_printf(out, "\n\tparent_class = ");
2281 out_printf(out, "(%sClass *)", ptypebase);
2282 out_printf(out, "g_type_class_ref (%s);\n",
2288 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2290 /* if there are no handlers for these things, we
2291 * need to set them up here */
2292 if(need_dispose && !dispose_handler)
2293 out_printf(out, "\tg_object_class->dispose "
2295 if(need_finalize && !finalize_handler)
2296 out_printf(out, "\tg_object_class->finalize = "
2299 if(get_properties > 0 || set_properties > 0)
2302 if (c->bonobo_object_class != NULL) {
2303 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2309 out_printf(out, " {\n");
2310 out_addline_infile(out, m->ccode_line);
2311 out_printf(out, "%s\n", m->cbuf);
2312 out_addline_outfile(out);
2313 out_printf(out, " }\n");
2315 out_printf(out, "\treturn;\n");
2318 ((FuncArg *)m->args->data)->name);
2319 if(add_unused_class) {
2320 out_printf (out, "\tg_object_class = NULL;\n");
2322 out_printf(out, "}\n"
2323 "#undef __GOB_FUNCTION__\n");
2328 add_argument (Argument *a, gboolean is_set)
2332 char *the_type_lower;
2337 line_no = a->set_line;
2340 line_no = a->get_line;
2344 s = g_strdup(a->name);
2346 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2348 the_type_lower = g_strdup (a->gtktype);
2349 gob_strdown (the_type_lower);
2351 /* HACK because there is no g_value_set/get for unichar */
2352 if (strcmp (the_type_lower, "unichar") == 0) {
2353 g_free (the_type_lower);
2354 the_type_lower = g_strdup ("uint");
2360 if (a->atype != NULL)
2361 cast = get_type (a->atype, TRUE);
2363 cast = g_strdup (get_cast (a->gtktype, FALSE));
2365 out_printf (out, "\t%s ARG = (%s) g_value_get_%s (VAL);\n",
2366 cast, cast, the_type_lower);
2369 } else if ( ! is_set) {
2372 if (a->atype != NULL)
2373 cast = get_type (a->atype, TRUE);
2375 cast = g_strdup (get_cast (a->gtktype, FALSE));
2376 out_printf (out, "\t%s ARG;\n"
2377 "\tmemset (&ARG, 0, sizeof (%s));\n",
2383 out_printf(out, "\t\t{\n");
2385 out_addline_infile (out, line_no);
2386 out_printf (out, "%s\n", cbuf);
2388 out_addline_outfile (out);
2389 out_printf (out, "\t\t}\n");
2391 if (strcmp (a->gtktype, "OBJECT") == 0)
2392 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2395 out_printf (out, "\t\t"
2396 "g_value_set_%s (VAL, ARG);\n",
2399 g_free (the_type_lower);
2402 out_printf (out, "\t\tif (&ARG) ;\n");
2405 out_printf (out, "\t\tbreak;\n");
2407 out_printf (out, "\t}\n");
2411 add_property (Property *p, gboolean is_set)
2414 char *the_type_lower;
2420 line_no = p->set_line;
2423 line_no = p->get_line;
2428 name_upper = g_strdup (p->name);
2429 gob_strup (name_upper);
2430 the_type_lower = g_strdup (p->gtktype);
2431 gob_strdown (the_type_lower);
2433 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2435 out_printf(out, "\t\t{\n");
2437 out_addline_infile (out, line_no);
2438 out_printf (out, "%s\n", cbuf);
2440 out_addline_outfile (out);
2441 out_printf (out, "\t\t}\n");
2443 g_free (name_upper);
2444 g_free (the_type_lower);
2446 out_printf (out, "\t\tbreak;\n");
2450 add_getset_arg(Class *c, gboolean is_set)
2453 out_printf(out, "\nstatic void\n"
2454 "___object_%s_property (GObject *object,\n"
2455 "\tguint property_id,\n"
2456 "\t%sGValue *VAL,\n"
2457 "\tGParamSpec *pspec)\n"
2458 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2461 "\tself = %s (object);\n\n"
2462 "\tswitch (property_id) {\n",
2463 is_set ? "set" : "get",
2464 is_set ? "const " : "",
2465 c->otype, is_set ? "set" : "get",
2466 typebase, macrobase);
2468 for (li = c->nodes; li != NULL; li = li->next) {
2470 if (n->type == PROPERTY_NODE)
2471 add_property ((Property *)n, is_set);
2472 else if (n->type == ARGUMENT_NODE)
2473 add_argument ((Argument *)n, is_set);
2475 out_printf (out, "\tdefault:\n"
2476 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2477 "#ifndef __PRETTY_FUNCTION__\n"
2478 "# undef G_STRLOC\n"
2479 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2481 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2483 "\treturn;\n\tself = NULL;\n\tVAL = NULL;\n\tpspec = NULL;\n}\n"
2484 "#undef __GOB_FUNCTION__\n");
2488 print_checks (Method *m, FuncArg *fa)
2492 gboolean checked_null = FALSE;
2493 is_void = (strcmp(m->mtype->name, "void")==0 &&
2494 m->mtype->pointer == NULL);
2496 for(li = fa->checks; li != NULL; li = li->next) {
2497 Check *ch = li->data;
2499 /* point to the method prot in .gob for failed checks */
2501 out_addline_infile(out, m->line_no);
2503 out_printf(out, "\tg_return_if_fail (");
2505 out_printf(out, "\tg_return_val_if_fail (");
2506 switch(ch->chtype) {
2508 out_printf(out, "%s != NULL", fa->name);
2509 checked_null = TRUE;
2512 s = make_pre_macro(fa->atype->name, "IS");
2514 out_printf(out, "%s (%s)", s, fa->name);
2516 /* if not check null, null may be valid */
2517 out_printf(out, "!(%s) || %s (%s)", fa->name,
2522 out_printf(out, "%s < %s", fa->name, ch->number);
2525 out_printf(out, "%s > %s", fa->name, ch->number);
2528 out_printf(out, "%s <= %s", fa->name, ch->number);
2531 out_printf(out, "%s >= %s", fa->name, ch->number);
2534 out_printf(out, "%s == %s", fa->name, ch->number);
2537 out_printf(out, "%s != %s", fa->name, ch->number);
2541 out_printf(out, ");\n");
2543 out_printf(out, ", (");
2544 print_type(out, m->mtype, TRUE);
2545 out_printf(out, ")%s);\n",
2546 m->onerror?m->onerror:"0");
2552 print_preconditions(Method *m)
2556 for(li=m->args;li;li=g_list_next(li)) {
2557 FuncArg *fa = li->data;
2559 print_checks(m, fa);
2562 out_addline_outfile(out);
2566 print_method_body(Method *m, int pre)
2569 out_addline_outfile(out);
2570 out_printf(out, "{\n"
2571 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2572 ((Class *)class)->otype,
2575 print_preconditions(m);
2577 /* Note: the trailing }'s are on one line, this is so
2578 that we get the no return warning correctly and point to
2579 the correct line in the .gob file, yes this is slightly
2580 ugly in the .c file, but that is not supposed to be
2581 human readable anyway. */
2583 out_printf(out, "{\n");
2585 out_addline_infile(out, m->ccode_line);
2586 out_printf(out, "\t%s}", m->cbuf);
2589 /* Note, there is no \n between the last } and this } so that
2590 * errors/warnings reported on the end of the body get pointed to the
2591 * right line in the .gob source */
2592 out_printf(out, "}\n");
2595 out_addline_outfile(out);
2596 out_printf(out, "#undef __GOB_FUNCTION__\n");
2600 put_signal_args (Method *m)
2606 if (m->args->next == NULL)
2609 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2610 li != NULL && ali != NULL;
2611 li = li->next, ali = ali->next, i++) {
2612 FuncArg *fa = li->data;
2613 char *cast = g_strdup (get_cast (ali->data, FALSE));
2614 /* FIXME: This code is so fucking ugly it hurts */
2615 gboolean do_static =
2616 (strcmp ((char *)ali->data, "STRING") == 0 ||
2617 strcmp ((char *)ali->data, "BOXED") == 0);
2621 cast = get_type (fa->atype, TRUE);
2623 /* we should have already proved before that
2624 the we know all the types */
2625 g_assert (cast != NULL);
2628 "\t___param_values[%d].g_type = 0;\n"
2629 "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
2630 i, i, (char *)ali->data);
2632 if (strcmp (ali->data, "UNICHAR") == 0)
2633 /* hack because glib is braindamaged */
2634 set_func = g_strdup ("g_value_set_uint");
2636 set_func = g_strdup_printf ("g_value_set%s_%s",
2637 do_static ? "_static" : "",
2639 gob_strdown (set_func);
2641 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2642 set_func, i, cast, fa->name);
2650 clear_signal_args (Method *m)
2655 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2657 if (m->args->next == NULL)
2660 for (li = m->args->next, i = 1;
2662 li = li->next, i++) {
2664 "\tg_value_unset (&___param_values[%d]);\n", i);
2669 get_arg_names_for_macro (Method *m)
2673 GString *gs = g_string_new(NULL);
2675 for(li=m->args;li;li=g_list_next(li)) {
2676 FuncArg *arg = li->data;
2677 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2680 return g_string_free (gs, FALSE);
2684 put_method(Method *m)
2686 char *s, *args, *doc;
2688 is_void = (strcmp(m->mtype->name, "void")==0 &&
2689 m->mtype->pointer == NULL);
2690 out_printf(out, "\n");
2691 if(m->method != OVERRIDE_METHOD) {
2692 doc = get_gtk_doc(m->id);
2694 out_printf(out, "%s", doc);
2699 case REGULAR_METHOD:
2701 out_addline_infile(out, m->line_no);
2702 if(m->scope == PRIVATE_SCOPE)
2703 print_method(out, "static ", "\n", "", " ", "", "\n",
2704 m, FALSE, FALSE, TRUE);
2705 else /* PUBLIC, PROTECTED */
2706 print_method(out, "", "\n", "", " ", "", "\n",
2707 m, FALSE, FALSE, TRUE);
2708 print_method_body(m, TRUE);
2709 /* the outfile line was added above */
2711 case SIGNAL_FIRST_METHOD:
2712 case SIGNAL_LAST_METHOD:
2714 out_addline_infile(out, m->line_no);
2715 if(m->scope == PRIVATE_SCOPE)
2716 print_method(out, "static ", "\n", "", " ", "", "\n",
2717 m, FALSE, FALSE, TRUE);
2718 else /* PUBLIC, PROTECTED */
2719 print_method(out, "", "\n", "", " ", "", "\n",
2720 m, FALSE, FALSE, TRUE);
2721 out_addline_outfile (out);
2723 out_printf (out, "{\n");
2726 "\tGValue ___param_values[%d];\n"
2727 "\tGValue ___return_val = {0};\n\n",
2728 g_list_length (m->args));
2730 print_preconditions (m);
2733 "\n\t___param_values[0].g_type = 0;\n"
2734 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2735 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2736 ((FuncArg *)m->args->data)->name,
2737 ((FuncArg *)m->args->data)->name);
2739 put_signal_args (m);
2741 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2742 const char *defret = NULL;
2744 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2745 (char *)m->gtktypes->data);
2747 if (m->defreturn != NULL)
2748 defret = m->defreturn;
2749 else if (m->onerror != NULL)
2750 defret = m->onerror;
2752 if (defret != NULL) {
2754 /* FIXME: This code is so fucking ugly it hurts */
2755 gboolean do_static =
2756 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2757 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2758 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2760 cast = get_type (m->mtype, TRUE);
2762 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2763 /* hack because glib is braindamaged */
2764 set_func = g_strdup ("g_value_set_uint");
2766 set_func = g_strdup_printf ("g_value_set%s_%s",
2767 do_static ? "_static" : "",
2768 (char *)m->gtktypes->data);
2769 gob_strdown (set_func);
2771 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2772 set_func, cast, defret);
2777 out_printf (out, "\n");
2780 s = g_strdup (m->id);
2783 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2784 "\t\tobject_signals[%s_SIGNAL],\n"
2785 "\t\t0 /* detail */,\n"
2786 "\t\t&___return_val);\n", s);
2790 clear_signal_args (m);
2792 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2793 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2795 /* Hack because glib is very very braindead */
2797 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2798 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
2799 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
2800 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
2802 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2803 /* hack because glib is braindamaged */
2804 getfunc = g_strdup ("g_value_get_uint");
2806 getfunc = g_strdup_printf ("g_value_%s_%s",
2807 do_dup ? "dup" : "get",
2808 (char *)m->gtktypes->data);
2809 gob_strdown (getfunc);
2812 cast = get_type (m->mtype, TRUE);
2817 print_type (out, m->mtype, TRUE);
2819 " ___ret = (%s) %s (&___return_val);\n"
2820 "\t\tg_value_unset (&___return_val);\n"
2821 "\t\treturn ___ret;\n"
2828 out_printf(out, "}\n");
2833 out_addline_infile(out, m->line_no);
2834 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2835 m, FALSE, FALSE, TRUE);
2836 print_method_body(m, FALSE);
2837 /* the outfile line was added above */
2839 case VIRTUAL_METHOD:
2841 out_addline_infile(out, m->line_no);
2842 if(m->scope==PRIVATE_SCOPE)
2843 print_method(out, "static ", "\n", "", " ", "", "\n",
2844 m, FALSE, FALSE, TRUE);
2845 else /* PUBLIC, PROTECTED */
2846 print_method(out, "", "\n", "", " ", "", "\n",
2847 m, FALSE, FALSE, TRUE);
2848 out_addline_outfile(out);
2849 out_printf(out, "{\n"
2850 "\t%sClass *klass;\n", typebase);
2851 print_preconditions(m);
2852 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2853 "\tif(klass->%s)\n",
2854 macrobase, ((FuncArg *)m->args->data)->name,
2856 if(strcmp(m->mtype->name, "void") == 0 &&
2857 m->mtype->pointer == NULL) {
2859 out_printf(out, "\t\t(*klass->%s)(%s",
2861 ((FuncArg *)m->args->data)->name);
2862 for(li=m->args->next;li;li=g_list_next(li)) {
2863 FuncArg *fa = li->data;
2864 out_printf(out, ",%s", fa->name);
2866 out_printf(out, ");\n}\n");
2869 out_printf(out, "\t\treturn (*klass->%s)(%s",
2871 ((FuncArg *)m->args->data)->name);
2872 for(li=m->args->next;li;li=g_list_next(li)) {
2873 FuncArg *fa = li->data;
2874 out_printf(out, ",%s", fa->name);
2876 out_printf(out, ");\n"
2879 print_type(out, m->mtype, TRUE);
2881 out_printf(out, ")(%s);\n}\n", m->defreturn);
2883 out_printf(out, ")(%s);\n}\n", m->onerror);
2885 out_printf(out, ")(0);\n}\n");
2891 out_addline_infile(out, m->line_no);
2892 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2893 m, FALSE, FALSE, TRUE);
2894 print_method_body(m, FALSE);
2895 /* the outfile line was added above */
2897 case OVERRIDE_METHOD:
2901 out_addline_infile(out, m->line_no);
2902 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2903 print_method(out, "static ", s, "", " ", "", "\n",
2904 m, FALSE, FALSE, FALSE);
2906 out_addline_outfile(out);
2907 s = replace_sep(m->otype, '_');
2909 args = get_arg_names_for_macro(m);
2911 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2912 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2913 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2914 args, s, m->id, s, m->id, args);
2916 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2917 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2918 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2920 args, s, m->id, s, m->id, args);
2921 out_printf(out, "(");
2922 print_type(out, m->mtype, TRUE);
2923 out_printf(out, ")%s))\n",
2924 m->onerror?m->onerror:"0");
2928 print_method_body(m, TRUE);
2929 /* the outfile line was added above */
2930 out_printf(out, "#undef PARENT_HANDLER\n");
2940 char *outfile, *outfileh, *outfileph;
2943 outfile = g_strconcat (fullfilebase, ".c", NULL);
2945 outfile = g_strconcat (fullfilebase, ".cc", NULL);
2946 if (no_touch_headers)
2947 outfileh = g_strconcat (fullfilebase, ".h#gob#", NULL);
2949 outfileh = g_strconcat (fullfilebase, ".h", NULL);
2951 if ((privates > 0 || protecteds > 0 ||
2952 private_header == PRIVATE_HEADER_ALWAYS) &&
2953 private_header != PRIVATE_HEADER_NEVER)
2954 outfileph = g_strconcat (fullfilebase, "-private.h", NULL);
2960 devnull = fopen ("/dev/null", "w");
2961 if (devnull == NULL)
2962 error_print (GOB_ERROR, 0, "Cannot open null device");
2965 if (outfileph != NULL)
2968 out = fopen (outfile, "w");
2970 error_printf (GOB_ERROR, 0,
2971 "Cannot open outfile: %s", outfile);
2973 outh = fopen (outfileh, "w");
2975 error_printf (GOB_ERROR, 0,
2976 "Cannot open outfile: %s", outfileh);
2978 if (outfileph != NULL) {
2979 outph = fopen (outfileph, "w");
2980 if (outph == NULL) {
2981 error_printf (GOB_ERROR, 0,
2982 "Cannot open outfile: %s",
2990 put_argument_nongnu_wrappers (Class *c)
2994 if (get_properties < 0 && set_properties < 0)
2997 for (li = c->nodes; li != NULL; li = li->next) {
2999 const char *name, *gtktype;
3005 if (n->type == ARGUMENT_NODE) {
3006 Argument *a = (Argument *)n;
3008 gtktype = a->gtktype;
3010 get = a->get != NULL;
3011 set = a->set != NULL;
3012 } else if (n->type == PROPERTY_NODE) {
3013 Property *p = (Property *)n;
3015 gtktype = p->gtktype;
3017 get = p->get != NULL;
3018 set = p->set != NULL;
3023 aname = g_strdup (name);
3027 cast = get_type (atype, TRUE);
3029 cast = g_strdup (get_cast (gtktype, TRUE));
3033 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3034 "\"%s\",(%s)(arg)\n",
3035 macrobase, aname, name, cast);
3037 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3038 "\"%s\",(%s*)(arg)\n",
3039 macrobase, aname, name, cast);
3042 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3044 macrobase, aname, name);
3046 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3048 macrobase, aname, name);
3056 put_argument_gnu_wrappers(Class *c)
3060 if(get_properties < 0 && set_properties < 0)
3063 for (li = c->nodes; li != NULL; li = li->next) {
3065 const char *name, *gtktype;
3071 if (n->type == ARGUMENT_NODE) {
3072 Argument *a = (Argument *)n;
3074 gtktype = a->gtktype;
3076 get = a->get != NULL;
3077 set = a->set != NULL;
3078 } else if (n->type == PROPERTY_NODE) {
3079 Property *p = (Property *)n;
3081 gtktype = p->gtktype;
3083 get = p->get != NULL;
3084 set = p->set != NULL;
3089 aname = g_strdup (name);
3093 cast = get_type (atype, TRUE);
3095 cast = g_strdup (get_cast (gtktype, TRUE));
3099 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3100 "\"%s\",({%sz = (arg); z;})\n",
3101 macrobase, aname, name, cast);
3103 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3104 "\"%s\",({%s*z = (arg); z;})\n",
3105 macrobase, aname, name, cast);
3108 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3110 macrobase, aname, name);
3112 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3114 macrobase, aname, name);
3122 print_ccode_block(CCode *cc)
3125 switch(cc->cctype) {
3127 /* HT code is printed exactly like normal header
3128 code but is printed before */
3131 out_printf(fp, "\n");
3134 /* AT code is printed exactly like normal 'all'
3135 code but is printed before */
3138 out_printf(outph, "\n");
3139 out_printf(outph, "%s\n", cc->cbuf);
3140 out_addline_infile(outph, cc->line_no);
3141 out_addline_outfile(outph);
3143 out_printf(outh, "\n");
3144 out_printf(outh, "%s\n", cc->cbuf);
3146 out_printf(fp, "\n");
3147 out_addline_infile(fp, cc->line_no);
3152 out_printf(fp, "\n");
3153 out_addline_infile(fp, cc->line_no);
3160 out_printf(fp, "\n");
3161 out_addline_infile(fp, cc->line_no);
3164 out_printf(fp, "%s\n", cc->cbuf);
3165 if(cc->cctype == C_CCODE ||
3166 cc->cctype == A_CCODE ||
3167 cc->cctype == AT_CCODE ||
3168 cc->cctype == PH_CCODE)
3169 out_addline_outfile(fp);
3173 print_class_block(Class *c)
3177 gboolean printed_private = FALSE;
3180 out_printf(out, "/* utility types we may need */\n");
3181 if(special_array[SPECIAL_2POINTER])
3182 out_printf(out, "typedef struct { "
3183 "gpointer a; gpointer b; "
3184 "} ___twopointertype;\n");
3185 if(special_array[SPECIAL_3POINTER])
3186 out_printf(out, "typedef struct { "
3187 "gpointer a; gpointer b; "
3189 "} ___threepointertype;\n");
3190 if(special_array[SPECIAL_INT_POINTER])
3191 out_printf(out, "typedef struct { "
3192 "gint a; gpointer b; "
3193 "} ___intpointertype;\n");
3194 out_printf(out, "\n");
3197 out_printf(outh, "\n/*\n"
3198 " * Type checking and casting macros\n"
3200 out_printf(outh, "#define %s\t"
3201 "(%s_get_type())\n",
3202 macrotype, funcbase);
3203 out_printf(outh, "#define %s(obj)\t"
3204 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3205 macrobase, funcbase, typebase);
3206 out_printf(outh, "#define %s_CONST(obj)\t"
3207 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3208 macrobase, funcbase, typebase);
3209 out_printf(outh, "#define %s_CLASS(klass)\t"
3210 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3211 macrobase, funcbase, typebase);
3212 out_printf(outh, "#define %s(obj)\t"
3213 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3216 "#define %s_GET_CLASS(obj)\t"
3217 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3218 macrobase, funcbase, typebase);
3220 if ( ! no_self_alias) {
3221 out_printf(out, "/* self casting macros */\n");
3222 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3223 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3224 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3225 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3226 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3228 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3231 out_printf(out, "/* self typedefs */\n");
3232 out_printf(out, "typedef %s Self;\n", typebase);
3233 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3237 always_private_struct) {
3238 out_printf (outh, "\n/* Private structure type */\n");
3239 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3240 typebase, typebase);
3242 out_printf (outh, "/* There are no privates, this "
3243 "structure is thus never defined */\n");
3246 out_printf (outh, "\n/*\n"
3247 " * Main object structure\n"
3249 s = replace_sep (c->otype, '_');
3251 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3252 "#define __TYPEDEF_%s__\n", s, s);
3254 out_printf (outh, "typedef struct _%s %s;\n"
3255 "#endif\n", typebase, typebase);
3256 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3257 typebase, ptypebase);
3258 for (li = c->nodes; li; li=li->next) {
3259 static gboolean printed_public = FALSE;
3261 Variable *v = (Variable *)n;
3262 if(n->type == VARIABLE_NODE &&
3263 v->scope == PUBLIC_SCOPE) {
3264 if( ! printed_public) {
3265 out_printf(outh, "\t/*< public >*/\n");
3266 printed_public = TRUE;
3268 put_variable((Variable *)n, outh);
3271 /* put protecteds always AFTER publics */
3272 for (li = c->nodes; li != NULL; li = li->next) {
3274 Variable *v = (Variable *)n;
3275 if (n->type == VARIABLE_NODE &&
3276 v->scope == PROTECTED_SCOPE) {
3277 if ( ! printed_private) {
3278 out_printf (outh, "\t/*< private >*/\n");
3279 printed_private = TRUE;
3281 put_variable ((Variable *)n, outh);
3285 always_private_struct) {
3286 if ( ! printed_private)
3287 out_printf (outh, "\t/*< private >*/\n");
3288 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3290 out_printf (outh, "};\n");
3295 /* if we are to stick this into the private
3296 header, if not stick it directly into the
3303 out_printf (outfp, "struct _%sPrivate {\n",
3305 for(li=c->nodes; li; li=li->next) {
3307 Variable *v = (Variable *)n;
3308 if(n->type == VARIABLE_NODE &&
3309 v->scope == PRIVATE_SCOPE) {
3310 out_addline_infile(outfp, v->line_no);
3311 put_variable(v, outfp);
3314 out_addline_outfile(outfp);
3315 out_printf(outfp, "};\n");
3318 out_printf(outh, "\n/*\n"
3319 " * Class definition\n"
3321 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3322 typebase, typebase);
3324 "struct _%sClass {\n\t%sClass __parent__;\n",
3325 typebase, ptypebase);
3326 for(li = c->nodes; li != NULL; li = li->next) {
3328 if(n->type == METHOD_NODE)
3329 put_vs_method((Method *)n);
3331 /* If BonoboX type class put down the epv */
3332 if (c->bonobo_object_class != NULL) {
3334 "\t/* Bonobo object epv */\n"
3335 "\tPOA_%s__epv _epv;\n",
3336 c->bonobo_object_class);
3338 /* put class scope variables */
3339 for (li = c->nodes; li != NULL; li = li->next) {
3341 Variable *v = (Variable *)n;
3342 if (n->type == VARIABLE_NODE &&
3343 v->scope == CLASS_SCOPE)
3344 put_variable ((Variable *)n, outh);
3346 out_printf (outh, "};\n\n");
3348 out_printf (out, "/* here are local prototypes */\n");
3349 if (set_properties > 0) {
3350 out_printf (out, "static void ___object_set_property "
3351 "(GObject *object, guint property_id, "
3352 "const GValue *value, GParamSpec *pspec);\n");
3354 if (get_properties > 0) {
3355 out_printf (out, "static void ___object_get_property "
3356 "(GObject *object, guint property_id, "
3357 "GValue *value, GParamSpec *pspec);\n");
3360 out_printf (outh, "\n/*\n"
3361 " * Public methods\n"
3364 if ( ! overrode_get_type) {
3365 out_printf (outh, "GType\t%s_get_type\t(void);\n", funcbase);
3368 for(li = c->nodes; li != NULL; li = li->next) {
3370 if(n->type == METHOD_NODE) {
3371 put_pub_method((Method *)n);
3372 put_prot_method((Method *)n);
3373 put_priv_method_prot((Method *)n);
3377 /* this idea is less and less apealing to me */
3379 out_printf (outh, "\n/*\n"
3380 " * Signal connection wrapper macros\n"
3383 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3384 put_signal_macros (c, TRUE);
3385 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3386 put_signal_macros (c, FALSE);
3387 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3389 put_signal_macros (c, FALSE);
3390 out_printf(outh, "\n");
3393 out_printf (out, "\n/*\n"
3394 " * Signal connection wrapper macro shortcuts\n"
3396 put_local_signal_macros (c);
3397 out_printf(outh, "\n");
3400 /* argument wrapping macros */
3401 if(get_properties > 0 || set_properties > 0) {
3402 out_printf(outh, "\n/*\n"
3403 " * Argument wrapping macros\n"
3406 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3407 put_argument_gnu_wrappers(c);
3408 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3409 put_argument_nongnu_wrappers(c);
3410 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3412 put_argument_nongnu_wrappers(c);
3417 for(li = c->nodes; li != NULL; li = li->next) {
3419 if(n->type == METHOD_NODE)
3420 add_signal_prots((Method *)n);
3426 if(any_method_to_alias(c)) {
3428 out_printf(out, "/* Short form macros */\n");
3429 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3430 make_method_gnu_aliases(c);
3431 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3433 make_method_nongnu_aliases(c);
3436 add_interface_inits (c);
3438 if ( ! overrode_get_type) {
3439 if (c->bonobo_object_class != NULL)
3440 add_bonobo_object_get_type ();
3445 out_printf (out, "/* a macro for creating a new object of our type */\n");
3447 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3448 typebase, funcbase);
3450 out_printf (out, "/* a function for creating a new object of our type */\n");
3451 out_printf (out, "#include <stdarg.h>\n");
3453 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3454 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3455 "{\n\t%s *ret;\n\tva_list ap;\n"
3456 "\tva_start (ap, first);\n"
3457 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3460 "\treturn ret;\n}\n\n",
3462 no_gnu ? "" : " G_GNUC_UNUSED",
3463 typebase, typebase, typebase, funcbase);
3473 if(set_properties > 0) {
3474 add_getset_arg(c, TRUE);
3477 if(get_properties > 0) {
3478 add_getset_arg(c, FALSE);
3481 for(li = c->nodes; li != NULL; li = li->next) {
3483 if(n->type == METHOD_NODE)
3484 put_method((Method *)n);
3487 add_bad_hack_to_avoid_unused_warnings(c);
3491 print_useful_macros(void)
3493 int major = 0, minor = 0, pl = 0;
3496 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3497 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3498 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3499 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3501 /* Useful priv macro thingie */
3502 /* FIXME: this should be done the same way that priv is, as a var,
3504 out_printf (out, "#define selfp (self->_priv)\n\n");
3508 print_more_useful_macros (void)
3511 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3512 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3514 out_printf (out, "#ifdef G_LIKELY\n");
3515 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3516 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3517 out_printf (out, "#else /* ! G_LIKELY */\n");
3518 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3519 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3520 out_printf (out, "#endif /* G_LIKELY */\n");
3525 print_file_comments(void)
3529 out_printf(outh, "/* Generated by GOB (v%s)"
3530 " (do not edit directly) */\n\n", VERSION);
3532 out_printf(outph, "/* Generated by GOB (v%s)"
3533 " (do not edit directly) */\n\n", VERSION);
3534 out_printf(out, "/* Generated by GOB (v%s) on %s"
3535 " (do not edit directly) */\n\n",
3536 VERSION, ctime(&curtime));
3538 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3542 print_includes(void)
3544 gboolean found_header;
3547 /* We may need string.h for memset */
3548 if(destructors > 0 &&
3549 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3550 out_printf(out, "#include <string.h> /* memset() */\n\n");
3553 p = g_strconcat(filebase, ".h", NULL);
3554 found_header = TRUE;
3555 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3556 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3557 found_header = FALSE;
3561 /* if we are creating a private header see if it was included */
3563 p = g_strconcat(filebase, "-private.h", NULL);
3564 if( ! g_list_find_custom(include_files, p,
3565 (GCompareFunc)strcmp)) {
3566 out_printf(out, "#include \"%s-private.h\"\n\n",
3569 error_printf(GOB_WARN, 0,
3570 "Implicit private header include "
3572 "\tsource file, while public "
3573 "header is at a custom location, "
3575 "\texplicitly include "
3576 "the private header below the "
3584 print_header_prefixes(void)
3588 p = replace_sep(((Class *)class)->otype, '_');
3590 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3592 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3593 "#define __%s_PRIVATE_H__\n\n"
3594 "#include \"%s.h\"\n\n", p, p, filebase);
3597 if( ! no_extern_c) {
3598 out_printf(outh, "#ifdef __cplusplus\n"
3600 "#endif /* __cplusplus */\n\n");
3602 out_printf(outph, "#ifdef __cplusplus\n"
3604 "#endif /* __cplusplus */\n\n");
3609 print_header_postfixes(void)
3612 out_printf(outh, "\n#ifdef __cplusplus\n"
3614 "#endif /* __cplusplus */\n");
3615 out_printf(outh, "\n#endif\n");
3618 out_printf(outph, "\n#ifdef __cplusplus\n"
3620 "#endif /* __cplusplus */\n");
3621 out_printf(outph, "\n#endif\n");
3630 /* print the AT_CCODE blocks */
3631 for(li = nodes; li != NULL; li = li->next) {
3632 Node *node = li->data;
3633 if(node->type == CCODE_NODE) {
3634 CCode *cc = (CCode *)node;
3635 if(cc->cctype == AT_CCODE)
3636 print_ccode_block((CCode *)node);
3642 print_header_top(void)
3646 /* mandatory includes */
3647 out_printf (outh, "#include <glib.h>\n");
3648 out_printf (outh, "#include <glib-object.h>\n");
3650 /* print the HT_CCODE blocks */
3651 for (li = nodes; li != NULL; li = li->next) {
3652 Node *node = li->data;
3653 if (node->type == CCODE_NODE) {
3654 CCode *cc = (CCode *)node;
3655 if (cc->cctype == HT_CCODE)
3656 print_ccode_block ((CCode *)node);
3662 print_enum (EnumDef *enode)
3669 funcprefix = replace_sep (enode->etype, '_');
3670 gob_strdown (funcprefix);
3671 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3673 type = remove_sep (enode->etype);
3675 out_printf (outh, "\ntypedef enum {\n");
3677 for (li = enode->values; li != NULL; li = li->next) {
3678 EnumValue *value = li->data;
3680 char *sname = gob_strdown (g_strdup (value->name));
3682 while ((p = strchr (sname, '_')) != NULL)
3685 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3686 if (value->value != NULL)
3687 out_printf (outh, " = %s", value->value);
3688 if (li->next != NULL)
3689 out_printf (outh, ",\n");
3691 out_printf (outh, "\n");
3693 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3694 enode->prefix, value->name,
3695 enode->prefix, value->name,
3701 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3703 out_printf (outh, "} %s;\n", type);
3705 str = make_pre_macro (enode->etype, "TYPE");
3706 out_printf (outh, "#define %s ", str);
3709 out_printf (outh, "%s_get_type()\n", funcprefix);
3710 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3713 "GType\n%s_get_type (void)\n"
3715 "\tstatic GType type = 0;\n"
3716 "\tif ___GOB_UNLIKELY(type == 0)\n"
3717 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3720 funcprefix, type, funcprefix);
3722 g_free (funcprefix);
3727 print_flags (Flags *fnode)
3735 funcprefix = replace_sep (fnode->ftype, '_');
3736 gob_strdown (funcprefix);
3737 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3739 type = remove_sep (fnode->ftype);
3741 out_printf (outh, "\ntypedef enum {\n");
3743 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3744 const char *name = li->data;
3746 char *sname = gob_strdown (g_strdup (name));
3748 while ((p = strchr (sname, '_')) != NULL)
3751 out_printf (outh, "\t%s_%s = 1<<%d",
3752 fnode->prefix, name, i);
3753 if (li->next != NULL)
3754 out_printf (outh, ",\n");
3756 out_printf (outh, "\n");
3758 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3759 fnode->prefix, name,
3760 fnode->prefix, name,
3766 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3768 out_printf (outh, "} %s;\n", type);
3770 str = make_pre_macro (fnode->ftype, "TYPE");
3771 out_printf (outh, "#define %s ", str);
3774 out_printf (outh, "%s_get_type()\n", funcprefix);
3775 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3778 "GType\n%s_get_type (void)\n"
3780 "\tstatic GType type = 0;\n"
3781 "\tif ___GOB_UNLIKELY(type == 0)\n"
3782 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3785 funcprefix, type, funcprefix);
3787 g_free (funcprefix);
3792 print_error (Error *enode)
3799 funcprefix = replace_sep (enode->etype, '_');
3800 gob_strdown (funcprefix);
3801 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3803 type = remove_sep (enode->etype);
3805 out_printf (outh, "\ntypedef enum {\n");
3807 for (li = enode->values; li != NULL; li = li->next) {
3808 const char *name = li->data;
3810 char *sname = gob_strdown (g_strdup (name));
3812 while ((p = strchr (sname, '_')) != NULL)
3815 out_printf (outh, "\t%s_%s", enode->prefix, name);
3816 if (li->next != NULL)
3817 out_printf (outh, ",\n");
3819 out_printf (outh, "\n");
3821 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3822 enode->prefix, name,
3823 enode->prefix, name,
3829 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3831 out_printf (outh, "} %s;\n", type);
3833 str = make_pre_macro (enode->etype, "TYPE");
3834 out_printf (outh, "#define %s ", str);
3837 out_printf (outh, "%s_get_type ()\n", funcprefix);
3838 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3841 "GType\n%s_get_type (void)\n"
3843 "\tstatic GType type = 0;\n"
3844 "\tif ___GOB_UNLIKELY(type == 0)\n"
3845 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3848 funcprefix, type, funcprefix);
3850 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3851 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3853 str = replace_sep (enode->etype, '-');
3857 "GQuark\n%s_quark (void)\n"
3859 "\tstatic GQuark q = 0;\n"
3861 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3868 g_free (funcprefix);
3873 generate_outfiles(void)
3877 print_file_comments();
3883 print_header_prefixes();
3885 print_useful_macros();
3889 print_more_useful_macros ();
3891 for (li = nodes; li != NULL; li = li->next) {
3892 Node *node = li->data;
3893 if (node->type == CCODE_NODE) {
3894 CCode *cc = (CCode *)node;
3895 if (cc->cctype != HT_CCODE &&
3896 cc->cctype != AT_CCODE)
3897 print_ccode_block ((CCode *)node);
3898 } else if (node->type == CLASS_NODE) {
3899 print_class_block ((Class *)node);
3900 } else if (node->type == ENUMDEF_NODE) {
3901 print_enum ((EnumDef *)node);
3902 } else if (node->type == FLAGS_NODE) {
3903 print_flags ((Flags *)node);
3904 } else if (node->type == ERROR_NODE) {
3905 print_error ((Error *)node);
3907 g_assert_not_reached();
3911 print_header_postfixes();
3917 fprintf(stderr, "Gob version %s\n\n", VERSION);
3918 fprintf(stderr, "gob [options] file.gob\n\n");
3919 fprintf(stderr, "Options:\n"
3920 "\t--help,-h,-? Display this help\n"
3921 "\t--version Display version\n"
3922 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3923 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3924 "\t--for-cpp Create C++ files\n"
3925 "\t--no-extern-c Never print extern \"C\" into the "
3927 "\t--no-gnu Never use GNU extentions\n"
3928 "\t--no-touch-headers Don't touch headers unless they "
3930 "\t--always-private-header Always create a private header "
3932 "\t even if it would be empty\n"
3933 "\t--ondemand-private-header Create private header only when "
3936 "\t--no-private-header Don't create a private header, "
3938 "\t structure and protected "
3939 "prototypes inside c file\n"
3940 "\t--always-private-struct Always create a private pointer "
3942 "\t the object structure\n"
3943 "\t--m4 Preprocess source with m4. "
3944 "Following args will\n"
3945 "\t be passed to m4\n"
3946 "\t--m4-dir Print directory that will be "
3949 "\t--no-write,-n Don't write output files, just "
3951 "\t--no-lines Don't print '#line' to output\n"
3952 "\t--no-self-alias Don't create self type and macro "
3954 "\t--no-kill-underscores Ignored for compatibility\n"
3955 "\t-o,--output-dir The directory where output "
3956 "should be placed\n");
3960 parse_options(int argc, char *argv[])
3963 int got_file = FALSE;
3964 int no_opts = FALSE;
3965 int m4_opts = FALSE; /* if we are just passing on args to m4 */
3969 for(i = 1 ; i < argc; i++) {
3971 char *new_commandline;
3972 g_assert(m4_commandline!=NULL);
3974 /* check whether this one looks like the filename */
3975 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
3977 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
3981 /* insert flags before the filename */
3982 new_commandline=g_strconcat(m4_commandline,
3990 /* just an ordinary option */
3992 new_commandline=g_strconcat(m4_commandline,
3997 /* free old commandline */
3998 g_free(m4_commandline);
3999 m4_commandline=new_commandline;
4001 } else if(no_opts ||
4002 argv[i][0] != '-') {
4005 fprintf(stderr, "Specify only one file!\n");
4011 } else if(strcmp(argv[i], "--help")==0) {
4014 } else if(strcmp(argv[i], "--version")==0) {
4015 fprintf(stderr, "Gob version %s\n", VERSION);
4017 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4018 exit_on_warn = TRUE;
4019 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4020 exit_on_warn = FALSE;
4021 } else if(strcmp(argv[i], "--for-cpp")==0) {
4023 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4024 no_touch_headers = TRUE;
4025 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4026 private_header = PRIVATE_HEADER_ONDEMAND;
4027 } else if(strcmp(argv[i], "--always-private-header")==0) {
4028 private_header = PRIVATE_HEADER_ALWAYS;
4029 } else if(strcmp(argv[i], "--no-private-header")==0) {
4030 private_header = PRIVATE_HEADER_NEVER;
4031 } else if(strcmp(argv[i], "--no-gnu")==0) {
4033 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4035 } else if(strcmp(argv[i], "--no-write")==0) {
4037 } else if(strcmp(argv[i], "--no-lines")==0) {
4039 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4040 no_self_alias = TRUE;
4041 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4043 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4044 always_private_struct = TRUE;
4045 } else if(strcmp(argv[i], "--m4-dir")==0) {
4046 printf("%s\n",M4_INCLUDE_DIR);
4048 } else if(strcmp(argv[i], "--m4")==0) {
4052 m4_commandline=g_strdup(M4_COMMANDLINE);
4053 } else if(strcmp(argv[i], "--m4-clean")==0) {
4057 m4_commandline=g_strdup(M4_COMMANDLINE);
4058 } else if (strcmp (argv[i], "-o") == 0 ||
4059 strcmp (argv[i], "--output-dir") == 0) {
4061 output_dir = g_strdup (argv[i+1]);
4066 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4069 strlen ("--output-dir=")) == 0) {
4070 char *p = strchr (argv[i], '=');
4071 g_assert (p != NULL);
4072 output_dir = g_strdup (p+1);
4073 } else if(strcmp(argv[i], "--")==0) {
4074 /*further arguments are files*/
4076 } else if(strncmp(argv[i], "--", 2)==0) {
4077 /*unknown long option*/
4078 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4082 /*by now we know we have a string starting with
4083 - which is a short option string*/
4085 for(p = argv[i] + 1; *p; p++) {
4099 "Unknown option '%c'!\n", *p);
4108 /* if we are using m4, and got no filename, append m4 flags now */
4109 if(!got_file && use_m4 && !use_m4_clean) {
4110 char *new_commandline;
4111 new_commandline=g_strconcat(m4_commandline,
4115 g_free(m4_commandline);
4116 m4_commandline=new_commandline;
4121 /* this is a somewhat ugly hack, but it appears to work */
4123 compare_and_move_header(void)
4125 char *hfnew = g_strconcat(fullfilebase, ".h#gob#", NULL);
4126 char *hf = g_strconcat(fullfilebase, ".h", NULL);
4128 if(stat(hf, &s) == 0) {
4130 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
4131 if(system(s) == 0) {
4132 if(unlink(hfnew) != 0)
4133 error_printf(GOB_ERROR, 0,
4134 "Can't remove new header file");
4142 error_printf(GOB_ERROR, 0,
4143 "Can't remove old header file");
4145 if(rename(hfnew, hf) != 0)
4146 error_printf(GOB_ERROR, 0,
4147 "Can't rename new header file");
4153 main(int argc, char *argv[])
4155 parse_options(argc, argv);
4158 yyin = popen(m4_commandline, "r");
4160 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4164 } else if(filename) {
4165 yyin = fopen(filename, "r");
4167 fprintf(stderr, "Error: can't open file '%s'\n",
4176 /* This is where parsing is done */
4179 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4181 /* close input file */
4182 if(use_m4) pclose(yyin);
4187 error_print (GOB_ERROR, 0, "no class defined");
4190 exit_on_error = FALSE;
4192 signals = count_signals ((Class *)class);
4193 set_properties = count_set_properties ((Class *)class) +
4194 count_set_arguments ((Class *)class);
4195 get_properties = count_get_properties ((Class *)class) +
4196 count_get_arguments ((Class *)class);
4197 overrides = count_overrides ((Class *)class);
4198 privates = count_privates ((Class *)class);
4199 protecteds = count_protecteds ((Class *)class);
4200 unreftors = count_unreftors ((Class *)class);
4201 destructors = count_destructors ((Class *)class);
4202 initializers = count_initializers ((Class *)class);
4203 overrode_get_type = find_get_type ((Class *)class);
4206 make_inits ((Class *)class);
4208 need_dispose = TRUE;
4209 find_dispose ((Class *)class);
4211 if (destructors > 0 ||
4213 need_finalize = TRUE;
4214 find_finalize ((Class *)class);
4216 check_bad_symbols ((Class *)class);
4217 check_duplicate_symbols ((Class *)class);
4218 check_duplicate_overrides ((Class *)class);
4219 check_duplicate_signals_args ((Class *)class);
4220 check_public_new ((Class *)class);
4221 check_vararg ((Class *)class);
4222 check_firstarg ((Class *)class);
4223 check_nonvoidempty ((Class *)class);
4224 check_signal_args ((Class *)class);
4225 check_property_types ((Class *)class);
4226 check_argument_types ((Class *)class);
4227 check_func_arg_checks ((Class *)class);
4228 check_for_class_destructors ((Class *)class);
4230 exit_on_error = TRUE;
4235 any_special = setup_special_array ((Class *)class, special_array);
4239 generate_outfiles ();
4250 if (no_touch_headers &&
4252 compare_and_move_header ();