2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001 George Lebl
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
33 #include "treefuncs.h"
41 char *filename = NULL;
51 extern GList *include_files;
53 extern GHashTable *gtk_doc_hash;
56 static char *funcbase;
57 static char *pfuncbase;
58 static char *macrobase;
60 static char *pmacrois;
61 static char *macrotype;
62 static char *pmacrotype;
63 static char *typebase;
64 static char *ptypebase;
66 static int signals = 0; /* number of signals */
67 static int set_properties = 0; /* number of named (set) properties */
68 static int get_properties = 0; /* number of named (get) properties */
69 static int overrides = 0; /* number of override methods */
70 static int privates = 0; /* number of private data members */
71 static int protecteds = 0; /* number of protected methods */
72 static int unreftors = 0; /* number of variable unreffing destructors */
73 static int destructors = 0; /* number of variable non-unreffing destructors */
74 static int initializers = 0; /* number of variable initializers */
75 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
77 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
78 and need the REALLY UGLY HACK to
81 /* the special variable types we need to define */
82 static gboolean special_array[SPECIAL_LAST] = {0};
83 static gboolean any_special = FALSE;
85 static gboolean need_dispose = FALSE;
86 static Method * dispose_handler = NULL;
88 static gboolean need_finalize = FALSE;
89 static Method * finalize_handler = NULL;
96 gboolean no_touch_headers = FALSE;
97 gboolean for_cpp = FALSE;
98 gboolean no_gnu = FALSE;
99 gboolean exit_on_warn = FALSE;
100 gboolean exit_on_error = TRUE;
101 gboolean got_error = FALSE;
102 gint private_header = PRIVATE_HEADER_ONDEMAND;
103 gboolean no_extern_c = FALSE;
104 gboolean no_write = FALSE;
105 gboolean no_lines = FALSE;
106 gboolean no_self_alias = FALSE;
107 gboolean always_private_struct = FALSE;
109 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
110 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
111 char *m4_commandline = NULL;
112 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
113 #define M4_BASE_FILENAME "gobm4.m4"
114 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
115 #define M4_COMMANDLINE "m4"
117 int method_unique_id = 1;
122 filebase = replace_sep (((Class *)class)->otype, '-');
123 g_strdown (filebase);
125 funcbase = replace_sep (((Class *)class)->otype, '_');
126 g_strdown (funcbase);
128 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
129 g_strdown (pfuncbase);
131 macrobase = replace_sep (((Class *)class)->otype, '_');
134 macrois = make_pre_macro (((Class *)class)->otype, "IS");
135 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
137 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
138 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
140 typebase = remove_sep (((Class *)class)->otype);
142 ptypebase = remove_sep (((Class *)class)->ptype);
146 get_gtk_doc (const char *id)
153 val = g_hash_table_lookup(gtk_doc_hash, id);
155 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
157 val = g_hash_table_lookup(gtk_doc_hash, id);
159 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
165 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
169 s = get_type(t, postfix_to_stars);
170 out_printf(fp, "%s", s);
176 print_method (FILE *fp,
177 const char *typeprefix,
178 const char *nameprefix,
179 const char *subnameprefix,
180 const char *namepostfix,
181 const char *afterargs,
184 gboolean one_arg_per_line,
185 gboolean no_funcbase,
186 gboolean kill_underscore)
191 out_printf(fp, "%s", typeprefix);
192 print_type(fp, m->mtype, TRUE);
197 out_printf(fp, "%s%s%s%s(",
198 nameprefix, subnameprefix, id, namepostfix);
200 out_printf(fp, "%s%s_%s%s%s(",
201 nameprefix, funcbase, subnameprefix, id,
205 for(li=m->args; li; li=g_list_next(li)) {
206 FuncArg *arg = li->data;
207 print_type(fp, arg->atype, FALSE);
209 out_printf(fp, "%s%s,%s", arg->name,
210 arg->atype->postfix ?
211 arg->atype->postfix : "",
212 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
214 out_printf(fp, "%s%s", arg->name,
215 arg->atype->postfix ?
216 arg->atype->postfix : "");
219 out_printf(fp, ",%s...",
220 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
222 out_printf(fp, "void");
224 out_printf(fp, "%s)%s", afterargs, postfix);
228 any_method_to_alias(Class *c)
232 for(li=c->nodes;li;li=g_list_next(li)) {
233 Node *node = li->data;
234 if(node->type == METHOD_NODE) {
235 Method *m = (Method *)node;
237 if(m->method == INIT_METHOD ||
238 m->method == CLASS_INIT_METHOD ||
239 m->method == OVERRIDE_METHOD)
249 /* just the vararg macros, we use the same func pointers for these as in non-gnu */
251 make_method_gnu_aliases(Class *c)
255 for(li = c->nodes; li != NULL; li = li->next) {
256 Node *node = li->data;
257 if(node->type == METHOD_NODE) {
258 Method *m = (Method *)node;
260 if(m->method == INIT_METHOD ||
261 m->method == CLASS_INIT_METHOD ||
262 m->method == OVERRIDE_METHOD)
266 out_printf(out, "#define self_%s(args...) "
267 "%s_%s(args)\n", m->id,
270 out_printf(out, "#define self_%s() "
278 make_method_nongnu_aliases(Class *c)
282 gboolean local_made_aliases = FALSE;
284 for(li=c->nodes; li; li=g_list_next(li)) {
285 Node *node = li->data;
286 if(node->type == METHOD_NODE) {
287 Method *m = (Method *)node;
289 if(m->method == INIT_METHOD ||
290 m->method == CLASS_INIT_METHOD ||
291 m->method == OVERRIDE_METHOD)
294 if( ! local_made_aliases)
295 out_printf(out, "\n/* Short form pointers */\n");
297 print_method(out, "static ", "(* const self_", "", ") ",
299 m, FALSE, TRUE, FALSE);
300 out_printf(out, " = %s_%s;\n", funcbase,
303 local_made_aliases = TRUE;
306 if(local_made_aliases) {
307 out_printf(out, "\n");
313 add_bad_hack_to_avoid_unused_warnings(const Class *c)
317 /* if we haven't had any methods, just return */
322 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
324 "/*REALLY BAD HACK\n"
325 " This is to avoid unused warnings if you don't call\n"
326 " some method. I need to find a better way to do\n"
327 " this, not needed in GCC since we use some gcc\n"
328 " extentions to make saner, faster code */\n"
330 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
332 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
333 for(li=c->nodes;li;li=g_list_next(li)) {
334 Node *node = li->data;
335 if(node->type == METHOD_NODE) {
336 Method *m = (Method *)node;
338 if(m->method == INIT_METHOD ||
339 m->method == CLASS_INIT_METHOD ||
340 m->method == OVERRIDE_METHOD)
343 /* in C++ mode we don't alias new */
344 if(for_cpp && strcmp(m->id, "new")==0)
347 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
350 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
353 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
355 out_printf(out, "}\n\n");
359 put_variable(const Variable *v, FILE *fp)
361 out_printf(fp, "\t");
362 print_type(fp, v->vtype, FALSE);
363 out_printf(fp, "%s%s;", v->id,
365 v->vtype->postfix:"");
366 if(v->scope == PROTECTED_SCOPE)
367 out_printf(fp, " /* protected */");
368 out_printf(fp, "\n");
372 put_vs_method(const Method *m)
374 if(m->method != SIGNAL_LAST_METHOD &&
375 m->method != SIGNAL_FIRST_METHOD &&
376 m->method != VIRTUAL_METHOD)
379 /* if a signal mark it as such */
380 if(m->method != VIRTUAL_METHOD)
381 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
382 m, FALSE, TRUE, TRUE);
384 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
385 m, FALSE, TRUE, TRUE);
389 put_pub_method(const Method *m)
391 if(m->scope != PUBLIC_SCOPE)
394 print_method(outh, "", "\t", "", "\t", "", ";\n", m, TRUE, FALSE, TRUE);
398 put_signal_macro (const Method *m, gboolean gnu)
400 if(m->method != SIGNAL_LAST_METHOD &&
401 m->method != SIGNAL_FIRST_METHOD)
406 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
407 "g_signal_connect(%s(object),\"%s\","
408 "(GCallback)(func),(data))\n",
409 funcbase, m->id, macrobase, m->id);
412 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
413 "g_signal_connect_after(%s(object),\"%s\","
414 "(GCallback)(func),(data))\n",
415 funcbase, m->id, macrobase, m->id);
418 out_printf (outh, "#define %s_connect_data__%s"
419 "(object,func,data,destroy_data,flags)\t"
420 "g_signal_connect_data(%s(object),\"%s\","
421 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
422 funcbase, m->id, macrobase, m->id);
425 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
427 "%s(({%s *___object = (object); ___object; })),"
430 funcbase, m->id, macrobase, typebase, m->id);
431 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
432 " = (func); ", m, FALSE, TRUE, TRUE);
433 out_printf (outh, "___%s; }), (data))\n", m->id);
436 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
437 "g_signal_connect_after("
438 "%s(({%s *___object = (object); ___object; })),"
441 funcbase, m->id, macrobase, typebase, m->id);
442 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
443 " = (func); ", m, FALSE, TRUE, TRUE);
444 out_printf (outh, "___%s; }), (data))\n", m->id);
447 out_printf (outh, "#define %s_connect_data__%s"
448 "(object,func,data,destroy_data,flags)\t"
449 "g_signal_connect_data("
450 "%s(({%s *___object = (object); ___object; })),"
453 funcbase, m->id, macrobase, typebase, m->id);
454 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
455 " = (func); ", m, FALSE, TRUE, TRUE);
456 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
461 put_signal_macros (const Class *c, gboolean gnu)
468 for (li = c->nodes; li != NULL; li = li->next) {
469 const Node *n = li->data;
470 if (n->type == METHOD_NODE)
471 put_signal_macro ((Method *)n, gnu);
476 put_local_signal_macro (const Method *m)
478 if(m->method != SIGNAL_LAST_METHOD &&
479 m->method != SIGNAL_FIRST_METHOD)
483 out_printf (out, "#define self_connect__%s(object,func,data)\t"
484 "%s_connect__%s((object),(func),(data))\n",
485 m->id, funcbase, m->id);
488 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
489 "%s_connect_after__%s((object),(func),(data))\n",
490 m->id, funcbase, m->id);
493 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
494 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
495 m->id, funcbase, m->id);
499 put_local_signal_macros (const Class *c)
506 for (li = c->nodes; li != NULL; li = li->next) {
507 const Node *n = li->data;
508 if (n->type == METHOD_NODE)
509 put_local_signal_macro ((Method *)n);
515 put_prot_method(const Method *m)
517 if(m->scope != PROTECTED_SCOPE)
521 print_method(outph, "", "\t", "", "\t", "", ";\n",
522 m, FALSE, FALSE, TRUE);
524 print_method(out, "", "\t", "", "\t", "", ";\n",
525 m, FALSE, FALSE, TRUE);
529 put_priv_method_prot(const Method *m)
531 if(m->method == SIGNAL_LAST_METHOD ||
532 m->method == SIGNAL_FIRST_METHOD ||
533 m->method == VIRTUAL_METHOD) {
536 "static ", "___real_", "", " ", "", ";\n",
537 m, FALSE, FALSE, TRUE);
539 /* no else, here, it might still have a private prototype, it's not
542 if((m->method == OVERRIDE_METHOD &&
545 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
546 print_method(out, "static ", s, "", " ", "",
547 no_gnu?";\n":" G_GNUC_UNUSED;\n",
548 m, FALSE, FALSE, FALSE);
550 } else if(m->scope == PRIVATE_SCOPE ||
551 m->method == INIT_METHOD ||
552 m->method == CLASS_INIT_METHOD) {
553 print_method(out, "static ", "", "", " ", "",
554 no_gnu?";\n":" G_GNUC_UNUSED;\n",
555 m, FALSE, FALSE, TRUE);
560 make_func_arg (const char *typename, gboolean is_class, const char *name)
567 tn = g_strconcat (typename, ":Class", NULL);
569 tn = g_strdup (typename);
571 type = node_new (TYPE_NODE,
575 node = node_new (FUNCARG_NODE,
576 "atype:steal", (Type *)type,
579 return g_list_prepend (NULL, node);
583 make_inits(Class *cl)
585 int got_class_init = FALSE;
586 int got_init = FALSE;
589 for(li=cl->nodes;li;li=g_list_next(li)) {
591 if(n->type == METHOD_NODE) {
592 Method *m = (Method *)n;
593 if(m->method == INIT_METHOD) {
595 error_print(GOB_ERROR, m->line_no, "init defined more then once");
597 } else if(m->method == CLASS_INIT_METHOD) {
599 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
600 got_class_init = TRUE;
604 if(!got_class_init) {
605 Type *type = (Type *)node_new (TYPE_NODE,
608 node = node_new (METHOD_NODE,
610 "method", CLASS_INIT_METHOD,
613 "args:steal", make_func_arg (cl->otype,
616 "unique_id", method_unique_id++,
618 cl->nodes = g_list_prepend(cl->nodes, node);
621 Type *type = (Type *)node_new (TYPE_NODE,
624 node = node_new (METHOD_NODE,
626 "method", INIT_METHOD,
629 "args:steal", make_func_arg (cl->otype,
630 FALSE /* is_class */,
632 "unique_id", method_unique_id++,
634 cl->nodes = g_list_prepend(cl->nodes, node);
639 find_dispose(const Class *cl)
643 dispose_handler = NULL;
644 for(li=cl->nodes;li;li=g_list_next(li)) {
646 if(n->type == METHOD_NODE) {
647 Method *m = (Method *)n;
648 if(m->method == OVERRIDE_METHOD &&
649 strcmp(m->id, "dispose")==0) {
650 if(strcmp(m->otype, "G:Object") != 0) {
651 error_print(GOB_ERROR, m->line_no,
652 "dispose method override "
653 "of class other then "
656 if(g_list_length(m->args) != 1) {
657 error_print(GOB_ERROR, m->line_no,
658 "dispose method override "
659 "with more then one "
670 find_finalize(const Class *cl)
674 finalize_handler = NULL;
675 for(li=cl->nodes;li;li=g_list_next(li)) {
677 if(n->type == METHOD_NODE) {
678 Method *m = (Method *)n;
679 if(m->method == OVERRIDE_METHOD &&
680 strcmp(m->id, "finalize")==0) {
681 if(strcmp(m->otype, "G:Object") != 0) {
682 error_print(GOB_ERROR, m->line_no,
683 "finalize method override "
684 "of class other then "
687 if(g_list_length(m->args) != 1) {
688 error_print(GOB_ERROR, m->line_no,
689 "finalize method override "
690 "with more then one "
693 finalize_handler = m;
701 /* hash of method -> name of signal prototype */
702 static GHashTable *marsh = NULL;
704 /* list of methods with different signal prototypes,
705 we check this list if we can use a signal prototype of a
706 previous signal method, there are only uniques here */
707 static GList *eq_signal_methods = NULL;
709 /* compare a list of strings */
711 is_list_equal(const GList *a, const GList *b)
713 for(;a && b; a=a->next, b=b->next) {
714 if(strcmp(a->data, b->data)!=0) {
718 /* the the lists were different length */
725 find_same_type_signal(const Method *m)
728 for(li=eq_signal_methods;li;li=li->next) {
729 Method *mm = li->data;
730 if(is_list_equal(mm->gtktypes, m->gtktypes))
737 print_signal_marsal_args (const Method *m)
739 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
742 for (i = 0, li = m->gtktypes->next;
744 i++, li = li->next) {
747 if (strcmp (li->data, "UNICHAR") == 0)
748 /* hack because glib is braindamaged */
749 get_func = g_strdup ("g_value_get_uint");
751 get_func = g_strdup_printf
752 ("g_value_get_%s", (char *)li->data);
754 g_strdown (get_func);
755 out_printf (out, ",\n\t\t(%s) "
756 "%s (param_values + %d)",
757 get_cast (li->data, FALSE),
762 out_printf (out, ",\n\t\tdata2);\n");
767 add_signal_prots(Method *m)
773 gboolean ret_none = FALSE;
774 gboolean arglist_none = FALSE;
777 if (m->method != SIGNAL_LAST_METHOD &&
778 m->method != SIGNAL_FIRST_METHOD)
782 marsh = g_hash_table_new(NULL, NULL);
784 g_assert (m->gtktypes->next != NULL);
786 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
787 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
789 if (ret_none && arglist_none)
792 /* if we already did a signal prototype just use that */
793 mm = find_same_type_signal (m);
795 s = g_hash_table_lookup (marsh, mm);
796 g_hash_table_insert (marsh, m, s);
803 retcast = get_cast (m->gtktypes->data, FALSE);
805 s = g_strdup_printf("Sig%d", sig++);
807 g_hash_table_insert(marsh, m, s);
808 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
810 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
811 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
812 get_cast(m->gtktypes->data, FALSE), s, typebase);
814 if ( ! arglist_none) {
815 for (li = m->gtktypes->next; li != NULL; li = li->next)
816 out_printf (out, "%s, ", get_cast (li->data, FALSE));
818 out_printf (out, "gpointer);\n");
820 out_printf (out, "\nstatic void\n"
821 "___marshal_%s (GClosure *closure,\n"
822 "\tGValue *return_value,\n"
823 "\tguint n_param_values,\n"
824 "\tconst GValue *param_values,\n"
825 "\tgpointer invocation_hint,\n"
826 "\tgpointer marshal_data)\n"
830 out_printf (out, "\t%s v_return;\n", retcast);
832 out_printf (out, "\tregister ___%s callback;\n"
833 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
834 "\tregister gpointer data1, data2;\n\n",
837 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
838 arglist_none ? 1 : g_list_length (m->gtktypes));
841 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
842 "\t\tdata1 = closure->data;\n"
843 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
845 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
846 "\t\tdata2 = closure->data;\n"
849 out_printf (out, "\tcallback = (___%s) "
850 "(marshal_data != NULL ? marshal_data : cc->callback);"
854 out_printf (out, "\tcallback ((%s *)data1", typebase);
856 out_printf (out, "\tv_return = callback ((%s *)data1",
860 print_signal_marsal_args (m);
863 /* FIXME: This code is so fucking ugly it hurts */
864 gboolean take_ownership =
865 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
866 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
870 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
871 /* hack because glib is braindamaged */
872 set_func = g_strdup ("g_value_set_uint");
874 set_func = g_strdup_printf ("g_value_set_%s%s",
875 (char *)m->gtktypes->data,
877 "_take_ownership" : "");
878 g_strdown (set_func);
880 out_printf (out, "\n\t%s (return_value, v_return);\n",
885 out_printf (out, "}\n\n");
892 out_printf(out, "\n");
894 out_printf(out, "enum {\n");
895 for(li=c->nodes;li;li=g_list_next(li)) {
897 if(n->type == METHOD_NODE) {
898 Method *m = (Method *)n;
899 if(m->method == SIGNAL_LAST_METHOD ||
900 m->method == SIGNAL_FIRST_METHOD) {
901 char *s = g_strdup(m->id);
903 out_printf(out, "\t%s_SIGNAL,\n", s);
908 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
910 if (set_properties > 0 ||
911 get_properties > 0) {
912 out_printf(out, "enum {\n\tPROP_0");
913 for(li=c->nodes;li;li=g_list_next(li)) {
915 if (n->type == PROPERTY_NODE) {
916 Property *p = (Property *)n;
917 char *s = g_strdup (p->name);
919 out_printf (out, ",\n\tPROP_%s", s);
921 } else if (n->type == ARGUMENT_NODE) {
922 Argument *a = (Argument *)n;
923 char *s = g_strdup(a->name);
925 out_printf(out, ",\n\tPROP_%s", s);
929 out_printf(out, "\n};\n\n");
934 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
936 out_printf(out, "/* pointer to the class of our parent */\n");
937 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
941 add_interface_methods (Class *c, const char *interface)
944 gboolean added_line = FALSE;
946 for (li = c->nodes; li != NULL; li = li->next) {
948 Method *m = (Method *)n;
949 if (n->type != METHOD_NODE ||
950 m->method == OVERRIDE_METHOD ||
951 m->interface == NULL ||
952 strcmp (m->interface, interface) != 0)
955 if (m->line_no > 0) {
956 out_addline_infile (out, m->line_no);
958 } else if (m->line_no == 0 &&
960 out_addline_outfile (out);
963 out_printf (out, "\tiface->%s = self_%s;\n",
967 out_addline_outfile (out);
971 add_interface_inits (Class *c)
975 if (c->interfaces == NULL)
978 out_printf(out, "\n");
980 for (li = c->interfaces; li != NULL; li = li->next) {
981 const char *interface = li->data;
983 char *name = replace_sep (interface, '_');
984 char *type = remove_sep (interface);
986 /* EEEK! evil, we should have some sort of option
987 * to force this for arbitrary interfaces, since
988 * some are Class and some are Iface. Glib is shite
990 if (strcmp (type, "GtkEditable") == 0 ||
991 strcmp (type, "GTypePlugin") == 0)
994 /* We'll assume Iface is the standard ending */
997 out_printf (out, "\nstatic void\n"
998 "___%s_init (%s%s *iface)\n"
1002 add_interface_methods (c, interface);
1004 out_printf (out, "}\n\n");
1012 add_interface_infos (void)
1015 for (li = ((Class *)class)->interfaces;
1018 char *name = replace_sep (li->data, '_');
1020 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1021 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1031 add_interfaces (void)
1034 for (li = ((Class *)class)->interfaces;
1037 char *name = replace_sep (li->data, '_');
1038 char *type = make_pre_macro (li->data, "TYPE");
1041 "\t\tg_type_add_interface_static (type,\n"
1043 "\t\t\t&%s_info);\n",
1055 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1059 "%s_get_type (void)\n"
1061 "\tstatic GType type = 0;\n\n"
1062 "\tif (type == 0) {\n"
1063 "\t\tstatic const GTypeInfo info = {\n"
1064 "\t\t\tsizeof (%sClass),\n"
1065 "\t\t\t(GBaseInitFunc) NULL,\n"
1066 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1067 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1068 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1069 "\t\t\tNULL /* class_data */,\n"
1070 "\t\t\tsizeof (%s),\n"
1071 "\t\t\t0 /* n_preallocs */,\n"
1072 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1074 funcbase, typebase, funcbase, typebase, funcbase);
1076 add_interface_infos ();
1079 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)0);\n",
1080 pmacrotype, typebase);
1088 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1090 chunk_size, chunk_size);
1100 add_bonobo_object_get_type (void)
1102 /* char *chunk_size = ((Class*)class)->chunk_size; */
1103 /* _vicious_ spanks seth with a rusty nail
1105 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1106 "gob2 doesn't officially support it yet. It'd be safer "
1107 "and a lot more fun to blow goats.\"\n");
1112 "%s_get_type (void)\n" /* 1 */
1114 "\tstatic GType type = 0;\n\n"
1115 "\tif (type == 0) {\n"
1116 "\t\tstatic const GTypeInfo info = {\n"
1117 "\t\t\tsizeof (%sClass),\n" /* 2 */
1118 "\t\t\t(GBaseInitFunc) NULL,\n"
1119 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1120 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1121 "\t\t\tNULL, /* class_finalize */\n"
1122 "\t\t\tNULL, /* class_data */\n"
1123 "\t\t\tsizeof (%s),\n" /* 4 */
1124 "\t\t\t0, /* n_preallocs */\n"
1125 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1134 add_interface_infos ();
1137 "\t\ttype = bonobo_type_unique (\n"
1138 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1139 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1140 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1141 "\t\t\t&info, \"%s\");\n", /* 3 */
1142 ((Class*)class)->bonobo_object_class /* 1 */,
1151 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1153 chunk_size, chunk_size);
1162 add_overrides(Class *c, const char *oname,
1163 gboolean did_base_obj)
1169 done = g_hash_table_new (g_str_hash, g_str_equal);
1171 s = g_strdup ("GObject");
1172 g_hash_table_insert (done, s, s);
1174 for (li = c->nodes; li != NULL; li = li->next) {
1177 Method *m = (Method *)n;
1178 if(n->type != METHOD_NODE ||
1179 m->method != OVERRIDE_METHOD)
1182 s = remove_sep(m->otype);
1184 if(g_hash_table_lookup(done, s)) {
1188 g_hash_table_insert(done, s, s);
1190 f = replace_sep(m->otype, '_');
1193 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1198 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1199 g_hash_table_destroy (done);
1203 make_run_signal_flags(Method *m, gboolean last)
1218 gs = g_string_new(NULL);
1221 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1223 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1225 if(m->scope == PUBLIC_SCOPE)
1226 g_string_append(gs, " | G_SIGNAL_ACTION");
1228 for(li = m->flags; li; li = li->next) {
1229 char *flag = li->data;
1231 for(i=0;flags[i];i++) {
1232 if(strcmp(flags[i], flag)==0)
1235 /* if we haven't found it in our list */
1237 error_printf(GOB_WARN, m->line_no,
1238 "Unknown flag '%s' used, "
1239 "perhaps it was misspelled",
1242 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1246 char *ret = gs->str;
1247 g_string_free(gs, FALSE);
1254 add_signals(Class *c)
1258 out_printf(out, "\n");
1259 for(li=c->nodes;li;li=g_list_next(li)) {
1261 char *mar, *sig, *flags;
1262 gboolean is_none, last = FALSE;
1263 Method *m = (Method *)n;
1265 if(n->type != METHOD_NODE ||
1266 (m->method != SIGNAL_FIRST_METHOD &&
1267 m->method != SIGNAL_LAST_METHOD))
1270 if(m->method == SIGNAL_FIRST_METHOD)
1275 if(g_hash_table_lookup(marsh, m))
1276 mar = g_strconcat("___marshal_",
1277 (char *)g_hash_table_lookup(marsh, m),
1280 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1282 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1284 sig = g_strdup (m->id);
1286 flags = make_run_signal_flags (m, last);
1287 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1288 "\t\tg_signal_new (\"%s\",\n"
1289 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1290 "\t\t\t(GSignalFlags)(%s),\n"
1291 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1292 "\t\t\tNULL, NULL,\n"
1294 "\t\t\tG_TYPE_%s, %d",
1297 typebase, m->id, mar,
1298 (char *)m->gtktypes->data,
1299 is_none ? 0 : g_list_length(m->gtktypes->next));
1306 for(l = m->gtktypes->next; l != NULL; l = l->next)
1307 out_printf(out, ",\n\t\t\tG_TYPE_%s",
1311 out_printf(out, ");\n");
1313 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1316 const char *sep = "";
1317 out_printf(out, "\tif(");
1318 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1319 out_printf(out, "%s sizeof(", sep);
1320 print_type(out, m->mtype, FALSE);
1321 out_printf(out, "%s",
1323 m->mtype->postfix : "");
1324 out_printf(out, ") != sizeof(%s)",
1325 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, "%ssizeof(", sep);
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 out_printf(out, ") {\n"
1347 "\t\tg_error(\"%s line %d: Type mismatch "
1348 "of \\\"%s\\\" signal signature\");\n"
1350 filename, m->line_no, m->id);
1357 set_def_handlers(Class *c, const char *oname)
1360 gboolean set_line = FALSE;
1362 out_printf(out, "\n");
1363 for(li = c->nodes; li; li = g_list_next(li)) {
1365 Method *m = (Method *)n;
1367 if(n->type != METHOD_NODE ||
1368 (m->method != SIGNAL_FIRST_METHOD &&
1369 m->method != SIGNAL_LAST_METHOD &&
1370 m->method != VIRTUAL_METHOD &&
1371 m->method != OVERRIDE_METHOD))
1374 if(m->line_no > 0 && m->cbuf) {
1375 out_addline_infile(out, m->line_no);
1377 } else if(set_line) {
1378 out_addline_outfile(out);
1383 if (m->method == OVERRIDE_METHOD) {
1385 s = replace_sep (m->otype, '_');
1389 dispose_handler != NULL &&
1390 strcmp (m->id, "dispose") == 0)
1391 out_printf (out, "\tg_object_class->dispose "
1393 else if (need_finalize &&
1395 strcmp(m->id, "finalize") == 0)
1397 "\tg_object_class->finalize = ___finalize;\n");
1398 else if (m->cbuf != NULL)
1400 "\t%s_class->%s = ___%x_%s_%s;\n",
1401 s, m->id, (guint)m->unique_id,
1404 out_printf(out, "\t%s_class->%s = NULL;\n",
1408 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1412 out_printf(out, "\t%s->%s = NULL;\n",
1417 out_addline_outfile(out);
1421 make_argument (Argument *a)
1426 char *argflags[] = {
1434 flags = g_string_new ("(GParamFlags)(");
1436 if(a->get && a->set)
1437 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1439 g_string_append (flags, "G_PARAM_READABLE");
1441 g_string_append (flags, "G_PARAM_WRITABLE");
1443 g_assert(a->get || a->set);
1445 for (l = a->flags; l != NULL; l = l->next) {
1446 char *flag = l->data;
1448 if(strcmp (flag, "READABLE") == 0 ||
1449 strcmp (flag, "WRITABLE") == 0) {
1450 error_print(GOB_WARN, a->line_no,
1452 "WRITABLE argument flags are "
1453 "set automatically");
1456 for(i = 0; argflags[i]; i++) {
1457 if(strcmp(argflags[i], flag)==0)
1460 /* if we haven't found it in our list */
1461 if( ! argflags[i]) {
1462 error_printf(GOB_WARN, a->line_no,
1463 "Unknown flag '%s' used, "
1464 "perhaps it was misspelled", flag);
1466 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1469 g_string_append (flags, ")");
1471 s = g_strdup(a->name);
1473 if (!strcmp (a->gtktype, "ENUM"))
1474 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1475 "\t\tG_TYPE_ENUM, 0,\n"
1477 a->name, flags->str);
1478 if (!strcmp (a->gtktype, "FLAGS"))
1479 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1480 "\t\tG_TYPE_FLAGS, 0,\n"
1482 a->name, flags->str);
1483 else if (!strcmp (a->gtktype, "OBJECT"))
1484 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1485 "\t\tG_TYPE_OBJECT,\n"
1487 a->name, flags->str);
1488 else if (!strcmp (a->gtktype, "STRING"))
1489 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1492 a->name, flags->str);
1493 else if (!strcmp (a->gtktype, "INT"))
1494 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1495 "\t\tG_MININT, G_MAXINT,\n"
1498 a->name, flags->str);
1499 else if (!strcmp (a->gtktype, "UINT"))
1500 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1501 "\t\t0, G_MAXUINT,\n"
1504 a->name, flags->str);
1505 else if (!strcmp (a->gtktype, "INT"))
1506 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1507 "\t\tG_MININT, G_MAXINT,\n"
1510 a->name, flags->str);
1511 else if (!strcmp (a->gtktype, "CHAR"))
1512 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1516 a->name, flags->str);
1517 else if (!strcmp (a->gtktype, "UCHAR"))
1518 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1522 a->name, flags->str);
1523 else if (!strcmp (a->gtktype, "BOOL") ||
1524 !strcmp (a->gtktype, "BOOLEAN"))
1525 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1528 a->name, flags->str);
1529 else if (!strcmp (a->gtktype, "LONG"))
1530 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1531 "\t\tG_MINLONG, G_MAXLONG,\n"
1534 a->name, flags->str);
1535 else if (!strcmp (a->gtktype, "ULONG"))
1536 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1537 "\t\t0, G_MAXULONG,\n"
1540 a->name, flags->str);
1541 else if (!strcmp (a->gtktype, "FLOAT"))
1542 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1543 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1546 a->name, flags->str);
1547 else if (!strcmp (a->gtktype, "DOUBLE"))
1548 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1549 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1552 a->name, flags->str);
1553 else if (!strcmp (a->gtktype, "POINTER"))
1554 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1556 a->name, flags->str);
1558 error_printf (GOB_ERROR, a->line_no,
1559 "%s type is not supported for arguments, try using properties",
1562 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1563 "\t\tPROP_%s, param_spec);\n", s);
1567 g_string_free(flags, TRUE);
1570 #define value_for_print(str, alt) (str != NULL ? str : alt)
1573 make_me_type (const char *type, const char *alt)
1576 return g_strdup (alt);
1577 /* HACK! just in case someone made this
1578 * work with 2.0.0 by using the TYPE
1580 if ((strstr (type, "_TYPE_") != NULL ||
1581 strstr (type, "TYPE_") == type) &&
1582 strchr (type, ':') == NULL)
1583 return g_strdup (type);
1584 return make_pre_macro (type, "TYPE");
1588 make_property (Property *p)
1593 char *argflags[] = {
1601 flags = g_string_new ("(GParamFlags)(");
1603 if (p->get != NULL && p->set != NULL)
1604 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1605 else if (p->get != NULL)
1606 g_string_append (flags, "G_PARAM_READABLE");
1608 g_string_append (flags, "G_PARAM_WRITABLE");
1610 if (p->get == NULL && p->set == NULL) {
1611 error_print (GOB_ERROR, p->line_no,
1612 "Property has no getter nor setter");
1615 for (l = p->flags; l != NULL; l = l->next) {
1616 char *flag = l->data;
1618 if(strcmp (flag, "READABLE") == 0 ||
1619 strcmp (flag, "WRITABLE") == 0) {
1620 error_print(GOB_WARN, p->line_no,
1622 "WRITABLE argument flags are "
1623 "set automatically");
1626 for(i = 0; argflags[i]; i++) {
1627 if(strcmp(argflags[i], flag)==0)
1630 /* if we haven't found it in our list */
1631 if( ! argflags[i]) {
1632 error_printf(GOB_WARN, p->line_no,
1633 "Unknown flag '%s' used, "
1634 "perhaps it was misspelled", flag);
1636 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1639 g_string_append (flags, ")");
1641 if (strcmp (p->gtktype, "CHAR") == 0) {
1642 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1643 "\t\t(\"%s\" /* name */,\n"
1644 "\t\t %s /* nick */,\n"
1645 "\t\t %s /* blurb */,\n"
1646 "\t\t %s /* minimum */,\n"
1647 "\t\t %s /* maximum */,\n"
1648 "\t\t %s /* default_value */,\n"
1651 value_for_print (p->nick, "NULL"),
1652 value_for_print (p->blurb, "NULL"),
1653 value_for_print (p->minimum, "-128"),
1654 value_for_print (p->maximum, "127"),
1655 value_for_print (p->default_value, "0"),
1657 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1658 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1659 "\t\t(\"%s\" /* name */,\n"
1660 "\t\t %s /* nick */,\n"
1661 "\t\t %s /* blurb */,\n"
1662 "\t\t %s /* minimum */,\n"
1663 "\t\t %s /* maximum */,\n"
1664 "\t\t %s /* default_value */,\n"
1667 value_for_print (p->nick, "NULL"),
1668 value_for_print (p->blurb, "NULL"),
1669 value_for_print (p->minimum, "0"),
1670 value_for_print (p->maximum, "0xFF"),
1671 value_for_print (p->default_value, "0"),
1673 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1674 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1675 "\t\t(\"%s\" /* name */,\n"
1676 "\t\t %s /* nick */,\n"
1677 "\t\t %s /* blurb */,\n"
1678 "\t\t %s /* default_value */,\n"
1681 value_for_print (p->nick, "NULL"),
1682 value_for_print (p->blurb, "NULL"),
1683 value_for_print (p->default_value, "FALSE"),
1685 } else if (strcmp (p->gtktype, "INT") == 0) {
1686 out_printf (out, "\tparam_spec = g_param_spec_int\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, "G_MININT"),
1698 value_for_print (p->maximum, "G_MAXINT"),
1699 value_for_print (p->default_value, "0"),
1701 } else if (strcmp (p->gtktype, "UINT") == 0) {
1702 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1703 "\t\t(\"%s\" /* name */,\n"
1704 "\t\t %s /* nick */,\n"
1705 "\t\t %s /* blurb */,\n"
1706 "\t\t %s /* minimum */,\n"
1707 "\t\t %s /* maximum */,\n"
1708 "\t\t %s /* default_value */,\n"
1711 value_for_print (p->nick, "NULL"),
1712 value_for_print (p->blurb, "NULL"),
1713 value_for_print (p->minimum, "0"),
1714 value_for_print (p->maximum, "G_MAXUINT"),
1715 value_for_print (p->default_value, "0"),
1717 } else if (strcmp (p->gtktype, "LONG") == 0) {
1718 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1719 "\t\t(\"%s\" /* name */,\n"
1720 "\t\t %s /* nick */,\n"
1721 "\t\t %s /* blurb */,\n"
1722 "\t\t %s /* minimum */,\n"
1723 "\t\t %s /* maximum */,\n"
1724 "\t\t %s /* default_value */,\n"
1727 value_for_print (p->nick, "NULL"),
1728 value_for_print (p->blurb, "NULL"),
1729 value_for_print (p->minimum, "G_MINLONG"),
1730 value_for_print (p->maximum, "G_MAXLONG"),
1731 value_for_print (p->default_value, "0"),
1733 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1734 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1735 "\t\t(\"%s\" /* name */,\n"
1736 "\t\t %s /* nick */,\n"
1737 "\t\t %s /* blurb */,\n"
1738 "\t\t %s /* minimum */,\n"
1739 "\t\t %s /* maximum */,\n"
1740 "\t\t %s /* default_value */,\n"
1743 value_for_print (p->nick, "NULL"),
1744 value_for_print (p->blurb, "NULL"),
1745 value_for_print (p->minimum, "0"),
1746 value_for_print (p->maximum, "G_MAXULONG"),
1747 value_for_print (p->default_value, "0"),
1749 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1750 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1751 "\t\t(\"%s\" /* name */,\n"
1752 "\t\t %s /* nick */,\n"
1753 "\t\t %s /* blurb */,\n"
1754 "\t\t %s /* default_value */,\n"
1757 value_for_print (p->nick, "NULL"),
1758 value_for_print (p->blurb, "NULL"),
1759 value_for_print (p->default_value, "0"),
1761 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1762 char *type = make_me_type (p->extra_gtktype,
1764 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1765 "\t\t(\"%s\" /* name */,\n"
1766 "\t\t %s /* nick */,\n"
1767 "\t\t %s /* blurb */,\n"
1768 "\t\t %s /* enum_type */,\n"
1769 "\t\t %s /* default_value */,\n"
1772 value_for_print (p->nick, "NULL"),
1773 value_for_print (p->blurb, "NULL"),
1775 value_for_print (p->default_value, "0"),
1778 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1779 char *type = make_me_type (p->extra_gtktype,
1781 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1782 "\t\t(\"%s\" /* name */,\n"
1783 "\t\t %s /* nick */,\n"
1784 "\t\t %s /* blurb */,\n"
1785 "\t\t %s /* flags_type */,\n"
1786 "\t\t %s /* default_value */,\n"
1789 value_for_print (p->nick, "NULL"),
1790 value_for_print (p->blurb, "NULL"),
1792 value_for_print (p->default_value, "0"),
1795 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1796 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1797 "\t\t(\"%s\" /* name */,\n"
1798 "\t\t %s /* nick */,\n"
1799 "\t\t %s /* blurb */,\n"
1800 "\t\t %s /* minimum */,\n"
1801 "\t\t %s /* maximum */,\n"
1802 "\t\t %s /* default_value */,\n"
1805 value_for_print (p->nick, "NULL"),
1806 value_for_print (p->blurb, "NULL"),
1807 value_for_print (p->minimum, "G_MINFLOAT"),
1808 value_for_print (p->maximum, "G_MAXFLOAT"),
1809 value_for_print (p->default_value, "0.0"),
1811 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1812 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1813 "\t\t(\"%s\" /* name */,\n"
1814 "\t\t %s /* nick */,\n"
1815 "\t\t %s /* blurb */,\n"
1816 "\t\t %s /* minimum */,\n"
1817 "\t\t %s /* maximum */,\n"
1818 "\t\t %s /* default_value */,\n"
1821 value_for_print (p->nick, "NULL"),
1822 value_for_print (p->blurb, "NULL"),
1823 value_for_print (p->minimum, "G_MINDOUBLE"),
1824 value_for_print (p->maximum, "G_MAXDOUBLE"),
1825 value_for_print (p->default_value, "0.0"),
1827 } else if (strcmp (p->gtktype, "STRING") == 0) {
1828 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1829 "\t\t(\"%s\" /* name */,\n"
1830 "\t\t %s /* nick */,\n"
1831 "\t\t %s /* blurb */,\n"
1832 "\t\t %s /* default_value */,\n"
1835 value_for_print (p->nick, "NULL"),
1836 value_for_print (p->blurb, "NULL"),
1837 value_for_print (p->default_value, "NULL"),
1839 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1840 char *type = make_me_type (p->extra_gtktype,
1842 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1843 "\t\t(\"%s\" /* name */,\n"
1844 "\t\t %s /* nick */,\n"
1845 "\t\t %s /* blurb */,\n"
1846 "\t\t %s /* param_type */,\n"
1849 value_for_print (p->nick, "NULL"),
1850 value_for_print (p->blurb, "NULL"),
1854 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1855 char *type = make_me_type (p->extra_gtktype,
1857 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1858 "\t\t(\"%s\" /* name */,\n"
1859 "\t\t %s /* nick */,\n"
1860 "\t\t %s /* blurb */,\n"
1861 "\t\t %s /* boxed_type */,\n"
1864 value_for_print (p->nick, "NULL"),
1865 value_for_print (p->blurb, "NULL"),
1869 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1870 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1871 "\t\t(\"%s\" /* name */,\n"
1872 "\t\t %s /* nick */,\n"
1873 "\t\t %s /* blurb */,\n"
1876 value_for_print (p->nick, "NULL"),
1877 value_for_print (p->blurb, "NULL"),
1879 /* FIXME: VALUE_ARRAY */
1880 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1881 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1882 "\t\t(\"%s\" /* name */,\n"
1883 "\t\t %s /* nick */,\n"
1884 "\t\t %s /* blurb */,\n"
1887 value_for_print (p->nick, "NULL"),
1888 value_for_print (p->blurb, "NULL"),
1890 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
1891 char *type = make_me_type (p->extra_gtktype,
1893 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1894 "\t\t(\"%s\" /* name */,\n"
1895 "\t\t %s /* nick */,\n"
1896 "\t\t %s /* blurb */,\n"
1897 "\t\t %s /* object_type */,\n"
1900 value_for_print (p->nick, "NULL"),
1901 value_for_print (p->blurb, "NULL"),
1906 error_printf (GOB_ERROR, p->line_no,
1907 "%s type is not supported by properties",
1911 s = g_strdup (p->name);
1913 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1915 "\t\tparam_spec);\n", s);
1918 g_string_free (flags, TRUE);
1922 make_arguments(Class *c)
1925 if (get_properties > 0)
1926 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1927 if (set_properties > 0)
1928 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1929 out_printf (out, " {\n"
1930 "\tGParamSpec *param_spec;\n\n");
1932 for (li = c->nodes; li != NULL; li = li->next) {
1934 if (n->type == PROPERTY_NODE)
1935 make_property ((Property *)n);
1936 else if (n->type == ARGUMENT_NODE)
1937 make_argument ((Argument *)n);
1939 out_printf(out, " }\n");
1943 print_initializer(Method *m, Variable *v)
1947 if(v->initializer == NULL)
1950 if(v->scope == PRIVATE_SCOPE)
1951 root = g_strconcat(((FuncArg *)m->args->data)->name,
1954 root = g_strdup(((FuncArg *)m->args->data)->name);
1956 if(v->initializer_line > 0)
1957 out_addline_infile(out, v->initializer_line);
1959 out_printf(out, "\t%s->%s = %s;\n",
1960 root, v->id, v->initializer);
1962 if(v->initializer_line > 0)
1963 out_addline_outfile(out);
1969 print_destructor (Variable *v)
1973 if(v->destructor == NULL)
1976 if(v->scope == PRIVATE_SCOPE)
1977 root = "self->_priv";
1981 if(v->destructor_simple) {
1982 if(v->destructor_line > 0)
1983 out_addline_infile(out, v->destructor_line);
1985 out_printf(out, "\tif(%s->%s) { "
1986 "((*(void (*)(void *))%s)) (%s->%s); "
1987 "%s->%s = NULL; }\n",
1988 root, v->id, v->destructor, root, v->id,
1991 if(v->destructor_line > 0)
1992 out_addline_outfile(out);
1994 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
1995 out_printf(out, "#define VAR %s\n", v->id);
1996 out_printf(out, "\t{\n");
1997 if(v->destructor_line > 0)
1998 out_addline_infile(out, v->destructor_line);
2000 out_printf(out, "\t%s}\n", v->destructor);
2002 if(v->destructor_line > 0)
2003 out_addline_outfile(out);
2004 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
2006 out_printf(out, "#undef VAR\n");
2007 out_printf(out, "#undef %s\n", v->id);
2012 add_dispose (Class *c)
2014 out_printf(out, "\nstatic void\n"
2015 "___dispose (GObject *obj_self)\n"
2018 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2021 if (unreftors > 0) {
2022 out_printf (out, "\t%s *self = %s (obj_self);\n",
2023 typebase, macrobase);
2026 if (dispose_handler != NULL) {
2027 /* so we get possible bad argument warning */
2028 if (dispose_handler->line_no > 0)
2029 out_addline_infile (out, dispose_handler->line_no);
2030 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2031 (guint)dispose_handler->unique_id, funcbase);
2032 if (dispose_handler->line_no > 0)
2033 out_addline_outfile (out);
2036 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2037 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2040 if (unreftors > 0) {
2042 for(li = ((Class *)class)->nodes;
2046 Variable *v = (Variable *)n;
2047 if (n->type == VARIABLE_NODE &&
2048 v->scope != CLASS_SCOPE &&
2049 v->destructor_unref)
2050 print_destructor (v);
2054 out_printf (out, "\treturn;\n");
2056 out_printf(out, "\tself = NULL;\n");
2057 out_printf(out, "}\n"
2058 "#undef __GOB_FUNCTION__\n\n");
2062 add_finalize (Class *c)
2066 "___finalize(GObject *obj_self)\n"
2069 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2074 out_printf(out, "\t%s *self = %s (obj_self);\n",
2075 typebase, macrobase);
2078 out_printf(out, "\tgpointer priv = self->_priv;\n");
2081 if(finalize_handler) {
2082 /* so we get possible bad argument warning */
2083 if(finalize_handler->line_no > 0)
2084 out_addline_infile(out, finalize_handler->line_no);
2085 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2086 (guint)finalize_handler->unique_id, funcbase);
2087 if(finalize_handler->line_no > 0)
2088 out_addline_outfile(out);
2091 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2092 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2095 if (destructors > 0) {
2097 for (li = ((Class *)class)->nodes;
2101 Variable *v = (Variable *)n;
2102 if (n->type == VARIABLE_NODE &&
2103 v->scope != CLASS_SCOPE &&
2104 ! v->destructor_unref)
2105 print_destructor (v);
2110 out_printf(out, "\tg_free (priv);\n");
2112 out_printf (out, "\treturn;\n");
2113 if (destructors > 0 ||
2115 out_printf (out, "\tself = NULL;\n");
2117 out_printf(out, "}\n"
2118 "#undef __GOB_FUNCTION__\n\n");
2122 make_bonobo_object_epv (Class *c, const char *classname)
2125 gboolean added_line = FALSE;
2127 for (li = c->nodes; li != NULL; li = li->next) {
2129 Method *m = (Method *)n;
2130 if(n->type != METHOD_NODE ||
2131 m->method == OVERRIDE_METHOD)
2134 if (m->bonobo_object_func) {
2135 if(m->line_no > 0) {
2136 out_addline_infile(out, m->line_no);
2138 } else if (m->line_no == 0 &&
2140 out_addline_outfile(out);
2143 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2144 classname, m->id, m->id);
2148 out_addline_outfile(out);
2155 for(li=c->nodes;li;li=g_list_next(li)) {
2159 gboolean add_unused_class = FALSE;
2161 if(n->type != METHOD_NODE)
2164 if(m->method == INIT_METHOD) {
2166 out_addline_infile(out, m->line_no);
2167 print_method(out, "static ", "\n", "", " ", "", "\n",
2168 m, FALSE, FALSE, TRUE);
2170 out_addline_outfile(out);
2171 out_printf(out, "{\n"
2172 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2175 out_printf(out, "\t%s->_priv = "
2176 "g_new0 (%sPrivate, 1);\n",
2177 ((FuncArg *)m->args->data)->name,
2179 } else if(always_private_struct) {
2180 out_printf(out, "\t%s->_priv = NULL;\n",
2181 ((FuncArg *)m->args->data)->name);
2183 if(initializers > 0) {
2185 for(li = ((Class *)class)->nodes;
2189 Variable *v = (Variable *)n;
2190 if(n->type != VARIABLE_NODE ||
2191 v->scope == CLASS_SCOPE)
2193 print_initializer(m, v);
2196 } else if(m->method == CLASS_INIT_METHOD) {
2197 gboolean did_base_obj = FALSE;
2200 out_addline_infile(out, m->line_no);
2201 print_method(out, "static ", "\n", "", " ", "", "\n",
2202 m, FALSE, FALSE, TRUE);
2204 out_addline_outfile(out);
2205 out_printf(out, "{\n"
2206 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2208 if (set_properties > 0 ||
2209 get_properties > 0 ||
2216 "(GObjectClass*) %s;\n",
2217 ((FuncArg *)m->args->data)->name);
2218 add_unused_class = TRUE;
2219 did_base_obj = TRUE;
2224 ((FuncArg *)m->args->data)->name,
2227 if (initializers > 0) {
2229 for(li = ((Class *)class)->nodes;
2233 Variable *v = (Variable *)n;
2234 if(n->type == VARIABLE_NODE &&
2235 v->scope == CLASS_SCOPE)
2236 print_initializer(m, v);
2240 out_printf(out, "\n\tparent_class = ");
2242 out_printf(out, "(%sClass *)", ptypebase);
2243 out_printf(out, "g_type_class_ref (%s);\n",
2249 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2251 /* if there are no handlers for these things, we
2252 * need to set them up here */
2253 if(need_dispose && !dispose_handler)
2254 out_printf(out, "\tg_object_class->dispose "
2256 if(need_finalize && !finalize_handler)
2257 out_printf(out, "\tg_object_class->finalize = "
2260 if(get_properties > 0 || set_properties > 0)
2263 if (c->bonobo_object_class != NULL) {
2264 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2270 out_printf(out, " {\n");
2271 out_addline_infile(out, m->ccode_line);
2272 out_printf(out, "%s\n", m->cbuf);
2273 out_addline_outfile(out);
2274 out_printf(out, " }\n");
2276 out_printf(out, "\treturn;\n");
2279 ((FuncArg *)m->args->data)->name);
2280 if(add_unused_class) {
2281 out_printf (out, "\tg_object_class = NULL;\n");
2283 out_printf(out, "}\n"
2284 "#undef __GOB_FUNCTION__\n");
2289 add_argument (Argument *a, gboolean is_set)
2293 char *the_type_lower;
2298 line_no = a->set_line;
2301 line_no = a->get_line;
2305 s = g_strdup(a->name);
2307 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2309 the_type_lower = g_strdup (a->gtktype);
2310 g_strdown (the_type_lower);
2312 /* HACK because there is no g_value_set/get for unichar */
2313 if (strcmp (the_type_lower, "unichar") == 0) {
2314 g_free (the_type_lower);
2315 the_type_lower = g_strdup ("uint");
2321 if (a->atype != NULL)
2322 cast = get_type (a->atype, TRUE);
2324 cast = g_strdup (get_cast (a->gtktype, FALSE));
2326 out_printf (out, "\t%s ARG = (%s) g_value_get_%s (VAL);\n",
2327 cast, cast, the_type_lower);
2330 } else if ( ! is_set) {
2333 if (a->atype != NULL)
2334 cast = get_type (a->atype, TRUE);
2336 cast = g_strdup (get_cast (a->gtktype, FALSE));
2337 out_printf (out, "\t%s ARG;\n"
2338 "\tmemset (&ARG, 0, sizeof (%s));\n",
2344 out_printf(out, "\t\t{\n");
2346 out_addline_infile (out, line_no);
2347 out_printf (out, "%s\n", cbuf);
2349 out_addline_outfile (out);
2350 out_printf (out, "\t\t}\n");
2352 if (strcmp (a->gtktype, "OBJECT") == 0)
2353 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2356 out_printf (out, "\t\t"
2357 "g_value_set_%s (VAL, ARG);\n",
2360 g_free (the_type_lower);
2363 out_printf (out, "\t\tif (&ARG) ;\n");
2366 out_printf (out, "\t\tbreak;\n");
2368 out_printf (out, "\t}\n");
2372 add_property (Property *p, gboolean is_set)
2375 char *the_type_lower;
2381 line_no = p->set_line;
2384 line_no = p->get_line;
2389 name_upper = g_strdup (p->name);
2390 g_strup (name_upper);
2391 the_type_lower = g_strdup (p->gtktype);
2392 g_strdown (the_type_lower);
2394 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2396 out_printf(out, "\t\t{\n");
2398 out_addline_infile (out, line_no);
2399 out_printf (out, "%s\n", cbuf);
2401 out_addline_outfile (out);
2402 out_printf (out, "\t\t}\n");
2404 g_free (name_upper);
2405 g_free (the_type_lower);
2407 out_printf (out, "\t\tbreak;\n");
2411 add_getset_arg(Class *c, gboolean is_set)
2414 out_printf(out, "\nstatic void\n"
2415 "___object_%s_property (GObject *object,\n"
2416 "\tguint property_id,\n"
2417 "\t%sGValue *VAL,\n"
2418 "\tGParamSpec *pspec)\n"
2419 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2422 "\tself = %s (object);\n\n"
2423 "\tswitch (property_id) {\n",
2424 is_set ? "set" : "get",
2425 is_set ? "const " : "",
2426 c->otype, is_set ? "set" : "get",
2427 typebase, macrobase);
2429 for (li = c->nodes; li != NULL; li = li->next) {
2431 if (n->type == PROPERTY_NODE)
2432 add_property ((Property *)n, is_set);
2433 else if (n->type == ARGUMENT_NODE)
2434 add_argument ((Argument *)n, is_set);
2436 out_printf (out, "\tdefault:\n"
2437 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2438 "#ifndef __PRETTY_FUNCTION__\n"
2439 "# undef G_STRLOC\n"
2440 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2442 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2444 "\treturn;\n\tself = NULL;\n\tVAL = NULL;\n\tpspec = NULL;\n}\n"
2445 "#undef __GOB_FUNCTION__\n");
2449 print_checks (Method *m, FuncArg *fa)
2453 gboolean checked_null = FALSE;
2454 is_void = (strcmp(m->mtype->name, "void")==0 &&
2455 m->mtype->pointer == NULL);
2457 for(li = fa->checks; li != NULL; li = li->next) {
2458 Check *ch = li->data;
2460 /* point to the method prot in .gob for failed checks */
2462 out_addline_infile(out, m->line_no);
2464 out_printf(out, "\tg_return_if_fail (");
2466 out_printf(out, "\tg_return_val_if_fail (");
2467 switch(ch->chtype) {
2469 out_printf(out, "%s != NULL", fa->name);
2470 checked_null = TRUE;
2473 s = make_pre_macro(fa->atype->name, "IS");
2475 out_printf(out, "%s (%s)", s, fa->name);
2477 /* if not check null, null may be valid */
2478 out_printf(out, "!(%s) || %s (%s)", fa->name,
2483 out_printf(out, "%s < %s", fa->name, ch->number);
2486 out_printf(out, "%s > %s", fa->name, ch->number);
2489 out_printf(out, "%s <= %s", fa->name, ch->number);
2492 out_printf(out, "%s >= %s", fa->name, ch->number);
2495 out_printf(out, "%s == %s", fa->name, ch->number);
2498 out_printf(out, "%s != %s", fa->name, ch->number);
2502 out_printf(out, ");\n");
2504 out_printf(out, ", (");
2505 print_type(out, m->mtype, TRUE);
2506 out_printf(out, ")%s);\n",
2507 m->onerror?m->onerror:"0");
2513 print_preconditions(Method *m)
2517 for(li=m->args;li;li=g_list_next(li)) {
2518 FuncArg *fa = li->data;
2520 print_checks(m, fa);
2523 out_addline_outfile(out);
2527 print_method_body(Method *m, int pre)
2530 out_addline_outfile(out);
2531 out_printf(out, "{\n"
2532 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2533 ((Class *)class)->otype,
2536 print_preconditions(m);
2538 /* Note: the trailing }'s are on one line, this is so
2539 that we get the no return warning correctly and point to
2540 the correct line in the .gob file, yes this is slightly
2541 ugly in the .c file, but that is not supposed to be
2542 human readable anyway. */
2544 out_printf(out, "{\n");
2546 out_addline_infile(out, m->ccode_line);
2547 out_printf(out, "\t%s}", m->cbuf);
2550 /* Note, there is no \n between the last } and this } so that
2551 * errors/warnings reported on the end of the body get pointed to the
2552 * right line in the .gob source */
2553 out_printf(out, "}\n");
2556 out_addline_outfile(out);
2557 out_printf(out, "#undef __GOB_FUNCTION__\n");
2561 put_signal_args (Method *m)
2567 if (m->args->next == NULL)
2570 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2571 li != NULL && ali != NULL;
2572 li = li->next, ali = ali->next, i++) {
2573 FuncArg *fa = li->data;
2574 char *cast = g_strdup (get_cast (ali->data, FALSE));
2575 /* FIXME: This code is so fucking ugly it hurts */
2576 gboolean do_static =
2577 (strcmp ((char *)ali->data, "STRING") == 0 ||
2578 strcmp ((char *)ali->data, "BOXED") == 0);
2582 cast = get_type (fa->atype, TRUE);
2584 /* we should have already proved before that
2585 the we know all the types */
2586 g_assert (cast != NULL);
2589 "\t___param_values[%d].g_type = 0;\n"
2590 "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
2591 i, i, (char *)ali->data);
2593 if (strcmp (ali->data, "UNICHAR") == 0)
2594 /* hack because glib is braindamaged */
2595 set_func = g_strdup ("g_value_set_uint");
2597 set_func = g_strdup_printf ("g_value_set%s_%s",
2598 do_static ? "_static" : "",
2600 g_strdown (set_func);
2602 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2603 set_func, i, cast, fa->name);
2611 get_arg_names_for_macro (Method *m)
2615 GString *gs = g_string_new(NULL);
2617 for(li=m->args;li;li=g_list_next(li)) {
2618 FuncArg *arg = li->data;
2619 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2622 return g_string_free (gs, FALSE);
2626 put_method(Method *m)
2628 char *s, *args, *doc;
2630 is_void = (strcmp(m->mtype->name, "void")==0 &&
2631 m->mtype->pointer == NULL);
2632 out_printf(out, "\n");
2633 if(m->method != OVERRIDE_METHOD) {
2634 doc = get_gtk_doc(m->id);
2636 out_printf(out, "%s", doc);
2641 case REGULAR_METHOD:
2643 out_addline_infile(out, m->line_no);
2644 if(m->scope == PRIVATE_SCOPE)
2645 print_method(out, "static ", "\n", "", " ", "", "\n",
2646 m, FALSE, FALSE, TRUE);
2647 else /* PUBLIC, PROTECTED */
2648 print_method(out, "", "\n", "", " ", "", "\n",
2649 m, FALSE, FALSE, TRUE);
2650 print_method_body(m, TRUE);
2651 /* the outfile line was added above */
2653 case SIGNAL_FIRST_METHOD:
2654 case SIGNAL_LAST_METHOD:
2656 out_addline_infile(out, m->line_no);
2657 if(m->scope == PRIVATE_SCOPE)
2658 print_method(out, "static ", "\n", "", " ", "", "\n",
2659 m, FALSE, FALSE, TRUE);
2660 else /* PUBLIC, PROTECTED */
2661 print_method(out, "", "\n", "", " ", "", "\n",
2662 m, FALSE, FALSE, TRUE);
2663 out_addline_outfile (out);
2665 out_printf (out, "{\n");
2668 "\tGValue ___param_values[%d];\n"
2669 "\tGValue ___return_val = {0};\n\n",
2670 g_list_length (m->args));
2672 print_preconditions (m);
2675 "\n\t___param_values[0].g_type = 0;\n"
2676 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2677 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2678 ((FuncArg *)m->args->data)->name,
2679 ((FuncArg *)m->args->data)->name);
2681 put_signal_args (m);
2683 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2684 const char *defret = NULL;
2686 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2687 (char *)m->gtktypes->data);
2689 if (m->defreturn != NULL)
2690 defret = m->defreturn;
2691 else if (m->onerror != NULL)
2692 defret = m->onerror;
2694 if (defret != NULL) {
2696 /* FIXME: This code is so fucking ugly it hurts */
2697 gboolean do_static =
2698 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2699 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2700 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2702 cast = get_type (m->mtype, TRUE);
2704 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2705 /* hack because glib is braindamaged */
2706 set_func = g_strdup ("g_value_set_uint");
2708 set_func = g_strdup_printf ("g_value_set%s_%s",
2709 do_static ? "_static" : "",
2710 (char *)m->gtktypes->data);
2711 g_strdown (set_func);
2713 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2714 set_func, cast, defret);
2719 out_printf (out, "\n");
2722 s = g_strdup (m->id);
2725 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2726 "\t\tobject_signals[%s_SIGNAL],\n"
2727 "\t\t0 /* detail */,\n"
2728 "\t\t&___return_val);\n", s);
2732 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2733 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2736 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2737 /* hack because glib is braindamaged */
2738 getfunc = g_strdup ("g_value_get_uint");
2740 getfunc = g_strdup_printf ("g_value_get_%s",
2741 (char *)m->gtktypes->data);
2742 g_strdown (getfunc);
2745 cast = get_type (m->mtype, TRUE);
2747 out_printf (out, "\n\treturn (%s) %s (&___return_val);\n",
2753 out_printf(out, "}\n");
2758 out_addline_infile(out, m->line_no);
2759 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2760 m, FALSE, FALSE, TRUE);
2761 print_method_body(m, FALSE);
2762 /* the outfile line was added above */
2764 case VIRTUAL_METHOD:
2766 out_addline_infile(out, m->line_no);
2767 if(m->scope==PRIVATE_SCOPE)
2768 print_method(out, "static ", "\n", "", " ", "", "\n",
2769 m, FALSE, FALSE, TRUE);
2770 else /* PUBLIC, PROTECTED */
2771 print_method(out, "", "\n", "", " ", "", "\n",
2772 m, FALSE, FALSE, TRUE);
2773 out_addline_outfile(out);
2774 out_printf(out, "{\n"
2775 "\t%sClass *klass;\n", typebase);
2776 print_preconditions(m);
2777 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2778 "\tif(klass->%s)\n",
2779 macrobase, ((FuncArg *)m->args->data)->name,
2781 if(strcmp(m->mtype->name, "void") == 0 &&
2782 m->mtype->pointer == NULL) {
2784 out_printf(out, "\t\t(*klass->%s)(%s",
2786 ((FuncArg *)m->args->data)->name);
2787 for(li=m->args->next;li;li=g_list_next(li)) {
2788 FuncArg *fa = li->data;
2789 out_printf(out, ",%s", fa->name);
2791 out_printf(out, ");\n}\n");
2794 out_printf(out, "\t\treturn (*klass->%s)(%s",
2796 ((FuncArg *)m->args->data)->name);
2797 for(li=m->args->next;li;li=g_list_next(li)) {
2798 FuncArg *fa = li->data;
2799 out_printf(out, ",%s", fa->name);
2801 out_printf(out, ");\n"
2804 print_type(out, m->mtype, TRUE);
2806 out_printf(out, ")(%s);\n}\n", m->defreturn);
2808 out_printf(out, ")(%s);\n}\n", m->onerror);
2810 out_printf(out, ")(0);\n}\n");
2816 out_addline_infile(out, m->line_no);
2817 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2818 m, FALSE, FALSE, TRUE);
2819 print_method_body(m, FALSE);
2820 /* the outfile line was added above */
2822 case OVERRIDE_METHOD:
2826 out_addline_infile(out, m->line_no);
2827 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2828 print_method(out, "static ", s, "", " ", "", "\n",
2829 m, FALSE, FALSE, FALSE);
2831 out_addline_outfile(out);
2832 s = replace_sep(m->otype, '_');
2834 args = get_arg_names_for_macro(m);
2836 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2837 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2838 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2839 args, s, m->id, s, m->id, args);
2841 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2842 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2843 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2845 args, s, m->id, s, m->id, args);
2846 out_printf(out, "(");
2847 print_type(out, m->mtype, TRUE);
2848 out_printf(out, ")%s))\n",
2849 m->onerror?m->onerror:"0");
2853 print_method_body(m, TRUE);
2854 /* the outfile line was added above */
2855 out_printf(out, "#undef PARENT_HANDLER\n");
2865 char *outfile, *outfileh, *outfileph;
2868 outfile = g_strconcat (filebase, ".c", NULL);
2870 outfile = g_strconcat (filebase, ".cc", NULL);
2871 if (no_touch_headers)
2872 outfileh = g_strconcat ("#gob#", filebase, ".h#gob#", NULL);
2874 outfileh = g_strconcat (filebase, ".h", NULL);
2876 if ((privates > 0 || protecteds > 0 ||
2877 private_header == PRIVATE_HEADER_ALWAYS) &&
2878 private_header != PRIVATE_HEADER_NEVER)
2879 outfileph = g_strconcat (filebase, "-private.h", NULL);
2885 devnull = fopen ("/dev/null", "w");
2886 if (devnull == NULL)
2887 g_error ("Cannot open null device");
2890 if (outfileph != NULL)
2893 out = fopen (outfile, "w");
2895 g_error ("Cannot open outfile: %s", outfile);
2897 outh = fopen (outfileh, "w");
2899 g_error ("Cannot open outfile: %s", outfileh);
2900 if (outfileph != NULL) {
2901 outph = fopen (outfileph, "w");
2903 g_error ("Cannot open outfile: %s", outfileh);
2909 put_argument_nongnu_wrappers (Class *c)
2913 if (get_properties < 0 && set_properties < 0)
2916 for (li = c->nodes; li != NULL; li = li->next) {
2918 const char *name, *gtktype;
2924 if (n->type == ARGUMENT_NODE) {
2925 Argument *a = (Argument *)n;
2927 gtktype = a->gtktype;
2929 get = a->get != NULL;
2930 set = a->set != NULL;
2931 } else if (n->type == PROPERTY_NODE) {
2932 Property *p = (Property *)n;
2934 gtktype = p->gtktype;
2936 get = p->get != NULL;
2937 set = p->set != NULL;
2942 aname = g_strdup (name);
2946 cast = get_type (atype, TRUE);
2948 cast = g_strdup (get_cast (gtktype, TRUE));
2952 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2953 "\"%s\",(%s)(arg)\n",
2954 macrobase, aname, name, cast);
2956 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2957 "\"%s\",(%s*)(arg)\n",
2958 macrobase, aname, name, cast);
2961 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2963 macrobase, aname, name);
2965 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2967 macrobase, aname, name);
2975 put_argument_gnu_wrappers(Class *c)
2979 if(get_properties < 0 && set_properties < 0)
2982 for (li = c->nodes; li != NULL; li = li->next) {
2984 const char *name, *gtktype;
2990 if (n->type == ARGUMENT_NODE) {
2991 Argument *a = (Argument *)n;
2993 gtktype = a->gtktype;
2995 get = a->get != NULL;
2996 set = a->set != NULL;
2997 } else if (n->type == PROPERTY_NODE) {
2998 Property *p = (Property *)n;
3000 gtktype = p->gtktype;
3002 get = p->get != NULL;
3003 set = p->set != NULL;
3008 aname = g_strdup (name);
3012 cast = get_type (atype, TRUE);
3014 cast = g_strdup (get_cast (gtktype, TRUE));
3018 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3019 "\"%s\",({%sz = (arg); z;})\n",
3020 macrobase, aname, name, cast);
3022 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3023 "\"%s\",({%s*z = (arg); z;})\n",
3024 macrobase, aname, name, cast);
3027 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3029 macrobase, aname, name);
3031 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3033 macrobase, aname, name);
3041 print_ccode_block(CCode *cc)
3044 switch(cc->cctype) {
3046 /* HT code is printed exactly like normal header
3047 code but is printed before */
3050 out_printf(fp, "\n");
3053 /* AT code is printed exactly like normal 'all'
3054 code but is printed before */
3057 out_printf(outph, "\n");
3058 out_printf(outph, "%s\n", cc->cbuf);
3059 out_addline_infile(outph, cc->line_no);
3060 out_addline_outfile(outph);
3062 out_printf(outh, "\n");
3063 out_printf(outh, "%s\n", cc->cbuf);
3065 out_printf(fp, "\n");
3066 out_addline_infile(fp, cc->line_no);
3071 out_printf(fp, "\n");
3072 out_addline_infile(fp, cc->line_no);
3079 out_printf(fp, "\n");
3080 out_addline_infile(fp, cc->line_no);
3083 out_printf(fp, "%s\n", cc->cbuf);
3084 if(cc->cctype == C_CCODE ||
3085 cc->cctype == A_CCODE ||
3086 cc->cctype == AT_CCODE ||
3087 cc->cctype == PH_CCODE)
3088 out_addline_outfile(fp);
3092 print_class_block(Class *c)
3096 gboolean printed_private = FALSE;
3099 out_printf(out, "/* utility types we may need */\n");
3100 if(special_array[SPECIAL_2POINTER])
3101 out_printf(out, "typedef struct { "
3102 "gpointer a; gpointer b; "
3103 "} ___twopointertype;\n");
3104 if(special_array[SPECIAL_3POINTER])
3105 out_printf(out, "typedef struct { "
3106 "gpointer a; gpointer b; "
3108 "} ___threepointertype;\n");
3109 if(special_array[SPECIAL_INT_POINTER])
3110 out_printf(out, "typedef struct { "
3111 "gint a; gpointer b; "
3112 "} ___intpointertype;\n");
3113 out_printf(out, "\n");
3116 out_printf(outh, "\n/*\n"
3117 " * Type checking and casting macros\n"
3119 out_printf(outh, "#define %s\t"
3120 "(%s_get_type())\n",
3121 macrotype, funcbase);
3122 out_printf(outh, "#define %s(obj)\t"
3123 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3124 macrobase, funcbase, typebase);
3125 out_printf(outh, "#define %s_CONST(obj)\t"
3126 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3127 macrobase, funcbase, typebase);
3128 out_printf(outh, "#define %s_CLASS(klass)\t"
3129 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3130 macrobase, funcbase, typebase);
3131 out_printf(outh, "#define %s(obj)\t"
3132 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3135 "#define %s_GET_CLASS(obj)\t"
3136 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3137 macrobase, funcbase, typebase);
3139 if ( ! no_self_alias) {
3140 out_printf(out, "/* self casting macros */\n");
3141 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3142 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3143 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3144 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3145 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3147 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3150 out_printf(out, "/* self typedefs */\n");
3151 out_printf(out, "typedef %s Self;\n", typebase);
3152 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3156 always_private_struct) {
3157 out_printf (outh, "\n/* Private structure type */\n");
3158 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3159 typebase, typebase);
3161 out_printf (outh, "/* There are no privates, this "
3162 "structure is thus never defined */\n");
3165 out_printf (outh, "\n/*\n"
3166 " * Main object structure\n"
3168 s = replace_sep (c->otype, '_');
3170 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3171 "#define __TYPEDEF_%s__\n", s, s);
3173 out_printf (outh, "typedef struct _%s %s;\n"
3174 "#endif\n", typebase, typebase);
3175 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3176 typebase, ptypebase);
3177 for (li = c->nodes; li; li=li->next) {
3178 static gboolean printed_public = FALSE;
3180 Variable *v = (Variable *)n;
3181 if(n->type == VARIABLE_NODE &&
3182 v->scope == PUBLIC_SCOPE) {
3183 if( ! printed_public) {
3184 out_printf(outh, "\t/*< public >*/\n");
3185 printed_public = TRUE;
3187 put_variable((Variable *)n, outh);
3190 /* put protecteds always AFTER publics */
3191 for (li = c->nodes; li != NULL; li = li->next) {
3193 Variable *v = (Variable *)n;
3194 if (n->type == VARIABLE_NODE &&
3195 v->scope == PROTECTED_SCOPE) {
3196 if ( ! printed_private) {
3197 out_printf (outh, "\t/*< private >*/\n");
3198 printed_private = TRUE;
3200 put_variable ((Variable *)n, outh);
3204 always_private_struct) {
3205 if ( ! printed_private)
3206 out_printf (outh, "\t/*< private >*/\n");
3207 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3209 out_printf (outh, "};\n");
3214 /* if we are to stick this into the private
3215 header, if not stick it directly into the
3222 out_printf (outfp, "struct _%sPrivate {\n",
3224 for(li=c->nodes; li; li=li->next) {
3226 Variable *v = (Variable *)n;
3227 if(n->type == VARIABLE_NODE &&
3228 v->scope == PRIVATE_SCOPE) {
3229 out_addline_infile(outfp, v->line_no);
3230 put_variable(v, outfp);
3233 out_addline_outfile(outfp);
3234 out_printf(outfp, "};\n");
3237 out_printf(outh, "\n/*\n"
3238 " * Class definition\n"
3240 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3241 typebase, typebase);
3243 "struct _%sClass {\n\t%sClass __parent__;\n",
3244 typebase, ptypebase);
3245 for(li = c->nodes; li != NULL; li = li->next) {
3247 if(n->type == METHOD_NODE)
3248 put_vs_method((Method *)n);
3250 /* If BonoboX type class put down the epv */
3251 if (c->bonobo_object_class != NULL) {
3253 "\t/* Bonobo object epv */\n"
3254 "\tPOA_%s__epv _epv;\n",
3255 c->bonobo_object_class);
3257 /* put class scope variables */
3258 for (li = c->nodes; li != NULL; li = li->next) {
3260 Variable *v = (Variable *)n;
3261 if (n->type == VARIABLE_NODE &&
3262 v->scope == CLASS_SCOPE)
3263 put_variable ((Variable *)n, outh);
3265 out_printf (outh, "};\n\n");
3267 out_printf (out, "/* here are local prototypes */\n");
3268 if (set_properties > 0) {
3269 out_printf (out, "static void ___object_set_property "
3270 "(GObject *object, guint property_id, "
3271 "const GValue *value, GParamSpec *pspec);\n");
3273 if (get_properties > 0) {
3274 out_printf (out, "static void ___object_get_property "
3275 "(GObject *object, guint property_id, "
3276 "GValue *value, GParamSpec *pspec);\n");
3279 out_printf (outh, "\n/*\n"
3280 " * Public methods\n"
3283 if ( ! overrode_get_type) {
3284 out_printf (outh, "GType\t%s_get_type\t(void);", funcbase);
3287 for(li = c->nodes; li != NULL; li = li->next) {
3289 if(n->type == METHOD_NODE) {
3290 put_pub_method((Method *)n);
3291 put_prot_method((Method *)n);
3292 put_priv_method_prot((Method *)n);
3296 /* this idea is less and less apealing to me */
3298 out_printf (outh, "\n/*\n"
3299 " * Signal connection wrapper macros\n"
3302 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3303 put_signal_macros (c, TRUE);
3304 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3305 put_signal_macros (c, FALSE);
3306 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3308 put_signal_macros (c, FALSE);
3309 out_printf(outh, "\n");
3312 out_printf (out, "\n/*\n"
3313 " * Signal connection wrapper macro shortcuts\n"
3315 put_local_signal_macros (c);
3316 out_printf(outh, "\n");
3319 /* argument wrapping macros */
3320 if(get_properties > 0 || set_properties > 0) {
3321 out_printf(outh, "\n/*\n"
3322 " * Argument wrapping macros\n"
3325 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3326 put_argument_gnu_wrappers(c);
3327 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3328 put_argument_nongnu_wrappers(c);
3329 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3331 put_argument_nongnu_wrappers(c);
3336 for(li = c->nodes; li != NULL; li = li->next) {
3338 if(n->type == METHOD_NODE)
3339 add_signal_prots((Method *)n);
3345 if(any_method_to_alias(c)) {
3347 out_printf(out, "/* Short form macros */\n");
3348 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3349 make_method_gnu_aliases(c);
3350 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3352 make_method_nongnu_aliases(c);
3355 add_interface_inits (c);
3357 if ( ! overrode_get_type) {
3358 if (c->bonobo_object_class != NULL)
3359 add_bonobo_object_get_type ();
3364 out_printf (out, "/* a macro for creating a new object of our type */\n");
3366 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3367 typebase, funcbase);
3369 out_printf (out, "/* a function for creating a new object of our type */\n");
3370 out_printf (out, "#include <stdarg.h>\n");
3372 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3373 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3374 "{\n\t%s *ret;\n\tva_list ap;\n"
3375 "\tva_start (ap, first);\n"
3376 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3379 "\treturn ret;\n}\n\n",
3381 no_gnu ? "" : " G_GNUC_UNUSED",
3382 typebase, typebase, typebase, funcbase);
3392 if(set_properties > 0) {
3393 add_getset_arg(c, TRUE);
3396 if(get_properties > 0) {
3397 add_getset_arg(c, FALSE);
3400 for(li = c->nodes; li != NULL; li = li->next) {
3402 if(n->type == METHOD_NODE)
3403 put_method((Method *)n);
3406 add_bad_hack_to_avoid_unused_warnings(c);
3410 print_useful_macros(void)
3412 int major = 0, minor = 0, pl = 0;
3415 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3416 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3417 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3418 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3420 /* Useful priv macro thingie */
3421 /* FIXME: this should be done the same way that priv is, as a var,
3423 out_printf (out, "#define selfp (self->_priv)\n\n");
3427 print_file_comments(void)
3431 out_printf(outh, "/* Generated by GOB (v%s)"
3432 " (do not edit directly) */\n\n", VERSION);
3434 out_printf(outph, "/* Generated by GOB (v%s)"
3435 " (do not edit directly) */\n\n", VERSION);
3436 out_printf(out, "/* Generated by GOB (v%s) on %s"
3437 " (do not edit directly) */\n\n",
3438 VERSION, ctime(&curtime));
3440 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3444 print_includes(void)
3446 gboolean found_header;
3449 /* We may need string.h for memset */
3450 if(destructors > 0 &&
3451 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3452 out_printf(out, "#include <string.h> /* memset() */\n\n");
3455 p = g_strconcat(filebase, ".h", NULL);
3456 found_header = TRUE;
3457 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3458 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3459 found_header = FALSE;
3463 /* if we are creating a private header see if it was included */
3465 p = g_strconcat(filebase, "-private.h", NULL);
3466 if( ! g_list_find_custom(include_files, p,
3467 (GCompareFunc)strcmp)) {
3468 out_printf(out, "#include \"%s-private.h\"\n\n",
3471 error_printf(GOB_WARN, 0,
3472 "Implicit private header include "
3474 "\tsource file, while public "
3475 "header is at a custom location, "
3477 "\texplicitly include "
3478 "the private header below the "
3486 print_header_prefixes(void)
3490 p = replace_sep(((Class *)class)->otype, '_');
3492 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3494 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3495 "#define __%s_PRIVATE_H__\n\n"
3496 "#include \"%s.h\"\n\n", p, p, filebase);
3499 if( ! no_extern_c) {
3500 out_printf(outh, "#ifdef __cplusplus\n"
3502 "#endif /* __cplusplus */\n\n");
3504 out_printf(outph, "#ifdef __cplusplus\n"
3506 "#endif /* __cplusplus */\n\n");
3511 print_header_postfixes(void)
3514 out_printf(outh, "\n#ifdef __cplusplus\n"
3516 "#endif /* __cplusplus */\n");
3517 out_printf(outh, "\n#endif\n");
3520 out_printf(outph, "\n#ifdef __cplusplus\n"
3522 "#endif /* __cplusplus */\n");
3523 out_printf(outph, "\n#endif\n");
3532 /* print the AT_CCODE blocks */
3533 for(li = nodes; li != NULL; li = li->next) {
3534 Node *node = li->data;
3535 if(node->type == CCODE_NODE) {
3536 CCode *cc = (CCode *)node;
3537 if(cc->cctype == AT_CCODE)
3538 print_ccode_block((CCode *)node);
3544 print_header_top(void)
3548 /* mandatory includes */
3549 out_printf (outh, "#include <glib.h>\n");
3550 out_printf (outh, "#include <glib-object.h>\n");
3552 /* print the HT_CCODE blocks */
3553 for (li = nodes; li != NULL; li = li->next) {
3554 Node *node = li->data;
3555 if (node->type == CCODE_NODE) {
3556 CCode *cc = (CCode *)node;
3557 if (cc->cctype == HT_CCODE)
3558 print_ccode_block ((CCode *)node);
3564 print_enum (EnumDef *enode)
3571 funcprefix = replace_sep (enode->etype, '_');
3572 g_strdown (funcprefix);
3573 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3575 type = remove_sep (enode->etype);
3577 out_printf (outh, "\ntypedef enum {\n");
3579 for (li = enode->values; li != NULL; li = li->next) {
3580 EnumValue *value = li->data;
3582 char *sname = g_strdown (g_strdup (value->name));
3584 while ((p = strchr (sname, '_')) != NULL)
3587 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3588 if (value->value != NULL)
3589 out_printf (outh, " = %s", value->value);
3590 if (li->next != NULL)
3591 out_printf (outh, ",\n");
3593 out_printf (outh, "\n");
3595 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3596 enode->prefix, value->name,
3597 enode->prefix, value->name,
3603 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3605 out_printf (outh, "} %s;\n", type);
3607 str = make_pre_macro (enode->etype, "TYPE");
3608 out_printf (outh, "#define %s ", str);
3611 out_printf (outh, "%s_get_type()\n", funcprefix);
3612 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3615 "GType\n%s_get_type (void)\n"
3617 "\tstatic GType type = 0;\n"
3618 "\tif (type == 0)\n"
3619 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3622 funcprefix, type, funcprefix);
3624 g_free (funcprefix);
3629 print_flags (Flags *fnode)
3637 funcprefix = replace_sep (fnode->ftype, '_');
3638 g_strdown (funcprefix);
3639 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3641 type = remove_sep (fnode->ftype);
3643 out_printf (outh, "\ntypedef enum {\n");
3645 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3646 const char *name = li->data;
3648 char *sname = g_strdown (g_strdup (name));
3650 while ((p = strchr (sname, '_')) != NULL)
3653 out_printf (outh, "\t%s_%s = 1<<%d",
3654 fnode->prefix, name, i);
3655 if (li->next != NULL)
3656 out_printf (outh, ",\n");
3658 out_printf (outh, "\n");
3660 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3661 fnode->prefix, name,
3662 fnode->prefix, name,
3668 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3670 out_printf (outh, "} %s;\n", type);
3672 str = make_pre_macro (fnode->ftype, "TYPE");
3673 out_printf (outh, "#define %s ", str);
3676 out_printf (outh, "%s_get_type()\n", funcprefix);
3677 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3680 "GType\n%s_get_type (void)\n"
3682 "\tstatic GType type = 0;\n"
3683 "\tif (type == 0)\n"
3684 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3687 funcprefix, type, funcprefix);
3689 g_free (funcprefix);
3694 print_error (Error *enode)
3701 funcprefix = replace_sep (enode->etype, '_');
3702 g_strdown (funcprefix);
3703 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3705 type = remove_sep (enode->etype);
3707 out_printf (outh, "\ntypedef enum {\n");
3709 for (li = enode->values; li != NULL; li = li->next) {
3710 const char *name = li->data;
3712 char *sname = g_strdown (g_strdup (name));
3714 while ((p = strchr (sname, '_')) != NULL)
3717 out_printf (outh, "\t%s_%s", enode->prefix, name);
3718 if (li->next != NULL)
3719 out_printf (outh, ",\n");
3721 out_printf (outh, "\n");
3723 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3724 enode->prefix, name,
3725 enode->prefix, name,
3731 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3733 out_printf (outh, "} %s;\n", type);
3735 str = make_pre_macro (enode->etype, "TYPE");
3736 out_printf (outh, "#define %s ", str);
3739 out_printf (outh, "%s_get_type ()\n", funcprefix);
3740 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3743 "GType\n%s_get_type (void)\n"
3745 "\tstatic GType type = 0;\n"
3746 "\tif (type == 0)\n"
3747 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3750 funcprefix, type, funcprefix);
3752 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3753 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3755 str = replace_sep (enode->etype, '-');
3759 "GQuark\n%s_quark (void)\n"
3761 "\tstatic GQuark q = 0;\n"
3763 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3770 g_free (funcprefix);
3775 generate_outfiles(void)
3779 print_file_comments();
3785 print_header_prefixes();
3787 print_useful_macros();
3791 for (li = nodes; li != NULL; li = li->next) {
3792 Node *node = li->data;
3793 if (node->type == CCODE_NODE) {
3794 CCode *cc = (CCode *)node;
3795 if (cc->cctype != HT_CCODE &&
3796 cc->cctype != AT_CCODE)
3797 print_ccode_block ((CCode *)node);
3798 } else if (node->type == CLASS_NODE) {
3799 print_class_block ((Class *)node);
3800 } else if (node->type == ENUMDEF_NODE) {
3801 print_enum ((EnumDef *)node);
3802 } else if (node->type == FLAGS_NODE) {
3803 print_flags ((Flags *)node);
3804 } else if (node->type == ERROR_NODE) {
3805 print_error ((Error *)node);
3807 g_assert_not_reached();
3811 print_header_postfixes();
3817 fprintf(stderr, "Gob version %s\n\n", VERSION);
3818 fprintf(stderr, "gob [options] file.gob\n\n");
3819 fprintf(stderr, "Options:\n"
3820 "\t--help,-h,-? Display this help\n"
3821 "\t--version Display version\n"
3822 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3823 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3824 "\t--for-cpp Create C++ files\n"
3825 "\t--no-extern-c Never print extern \"C\" into the "
3827 "\t--no-gnu Never use GNU extentions\n"
3828 "\t--no-touch-headers Don't touch headers unless they "
3830 "\t--always-private-header Always create a private header "
3832 "\t even if it would be empty "
3834 "\t--ondemand-private-header Create private header only when "
3836 "\t--no-private-header Don't create a private header, "
3838 "\t structure and protected "
3839 "prototypes inside c file\n"
3840 "\t--always-private-struct Always create a private pointer "
3842 "\t the object structure\n"
3843 "\t--m4 Preprocess source with m4. "
3844 "Following args will\n"
3845 "\t be passed to m4\n"
3846 "\t--m4-dir Print directory that will be "
3849 "\t--no-write,-n Don't write output files, just "
3851 "\t--no-lines Don't print '#line' to output\n"
3852 "\t--no-self-alias Don't create self type and macro "
3854 "\t--no-kill-underscores Ignored for compatibility\n");
3858 parse_options(int argc, char *argv[])
3861 int got_file = FALSE;
3862 int no_opts = FALSE;
3863 int m4_opts = FALSE; /* if we are just passing on args to m4 */
3867 for(i = 1 ; i < argc; i++) {
3869 char *new_commandline;
3870 g_assert(m4_commandline!=NULL);
3872 /* check whether this one looks like the filename */
3873 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
3875 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
3879 /* insert flags before the filename */
3880 new_commandline=g_strconcat(m4_commandline,
3888 /* just an ordinary option */
3890 new_commandline=g_strconcat(m4_commandline,
3895 /* free old commandline */
3896 g_free(m4_commandline);
3897 m4_commandline=new_commandline;
3899 } else if(no_opts ||
3900 argv[i][0] != '-') {
3903 fprintf(stderr, "Specify only one file!\n");
3909 } else if(strcmp(argv[i], "--help")==0) {
3912 } else if(strcmp(argv[i], "--version")==0) {
3913 fprintf(stderr, "Gob version %s\n", VERSION);
3915 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
3916 exit_on_warn = TRUE;
3917 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
3918 exit_on_warn = FALSE;
3919 } else if(strcmp(argv[i], "--for-cpp")==0) {
3921 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
3922 no_touch_headers = TRUE;
3923 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
3924 private_header = PRIVATE_HEADER_ONDEMAND;
3925 } else if(strcmp(argv[i], "--always-private-header")==0) {
3926 private_header = PRIVATE_HEADER_ALWAYS;
3927 } else if(strcmp(argv[i], "--no-private-header")==0) {
3928 private_header = PRIVATE_HEADER_NEVER;
3929 } else if(strcmp(argv[i], "--no-gnu")==0) {
3931 } else if(strcmp(argv[i], "--no-extern-c")==0) {
3933 } else if(strcmp(argv[i], "--no-write")==0) {
3935 } else if(strcmp(argv[i], "--no-lines")==0) {
3937 } else if(strcmp(argv[i], "--no-self-alias")==0) {
3938 no_self_alias = TRUE;
3939 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
3941 } else if(strcmp(argv[i], "--always-private-struct")==0) {
3942 always_private_struct = TRUE;
3943 } else if(strcmp(argv[i], "--m4-dir")==0) {
3944 printf("%s\n",M4_INCLUDE_DIR);
3946 } else if(strcmp(argv[i], "--m4")==0) {
3950 m4_commandline=g_strdup(M4_COMMANDLINE);
3951 } else if(strcmp(argv[i], "--m4-clean")==0) {
3955 m4_commandline=g_strdup(M4_COMMANDLINE);
3956 } else if(strcmp(argv[i], "--")==0) {
3957 /*further arguments are files*/
3959 } else if(strncmp(argv[i], "--", 2)==0) {
3960 /*unknown long option*/
3961 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
3965 /*by now we know we have a string starting with
3966 - which is a short option string*/
3968 for(p = argv[i] + 1; *p; p++) {
3982 "Unknown option '%c'!\n", *p);
3991 /* if we are using m4, and got no filename, append m4 flags now */
3992 if(!got_file && use_m4 && !use_m4_clean) {
3993 char *new_commandline;
3994 new_commandline=g_strconcat(m4_commandline,
3998 g_free(m4_commandline);
3999 m4_commandline=new_commandline;
4004 /* this is a somewhat ugly hack, but it appears to work */
4006 compare_and_move_header(void)
4008 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
4009 char *hf = g_strconcat(filebase, ".h", NULL);
4011 if(stat(hf, &s) == 0) {
4013 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
4014 if(system(s) == 0) {
4015 if(unlink(hfnew) != 0)
4016 error_printf(GOB_ERROR, 0,
4017 "Can't remove new header file");
4025 error_printf(GOB_ERROR, 0,
4026 "Can't remove old header file");
4028 if(rename(hfnew, hf) != 0)
4029 error_printf(GOB_ERROR, 0,
4030 "Can't rename new header file");
4036 main(int argc, char *argv[])
4038 parse_options(argc, argv);
4041 yyin = popen(m4_commandline, "r");
4043 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4047 } else if(filename) {
4048 yyin = fopen(filename, "r");
4050 fprintf(stderr, "Error: can't open file '%s'\n",
4059 /* This is where parsing is done */
4062 g_error("Parsing errors, quitting");
4064 /* close input file */
4065 if(use_m4) pclose(yyin);
4070 error_print(GOB_ERROR, 0, " no class defined");
4073 exit_on_error = FALSE;
4075 signals = count_signals ((Class *)class);
4076 set_properties = count_set_properties ((Class *)class) +
4077 count_set_arguments ((Class *)class);
4078 get_properties = count_get_properties ((Class *)class) +
4079 count_get_arguments ((Class *)class);
4080 overrides = count_overrides ((Class *)class);
4081 privates = count_privates ((Class *)class);
4082 protecteds = count_protecteds ((Class *)class);
4083 unreftors = count_unreftors ((Class *)class);
4084 destructors = count_destructors ((Class *)class);
4085 initializers = count_initializers ((Class *)class);
4086 overrode_get_type = find_get_type ((Class *)class);
4089 make_inits ((Class *)class);
4091 need_dispose = TRUE;
4092 find_dispose ((Class *)class);
4094 if (destructors > 0 ||
4096 need_finalize = TRUE;
4097 find_finalize ((Class *)class);
4099 check_bad_symbols ((Class *)class);
4100 check_duplicate_symbols ((Class *)class);
4101 check_duplicate_overrides ((Class *)class);
4102 check_duplicate_signals_args ((Class *)class);
4103 check_public_new ((Class *)class);
4104 check_vararg ((Class *)class);
4105 check_firstarg ((Class *)class);
4106 check_nonvoidempty ((Class *)class);
4107 check_signal_args ((Class *)class);
4108 check_property_types ((Class *)class);
4109 check_argument_types ((Class *)class);
4110 check_func_arg_checks ((Class *)class);
4112 exit_on_error = TRUE;
4117 any_special = setup_special_array ((Class *)class, special_array);
4121 generate_outfiles ();
4132 if (no_touch_headers &&
4134 compare_and_move_header ();