2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2004 George (Jiri) Lebl
6 * Author: George (Jiri) Lebl
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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 char file_sep = '-';
71 static int signals = 0; /* number of signals */
72 static int set_properties = 0; /* number of named (set) properties */
73 static int get_properties = 0; /* number of named (get) properties */
74 static int overrides = 0; /* number of override methods */
75 static int privates = 0; /* number of private data members */
76 static int protecteds = 0; /* number of protected methods */
77 static int unreftors = 0; /* number of variable unreffing destructors */
78 static int destructors = 0; /* number of variable non-unreffing destructors */
79 static int initializers = 0; /* number of variable initializers */
80 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
82 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
83 and need the REALLY UGLY HACK to
86 /* the special variable types we need to define */
87 static gboolean special_array[SPECIAL_LAST] = {0};
88 static gboolean any_special = FALSE;
90 static gboolean need_dispose = FALSE;
91 static Method * dispose_handler = NULL;
93 static gboolean need_finalize = FALSE;
94 static Method * finalize_handler = NULL;
101 gboolean no_touch_headers = FALSE;
102 gboolean for_cpp = FALSE;
103 gboolean no_gnu = FALSE;
104 gboolean exit_on_warn = FALSE;
105 gboolean exit_on_error = TRUE;
106 gboolean got_error = FALSE;
107 gint private_header = PRIVATE_HEADER_ONDEMAND;
108 gboolean no_extern_c = FALSE;
109 gboolean no_write = FALSE;
110 gboolean no_lines = FALSE;
111 gboolean no_self_alias = FALSE;
112 gboolean always_private_struct = FALSE;
114 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
115 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
116 char *m4_commandline = NULL;
117 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
118 #define M4_BASE_FILENAME "gobm4.m4"
119 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
120 #define M4_COMMANDLINE "m4"
122 int method_unique_id = 1;
127 filebase = replace_sep (((Class *)class)->otype, file_sep);
128 gob_strdown (filebase);
130 if (output_dir != NULL &&
131 output_dir[0] != '\0') {
132 fullfilebase = g_build_filename (output_dir, filebase, NULL);
134 fullfilebase = g_strdup (filebase);
137 funcbase = replace_sep (((Class *)class)->otype, '_');
138 gob_strdown (funcbase);
140 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
141 gob_strdown (pfuncbase);
143 macrobase = replace_sep (((Class *)class)->otype, '_');
144 gob_strup (macrobase);
146 macrois = make_pre_macro (((Class *)class)->otype, "IS");
147 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
149 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
150 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
152 typebase = remove_sep (((Class *)class)->otype);
154 ptypebase = remove_sep (((Class *)class)->ptype);
158 get_gtk_doc (const char *id)
165 val = g_hash_table_lookup(gtk_doc_hash, id);
167 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
169 val = g_hash_table_lookup(gtk_doc_hash, id);
171 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
177 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
181 s = get_type(t, postfix_to_stars);
182 out_printf(fp, "%s", s);
188 print_method (FILE *fp,
189 const char *typeprefix,
190 const char *nameprefix,
191 const char *subnameprefix,
192 const char *namepostfix,
193 const char *afterargs,
196 gboolean one_arg_per_line,
197 gboolean no_funcbase,
198 gboolean kill_underscore,
199 gboolean first_unused,
205 out_printf(fp, "%s", typeprefix);
206 print_type(fp, m->mtype, TRUE);
211 out_printf(fp, "%s%s%s%s(",
212 nameprefix, subnameprefix, id, namepostfix);
214 out_printf(fp, "%s%s_%s%s%s(",
215 nameprefix, funcbase, subnameprefix, id,
219 for(li=m->args; li; li=g_list_next(li)) {
220 FuncArg *arg = li->data;
221 const char *unused = "";
224 ! for_cpp && /* g++ has a cow with this */
227 unused = " G_GNUC_UNUSED";
230 print_type(fp, arg->atype, FALSE);
232 out_printf (fp, "___fake___");
234 out_printf(fp, "%s%s%s,%s", arg->name,
235 arg->atype->postfix ?
236 arg->atype->postfix : "",
238 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
240 out_printf(fp, "%s%s%s", arg->name,
241 arg->atype->postfix ?
242 arg->atype->postfix : "",
246 out_printf(fp, ",%s...",
247 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
249 out_printf(fp, "void");
251 out_printf(fp, "%s)%s", afterargs, postfix);
255 any_method_to_alias(Class *c)
259 for(li=c->nodes;li;li=g_list_next(li)) {
260 Node *node = li->data;
261 if(node->type == METHOD_NODE) {
262 Method *m = (Method *)node;
264 if(m->method == INIT_METHOD ||
265 m->method == CLASS_INIT_METHOD ||
266 m->method == OVERRIDE_METHOD)
277 make_method_aliases (Class *c)
281 for(li = c->nodes; li != NULL; li = li->next) {
282 Node *node = li->data;
283 if(node->type == METHOD_NODE) {
284 Method *m = (Method *)node;
286 if(m->method == INIT_METHOD ||
287 m->method == CLASS_INIT_METHOD ||
288 m->method == OVERRIDE_METHOD)
291 out_printf (out, "#define self_%s %s_%s\n",
300 add_bad_hack_to_avoid_unused_warnings(const Class *c)
304 /* if we haven't had any methods, just return */
309 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
311 "/*REALLY BAD HACK\n"
312 " This is to avoid unused warnings if you don't call\n"
313 " some method. I need to find a better way to do\n"
314 " this, not needed in GCC since we use some gcc\n"
315 " extentions to make saner, faster code */\n"
317 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
319 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
320 for(li=c->nodes;li;li=g_list_next(li)) {
321 Node *node = li->data;
322 if(node->type == METHOD_NODE) {
323 Method *m = (Method *)node;
325 if(m->method == INIT_METHOD ||
326 m->method == CLASS_INIT_METHOD ||
327 m->method == OVERRIDE_METHOD)
330 /* in C++ mode we don't alias new */
331 if(for_cpp && strcmp(m->id, "new")==0)
334 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
337 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
340 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
342 out_printf(out, "}\n\n");
346 put_variable(const Variable *v, FILE *fp)
348 out_printf(fp, "\t");
349 print_type(fp, v->vtype, FALSE);
350 out_printf(fp, "%s%s;", v->id,
352 v->vtype->postfix:"");
353 if(v->scope == PROTECTED_SCOPE)
354 out_printf(fp, " /* protected */");
355 out_printf(fp, "\n");
359 put_vs_method(const Method *m)
361 if(m->method != SIGNAL_LAST_METHOD &&
362 m->method != SIGNAL_FIRST_METHOD &&
363 m->method != VIRTUAL_METHOD)
366 /* if a signal mark it as such */
367 if(m->method != VIRTUAL_METHOD)
368 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
369 m, FALSE, TRUE, TRUE, FALSE, FALSE);
371 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
372 m, FALSE, TRUE, TRUE, FALSE, FALSE);
376 put_pub_method(const Method *m)
378 if(m->scope != PUBLIC_SCOPE)
381 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
382 TRUE, FALSE, TRUE, FALSE, FALSE);
386 put_signal_macro (const Method *m, gboolean gnu)
388 if(m->method != SIGNAL_LAST_METHOD &&
389 m->method != SIGNAL_FIRST_METHOD)
394 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
395 "g_signal_connect(%s(object),\"%s\","
396 "(GCallback)(func),(data))\n",
397 funcbase, m->id, macrobase, m->id);
400 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
401 "g_signal_connect_after(%s(object),\"%s\","
402 "(GCallback)(func),(data))\n",
403 funcbase, m->id, macrobase, m->id);
406 out_printf (outh, "#define %s_connect_data__%s"
407 "(object,func,data,destroy_data,flags)\t"
408 "g_signal_connect_data(%s(object),\"%s\","
409 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
410 funcbase, m->id, macrobase, m->id);
413 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
415 "%s(__extension__ ({%s *___object = (object); ___object; })),"
417 "(GCallback) __extension__ ({",
418 funcbase, m->id, macrobase, typebase, m->id);
419 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
420 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
421 out_printf (outh, "___%s; }), (data))\n", m->id);
424 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
425 "g_signal_connect_after("
426 "%s(__extension__ ({%s *___object = (object); ___object; })),"
428 "(GCallback) __extension__ ({",
429 funcbase, m->id, macrobase, typebase, m->id);
430 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
431 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
432 out_printf (outh, "___%s; }), (data))\n", m->id);
435 out_printf (outh, "#define %s_connect_data__%s"
436 "(object,func,data,destroy_data,flags)\t"
437 "g_signal_connect_data("
438 "%s(__extension__ ({%s *___object = (object); ___object; })),"
440 "(GCallback) __extension__ ({",
441 funcbase, m->id, macrobase, typebase, m->id);
442 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
443 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
444 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
449 put_signal_macros (const Class *c, gboolean gnu)
456 for (li = c->nodes; li != NULL; li = li->next) {
457 const Node *n = li->data;
458 if (n->type == METHOD_NODE)
459 put_signal_macro ((Method *)n, gnu);
464 put_local_signal_macro (const Method *m)
466 if(m->method != SIGNAL_LAST_METHOD &&
467 m->method != SIGNAL_FIRST_METHOD)
471 out_printf (out, "#define self_connect__%s(object,func,data)\t"
472 "%s_connect__%s((object),(func),(data))\n",
473 m->id, funcbase, m->id);
476 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
477 "%s_connect_after__%s((object),(func),(data))\n",
478 m->id, funcbase, m->id);
481 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
482 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
483 m->id, funcbase, m->id);
487 put_local_signal_macros (const Class *c)
494 for (li = c->nodes; li != NULL; li = li->next) {
495 const Node *n = li->data;
496 if (n->type == METHOD_NODE)
497 put_local_signal_macro ((Method *)n);
503 put_prot_method(const Method *m)
505 if(m->scope != PROTECTED_SCOPE)
509 print_method(outph, "", "\t", "", "\t", "", ";\n",
510 m, FALSE, FALSE, TRUE, FALSE, FALSE);
512 print_method(out, "", "\t", "", "\t", "", ";\n",
513 m, FALSE, FALSE, TRUE, FALSE, FALSE);
517 put_priv_method_prot(const Method *m)
519 if(m->method == SIGNAL_LAST_METHOD ||
520 m->method == SIGNAL_FIRST_METHOD ||
521 m->method == VIRTUAL_METHOD) {
524 "static ", "___real_", "", " ", "", ";\n",
525 m, FALSE, FALSE, TRUE, FALSE, FALSE);
527 /* no else, here, it might still have a private prototype, it's not
530 if((m->method == OVERRIDE_METHOD &&
533 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
534 print_method(out, "static ", s, "", " ", "",
535 no_gnu?";\n":" G_GNUC_UNUSED;\n",
536 m, FALSE, FALSE, FALSE, FALSE, FALSE);
538 } else if(m->scope == PRIVATE_SCOPE ||
539 m->method == INIT_METHOD ||
540 m->method == CLASS_INIT_METHOD) {
541 print_method(out, "static ", "", "", " ", "",
542 no_gnu?";\n":" G_GNUC_UNUSED;\n",
543 m, FALSE, FALSE, TRUE, FALSE, FALSE);
548 make_func_arg (const char *typename, gboolean is_class, const char *name)
555 tn = g_strconcat (typename, ":Class", NULL);
557 tn = g_strdup (typename);
559 type = node_new (TYPE_NODE,
563 node = node_new (FUNCARG_NODE,
564 "atype:steal", (Type *)type,
567 return g_list_prepend (NULL, node);
571 make_inits(Class *cl)
573 int got_class_init = FALSE;
574 int got_init = FALSE;
577 for(li=cl->nodes;li;li=g_list_next(li)) {
579 if(n->type == METHOD_NODE) {
580 Method *m = (Method *)n;
581 if(m->method == INIT_METHOD) {
583 error_print(GOB_ERROR, m->line_no, "init defined more then once");
585 } else if(m->method == CLASS_INIT_METHOD) {
587 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
588 got_class_init = TRUE;
592 if(!got_class_init) {
593 Type *type = (Type *)node_new (TYPE_NODE,
596 node = node_new (METHOD_NODE,
598 "method", CLASS_INIT_METHOD,
601 "args:steal", make_func_arg (cl->otype,
604 "unique_id", method_unique_id++,
606 cl->nodes = g_list_prepend(cl->nodes, node);
609 Type *type = (Type *)node_new (TYPE_NODE,
612 node = node_new (METHOD_NODE,
614 "method", INIT_METHOD,
617 "args:steal", make_func_arg (cl->otype,
618 FALSE /* is_class */,
620 "unique_id", method_unique_id++,
622 cl->nodes = g_list_prepend(cl->nodes, node);
627 find_dispose(const Class *cl)
631 dispose_handler = NULL;
632 for(li=cl->nodes;li;li=g_list_next(li)) {
634 if(n->type == METHOD_NODE) {
635 Method *m = (Method *)n;
636 if(m->method == OVERRIDE_METHOD &&
637 strcmp(m->id, "dispose")==0) {
638 if(strcmp(m->otype, "G:Object") != 0) {
639 error_print(GOB_ERROR, m->line_no,
640 "dispose method override "
641 "of class other then "
644 if(g_list_length(m->args) != 1) {
645 error_print(GOB_ERROR, m->line_no,
646 "dispose method override "
647 "with more then one "
658 find_finalize(const Class *cl)
662 finalize_handler = NULL;
663 for(li=cl->nodes;li;li=g_list_next(li)) {
665 if(n->type == METHOD_NODE) {
666 Method *m = (Method *)n;
667 if(m->method == OVERRIDE_METHOD &&
668 strcmp(m->id, "finalize")==0) {
669 if(strcmp(m->otype, "G:Object") != 0) {
670 error_print(GOB_ERROR, m->line_no,
671 "finalize method override "
672 "of class other then "
675 if(g_list_length(m->args) != 1) {
676 error_print(GOB_ERROR, m->line_no,
677 "finalize method override "
678 "with more then one "
681 finalize_handler = m;
689 /* hash of method -> name of signal prototype */
690 static GHashTable *marsh = NULL;
692 /* list of methods with different signal prototypes,
693 we check this list if we can use a signal prototype of a
694 previous signal method, there are only uniques here */
695 static GList *eq_signal_methods = NULL;
697 /* compare a list of strings */
699 is_list_equal(const GList *a, const GList *b)
701 for(;a && b; a=a->next, b=b->next) {
702 if(strcmp(a->data, b->data)!=0) {
706 /* the the lists were different length */
713 find_same_type_signal(const Method *m)
716 for(li=eq_signal_methods;li;li=li->next) {
717 Method *mm = li->data;
718 if(is_list_equal(mm->gtktypes, m->gtktypes))
725 print_signal_marsal_args (const Method *m)
727 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
730 for (i = 0, li = m->gtktypes->next;
732 i++, li = li->next) {
735 if (strcmp (li->data, "UNICHAR") == 0)
736 /* hack because glib is braindamaged */
737 get_func = g_strdup ("g_value_get_uint");
739 get_func = g_strdup_printf
740 ("g_value_get_%s", (char *)li->data);
742 gob_strdown (get_func);
743 out_printf (out, ",\n\t\t(%s) "
744 "%s (param_values + %d)",
745 get_cast (li->data, FALSE),
750 out_printf (out, ",\n\t\tdata2);\n");
755 add_signal_prots(Method *m)
761 gboolean ret_none = FALSE;
762 gboolean arglist_none = FALSE;
764 const char *unused = "";
766 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
767 unused = " G_GNUC_UNUSED";
770 if (m->method != SIGNAL_LAST_METHOD &&
771 m->method != SIGNAL_FIRST_METHOD)
775 marsh = g_hash_table_new(NULL, NULL);
777 g_assert (m->gtktypes->next != NULL);
779 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
780 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
782 if (ret_none && arglist_none)
785 /* if we already did a signal prototype just use that */
786 mm = find_same_type_signal (m);
788 s = g_hash_table_lookup (marsh, mm);
789 g_hash_table_insert (marsh, m, s);
796 retcast = get_cast (m->gtktypes->data, FALSE);
798 s = g_strdup_printf("Sig%d", sig++);
800 g_hash_table_insert(marsh, m, s);
801 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
803 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
804 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
805 get_cast(m->gtktypes->data, FALSE), s, typebase);
807 if ( ! arglist_none) {
808 for (li = m->gtktypes->next; li != NULL; li = li->next)
809 out_printf (out, "%s, ", get_cast (li->data, FALSE));
811 out_printf (out, "gpointer);\n");
813 out_printf (out, "\nstatic void\n"
814 "___marshal_%s (GClosure *closure,\n"
815 "\tGValue *return_value%s,\n"
816 "\tguint n_param_values,\n"
817 "\tconst GValue *param_values,\n"
818 "\tgpointer invocation_hint%s,\n"
819 "\tgpointer marshal_data)\n"
826 out_printf (out, "\t%s v_return;\n", retcast);
828 out_printf (out, "\tregister ___%s callback;\n"
829 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
830 "\tregister gpointer data1, data2;\n\n",
833 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
834 arglist_none ? 1 : g_list_length (m->gtktypes));
837 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
838 "\t\tdata1 = closure->data;\n"
839 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
841 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
842 "\t\tdata2 = closure->data;\n"
845 out_printf (out, "\tcallback = (___%s) "
846 "(marshal_data != NULL ? marshal_data : cc->callback);"
850 out_printf (out, "\tcallback ((%s *)data1", typebase);
852 out_printf (out, "\tv_return = callback ((%s *)data1",
856 print_signal_marsal_args (m);
859 /* FIXME: This code is so fucking ugly it hurts */
860 gboolean take_ownership =
861 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
862 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
866 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
867 /* hack because glib is braindamaged */
868 set_func = g_strdup ("g_value_set_uint");
870 set_func = g_strdup_printf ("g_value_set_%s%s",
871 (char *)m->gtktypes->data,
873 "_take_ownership" : "");
874 gob_strdown (set_func);
876 out_printf (out, "\n\t%s (return_value, v_return);\n",
881 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
883 out_printf (out, "\n\treturn_value = NULL;\n");
884 out_printf (out, "\tinvocation_hint = NULL;\n");
887 out_printf (out, "}\n\n");
894 out_printf(out, "\n");
896 out_printf(out, "enum {\n");
897 for(li=c->nodes;li;li=g_list_next(li)) {
899 if(n->type == METHOD_NODE) {
900 Method *m = (Method *)n;
901 if(m->method == SIGNAL_LAST_METHOD ||
902 m->method == SIGNAL_FIRST_METHOD) {
903 char *s = g_strdup(m->id);
905 out_printf(out, "\t%s_SIGNAL,\n", s);
910 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
912 if (set_properties > 0 ||
913 get_properties > 0) {
914 out_printf(out, "enum {\n\tPROP_0");
915 for(li=c->nodes;li;li=g_list_next(li)) {
917 if (n->type == PROPERTY_NODE) {
918 Property *p = (Property *)n;
919 char *s = g_strdup (p->name);
921 out_printf (out, ",\n\tPROP_%s", s);
923 } else if (n->type == ARGUMENT_NODE) {
924 Argument *a = (Argument *)n;
925 char *s = g_strdup(a->name);
927 out_printf(out, ",\n\tPROP_%s", s);
931 out_printf(out, "\n};\n\n");
936 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
938 out_printf(out, "/* pointer to the class of our parent */\n");
939 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
943 add_interface_methods (Class *c, const char *interface)
946 gboolean added_line = FALSE;
948 for (li = c->nodes; li != NULL; li = li->next) {
950 Method *m = (Method *)n;
951 if (n->type != METHOD_NODE ||
952 m->method == OVERRIDE_METHOD ||
953 m->interface == NULL ||
954 strcmp (m->interface, interface) != 0)
957 if (m->line_no > 0) {
958 out_addline_infile (out, m->line_no);
960 } else if (m->line_no == 0 &&
962 out_addline_outfile (out);
965 out_printf (out, "\tiface->%s = self_%s;\n",
969 out_addline_outfile (out);
973 add_interface_inits (Class *c)
977 if (c->interfaces == NULL)
980 out_printf(out, "\n");
982 for (li = c->interfaces; li != NULL; li = li->next) {
983 const char *interface = li->data;
985 char *name = replace_sep (interface, '_');
986 char *type = remove_sep (interface);
988 /* EEEK! evil, we should have some sort of option
989 * to force this for arbitrary interfaces, since
990 * some are Class and some are Iface. Glib is shite
992 if (strcmp (type, "GtkEditable") == 0 ||
993 strcmp (type, "GTypePlugin") == 0)
996 /* We'll assume Iface is the standard ending */
999 out_printf (out, "\nstatic void\n"
1000 "___%s_init (%s%s *iface)\n"
1004 add_interface_methods (c, interface);
1006 out_printf (out, "}\n\n");
1014 add_interface_infos (void)
1017 for (li = ((Class *)class)->interfaces;
1020 char *name = replace_sep (li->data, '_');
1022 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1023 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1033 add_interfaces (void)
1036 for (li = ((Class *)class)->interfaces;
1039 char *name = replace_sep (li->data, '_');
1040 char *type = make_pre_macro (li->data, "TYPE");
1043 "\t\tg_type_add_interface_static (type,\n"
1045 "\t\t\t&%s_info);\n",
1057 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1061 "%s_get_type (void)\n"
1063 "\tstatic GType type = 0;\n\n"
1064 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1065 "\t\tstatic const GTypeInfo info = {\n"
1066 "\t\t\tsizeof (%sClass),\n"
1067 "\t\t\t(GBaseInitFunc) NULL,\n"
1068 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1069 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1070 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1071 "\t\t\tNULL /* class_data */,\n"
1072 "\t\t\tsizeof (%s),\n"
1073 "\t\t\t0 /* n_preallocs */,\n"
1074 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1077 funcbase, typebase, funcbase, typebase, funcbase);
1079 add_interface_infos ();
1082 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)0);\n",
1083 pmacrotype, typebase);
1091 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1093 chunk_size, chunk_size);
1103 add_bonobo_object_get_type (void)
1105 /* char *chunk_size = ((Class*)class)->chunk_size; */
1106 /* _vicious_ spanks seth with a rusty nail
1108 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1109 "gob2 doesn't officially support it yet. It'd be safer "
1110 "and a lot more fun to blow goats.\"\n");
1115 "%s_get_type (void)\n" /* 1 */
1117 "\tstatic GType type = 0;\n\n"
1118 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1119 "\t\tstatic const GTypeInfo info = {\n"
1120 "\t\t\tsizeof (%sClass),\n" /* 2 */
1121 "\t\t\t(GBaseInitFunc) NULL,\n"
1122 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1123 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1124 "\t\t\tNULL, /* class_finalize */\n"
1125 "\t\t\tNULL, /* class_data */\n"
1126 "\t\t\tsizeof (%s),\n" /* 4 */
1127 "\t\t\t0, /* n_preallocs */\n"
1128 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1137 add_interface_infos ();
1140 "\t\ttype = bonobo_type_unique (\n"
1141 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1142 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1143 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1144 "\t\t\t&info, \"%s\");\n", /* 3 */
1145 ((Class*)class)->bonobo_object_class /* 1 */,
1154 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1156 chunk_size, chunk_size);
1165 add_overrides(Class *c, const char *oname,
1166 gboolean did_base_obj)
1172 done = g_hash_table_new (g_str_hash, g_str_equal);
1174 s = g_strdup ("GObject");
1175 g_hash_table_insert (done, s, s);
1177 for (li = c->nodes; li != NULL; li = li->next) {
1180 Method *m = (Method *)n;
1181 if(n->type != METHOD_NODE ||
1182 m->method != OVERRIDE_METHOD)
1185 s = remove_sep(m->otype);
1187 if(g_hash_table_lookup(done, s)) {
1191 g_hash_table_insert(done, s, s);
1193 f = replace_sep(m->otype, '_');
1196 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1201 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1202 g_hash_table_destroy (done);
1206 make_run_signal_flags(Method *m, gboolean last)
1221 gs = g_string_new(NULL);
1224 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1226 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1228 if(m->scope == PUBLIC_SCOPE)
1229 g_string_append(gs, " | G_SIGNAL_ACTION");
1231 for(li = m->flags; li; li = li->next) {
1232 char *flag = li->data;
1234 for(i=0;flags[i];i++) {
1235 if(strcmp(flags[i], flag)==0)
1238 /* if we haven't found it in our list */
1240 error_printf(GOB_WARN, m->line_no,
1241 "Unknown flag '%s' used, "
1242 "perhaps it was misspelled",
1245 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1249 char *ret = gs->str;
1250 g_string_free(gs, FALSE);
1257 add_signals(Class *c)
1261 out_printf(out, "\n");
1262 for(li=c->nodes;li;li=g_list_next(li)) {
1264 char *mar, *sig, *flags;
1265 gboolean is_none, last = FALSE;
1266 Method *m = (Method *)n;
1268 if(n->type != METHOD_NODE ||
1269 (m->method != SIGNAL_FIRST_METHOD &&
1270 m->method != SIGNAL_LAST_METHOD))
1273 if(m->method == SIGNAL_FIRST_METHOD)
1278 if(g_hash_table_lookup(marsh, m))
1279 mar = g_strconcat("___marshal_",
1280 (char *)g_hash_table_lookup(marsh, m),
1283 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1285 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1287 sig = g_strdup (m->id);
1289 flags = make_run_signal_flags (m, last);
1290 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1291 "\t\tg_signal_new (\"%s\",\n"
1292 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1293 "\t\t\t(GSignalFlags)(%s),\n"
1294 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1295 "\t\t\tNULL, NULL,\n"
1297 "\t\t\tG_TYPE_%s, %d",
1300 typebase, m->id, mar,
1301 (char *)m->gtktypes->data,
1302 is_none ? 0 : g_list_length(m->gtktypes->next));
1309 for(l = m->gtktypes->next; l != NULL; l = l->next)
1310 out_printf(out, ",\n\t\t\tG_TYPE_%s",
1314 out_printf(out, ");\n");
1316 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1319 out_printf(out, "\tif ___GOB_UNLIKELY(");
1320 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1321 out_printf(out, "sizeof(");
1322 print_type(out, m->mtype, FALSE);
1323 out_printf(out, "%s",
1325 m->mtype->postfix : "");
1326 out_printf(out, ") != sizeof(%s) || ",
1327 get_cast(m->gtktypes->data, FALSE));
1330 for(al = m->args->next, gl = m->gtktypes->next;
1331 al != NULL && gl != NULL;
1332 al = al->next, gl = gl->next) {
1333 FuncArg *arg = al->data;
1334 char *gtkarg = gl->data;
1336 out_printf(out, "sizeof(");
1337 print_type(out, arg->atype, FALSE);
1338 out_printf(out, "%s",
1339 arg->atype->postfix ?
1340 arg->atype->postfix : "");
1341 out_printf(out, ") != sizeof(%s) || ",
1342 get_cast(gtkarg, FALSE));
1346 "parent_class == NULL /* avoid warning */");
1348 out_printf(out, ") {\n"
1349 "\t\tg_error(\"%s line %d: Type mismatch "
1350 "of \\\"%s\\\" signal signature\");\n"
1352 filename, m->line_no, m->id);
1359 set_def_handlers(Class *c, const char *oname)
1362 gboolean set_line = FALSE;
1364 out_printf(out, "\n");
1365 for(li = c->nodes; li; li = g_list_next(li)) {
1367 Method *m = (Method *)n;
1369 if(n->type != METHOD_NODE ||
1370 (m->method != SIGNAL_FIRST_METHOD &&
1371 m->method != SIGNAL_LAST_METHOD &&
1372 m->method != VIRTUAL_METHOD &&
1373 m->method != OVERRIDE_METHOD))
1376 if(m->line_no > 0 && m->cbuf) {
1377 out_addline_infile(out, m->line_no);
1379 } else if(set_line) {
1380 out_addline_outfile(out);
1385 if (m->method == OVERRIDE_METHOD) {
1387 s = replace_sep (m->otype, '_');
1391 dispose_handler != NULL &&
1392 strcmp (m->id, "dispose") == 0)
1393 out_printf (out, "\tg_object_class->dispose "
1395 else if (need_finalize &&
1397 strcmp(m->id, "finalize") == 0)
1399 "\tg_object_class->finalize = ___finalize;\n");
1400 else if (m->cbuf != NULL)
1402 "\t%s_class->%s = ___%x_%s_%s;\n",
1403 s, m->id, (guint)m->unique_id,
1406 out_printf(out, "\t%s_class->%s = NULL;\n",
1410 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1414 out_printf(out, "\t%s->%s = NULL;\n",
1419 out_addline_outfile(out);
1423 make_argument (Argument *a)
1428 char *argflags[] = {
1436 flags = g_string_new ("(GParamFlags)(");
1438 if(a->get && a->set)
1439 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1441 g_string_append (flags, "G_PARAM_READABLE");
1443 g_string_append (flags, "G_PARAM_WRITABLE");
1445 g_assert(a->get || a->set);
1447 for (l = a->flags; l != NULL; l = l->next) {
1448 char *flag = l->data;
1450 if(strcmp (flag, "READABLE") == 0 ||
1451 strcmp (flag, "WRITABLE") == 0) {
1452 error_print(GOB_WARN, a->line_no,
1454 "WRITABLE argument flags are "
1455 "set automatically");
1458 for(i = 0; argflags[i]; i++) {
1459 if(strcmp(argflags[i], flag)==0)
1462 /* if we haven't found it in our list */
1463 if( ! argflags[i]) {
1464 error_printf(GOB_WARN, a->line_no,
1465 "Unknown flag '%s' used, "
1466 "perhaps it was misspelled", flag);
1468 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1471 g_string_append (flags, ")");
1473 s = g_strdup(a->name);
1475 if (!strcmp (a->gtktype, "ENUM"))
1476 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1477 "\t\tG_TYPE_ENUM, 0,\n"
1479 a->name, flags->str);
1480 if (!strcmp (a->gtktype, "FLAGS"))
1481 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1482 "\t\tG_TYPE_FLAGS, 0,\n"
1484 a->name, flags->str);
1485 else if (!strcmp (a->gtktype, "OBJECT"))
1486 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1487 "\t\tG_TYPE_OBJECT,\n"
1489 a->name, flags->str);
1490 else if (!strcmp (a->gtktype, "STRING"))
1491 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1494 a->name, flags->str);
1495 else if (!strcmp (a->gtktype, "INT"))
1496 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1497 "\t\tG_MININT, G_MAXINT,\n"
1500 a->name, flags->str);
1501 else if (!strcmp (a->gtktype, "UINT"))
1502 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1503 "\t\t0, G_MAXUINT,\n"
1506 a->name, flags->str);
1507 else if (!strcmp (a->gtktype, "INT"))
1508 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1509 "\t\tG_MININT, G_MAXINT,\n"
1512 a->name, flags->str);
1513 else if (!strcmp (a->gtktype, "CHAR"))
1514 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1518 a->name, flags->str);
1519 else if (!strcmp (a->gtktype, "UCHAR"))
1520 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1524 a->name, flags->str);
1525 else if (!strcmp (a->gtktype, "BOOL") ||
1526 !strcmp (a->gtktype, "BOOLEAN"))
1527 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1530 a->name, flags->str);
1531 else if (!strcmp (a->gtktype, "LONG"))
1532 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1533 "\t\tG_MINLONG, G_MAXLONG,\n"
1536 a->name, flags->str);
1537 else if (!strcmp (a->gtktype, "ULONG"))
1538 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1539 "\t\t0, G_MAXULONG,\n"
1542 a->name, flags->str);
1543 else if (!strcmp (a->gtktype, "INT64"))
1544 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1545 "\t\tG_MININT64, G_MAXINT64,\n"
1548 a->name, flags->str);
1549 else if (!strcmp (a->gtktype, "UINT64"))
1550 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1551 "\t\t0, G_MAXUINT64,\n"
1554 a->name, flags->str);
1555 else if (!strcmp (a->gtktype, "FLOAT"))
1556 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1557 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1560 a->name, flags->str);
1561 else if (!strcmp (a->gtktype, "DOUBLE"))
1562 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1563 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1566 a->name, flags->str);
1567 else if (!strcmp (a->gtktype, "POINTER"))
1568 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1570 a->name, flags->str);
1572 error_printf (GOB_ERROR, a->line_no,
1573 "%s type is not supported for arguments, try using properties",
1576 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1577 "\t\tPROP_%s, param_spec);\n", s);
1581 g_string_free(flags, TRUE);
1584 #define value_for_print(str, alt) (str != NULL ? str : alt)
1587 make_property (Property *p)
1591 if (p->get == NULL && p->set == NULL) {
1592 error_print (GOB_ERROR, p->line_no,
1593 "Property has no getter nor setter");
1597 if (p->flags != NULL)
1598 error_print (GOB_WARN, p->line_no,
1599 "Overriden property, flags ignored");
1600 if (p->nick != NULL)
1601 error_print (GOB_WARN, p->line_no,
1602 "Overriden property, nick ignored");
1603 if (p->blurb != NULL)
1604 error_print (GOB_WARN, p->line_no,
1605 "Overriden property, blurb ignored");
1606 if (p->minimum != NULL)
1607 error_print (GOB_WARN, p->line_no,
1608 "Overriden property, minimum ignored");
1609 if (p->maximum != NULL)
1610 error_print (GOB_WARN, p->line_no,
1611 "Overriden property, maximum ignored");
1612 if (p->default_value != NULL)
1613 error_print (GOB_WARN, p->line_no,
1614 "Overriden property, default_value ignored");
1616 s = g_strdup (p->name);
1618 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1620 "\t\t\"%s\");\n", s, p->name);
1625 char *argflags[] = {
1633 flags = g_string_new ("(GParamFlags)(");
1635 if (p->get != NULL && p->set != NULL)
1636 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1637 else if (p->get != NULL)
1638 g_string_append (flags, "G_PARAM_READABLE");
1640 g_string_append (flags, "G_PARAM_WRITABLE");
1643 for (l = p->flags; l != NULL; l = l->next) {
1644 char *flag = l->data;
1646 if(strcmp (flag, "READABLE") == 0 ||
1647 strcmp (flag, "WRITABLE") == 0) {
1648 error_print(GOB_WARN, p->line_no,
1650 "WRITABLE argument flags are "
1651 "set automatically");
1654 for(i = 0; argflags[i]; i++) {
1655 if(strcmp(argflags[i], flag)==0)
1658 /* if we haven't found it in our list */
1659 if( ! argflags[i]) {
1660 error_printf(GOB_WARN, p->line_no,
1661 "Unknown flag '%s' used, "
1662 "perhaps it was misspelled", flag);
1664 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1667 g_string_append (flags, ")");
1669 if (strcmp (p->gtktype, "CHAR") == 0) {
1670 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1671 "\t\t(\"%s\" /* name */,\n"
1672 "\t\t %s /* nick */,\n"
1673 "\t\t %s /* blurb */,\n"
1674 "\t\t %s /* minimum */,\n"
1675 "\t\t %s /* maximum */,\n"
1676 "\t\t %s /* default_value */,\n"
1679 value_for_print (p->nick, "NULL"),
1680 value_for_print (p->blurb, "NULL"),
1681 value_for_print (p->minimum, "-128"),
1682 value_for_print (p->maximum, "127"),
1683 value_for_print (p->default_value, "0"),
1685 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1686 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1687 "\t\t(\"%s\" /* name */,\n"
1688 "\t\t %s /* nick */,\n"
1689 "\t\t %s /* blurb */,\n"
1690 "\t\t %s /* minimum */,\n"
1691 "\t\t %s /* maximum */,\n"
1692 "\t\t %s /* default_value */,\n"
1695 value_for_print (p->nick, "NULL"),
1696 value_for_print (p->blurb, "NULL"),
1697 value_for_print (p->minimum, "0"),
1698 value_for_print (p->maximum, "0xFF"),
1699 value_for_print (p->default_value, "0"),
1701 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1702 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1703 "\t\t(\"%s\" /* name */,\n"
1704 "\t\t %s /* nick */,\n"
1705 "\t\t %s /* blurb */,\n"
1706 "\t\t %s /* default_value */,\n"
1709 value_for_print (p->nick, "NULL"),
1710 value_for_print (p->blurb, "NULL"),
1711 value_for_print (p->default_value, "FALSE"),
1713 } else if (strcmp (p->gtktype, "INT") == 0) {
1714 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1715 "\t\t(\"%s\" /* name */,\n"
1716 "\t\t %s /* nick */,\n"
1717 "\t\t %s /* blurb */,\n"
1718 "\t\t %s /* minimum */,\n"
1719 "\t\t %s /* maximum */,\n"
1720 "\t\t %s /* default_value */,\n"
1723 value_for_print (p->nick, "NULL"),
1724 value_for_print (p->blurb, "NULL"),
1725 value_for_print (p->minimum, "G_MININT"),
1726 value_for_print (p->maximum, "G_MAXINT"),
1727 value_for_print (p->default_value, "0"),
1729 } else if (strcmp (p->gtktype, "UINT") == 0) {
1730 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1731 "\t\t(\"%s\" /* name */,\n"
1732 "\t\t %s /* nick */,\n"
1733 "\t\t %s /* blurb */,\n"
1734 "\t\t %s /* minimum */,\n"
1735 "\t\t %s /* maximum */,\n"
1736 "\t\t %s /* default_value */,\n"
1739 value_for_print (p->nick, "NULL"),
1740 value_for_print (p->blurb, "NULL"),
1741 value_for_print (p->minimum, "0"),
1742 value_for_print (p->maximum, "G_MAXUINT"),
1743 value_for_print (p->default_value, "0"),
1745 } else if (strcmp (p->gtktype, "LONG") == 0) {
1746 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1747 "\t\t(\"%s\" /* name */,\n"
1748 "\t\t %s /* nick */,\n"
1749 "\t\t %s /* blurb */,\n"
1750 "\t\t %s /* minimum */,\n"
1751 "\t\t %s /* maximum */,\n"
1752 "\t\t %s /* default_value */,\n"
1755 value_for_print (p->nick, "NULL"),
1756 value_for_print (p->blurb, "NULL"),
1757 value_for_print (p->minimum, "G_MINLONG"),
1758 value_for_print (p->maximum, "G_MAXLONG"),
1759 value_for_print (p->default_value, "0"),
1761 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1762 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1763 "\t\t(\"%s\" /* name */,\n"
1764 "\t\t %s /* nick */,\n"
1765 "\t\t %s /* blurb */,\n"
1766 "\t\t %s /* minimum */,\n"
1767 "\t\t %s /* maximum */,\n"
1768 "\t\t %s /* default_value */,\n"
1771 value_for_print (p->nick, "NULL"),
1772 value_for_print (p->blurb, "NULL"),
1773 value_for_print (p->minimum, "0"),
1774 value_for_print (p->maximum, "G_MAXULONG"),
1775 value_for_print (p->default_value, "0"),
1777 } else if (strcmp (p->gtktype, "INT64") == 0) {
1778 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1779 "\t\t(\"%s\" /* name */,\n"
1780 "\t\t %s /* nick */,\n"
1781 "\t\t %s /* blurb */,\n"
1782 "\t\t %s /* minimum */,\n"
1783 "\t\t %s /* maximum */,\n"
1784 "\t\t %s /* default_value */,\n"
1787 value_for_print (p->nick, "NULL"),
1788 value_for_print (p->blurb, "NULL"),
1789 value_for_print (p->minimum, "G_MININT64"),
1790 value_for_print (p->maximum, "G_MAXINT64"),
1791 value_for_print (p->default_value, "0"),
1793 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1794 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1795 "\t\t(\"%s\" /* name */,\n"
1796 "\t\t %s /* nick */,\n"
1797 "\t\t %s /* blurb */,\n"
1798 "\t\t %s /* minimum */,\n"
1799 "\t\t %s /* maximum */,\n"
1800 "\t\t %s /* default_value */,\n"
1803 value_for_print (p->nick, "NULL"),
1804 value_for_print (p->blurb, "NULL"),
1805 value_for_print (p->minimum, "0"),
1806 value_for_print (p->maximum, "G_MAXUINT64"),
1807 value_for_print (p->default_value, "0"),
1809 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1810 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1811 "\t\t(\"%s\" /* name */,\n"
1812 "\t\t %s /* nick */,\n"
1813 "\t\t %s /* blurb */,\n"
1814 "\t\t %s /* default_value */,\n"
1817 value_for_print (p->nick, "NULL"),
1818 value_for_print (p->blurb, "NULL"),
1819 value_for_print (p->default_value, "0"),
1821 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1822 char *type = make_me_type (p->extra_gtktype,
1824 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1825 "\t\t(\"%s\" /* name */,\n"
1826 "\t\t %s /* nick */,\n"
1827 "\t\t %s /* blurb */,\n"
1828 "\t\t %s /* enum_type */,\n"
1829 "\t\t %s /* default_value */,\n"
1832 value_for_print (p->nick, "NULL"),
1833 value_for_print (p->blurb, "NULL"),
1835 value_for_print (p->default_value, "0"),
1838 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1839 char *type = make_me_type (p->extra_gtktype,
1841 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1842 "\t\t(\"%s\" /* name */,\n"
1843 "\t\t %s /* nick */,\n"
1844 "\t\t %s /* blurb */,\n"
1845 "\t\t %s /* flags_type */,\n"
1846 "\t\t %s /* default_value */,\n"
1849 value_for_print (p->nick, "NULL"),
1850 value_for_print (p->blurb, "NULL"),
1852 value_for_print (p->default_value, "0"),
1855 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1856 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1857 "\t\t(\"%s\" /* name */,\n"
1858 "\t\t %s /* nick */,\n"
1859 "\t\t %s /* blurb */,\n"
1860 "\t\t %s /* minimum */,\n"
1861 "\t\t %s /* maximum */,\n"
1862 "\t\t %s /* default_value */,\n"
1865 value_for_print (p->nick, "NULL"),
1866 value_for_print (p->blurb, "NULL"),
1867 value_for_print (p->minimum, "G_MINFLOAT"),
1868 value_for_print (p->maximum, "G_MAXFLOAT"),
1869 value_for_print (p->default_value, "0.0"),
1871 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1872 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1873 "\t\t(\"%s\" /* name */,\n"
1874 "\t\t %s /* nick */,\n"
1875 "\t\t %s /* blurb */,\n"
1876 "\t\t %s /* minimum */,\n"
1877 "\t\t %s /* maximum */,\n"
1878 "\t\t %s /* default_value */,\n"
1881 value_for_print (p->nick, "NULL"),
1882 value_for_print (p->blurb, "NULL"),
1883 value_for_print (p->minimum, "G_MINDOUBLE"),
1884 value_for_print (p->maximum, "G_MAXDOUBLE"),
1885 value_for_print (p->default_value, "0.0"),
1887 } else if (strcmp (p->gtktype, "STRING") == 0) {
1888 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1889 "\t\t(\"%s\" /* name */,\n"
1890 "\t\t %s /* nick */,\n"
1891 "\t\t %s /* blurb */,\n"
1892 "\t\t %s /* default_value */,\n"
1895 value_for_print (p->nick, "NULL"),
1896 value_for_print (p->blurb, "NULL"),
1897 value_for_print (p->default_value, "NULL"),
1899 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1900 char *type = make_me_type (p->extra_gtktype,
1902 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1903 "\t\t(\"%s\" /* name */,\n"
1904 "\t\t %s /* nick */,\n"
1905 "\t\t %s /* blurb */,\n"
1906 "\t\t %s /* param_type */,\n"
1909 value_for_print (p->nick, "NULL"),
1910 value_for_print (p->blurb, "NULL"),
1914 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1915 char *type = make_me_type (p->extra_gtktype,
1917 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1918 "\t\t(\"%s\" /* name */,\n"
1919 "\t\t %s /* nick */,\n"
1920 "\t\t %s /* blurb */,\n"
1921 "\t\t %s /* boxed_type */,\n"
1924 value_for_print (p->nick, "NULL"),
1925 value_for_print (p->blurb, "NULL"),
1929 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1930 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1931 "\t\t(\"%s\" /* name */,\n"
1932 "\t\t %s /* nick */,\n"
1933 "\t\t %s /* blurb */,\n"
1936 value_for_print (p->nick, "NULL"),
1937 value_for_print (p->blurb, "NULL"),
1939 /* FIXME: VALUE_ARRAY */
1940 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1941 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1942 "\t\t(\"%s\" /* name */,\n"
1943 "\t\t %s /* nick */,\n"
1944 "\t\t %s /* blurb */,\n"
1947 value_for_print (p->nick, "NULL"),
1948 value_for_print (p->blurb, "NULL"),
1950 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
1951 char *type = make_me_type (p->extra_gtktype,
1953 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1954 "\t\t(\"%s\" /* name */,\n"
1955 "\t\t %s /* nick */,\n"
1956 "\t\t %s /* blurb */,\n"
1957 "\t\t %s /* object_type */,\n"
1960 value_for_print (p->nick, "NULL"),
1961 value_for_print (p->blurb, "NULL"),
1966 error_printf (GOB_ERROR, p->line_no,
1967 "%s type is not supported by properties",
1971 s = g_strdup (p->name);
1973 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1975 "\t\tparam_spec);\n", s);
1978 g_string_free (flags, TRUE);
1983 make_arguments(Class *c)
1986 if (get_properties > 0)
1987 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1988 if (set_properties > 0)
1989 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1990 out_printf (out, " {\n");
1991 for (li = c->nodes; li != NULL; li = li->next) {
1993 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
1994 || n->type == ARGUMENT_NODE) {
1995 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2000 for (li = c->nodes; li != NULL; li = li->next) {
2002 if (n->type == PROPERTY_NODE)
2003 make_property ((Property *)n);
2004 else if (n->type == ARGUMENT_NODE)
2005 make_argument ((Argument *)n);
2007 out_printf(out, " }\n");
2011 print_initializer(Method *m, Variable *v)
2015 if(v->initializer == NULL)
2018 if(v->scope == PRIVATE_SCOPE)
2019 root = g_strconcat(((FuncArg *)m->args->data)->name,
2022 root = g_strdup(((FuncArg *)m->args->data)->name);
2024 if(v->initializer_line > 0)
2025 out_addline_infile(out, v->initializer_line);
2027 out_printf(out, "\t%s->%s = %s;\n",
2028 root, v->id, v->initializer);
2030 if(v->initializer_line > 0)
2031 out_addline_outfile(out);
2037 print_destructor (Variable *v)
2041 if(v->destructor == NULL)
2044 if(v->scope == PRIVATE_SCOPE)
2045 root = "self->_priv";
2049 if(v->destructor_simple) {
2050 if(v->destructor_line > 0)
2051 out_addline_infile(out, v->destructor_line);
2054 out_printf(out, "\tif(%s->%s) { "
2055 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2056 "%s->%s = NULL; }\n",
2057 root, v->id, v->destructor, root, v->id,
2060 out_printf(out, "\tif(%s->%s) { "
2061 "%s ((gpointer) %s->%s); "
2062 "%s->%s = NULL; }\n",
2063 root, v->id, v->destructor, root, v->id,
2067 if(v->destructor_line > 0)
2068 out_addline_outfile(out);
2070 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2071 out_printf(out, "#define VAR %s\n", v->id);
2072 out_printf(out, "\t{\n");
2073 if(v->destructor_line > 0)
2074 out_addline_infile(out, v->destructor_line);
2076 out_printf(out, "\t%s}\n", v->destructor);
2078 if(v->destructor_line > 0)
2079 out_addline_outfile(out);
2080 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
2082 out_printf(out, "#undef VAR\n");
2083 out_printf(out, "#undef %s\n", v->id);
2088 add_dispose (Class *c)
2090 out_printf(out, "\nstatic void\n"
2091 "___dispose (GObject *obj_self)\n"
2094 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2097 if (unreftors > 0) {
2098 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2100 ! no_gnu ? " G_GNUC_UNUSED" : "",
2104 if (dispose_handler != NULL) {
2105 /* so we get possible bad argument warning */
2106 if (dispose_handler->line_no > 0)
2107 out_addline_infile (out, dispose_handler->line_no);
2108 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2109 (guint)dispose_handler->unique_id, funcbase);
2110 if (dispose_handler->line_no > 0)
2111 out_addline_outfile (out);
2114 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2115 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2118 if (unreftors > 0) {
2120 for(li = ((Class *)class)->nodes;
2124 Variable *v = (Variable *)n;
2125 if (n->type == VARIABLE_NODE &&
2126 v->scope != CLASS_SCOPE &&
2127 v->destructor_unref)
2128 print_destructor (v);
2132 out_printf(out, "}\n"
2133 "#undef __GOB_FUNCTION__\n\n");
2137 add_finalize (Class *c)
2141 "___finalize(GObject *obj_self)\n"
2144 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2149 const char *unused = "";
2151 unused = " G_GNUC_UNUSED";
2152 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2153 typebase, unused, macrobase);
2156 const char *unused = "";
2158 unused = " G_GNUC_UNUSED";
2159 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2163 if(finalize_handler) {
2164 /* so we get possible bad argument warning */
2165 if(finalize_handler->line_no > 0)
2166 out_addline_infile(out, finalize_handler->line_no);
2167 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2168 (guint)finalize_handler->unique_id, funcbase);
2169 if(finalize_handler->line_no > 0)
2170 out_addline_outfile(out);
2173 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2174 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2177 if (destructors > 0) {
2179 for (li = ((Class *)class)->nodes;
2183 Variable *v = (Variable *)n;
2184 if (n->type == VARIABLE_NODE &&
2185 v->scope != CLASS_SCOPE &&
2186 ! v->destructor_unref)
2187 print_destructor (v);
2191 out_printf(out, "}\n"
2192 "#undef __GOB_FUNCTION__\n\n");
2196 make_bonobo_object_epv (Class *c, const char *classname)
2199 gboolean added_line = FALSE;
2201 for (li = c->nodes; li != NULL; li = li->next) {
2203 Method *m = (Method *)n;
2204 if(n->type != METHOD_NODE ||
2205 m->method == OVERRIDE_METHOD)
2208 if (m->bonobo_object_func) {
2209 if(m->line_no > 0) {
2210 out_addline_infile(out, m->line_no);
2212 } else if (m->line_no == 0 &&
2214 out_addline_outfile(out);
2217 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2218 classname, m->id, m->id);
2222 out_addline_outfile(out);
2228 const char *unused = "";
2232 unused = " G_GNUC_UNUSED";
2234 for(li=c->nodes;li;li=g_list_next(li)) {
2238 if(n->type != METHOD_NODE)
2241 if(m->method == INIT_METHOD) {
2243 out_addline_infile(out, m->line_no);
2244 print_method(out, "static ", "\n", "", " ", "", "\n",
2245 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2247 out_addline_outfile(out);
2248 out_printf(out, "{\n"
2249 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2252 out_printf(out, "\t%s->_priv = "
2253 "G_TYPE_INSTANCE_GET_PRIVATE(%s,TYPE_SELF,%sPrivate);\n",
2254 ((FuncArg *)m->args->data)->name,
2255 ((FuncArg *)m->args->data)->name,
2257 } else if(always_private_struct) {
2258 out_printf(out, "\t%s->_priv = NULL;\n",
2259 ((FuncArg *)m->args->data)->name);
2261 if(initializers > 0) {
2263 for(li = ((Class *)class)->nodes;
2267 Variable *v = (Variable *)n;
2268 if(n->type != VARIABLE_NODE ||
2269 v->scope == CLASS_SCOPE)
2271 print_initializer(m, v);
2274 } else if(m->method == CLASS_INIT_METHOD) {
2275 gboolean did_base_obj = FALSE;
2278 out_addline_infile(out, m->line_no);
2279 print_method(out, "static ", "\n", "", " ", "", "\n",
2280 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2282 out_addline_outfile(out);
2283 out_printf(out, "{\n"
2284 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2286 if (set_properties > 0 ||
2287 get_properties > 0 ||
2293 "g_object_class%s = "
2294 "(GObjectClass*) %s;\n",
2296 ((FuncArg *)m->args->data)->name);
2297 did_base_obj = TRUE;
2302 ((FuncArg *)m->args->data)->name,
2307 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2308 ((FuncArg *)m->args->data)->name,
2311 if (initializers > 0) {
2313 for(li = ((Class *)class)->nodes;
2317 Variable *v = (Variable *)n;
2318 if(n->type == VARIABLE_NODE &&
2319 v->scope == CLASS_SCOPE)
2320 print_initializer(m, v);
2324 out_printf(out, "\n\tparent_class = ");
2326 out_printf(out, "(%sClass *)", ptypebase);
2327 out_printf(out, "g_type_class_ref (%s);\n",
2333 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2335 /* if there are no handlers for these things, we
2336 * need to set them up here */
2337 if(need_dispose && !dispose_handler)
2338 out_printf(out, "\tg_object_class->dispose "
2340 if(need_finalize && !finalize_handler)
2341 out_printf(out, "\tg_object_class->finalize = "
2344 if(get_properties > 0 || set_properties > 0)
2347 if (c->bonobo_object_class != NULL) {
2348 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2354 out_printf(out, " {\n");
2355 out_addline_infile(out, m->ccode_line);
2356 out_printf(out, "%s\n", m->cbuf);
2357 out_addline_outfile(out);
2358 out_printf(out, " }\n");
2360 out_printf(out, "}\n"
2361 "#undef __GOB_FUNCTION__\n");
2366 add_argument (Argument *a, gboolean is_set)
2370 char *the_type_lower;
2375 line_no = a->set_line;
2378 line_no = a->get_line;
2382 s = g_strdup(a->name);
2384 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2386 the_type_lower = g_strdup (a->gtktype);
2387 gob_strdown (the_type_lower);
2389 /* HACK because there is no g_value_set/get for unichar */
2390 if (strcmp (the_type_lower, "unichar") == 0) {
2391 g_free (the_type_lower);
2392 the_type_lower = g_strdup ("uint");
2397 const char *unused = "";
2399 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2400 unused = " G_GNUC_UNUSED";
2403 if (a->atype != NULL &&
2404 /* gcc -Wbad-function-cast is wanking stupid, moronic
2405 and otherwise evil so we should just use a (gint)
2406 or (guint) cast, not the specific type cast */
2408 (strcmp (a->gtktype, "ENUM") != 0 &&
2409 strcmp (a->gtktype, "FLAGS") != 0)))
2410 cast = get_type (a->atype, TRUE);
2412 cast = g_strdup (get_cast (a->gtktype, FALSE));
2414 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2415 cast, unused, cast, the_type_lower);
2418 } else if ( ! is_set) {
2421 if (a->atype != NULL)
2422 cast = get_type (a->atype, TRUE);
2424 cast = g_strdup (get_cast (a->gtktype, FALSE));
2425 out_printf (out, "\t%s ARG;\n"
2426 "\tmemset (&ARG, 0, sizeof (%s));\n",
2432 out_printf(out, "\t\t{\n");
2434 out_addline_infile (out, line_no);
2435 out_printf (out, "%s\n", cbuf);
2437 out_addline_outfile (out);
2438 out_printf (out, "\t\t}\n");
2440 if (strcmp (a->gtktype, "OBJECT") == 0)
2441 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2444 out_printf (out, "\t\t"
2445 "g_value_set_%s (VAL, ARG);\n",
2448 g_free (the_type_lower);
2451 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2452 out_printf (out, "\t\tif (&ARG) break;\n");
2455 out_printf (out, "\t\tbreak;\n");
2457 out_printf (out, "\t}\n");
2461 add_property (Property *p, gboolean is_set)
2464 char *the_type_lower;
2470 line_no = p->set_line;
2473 line_no = p->get_line;
2478 name_upper = g_strdup (p->name);
2479 gob_strup (name_upper);
2480 the_type_lower = g_strdup (p->gtktype);
2481 gob_strdown (the_type_lower);
2483 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2485 out_printf(out, "\t\t{\n");
2487 out_addline_infile (out, line_no);
2488 out_printf (out, "%s\n", cbuf);
2490 out_addline_outfile (out);
2491 out_printf (out, "\t\t}\n");
2493 g_free (name_upper);
2494 g_free (the_type_lower);
2496 out_printf (out, "\t\tbreak;\n");
2500 add_getset_arg(Class *c, gboolean is_set)
2503 const char *unused = "";
2504 const char *hack_unused = "";
2506 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2507 unused = " G_GNUC_UNUSED";
2509 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2512 out_printf(out, "\nstatic void\n"
2513 "___object_%s_property (GObject *object,\n"
2514 "\tguint property_id,\n"
2515 "\t%sGValue *VAL%s,\n"
2516 "\tGParamSpec *pspec%s)\n"
2517 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2520 "\tself = %s (object);\n\n"
2521 "\tswitch (property_id) {\n",
2522 is_set ? "set" : "get",
2523 is_set ? "const " : "",
2527 is_set ? "set" : "get",
2532 for (li = c->nodes; li != NULL; li = li->next) {
2534 if (n->type == PROPERTY_NODE)
2535 add_property ((Property *)n, is_set);
2536 else if (n->type == ARGUMENT_NODE)
2537 add_argument ((Argument *)n, is_set);
2539 out_printf (out, "\tdefault:\n"
2540 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2541 "#ifndef __PRETTY_FUNCTION__\n"
2542 "# undef G_STRLOC\n"
2543 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2545 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2546 "\t\t%sbreak;\n\t}\n"
2548 "#undef __GOB_FUNCTION__\n", hack_unused);
2552 print_checks (Method *m, FuncArg *fa)
2556 gboolean checked_null = FALSE;
2557 is_void = (strcmp(m->mtype->name, "void")==0 &&
2558 m->mtype->pointer == NULL);
2560 for(li = fa->checks; li != NULL; li = li->next) {
2561 Check *ch = li->data;
2563 /* point to the method prot in .gob for failed checks */
2565 out_addline_infile(out, m->line_no);
2567 out_printf(out, "\tg_return_if_fail (");
2569 out_printf(out, "\tg_return_val_if_fail (");
2570 switch(ch->chtype) {
2572 out_printf(out, "%s != NULL", fa->name);
2573 checked_null = TRUE;
2576 s = make_pre_macro(fa->atype->name, "IS");
2578 out_printf(out, "%s (%s)", s, fa->name);
2580 /* if not check null, null may be valid */
2581 out_printf(out, "!(%s) || %s (%s)", fa->name,
2586 out_printf(out, "%s < %s", fa->name, ch->number);
2589 out_printf(out, "%s > %s", fa->name, ch->number);
2592 out_printf(out, "%s <= %s", fa->name, ch->number);
2595 out_printf(out, "%s >= %s", fa->name, ch->number);
2598 out_printf(out, "%s == %s", fa->name, ch->number);
2601 out_printf(out, "%s != %s", fa->name, ch->number);
2605 out_printf(out, ");\n");
2607 out_printf(out, ", (");
2608 print_type(out, m->mtype, TRUE);
2609 out_printf(out, ")%s);\n",
2610 m->onerror?m->onerror:"0");
2616 print_preconditions(Method *m)
2620 for(li=m->args;li;li=g_list_next(li)) {
2621 FuncArg *fa = li->data;
2623 print_checks(m, fa);
2626 out_addline_outfile(out);
2630 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2633 out_addline_outfile(out);
2634 out_printf(out, "{\n"
2635 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2636 ((Class *)class)->otype,
2639 print_preconditions(m);
2643 (no_gnu || for_cpp) &&
2645 ((FuncArg *)(m->args->data))->name != NULL &&
2646 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2647 out_printf (out, "\tif (&self) { ; }\n");
2650 /* Note: the trailing }'s are on one line, this is so
2651 that we get the no return warning correctly and point to
2652 the correct line in the .gob file, yes this is slightly
2653 ugly in the .c file, but that is not supposed to be
2654 human readable anyway. */
2656 out_printf(out, "{\n");
2658 out_addline_infile(out, m->ccode_line);
2659 out_printf(out, "\t%s}", m->cbuf);
2662 /* Note, there is no \n between the last } and this } so that
2663 * errors/warnings reported on the end of the body get pointed to the
2664 * right line in the .gob source */
2665 out_printf(out, "}\n");
2668 out_addline_outfile(out);
2669 out_printf(out, "#undef __GOB_FUNCTION__\n");
2673 put_signal_args (Method *m)
2679 if (m->args->next == NULL)
2682 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2683 li != NULL && ali != NULL;
2684 li = li->next, ali = ali->next, i++) {
2685 FuncArg *fa = li->data;
2686 char *cast = g_strdup (get_cast (ali->data, FALSE));
2687 /* FIXME: This code is so fucking ugly it hurts */
2688 gboolean do_static =
2689 (strcmp ((char *)ali->data, "STRING") == 0 ||
2690 strcmp ((char *)ali->data, "BOXED") == 0);
2694 cast = get_type (fa->atype, TRUE);
2696 /* we should have already proved before that
2697 the we know all the types */
2698 g_assert (cast != NULL);
2701 "\t___param_values[%d].g_type = 0;\n"
2702 "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
2703 i, i, (char *)ali->data);
2705 if (strcmp (ali->data, "UNICHAR") == 0)
2706 /* hack because glib is braindamaged */
2707 set_func = g_strdup ("g_value_set_uint");
2709 set_func = g_strdup_printf ("g_value_set%s_%s",
2710 do_static ? "_static" : "",
2712 gob_strdown (set_func);
2714 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2715 set_func, i, cast, fa->name);
2723 clear_signal_args (Method *m)
2728 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2730 if (m->args->next == NULL)
2733 for (li = m->args->next, i = 1;
2735 li = li->next, i++) {
2737 "\tg_value_unset (&___param_values[%d]);\n", i);
2742 get_arg_names_for_macro (Method *m)
2746 GString *gs = g_string_new(NULL);
2748 for(li=m->args;li;li=g_list_next(li)) {
2749 FuncArg *arg = li->data;
2750 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2753 return g_string_free (gs, FALSE);
2757 put_method(Method *m)
2759 char *s, *args, *doc;
2761 is_void = (strcmp(m->mtype->name, "void")==0 &&
2762 m->mtype->pointer == NULL);
2763 out_printf(out, "\n");
2764 if(m->method != OVERRIDE_METHOD) {
2765 doc = get_gtk_doc(m->id);
2767 out_printf(out, "%s", doc);
2772 case REGULAR_METHOD:
2774 out_addline_infile(out, m->line_no);
2775 if(m->scope == PRIVATE_SCOPE)
2776 print_method(out, "static ", "\n", "", " ", "", "\n",
2777 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2778 else /* PUBLIC, PROTECTED */
2779 print_method(out, "", "\n", "", " ", "", "\n",
2780 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2781 print_method_body(m, TRUE, TRUE);
2782 /* the outfile line was added above */
2784 case SIGNAL_FIRST_METHOD:
2785 case SIGNAL_LAST_METHOD:
2787 out_addline_infile(out, m->line_no);
2788 if(m->scope == PRIVATE_SCOPE)
2789 print_method(out, "static ", "\n", "", " ", "", "\n",
2790 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2791 else /* PUBLIC, PROTECTED */
2792 print_method(out, "", "\n", "", " ", "", "\n",
2793 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2794 out_addline_outfile (out);
2796 out_printf (out, "{\n");
2799 "\tGValue ___param_values[%d];\n"
2800 "\tGValue ___return_val;\n\n"
2801 "memset (&___return_val, 0, "
2802 "sizeof (___return_val));\n"
2803 "memset (&___param_values, 0, "
2804 "sizeof (___param_values));\n\n",
2805 g_list_length (m->args));
2807 print_preconditions (m);
2810 "\n\t___param_values[0].g_type = 0;\n"
2811 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2812 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2813 ((FuncArg *)m->args->data)->name,
2814 ((FuncArg *)m->args->data)->name);
2816 put_signal_args (m);
2818 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2819 const char *defret = NULL;
2821 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2822 (char *)m->gtktypes->data);
2824 if (m->defreturn != NULL)
2825 defret = m->defreturn;
2826 else if (m->onerror != NULL)
2827 defret = m->onerror;
2829 if (defret != NULL) {
2831 /* FIXME: This code is so fucking ugly it hurts */
2832 gboolean do_static =
2833 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2834 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2835 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2837 cast = get_type (m->mtype, TRUE);
2839 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2840 /* hack because glib is braindamaged */
2841 set_func = g_strdup ("g_value_set_uint");
2843 set_func = g_strdup_printf ("g_value_set%s_%s",
2844 do_static ? "_static" : "",
2845 (char *)m->gtktypes->data);
2846 gob_strdown (set_func);
2848 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2849 set_func, cast, defret);
2854 out_printf (out, "\n");
2857 s = g_strdup (m->id);
2860 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2861 "\t\tobject_signals[%s_SIGNAL],\n"
2862 "\t\t0 /* detail */,\n"
2863 "\t\t&___return_val);\n", s);
2867 clear_signal_args (m);
2869 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2870 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2872 /* Hack because glib is very very braindead */
2874 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2875 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
2876 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
2877 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
2879 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2880 /* hack because glib is braindamaged */
2881 getfunc = g_strdup ("g_value_get_uint");
2883 getfunc = g_strdup_printf ("g_value_%s_%s",
2884 do_dup ? "dup" : "get",
2885 (char *)m->gtktypes->data);
2886 gob_strdown (getfunc);
2889 cast = get_type (m->mtype, TRUE);
2894 print_type (out, m->mtype, TRUE);
2896 " ___ret = (%s) %s (&___return_val);\n"
2897 "\t\tg_value_unset (&___return_val);\n"
2898 "\t\treturn ___ret;\n"
2905 out_printf(out, "}\n");
2910 out_addline_infile(out, m->line_no);
2911 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2912 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2913 print_method_body(m, FALSE, TRUE);
2914 /* the outfile line was added above */
2916 case VIRTUAL_METHOD:
2918 out_addline_infile(out, m->line_no);
2919 if(m->scope==PRIVATE_SCOPE)
2920 print_method(out, "static ", "\n", "", " ", "", "\n",
2921 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2922 else /* PUBLIC, PROTECTED */
2923 print_method(out, "", "\n", "", " ", "", "\n",
2924 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2925 out_addline_outfile(out);
2926 out_printf(out, "{\n"
2927 "\t%sClass *klass;\n", typebase);
2928 print_preconditions(m);
2929 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2930 "\tif(klass->%s)\n",
2931 macrobase, ((FuncArg *)m->args->data)->name,
2933 if(strcmp(m->mtype->name, "void") == 0 &&
2934 m->mtype->pointer == NULL) {
2936 out_printf(out, "\t\t(*klass->%s)(%s",
2938 ((FuncArg *)m->args->data)->name);
2939 for(li=m->args->next;li;li=g_list_next(li)) {
2940 FuncArg *fa = li->data;
2941 out_printf(out, ",%s", fa->name);
2943 out_printf(out, ");\n}\n");
2946 out_printf(out, "\t\treturn (*klass->%s)(%s",
2948 ((FuncArg *)m->args->data)->name);
2949 for(li=m->args->next;li;li=g_list_next(li)) {
2950 FuncArg *fa = li->data;
2951 out_printf(out, ",%s", fa->name);
2953 out_printf(out, ");\n"
2956 print_type(out, m->mtype, TRUE);
2958 out_printf(out, ")(%s);\n}\n", m->defreturn);
2960 out_printf(out, ")(%s);\n}\n", m->onerror);
2962 out_printf(out, ")(0);\n}\n");
2968 out_addline_infile(out, m->line_no);
2969 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2970 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2971 print_method_body(m, FALSE, TRUE);
2972 /* the outfile line was added above */
2974 case OVERRIDE_METHOD:
2978 out_addline_infile(out, m->line_no);
2979 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2980 print_method(out, "static ", s, "", " ", "", "\n",
2981 m, FALSE, FALSE, FALSE, TRUE, FALSE);
2983 out_addline_outfile(out);
2984 s = replace_sep(m->otype, '_');
2986 args = get_arg_names_for_macro(m);
2988 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2989 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2990 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2991 args, s, m->id, s, m->id, args);
2993 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2994 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2995 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2997 args, s, m->id, s, m->id, args);
2998 out_printf(out, "(");
2999 print_type(out, m->mtype, TRUE);
3000 out_printf(out, ")%s))\n",
3001 m->onerror?m->onerror:"0");
3005 print_method_body(m, TRUE, TRUE);
3006 /* the outfile line was added above */
3007 out_printf(out, "#undef PARENT_HANDLER\n");
3017 char *outfile, *outfileh, *outfileph;
3020 outfile = g_strconcat (fullfilebase, ".c", NULL);
3022 outfile = g_strconcat (fullfilebase, ".cc", NULL);
3023 if (no_touch_headers)
3024 outfileh = g_strconcat (fullfilebase, ".h#gob#", NULL);
3026 outfileh = g_strconcat (fullfilebase, ".h", NULL);
3028 if ((privates > 0 || protecteds > 0 ||
3029 private_header == PRIVATE_HEADER_ALWAYS) &&
3030 private_header != PRIVATE_HEADER_NEVER) {
3031 char sep[2] = {0,0};
3034 outfileph = g_strconcat (fullfilebase, sep, "private.h", NULL);
3041 devnull = fopen ("/dev/null", "w");
3042 if (devnull == NULL)
3043 error_print (GOB_ERROR, 0, "Cannot open null device");
3046 if (outfileph != NULL)
3049 out = fopen (outfile, "w");
3051 error_printf (GOB_ERROR, 0,
3052 "Cannot open outfile: %s", outfile);
3054 outh = fopen (outfileh, "w");
3056 error_printf (GOB_ERROR, 0,
3057 "Cannot open outfile: %s", outfileh);
3059 if (outfileph != NULL) {
3060 outph = fopen (outfileph, "w");
3061 if (outph == NULL) {
3062 error_printf (GOB_ERROR, 0,
3063 "Cannot open outfile: %s",
3071 put_argument_nongnu_wrappers (Class *c)
3075 if (get_properties < 0 && set_properties < 0)
3078 for (li = c->nodes; li != NULL; li = li->next) {
3080 const char *name, *gtktype;
3086 if (n->type == ARGUMENT_NODE) {
3087 Argument *a = (Argument *)n;
3089 gtktype = a->gtktype;
3091 get = a->get != NULL;
3092 set = a->set != NULL;
3093 } else if (n->type == PROPERTY_NODE) {
3094 Property *p = (Property *)n;
3096 gtktype = p->gtktype;
3098 get = p->get != NULL;
3099 set = p->set != NULL;
3104 aname = g_strdup (name);
3108 cast = get_type (atype, TRUE);
3110 cast = g_strdup (get_cast (gtktype, TRUE));
3114 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3115 "\"%s\",(%s)(arg)\n",
3116 macrobase, aname, name, cast);
3118 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3119 "\"%s\",(%s*)(arg)\n",
3120 macrobase, aname, name, cast);
3123 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3125 macrobase, aname, name);
3127 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3129 macrobase, aname, name);
3137 put_argument_gnu_wrappers(Class *c)
3141 if(get_properties < 0 && set_properties < 0)
3144 for (li = c->nodes; li != NULL; li = li->next) {
3146 const char *name, *gtktype;
3152 if (n->type == ARGUMENT_NODE) {
3153 Argument *a = (Argument *)n;
3155 gtktype = a->gtktype;
3157 get = a->get != NULL;
3158 set = a->set != NULL;
3159 } else if (n->type == PROPERTY_NODE) {
3160 Property *p = (Property *)n;
3162 gtktype = p->gtktype;
3164 get = p->get != NULL;
3165 set = p->set != NULL;
3170 aname = g_strdup (name);
3174 cast = get_type (atype, TRUE);
3176 cast = g_strdup (get_cast (gtktype, TRUE));
3180 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3181 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3182 macrobase, aname, name, cast);
3184 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3185 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3186 macrobase, aname, name, cast);
3189 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3191 macrobase, aname, name);
3193 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3195 macrobase, aname, name);
3203 print_ccode_block(CCode *cc)
3206 switch(cc->cctype) {
3208 /* HT code is printed exactly like normal header
3209 code but is printed before */
3212 out_printf(fp, "\n");
3215 /* AT code is printed exactly like normal 'all'
3216 code but is printed before */
3219 out_printf(outph, "\n");
3220 out_printf(outph, "%s\n", cc->cbuf);
3221 out_addline_infile(outph, cc->line_no);
3222 out_addline_outfile(outph);
3224 out_printf(outh, "\n");
3225 out_printf(outh, "%s\n", cc->cbuf);
3227 out_printf(fp, "\n");
3228 out_addline_infile(fp, cc->line_no);
3233 out_printf(fp, "\n");
3234 out_addline_infile(fp, cc->line_no);
3241 out_printf(fp, "\n");
3242 out_addline_infile(fp, cc->line_no);
3245 out_printf(fp, "%s\n", cc->cbuf);
3246 if(cc->cctype == C_CCODE ||
3247 cc->cctype == A_CCODE ||
3248 cc->cctype == AT_CCODE ||
3249 cc->cctype == PH_CCODE)
3250 out_addline_outfile(fp);
3254 print_class_block(Class *c)
3258 gboolean printed_private = FALSE;
3261 out_printf(out, "/* utility types we may need */\n");
3262 if(special_array[SPECIAL_2POINTER])
3263 out_printf(out, "typedef struct { "
3264 "gpointer a; gpointer b; "
3265 "} ___twopointertype;\n");
3266 if(special_array[SPECIAL_3POINTER])
3267 out_printf(out, "typedef struct { "
3268 "gpointer a; gpointer b; "
3270 "} ___threepointertype;\n");
3271 if(special_array[SPECIAL_INT_POINTER])
3272 out_printf(out, "typedef struct { "
3273 "gint a; gpointer b; "
3274 "} ___intpointertype;\n");
3275 out_printf(out, "\n");
3278 out_printf(outh, "\n/*\n"
3279 " * Type checking and casting macros\n"
3281 out_printf(outh, "#define %s\t"
3282 "(%s_get_type())\n",
3283 macrotype, funcbase);
3284 out_printf(outh, "#define %s(obj)\t"
3285 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3286 macrobase, funcbase, typebase);
3287 out_printf(outh, "#define %s_CONST(obj)\t"
3288 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3289 macrobase, funcbase, typebase);
3290 out_printf(outh, "#define %s_CLASS(klass)\t"
3291 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3292 macrobase, funcbase, typebase);
3293 out_printf(outh, "#define %s(obj)\t"
3294 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3297 "#define %s_GET_CLASS(obj)\t"
3298 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3299 macrobase, funcbase, typebase);
3301 if ( ! no_self_alias) {
3302 out_printf(out, "/* self casting macros */\n");
3303 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3304 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3305 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3306 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3307 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3309 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3312 out_printf(out, "/* self typedefs */\n");
3313 out_printf(out, "typedef %s Self;\n", typebase);
3314 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3318 always_private_struct) {
3319 out_printf (outh, "\n/* Private structure type */\n");
3320 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3321 typebase, typebase);
3323 out_printf (outh, "/* There are no privates, this "
3324 "structure is thus never defined */\n");
3327 out_printf (outh, "\n/*\n"
3328 " * Main object structure\n"
3330 s = replace_sep (c->otype, '_');
3332 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3333 "#define __TYPEDEF_%s__\n", s, s);
3335 out_printf (outh, "typedef struct _%s %s;\n"
3336 "#endif\n", typebase, typebase);
3337 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3338 typebase, ptypebase);
3339 for (li = c->nodes; li; li=li->next) {
3340 static gboolean printed_public = FALSE;
3342 Variable *v = (Variable *)n;
3343 if(n->type == VARIABLE_NODE &&
3344 v->scope == PUBLIC_SCOPE) {
3345 if( ! printed_public) {
3346 out_printf(outh, "\t/*< public >*/\n");
3347 printed_public = TRUE;
3349 put_variable((Variable *)n, outh);
3352 /* put protecteds always AFTER publics */
3353 for (li = c->nodes; li != NULL; li = li->next) {
3355 Variable *v = (Variable *)n;
3356 if (n->type == VARIABLE_NODE &&
3357 v->scope == PROTECTED_SCOPE) {
3358 if ( ! printed_private) {
3359 out_printf (outh, "\t/*< private >*/\n");
3360 printed_private = TRUE;
3362 put_variable ((Variable *)n, outh);
3366 always_private_struct) {
3367 if ( ! printed_private)
3368 out_printf (outh, "\t/*< private >*/\n");
3369 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3371 out_printf (outh, "};\n");
3376 /* if we are to stick this into the private
3377 header, if not stick it directly into the
3384 out_printf (outfp, "struct _%sPrivate {\n",
3386 for(li=c->nodes; li; li=li->next) {
3388 Variable *v = (Variable *)n;
3389 if(n->type == VARIABLE_NODE &&
3390 v->scope == PRIVATE_SCOPE) {
3391 out_addline_infile(outfp, v->line_no);
3392 put_variable(v, outfp);
3395 out_addline_outfile(outfp);
3396 out_printf(outfp, "};\n");
3399 out_printf(outh, "\n/*\n"
3400 " * Class definition\n"
3402 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3403 typebase, typebase);
3405 "struct _%sClass {\n\t%sClass __parent__;\n",
3406 typebase, ptypebase);
3407 for(li = c->nodes; li != NULL; li = li->next) {
3409 if(n->type == METHOD_NODE)
3410 put_vs_method((Method *)n);
3412 /* If BonoboX type class put down the epv */
3413 if (c->bonobo_object_class != NULL) {
3415 "\t/* Bonobo object epv */\n"
3416 "\tPOA_%s__epv _epv;\n",
3417 c->bonobo_object_class);
3419 /* put class scope variables */
3420 for (li = c->nodes; li != NULL; li = li->next) {
3422 Variable *v = (Variable *)n;
3423 if (n->type == VARIABLE_NODE &&
3424 v->scope == CLASS_SCOPE)
3425 put_variable ((Variable *)n, outh);
3427 out_printf (outh, "};\n\n");
3429 out_printf (out, "/* here are local prototypes */\n");
3430 if (set_properties > 0) {
3431 out_printf (out, "static void ___object_set_property "
3432 "(GObject *object, guint property_id, "
3433 "const GValue *value, GParamSpec *pspec);\n");
3435 if (get_properties > 0) {
3436 out_printf (out, "static void ___object_get_property "
3437 "(GObject *object, guint property_id, "
3438 "GValue *value, GParamSpec *pspec);\n");
3441 out_printf (outh, "\n/*\n"
3442 " * Public methods\n"
3445 if ( ! overrode_get_type) {
3446 out_printf (outh, "GType\t%s_get_type\t(void);\n", funcbase);
3449 for(li = c->nodes; li != NULL; li = li->next) {
3451 if(n->type == METHOD_NODE) {
3452 put_pub_method((Method *)n);
3453 put_prot_method((Method *)n);
3454 put_priv_method_prot((Method *)n);
3458 /* this idea is less and less apealing to me */
3460 out_printf (outh, "\n/*\n"
3461 " * Signal connection wrapper macros\n"
3464 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3465 put_signal_macros (c, TRUE);
3466 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3467 put_signal_macros (c, FALSE);
3468 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3470 put_signal_macros (c, FALSE);
3471 out_printf(outh, "\n");
3474 out_printf (out, "\n/*\n"
3475 " * Signal connection wrapper macro shortcuts\n"
3477 put_local_signal_macros (c);
3478 out_printf(outh, "\n");
3481 /* argument wrapping macros */
3482 if(get_properties > 0 || set_properties > 0) {
3483 out_printf(outh, "\n/*\n"
3484 " * Argument wrapping macros\n"
3487 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3488 put_argument_gnu_wrappers(c);
3489 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3490 put_argument_nongnu_wrappers(c);
3491 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3493 put_argument_nongnu_wrappers(c);
3498 for(li = c->nodes; li != NULL; li = li->next) {
3500 if(n->type == METHOD_NODE)
3501 add_signal_prots((Method *)n);
3507 if(any_method_to_alias(c)) {
3508 out_printf (out, "/* Short form macros */\n");
3509 make_method_aliases (c);
3512 add_interface_inits (c);
3514 if ( ! overrode_get_type) {
3515 if (c->bonobo_object_class != NULL)
3516 add_bonobo_object_get_type ();
3521 out_printf (out, "/* a macro for creating a new object of our type */\n");
3523 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3524 typebase, funcbase);
3526 out_printf (out, "/* a function for creating a new object of our type */\n");
3527 out_printf (out, "#include <stdarg.h>\n");
3529 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3530 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3531 "{\n\t%s *ret;\n\tva_list ap;\n"
3532 "\tva_start (ap, first);\n"
3533 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3536 "\treturn ret;\n}\n\n",
3538 no_gnu ? "" : " G_GNUC_UNUSED",
3539 typebase, typebase, typebase, funcbase);
3549 if(set_properties > 0) {
3550 add_getset_arg(c, TRUE);
3553 if(get_properties > 0) {
3554 add_getset_arg(c, FALSE);
3557 for(li = c->nodes; li != NULL; li = li->next) {
3559 if(n->type == METHOD_NODE)
3560 put_method((Method *)n);
3563 add_bad_hack_to_avoid_unused_warnings(c);
3567 print_useful_macros(void)
3569 int major = 0, minor = 0, pl = 0;
3572 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3573 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3574 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3575 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3577 /* Useful priv macro thingie */
3578 /* FIXME: this should be done the same way that priv is, as a var,
3580 out_printf (out, "#define selfp (self->_priv)\n\n");
3584 print_more_useful_macros (void)
3587 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3588 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3590 out_printf (out, "#ifdef G_LIKELY\n");
3591 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3592 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3593 out_printf (out, "#else /* ! G_LIKELY */\n");
3594 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3595 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3596 out_printf (out, "#endif /* G_LIKELY */\n");
3601 print_file_comments(void)
3605 out_printf(outh, "/* Generated by GOB (v%s)"
3606 " (do not edit directly) */\n\n", VERSION);
3608 out_printf(outph, "/* Generated by GOB (v%s)"
3609 " (do not edit directly) */\n\n", VERSION);
3610 out_printf(out, "/* Generated by GOB (v%s) on %s"
3611 " (do not edit directly) */\n\n",
3612 VERSION, ctime(&curtime));
3614 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3618 print_includes(void)
3620 gboolean found_header;
3623 /* We may need string.h for memset */
3624 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3625 out_printf(out, "#include <string.h> /* memset() */\n\n");
3628 p = g_strconcat(filebase, ".h", NULL);
3629 found_header = TRUE;
3630 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3631 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3632 found_header = FALSE;
3636 /* if we are creating a private header see if it was included */
3638 p = g_strconcat(filebase, "-private.h", NULL);
3639 if( ! g_list_find_custom(include_files, p,
3640 (GCompareFunc)strcmp)) {
3641 out_printf(out, "#include \"%s-private.h\"\n\n",
3644 error_printf(GOB_WARN, 0,
3645 "Implicit private header include "
3647 "\tsource file, while public "
3648 "header is at a custom location, "
3650 "\texplicitly include "
3651 "the private header below the "
3659 print_header_prefixes(void)
3663 p = replace_sep(((Class *)class)->otype, '_');
3665 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3667 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3668 "#define __%s_PRIVATE_H__\n\n"
3669 "#include \"%s.h\"\n\n", p, p, filebase);
3672 if( ! no_extern_c) {
3673 out_printf(outh, "#ifdef __cplusplus\n"
3675 "#endif /* __cplusplus */\n\n");
3677 out_printf(outph, "#ifdef __cplusplus\n"
3679 "#endif /* __cplusplus */\n\n");
3684 print_header_postfixes(void)
3687 out_printf(outh, "\n#ifdef __cplusplus\n"
3689 "#endif /* __cplusplus */\n");
3690 out_printf(outh, "\n#endif\n");
3693 out_printf(outph, "\n#ifdef __cplusplus\n"
3695 "#endif /* __cplusplus */\n");
3696 out_printf(outph, "\n#endif\n");
3705 /* print the AT_CCODE blocks */
3706 for(li = nodes; li != NULL; li = li->next) {
3707 Node *node = li->data;
3708 if(node->type == CCODE_NODE) {
3709 CCode *cc = (CCode *)node;
3710 if(cc->cctype == AT_CCODE)
3711 print_ccode_block((CCode *)node);
3717 print_header_top(void)
3721 /* mandatory includes */
3722 out_printf (outh, "#include <glib.h>\n");
3723 out_printf (outh, "#include <glib-object.h>\n");
3725 /* print the HT_CCODE blocks */
3726 for (li = nodes; li != NULL; li = li->next) {
3727 Node *node = li->data;
3728 if (node->type == CCODE_NODE) {
3729 CCode *cc = (CCode *)node;
3730 if (cc->cctype == HT_CCODE)
3731 print_ccode_block ((CCode *)node);
3737 print_enum (EnumDef *enode)
3744 funcprefix = replace_sep (enode->etype, '_');
3745 gob_strdown (funcprefix);
3746 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3748 type = remove_sep (enode->etype);
3750 out_printf (outh, "\ntypedef enum {\n");
3752 for (li = enode->values; li != NULL; li = li->next) {
3753 EnumValue *value = li->data;
3755 char *sname = gob_strdown (g_strdup (value->name));
3757 while ((p = strchr (sname, '_')) != NULL)
3760 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3761 if (value->value != NULL)
3762 out_printf (outh, " = %s", value->value);
3763 if (li->next != NULL)
3764 out_printf (outh, ",\n");
3766 out_printf (outh, "\n");
3768 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3769 enode->prefix, value->name,
3770 enode->prefix, value->name,
3776 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3778 out_printf (outh, "} %s;\n", type);
3780 str = make_pre_macro (enode->etype, "TYPE");
3781 out_printf (outh, "#define %s ", str);
3784 out_printf (outh, "%s_get_type()\n", funcprefix);
3785 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3788 "GType\n%s_get_type (void)\n"
3790 "\tstatic GType type = 0;\n"
3791 "\tif ___GOB_UNLIKELY(type == 0)\n"
3792 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3795 funcprefix, type, funcprefix);
3797 g_free (funcprefix);
3802 print_flags (Flags *fnode)
3810 funcprefix = replace_sep (fnode->ftype, '_');
3811 gob_strdown (funcprefix);
3812 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3814 type = remove_sep (fnode->ftype);
3816 out_printf (outh, "\ntypedef enum {\n");
3818 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3819 const char *name = li->data;
3821 char *sname = gob_strdown (g_strdup (name));
3823 while ((p = strchr (sname, '_')) != NULL)
3826 out_printf (outh, "\t%s_%s = 1<<%d",
3827 fnode->prefix, name, i);
3828 if (li->next != NULL)
3829 out_printf (outh, ",\n");
3831 out_printf (outh, "\n");
3833 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3834 fnode->prefix, name,
3835 fnode->prefix, name,
3841 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3843 out_printf (outh, "} %s;\n", type);
3845 str = make_pre_macro (fnode->ftype, "TYPE");
3846 out_printf (outh, "#define %s ", str);
3849 out_printf (outh, "%s_get_type()\n", funcprefix);
3850 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3853 "GType\n%s_get_type (void)\n"
3855 "\tstatic GType type = 0;\n"
3856 "\tif ___GOB_UNLIKELY(type == 0)\n"
3857 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3860 funcprefix, type, funcprefix);
3862 g_free (funcprefix);
3867 print_error (Error *enode)
3874 funcprefix = replace_sep (enode->etype, '_');
3875 gob_strdown (funcprefix);
3876 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3878 type = remove_sep (enode->etype);
3880 out_printf (outh, "\ntypedef enum {\n");
3882 for (li = enode->values; li != NULL; li = li->next) {
3883 const char *name = li->data;
3885 char *sname = gob_strdown (g_strdup (name));
3887 while ((p = strchr (sname, '_')) != NULL)
3890 out_printf (outh, "\t%s_%s", enode->prefix, name);
3891 if (li->next != NULL)
3892 out_printf (outh, ",\n");
3894 out_printf (outh, "\n");
3896 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3897 enode->prefix, name,
3898 enode->prefix, name,
3904 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3906 out_printf (outh, "} %s;\n", type);
3908 str = make_pre_macro (enode->etype, "TYPE");
3909 out_printf (outh, "#define %s ", str);
3912 out_printf (outh, "%s_get_type ()\n", funcprefix);
3913 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3916 "GType\n%s_get_type (void)\n"
3918 "\tstatic GType type = 0;\n"
3919 "\tif ___GOB_UNLIKELY(type == 0)\n"
3920 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3923 funcprefix, type, funcprefix);
3925 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3926 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3928 str = replace_sep (enode->etype, '-');
3932 "GQuark\n%s_quark (void)\n"
3934 "\tstatic GQuark q = 0;\n"
3936 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3943 g_free (funcprefix);
3948 generate_outfiles(void)
3952 print_file_comments();
3958 print_header_prefixes();
3960 print_useful_macros();
3964 print_more_useful_macros ();
3966 for (li = nodes; li != NULL; li = li->next) {
3967 Node *node = li->data;
3968 if (node->type == CCODE_NODE) {
3969 CCode *cc = (CCode *)node;
3970 if (cc->cctype != HT_CCODE &&
3971 cc->cctype != AT_CCODE)
3972 print_ccode_block ((CCode *)node);
3973 } else if (node->type == CLASS_NODE) {
3974 print_class_block ((Class *)node);
3975 } else if (node->type == ENUMDEF_NODE) {
3976 print_enum ((EnumDef *)node);
3977 } else if (node->type == FLAGS_NODE) {
3978 print_flags ((Flags *)node);
3979 } else if (node->type == ERROR_NODE) {
3980 print_error ((Error *)node);
3982 g_assert_not_reached();
3986 print_header_postfixes();
3992 fprintf(stderr, "Gob version %s\n\n", VERSION);
3993 fprintf(stderr, "gob [options] file.gob\n\n");
3994 fprintf(stderr, "Options:\n"
3995 "\t--help,-h,-? Display this help\n"
3996 "\t--version Display version\n"
3997 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3998 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3999 "\t--for-cpp Create C++ files\n"
4000 "\t--no-extern-c Never print extern \"C\" into the "
4002 "\t--no-gnu Never use GNU extentions\n"
4003 "\t--no-touch-headers Don't touch headers unless they "
4005 "\t--always-private-header Always create a private header "
4007 "\t even if it would be empty\n"
4008 "\t--ondemand-private-header Create private header only when "
4011 "\t--no-private-header Don't create a private header, "
4013 "\t structure and protected "
4014 "prototypes inside c file\n"
4015 "\t--always-private-struct Always create a private pointer "
4017 "\t the object structure\n"
4018 "\t--m4 Preprocess source with m4. "
4019 "Following args will\n"
4020 "\t be passed to m4\n"
4021 "\t--m4-dir Print directory that will be "
4024 "\t--no-write,-n Don't write output files, just "
4026 "\t--no-lines Don't print '#line' to output\n"
4027 "\t--no-self-alias Don't create self type and macro "
4029 "\t--no-kill-underscores Ignored for compatibility\n"
4030 "\t-o,--output-dir The directory where output "
4031 "should be placed\n"
4032 "\t--file-sep[=c] replace default \'-\' file "
4033 "name separator\n");
4037 parse_options(int argc, char *argv[])
4040 int got_file = FALSE;
4041 int no_opts = FALSE;
4042 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4046 for(i = 1 ; i < argc; i++) {
4048 char *new_commandline;
4049 g_assert(m4_commandline!=NULL);
4051 /* check whether this one looks like the filename */
4052 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4054 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4058 /* insert flags before the filename */
4059 new_commandline=g_strconcat(m4_commandline,
4067 /* just an ordinary option */
4069 new_commandline=g_strconcat(m4_commandline,
4074 /* free old commandline */
4075 g_free(m4_commandline);
4076 m4_commandline=new_commandline;
4078 } else if(no_opts ||
4079 argv[i][0] != '-') {
4082 fprintf(stderr, "Specify only one file!\n");
4088 } else if(strcmp(argv[i], "--help")==0) {
4091 } else if(strcmp(argv[i], "--version")==0) {
4092 fprintf(stderr, "Gob version %s\n", VERSION);
4094 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4095 exit_on_warn = TRUE;
4096 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4097 exit_on_warn = FALSE;
4098 } else if(strcmp(argv[i], "--for-cpp")==0) {
4100 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4101 no_touch_headers = TRUE;
4102 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4103 private_header = PRIVATE_HEADER_ONDEMAND;
4104 } else if(strcmp(argv[i], "--always-private-header")==0) {
4105 private_header = PRIVATE_HEADER_ALWAYS;
4106 } else if(strcmp(argv[i], "--no-private-header")==0) {
4107 private_header = PRIVATE_HEADER_NEVER;
4108 } else if(strcmp(argv[i], "--no-gnu")==0) {
4110 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4112 } else if(strcmp(argv[i], "--no-write")==0) {
4114 } else if(strcmp(argv[i], "--no-lines")==0) {
4116 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4117 no_self_alias = TRUE;
4118 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4120 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4121 always_private_struct = TRUE;
4122 } else if(strcmp(argv[i], "--m4-dir")==0) {
4123 printf("%s\n",M4_INCLUDE_DIR);
4125 } else if(strcmp(argv[i], "--m4")==0) {
4129 m4_commandline=g_strdup(M4_COMMANDLINE);
4130 } else if(strcmp(argv[i], "--m4-clean")==0) {
4134 m4_commandline=g_strdup(M4_COMMANDLINE);
4135 } else if (strcmp (argv[i], "-o") == 0 ||
4136 strcmp (argv[i], "--output-dir") == 0) {
4138 output_dir = g_strdup (argv[i+1]);
4143 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4146 strlen ("--output-dir=")) == 0) {
4147 char *p = strchr (argv[i], '=');
4148 g_assert (p != NULL);
4149 output_dir = g_strdup (p+1);
4150 } else if (strncmp (argv[i], "--file-sep=",
4151 strlen ("--file-sep=")) == 0) {
4152 char *p = strchr (argv[i], '=');
4153 g_assert (p != NULL);
4155 } else if (strncmp (argv[i], "--file-sep",
4156 strlen ("--file-sep")) == 0) {
4158 file_sep = (argv[i+1])[0];
4163 } else if(strcmp(argv[i], "--")==0) {
4164 /*further arguments are files*/
4166 } else if(strncmp(argv[i], "--", 2)==0) {
4167 /*unknown long option*/
4168 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4172 /*by now we know we have a string starting with
4173 - which is a short option string*/
4175 for(p = argv[i] + 1; *p; p++) {
4189 "Unknown option '%c'!\n", *p);
4198 /* if we are using m4, and got no filename, append m4 flags now */
4199 if(!got_file && use_m4 && !use_m4_clean) {
4200 char *new_commandline;
4201 new_commandline=g_strconcat(m4_commandline,
4205 g_free(m4_commandline);
4206 m4_commandline=new_commandline;
4211 /* this is a somewhat ugly hack, but it appears to work */
4213 compare_and_move_header(void)
4215 char *hfnew = g_strconcat(fullfilebase, ".h#gob#", NULL);
4216 char *hf = g_strconcat(fullfilebase, ".h", NULL);
4218 if(stat(hf, &s) == 0) {
4220 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
4221 if(system(s) == 0) {
4222 if(unlink(hfnew) != 0)
4223 error_printf(GOB_ERROR, 0,
4224 "Can't remove new header file");
4232 error_printf(GOB_ERROR, 0,
4233 "Can't remove old header file");
4235 if(rename(hfnew, hf) != 0)
4236 error_printf(GOB_ERROR, 0,
4237 "Can't rename new header file");
4243 main(int argc, char *argv[])
4245 parse_options(argc, argv);
4248 yyin = popen(m4_commandline, "r");
4250 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4254 } else if(filename) {
4255 yyin = fopen(filename, "r");
4257 fprintf(stderr, "Error: can't open file '%s'\n",
4266 /* This is where parsing is done */
4269 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4271 /* close input file */
4272 if(use_m4) pclose(yyin);
4277 error_print (GOB_ERROR, 0, "no class defined");
4280 exit_on_error = FALSE;
4282 signals = count_signals ((Class *)class);
4283 set_properties = count_set_properties ((Class *)class) +
4284 count_set_arguments ((Class *)class);
4285 get_properties = count_get_properties ((Class *)class) +
4286 count_get_arguments ((Class *)class);
4287 overrides = count_overrides ((Class *)class);
4288 privates = count_privates ((Class *)class);
4289 protecteds = count_protecteds ((Class *)class);
4290 unreftors = count_unreftors ((Class *)class);
4291 destructors = count_destructors ((Class *)class);
4292 initializers = count_initializers ((Class *)class);
4293 overrode_get_type = find_get_type ((Class *)class);
4296 make_inits ((Class *)class);
4298 need_dispose = TRUE;
4299 find_dispose ((Class *)class);
4301 if (destructors > 0 ||
4303 need_finalize = TRUE;
4304 find_finalize ((Class *)class);
4306 check_bad_symbols ((Class *)class);
4307 check_duplicate_symbols ((Class *)class);
4308 check_duplicate_overrides ((Class *)class);
4309 check_duplicate_signals_args ((Class *)class);
4310 check_public_new ((Class *)class);
4311 check_vararg ((Class *)class);
4312 check_firstarg ((Class *)class);
4313 check_nonvoidempty ((Class *)class);
4314 check_signal_args ((Class *)class);
4315 check_property_types ((Class *)class);
4316 check_argument_types ((Class *)class);
4317 check_func_arg_checks ((Class *)class);
4318 check_for_class_destructors ((Class *)class);
4320 exit_on_error = TRUE;
4325 any_special = setup_special_array ((Class *)class, special_array);
4329 generate_outfiles ();
4340 if (no_touch_headers &&
4342 compare_and_move_header ();