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_shutdown = FALSE;
86 static Method * shutdown_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(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(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(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_shutdown(Class *cl)
643 shutdown_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, "shutdown")==0) {
650 if(strcmp(m->otype, "G:Object") != 0) {
651 error_print(GOB_ERROR, m->line_no,
652 "shutdown method override "
653 "of class other then "
656 if(g_list_length(m->args) != 1) {
657 error_print(GOB_ERROR, m->line_no,
658 "shutdown method override "
659 "with more then one "
662 shutdown_handler = m;
670 find_finalize(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(GList *a, 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(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 (Method *m)
739 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
742 for (i = 0, li = m->gtktypes->next;
744 i++, li = li->next) {
745 char *get_func = g_strdup_printf
746 ("g_value_get_%s", (char *)li->data);
747 g_strdown (get_func);
748 out_printf (out, ",\n\t\t(%s) "
749 "%s (param_values + %d)",
750 get_cast (li->data, FALSE),
755 out_printf (out, ",\n\t\tdata2);\n");
760 add_signal_prots(Method *m)
766 gboolean ret_none = FALSE;
767 gboolean arglist_none = FALSE;
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,\n"
816 "\tguint n_param_values,\n"
817 "\tconst GValue *param_values,\n"
818 "\tgpointer invocation_hint,\n"
819 "\tgpointer marshal_data)\n"
823 out_printf (out, "\t%s v_return;\n", retcast);
825 out_printf (out, "\tregister ___%s callback;\n"
826 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
827 "\tregister gpointer data1, data2;\n\n",
830 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
831 arglist_none ? 1 : g_list_length (m->gtktypes));
834 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
835 "\t\tdata1 = closure->data;\n"
836 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
838 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
839 "\t\tdata2 = closure->data;\n"
842 out_printf (out, "\tcallback = (___%s) "
843 "(marshal_data != NULL ? marshal_data : cc->callback);"
847 out_printf (out, "\tcallback ((%s *)data1", typebase);
849 out_printf (out, "\tv_return = callback ((%s *)data1",
853 print_signal_marsal_args (m);
856 /* FIXME: This code is so fucking ugly it hurts */
857 gboolean take_ownership =
858 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
859 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
860 char *set_func = g_strdup_printf ("g_value_set_%s%s",
861 (char *)m->gtktypes->data,
863 "_take_ownership" : "");
864 g_strdown (set_func);
866 out_printf (out, "\n\t%s (return_value, v_return);\n",
871 out_printf (out, "}\n\n");
878 out_printf(out, "\n");
880 out_printf(out, "enum {\n");
881 for(li=c->nodes;li;li=g_list_next(li)) {
883 if(n->type == METHOD_NODE) {
884 Method *m = (Method *)n;
885 if(m->method == SIGNAL_LAST_METHOD ||
886 m->method == SIGNAL_FIRST_METHOD) {
887 char *s = g_strdup(m->id);
889 out_printf(out, "\t%s_SIGNAL,\n", s);
894 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
896 if (set_properties > 0 ||
897 get_properties > 0) {
898 out_printf(out, "enum {\n\tPROP_0");
899 for(li=c->nodes;li;li=g_list_next(li)) {
901 if (n->type == PROPERTY_NODE) {
902 Property *p = (Property *)n;
903 char *s = g_strdup (p->name);
905 out_printf (out, ",\n\tPROP_%s", s);
907 } else if (n->type == ARGUMENT_NODE) {
908 Argument *a = (Argument *)n;
909 char *s = g_strdup(a->name);
911 out_printf(out, ",\n\tPROP_%s", s);
915 out_printf(out, "\n};\n\n");
920 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
922 out_printf(out, "/* pointer to the class of our parent */\n");
923 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
927 add_interface_methods (Class *c, const char *interface)
930 gboolean added_line = FALSE;
932 for (li = c->nodes; li != NULL; li = li->next) {
934 Method *m = (Method *)n;
935 if (n->type != METHOD_NODE ||
936 m->method == OVERRIDE_METHOD ||
937 m->interface == NULL ||
938 strcmp (m->interface, interface) != 0)
941 if (m->line_no > 0) {
942 out_addline_infile (out, m->line_no);
944 } else if (m->line_no == 0 &&
946 out_addline_outfile (out);
949 out_printf (out, "\tiface->%s = self_%s;\n",
953 out_addline_outfile (out);
957 add_interface_inits (Class *c)
961 if (c->interfaces == NULL)
964 out_printf(out, "\n");
966 for (li = c->interfaces; li != NULL; li = li->next) {
967 const char *interface = li->data;
969 char *name = replace_sep (interface, '_');
970 char *type = remove_sep (interface);
972 /* EEEK! evil, we should have some sort of option
973 * to force this for arbitrary interfaces, since
974 * some are Class and some are Iface. Glib is shite
976 if (strcmp (type, "GtkEditable") == 0 ||
977 strcmp (type, "GTypePlugin") == 0)
980 /* We'll assume Iface is the standard ending */
983 out_printf (out, "\nstatic void\n"
984 "___%s_init (%s%s *iface)\n"
988 add_interface_methods (c, interface);
990 out_printf (out, "}\n\n");
998 add_interface_infos (void)
1001 for (li = ((Class *)class)->interfaces;
1004 char *name = replace_sep (li->data, '_');
1006 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1007 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1017 add_interfaces (void)
1020 for (li = ((Class *)class)->interfaces;
1023 char *name = replace_sep (li->data, '_');
1024 char *type = make_pre_macro (li->data, "TYPE");
1027 "\t\tg_type_add_interface_static (type,\n"
1029 "\t\t\t&%s_info);\n",
1041 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1045 "%s_get_type (void)\n"
1047 "\tstatic GType type = 0;\n\n"
1048 "\tif (type == 0) {\n"
1049 "\t\tstatic const GTypeInfo info = {\n"
1050 "\t\t\tsizeof (%sClass),\n"
1051 "\t\t\t(GBaseInitFunc) NULL,\n"
1052 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1053 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1054 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1055 "\t\t\tNULL /* class_data */,\n"
1056 "\t\t\tsizeof (%s),\n"
1057 "\t\t\t0 /* n_preallocs */,\n"
1058 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1060 funcbase, typebase, funcbase, typebase, funcbase);
1062 add_interface_infos ();
1065 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)0);\n",
1066 pmacrotype, typebase);
1074 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1076 chunk_size, chunk_size);
1086 add_bonobo_object_get_type (void)
1088 /* char *chunk_size = ((Class*)class)->chunk_size; */
1089 /* _vicious_ spanks seth with a rusty nail
1091 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1092 "gob2 doesn't officially support it yet. It'd be safer "
1093 "and a lot more fun to blow goats.\"\n");
1098 "%s_get_type (void)\n" /* 1 */
1100 "\tstatic GType type = 0;\n\n"
1101 "\tif (type == 0) {\n"
1102 "\t\tstatic const GTypeInfo info = {\n"
1103 "\t\t\tsizeof (%sClass),\n" /* 2 */
1104 "\t\t\t(GBaseInitFunc) NULL,\n"
1105 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1106 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1107 "\t\t\tNULL, /* class_finalize */\n"
1108 "\t\t\tNULL, /* class_data */\n"
1109 "\t\t\tsizeof (%s),\n" /* 4 */
1110 "\t\t\t0, /* n_preallocs */\n"
1111 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1120 add_interface_infos ();
1123 "\t\ttype = bonobo_type_unique (\n"
1124 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1125 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1126 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1127 "\t\t\t&info, \"%s\");\n", /* 3 */
1128 ((Class*)class)->bonobo_object_class /* 1 */,
1137 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1139 chunk_size, chunk_size);
1148 add_overrides(Class *c, const char *oname,
1149 gboolean did_base_obj)
1155 done = g_hash_table_new (g_str_hash, g_str_equal);
1157 s = g_strdup ("GObject");
1158 g_hash_table_insert (done, s, s);
1160 for (li = c->nodes; li != NULL; li = li->next) {
1163 Method *m = (Method *)n;
1164 if(n->type != METHOD_NODE ||
1165 m->method != OVERRIDE_METHOD)
1168 s = remove_sep(m->otype);
1170 if(g_hash_table_lookup(done, s)) {
1174 g_hash_table_insert(done, s, s);
1176 f = replace_sep(m->otype, '_');
1179 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1184 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1185 g_hash_table_destroy (done);
1189 make_run_signal_flags(Method *m, gboolean last)
1204 gs = g_string_new(NULL);
1207 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1209 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1211 if(m->scope == PUBLIC_SCOPE)
1212 g_string_append(gs, " | G_SIGNAL_ACTION");
1214 for(li = m->flags; li; li = li->next) {
1215 char *flag = li->data;
1217 for(i=0;flags[i];i++) {
1218 if(strcmp(flags[i], flag)==0)
1221 /* if we haven't found it in our list */
1223 error_printf(GOB_WARN, m->line_no,
1224 "Unknown flag '%s' used, "
1225 "perhaps it was misspelled",
1228 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1232 char *ret = gs->str;
1233 g_string_free(gs, FALSE);
1240 add_signals(Class *c)
1244 out_printf(out, "\n");
1245 for(li=c->nodes;li;li=g_list_next(li)) {
1247 char *mar, *sig, *flags;
1248 gboolean is_none, last = FALSE;
1249 Method *m = (Method *)n;
1251 if(n->type != METHOD_NODE ||
1252 (m->method != SIGNAL_FIRST_METHOD &&
1253 m->method != SIGNAL_LAST_METHOD))
1256 if(m->method == SIGNAL_FIRST_METHOD)
1261 if(g_hash_table_lookup(marsh, m))
1262 mar = g_strconcat("___marshal_",
1263 (char *)g_hash_table_lookup(marsh, m),
1266 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1268 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1270 sig = g_strdup (m->id);
1272 flags = make_run_signal_flags (m, last);
1273 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1274 "\t\tg_signal_new (\"%s\",\n"
1275 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1276 "\t\t\t(GSignalFlags)(%s),\n"
1277 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1278 "\t\t\tNULL, NULL,\n"
1280 "\t\t\tG_TYPE_%s, %d",
1283 typebase, m->id, mar,
1284 (char *)m->gtktypes->data,
1285 is_none ? 0 : g_list_length(m->gtktypes->next));
1292 for(l = m->gtktypes->next; l != NULL; l = l->next)
1293 out_printf(out, ",\n\t\t\tG_TYPE_%s",
1297 out_printf(out, ");\n");
1299 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1303 out_printf(out, "\tif(");
1304 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1305 out_printf(out, "%s sizeof(", sep);
1306 print_type(out, m->mtype, FALSE);
1307 out_printf(out, "%s",
1309 m->mtype->postfix : "");
1310 out_printf(out, ") != sizeof(%s)",
1311 get_cast(m->gtktypes->data, FALSE));
1316 for(al = m->args->next, gl = m->gtktypes->next;
1317 al != NULL && gl != NULL;
1318 al = al->next, gl = gl->next) {
1319 FuncArg *arg = al->data;
1320 char *gtkarg = gl->data;
1322 out_printf(out, "%ssizeof(", sep);
1323 print_type(out, arg->atype, FALSE);
1324 out_printf(out, "%s",
1325 arg->atype->postfix ?
1326 arg->atype->postfix : "");
1327 out_printf(out, ") != sizeof(%s)",
1328 get_cast(gtkarg, FALSE));
1332 out_printf(out, ") {\n"
1333 "\t\tg_error(\"%s line %d: Type mismatch "
1334 "of \\\"%s\\\" signal signature\");\n"
1336 filename, m->line_no, m->id);
1343 set_def_handlers(Class *c, const char *oname)
1346 gboolean set_line = FALSE;
1348 out_printf(out, "\n");
1349 for(li = c->nodes; li; li = g_list_next(li)) {
1351 Method *m = (Method *)n;
1353 if(n->type != METHOD_NODE ||
1354 (m->method != SIGNAL_FIRST_METHOD &&
1355 m->method != SIGNAL_LAST_METHOD &&
1356 m->method != VIRTUAL_METHOD &&
1357 m->method != OVERRIDE_METHOD))
1360 if(m->line_no > 0 && m->cbuf) {
1361 out_addline_infile(out, m->line_no);
1363 } else if(set_line) {
1364 out_addline_outfile(out);
1369 if (m->method == OVERRIDE_METHOD) {
1371 s = replace_sep (m->otype, '_');
1374 if (need_shutdown &&
1375 shutdown_handler != NULL &&
1376 strcmp (m->id, "shutdown") == 0)
1377 out_printf (out, "\tg_object_class->shutdown "
1378 "= ___shutdown;\n");
1379 else if (need_finalize &&
1381 strcmp(m->id, "finalize") == 0)
1383 "\tg_object_class->finalize = ___finalize;\n");
1384 else if (m->cbuf != NULL)
1386 "\t%s_class->%s = ___%x_%s_%s;\n",
1387 s, m->id, (guint)m->unique_id,
1390 out_printf(out, "\t%s_class->%s = NULL;\n",
1394 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1398 out_printf(out, "\t%s->%s = NULL;\n",
1403 out_addline_outfile(out);
1407 make_argument (Argument *a)
1412 char *argflags[] = {
1420 flags = g_string_new ("(GParamFlags)(");
1422 if(a->get && a->set)
1423 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1425 g_string_append (flags, "G_PARAM_READABLE");
1427 g_string_append (flags, "G_PARAM_WRITABLE");
1429 g_assert(a->get || a->set);
1431 for (l = a->flags; l != NULL; l = l->next) {
1432 char *flag = l->data;
1434 if(strcmp (flag, "READABLE") == 0 ||
1435 strcmp (flag, "WRITABLE") == 0) {
1436 error_print(GOB_WARN, a->line_no,
1438 "WRITABLE argument flags are "
1439 "set automatically");
1442 for(i = 0; argflags[i]; i++) {
1443 if(strcmp(argflags[i], flag)==0)
1446 /* if we haven't found it in our list */
1447 if( ! argflags[i]) {
1448 error_printf(GOB_WARN, a->line_no,
1449 "Unknown flag '%s' used, "
1450 "perhaps it was misspelled", flag);
1452 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1455 g_string_append (flags, ")");
1457 s = g_strdup(a->name);
1459 if (!strcmp (a->gtktype, "ENUM"))
1460 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1461 "\t\tG_TYPE_ENUM, 0,\n"
1463 a->name, flags->str);
1464 if (!strcmp (a->gtktype, "FLAGS"))
1465 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1466 "\t\tG_TYPE_FLAGS, 0,\n"
1468 a->name, flags->str);
1469 else if (!strcmp (a->gtktype, "OBJECT"))
1470 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1471 "\t\tG_TYPE_OBJECT,\n"
1473 a->name, flags->str);
1474 else if (!strcmp (a->gtktype, "STRING"))
1475 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1478 a->name, flags->str);
1479 else if (!strcmp (a->gtktype, "INT"))
1480 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1481 "\t\tG_MININT, G_MAXINT,\n"
1484 a->name, flags->str);
1485 else if (!strcmp (a->gtktype, "UINT"))
1486 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1487 "\t\t0, G_MAXUINT,\n"
1490 a->name, flags->str);
1491 else if (!strcmp (a->gtktype, "INT"))
1492 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1493 "\t\tG_MININT, G_MAXINT,\n"
1496 a->name, flags->str);
1497 else if (!strcmp (a->gtktype, "CHAR"))
1498 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1502 a->name, flags->str);
1503 else if (!strcmp (a->gtktype, "UCHAR"))
1504 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1508 a->name, flags->str);
1509 else if (!strcmp (a->gtktype, "BOOL") ||
1510 !strcmp (a->gtktype, "BOOLEAN"))
1511 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1514 a->name, flags->str);
1515 else if (!strcmp (a->gtktype, "LONG"))
1516 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1517 "\t\tG_MINLONG, G_MAXLONG,\n"
1520 a->name, flags->str);
1521 else if (!strcmp (a->gtktype, "ULONG"))
1522 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1523 "\t\t0, G_MAXULONG,\n"
1526 a->name, flags->str);
1527 else if (!strcmp (a->gtktype, "FLOAT"))
1528 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1529 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1532 a->name, flags->str);
1533 else if (!strcmp (a->gtktype, "DOUBLE"))
1534 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1535 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1538 a->name, flags->str);
1539 else if (!strcmp (a->gtktype, "POINTER"))
1540 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1542 a->name, flags->str);
1544 error_printf (GOB_ERROR, a->line_no,
1545 "%s type is not supported for arguments, try using properties",
1548 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1549 "\t\tPROP_%s, param_spec);\n", s);
1553 g_string_free(flags, TRUE);
1556 #define value_for_print(str, alt) (str != NULL ? str : alt)
1559 make_me_type (const char *type, const char *alt)
1562 return g_strdup (alt);
1563 /* HACK! just in case someone made this
1564 * work with 2.0.0 by using the TYPE
1566 if ((strstr (type, "_TYPE_") != NULL ||
1567 strstr (type, "TYPE_") == type) &&
1568 strchr (type, ':') == NULL)
1569 return g_strdup (type);
1570 return make_pre_macro (type, "TYPE");
1574 make_property (Property *p)
1579 char *argflags[] = {
1587 flags = g_string_new ("(GParamFlags)(");
1589 if (p->get != NULL && p->set != NULL)
1590 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1591 else if (p->get != NULL)
1592 g_string_append (flags, "G_PARAM_READABLE");
1594 g_string_append (flags, "G_PARAM_WRITABLE");
1596 if (p->get == NULL && p->set == NULL) {
1597 error_print (GOB_ERROR, p->line_no,
1598 "Property has no getter nor setter");
1601 for (l = p->flags; l != NULL; l = l->next) {
1602 char *flag = l->data;
1604 if(strcmp (flag, "READABLE") == 0 ||
1605 strcmp (flag, "WRITABLE") == 0) {
1606 error_print(GOB_WARN, p->line_no,
1608 "WRITABLE argument flags are "
1609 "set automatically");
1612 for(i = 0; argflags[i]; i++) {
1613 if(strcmp(argflags[i], flag)==0)
1616 /* if we haven't found it in our list */
1617 if( ! argflags[i]) {
1618 error_printf(GOB_WARN, p->line_no,
1619 "Unknown flag '%s' used, "
1620 "perhaps it was misspelled", flag);
1622 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1625 g_string_append (flags, ")");
1627 if (strcmp (p->gtktype, "CHAR") == 0) {
1628 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1629 "\t\t(\"%s\" /* name */,\n"
1630 "\t\t %s /* nick */,\n"
1631 "\t\t %s /* blurb */,\n"
1632 "\t\t %s /* minimum */,\n"
1633 "\t\t %s /* maximum */,\n"
1634 "\t\t %s /* default_value */,\n"
1637 value_for_print (p->nick, "NULL"),
1638 value_for_print (p->blurb, "NULL"),
1639 value_for_print (p->minimum, "-128"),
1640 value_for_print (p->maximum, "127"),
1641 value_for_print (p->default_value, "0"),
1643 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1644 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1645 "\t\t(\"%s\" /* name */,\n"
1646 "\t\t %s /* nick */,\n"
1647 "\t\t %s /* blurb */,\n"
1648 "\t\t %s /* minimum */,\n"
1649 "\t\t %s /* maximum */,\n"
1650 "\t\t %s /* default_value */,\n"
1653 value_for_print (p->nick, "NULL"),
1654 value_for_print (p->blurb, "NULL"),
1655 value_for_print (p->minimum, "0"),
1656 value_for_print (p->maximum, "0xFF"),
1657 value_for_print (p->default_value, "0"),
1659 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1660 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1661 "\t\t(\"%s\" /* name */,\n"
1662 "\t\t %s /* nick */,\n"
1663 "\t\t %s /* blurb */,\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->default_value, "FALSE"),
1671 } else if (strcmp (p->gtktype, "INT") == 0) {
1672 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1673 "\t\t(\"%s\" /* name */,\n"
1674 "\t\t %s /* nick */,\n"
1675 "\t\t %s /* blurb */,\n"
1676 "\t\t %s /* minimum */,\n"
1677 "\t\t %s /* maximum */,\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->minimum, "G_MININT"),
1684 value_for_print (p->maximum, "G_MAXINT"),
1685 value_for_print (p->default_value, "0"),
1687 } else if (strcmp (p->gtktype, "UINT") == 0) {
1688 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1689 "\t\t(\"%s\" /* name */,\n"
1690 "\t\t %s /* nick */,\n"
1691 "\t\t %s /* blurb */,\n"
1692 "\t\t %s /* minimum */,\n"
1693 "\t\t %s /* maximum */,\n"
1694 "\t\t %s /* default_value */,\n"
1697 value_for_print (p->nick, "NULL"),
1698 value_for_print (p->blurb, "NULL"),
1699 value_for_print (p->minimum, "0"),
1700 value_for_print (p->maximum, "G_MAXUINT"),
1701 value_for_print (p->default_value, "0"),
1703 } else if (strcmp (p->gtktype, "LONG") == 0) {
1704 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1705 "\t\t(\"%s\" /* name */,\n"
1706 "\t\t %s /* nick */,\n"
1707 "\t\t %s /* blurb */,\n"
1708 "\t\t %s /* minimum */,\n"
1709 "\t\t %s /* maximum */,\n"
1710 "\t\t %s /* default_value */,\n"
1713 value_for_print (p->nick, "NULL"),
1714 value_for_print (p->blurb, "NULL"),
1715 value_for_print (p->minimum, "G_MINLONG"),
1716 value_for_print (p->maximum, "G_MAXLONG"),
1717 value_for_print (p->default_value, "0"),
1719 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1720 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1721 "\t\t(\"%s\" /* name */,\n"
1722 "\t\t %s /* nick */,\n"
1723 "\t\t %s /* blurb */,\n"
1724 "\t\t %s /* minimum */,\n"
1725 "\t\t %s /* maximum */,\n"
1726 "\t\t %s /* default_value */,\n"
1729 value_for_print (p->nick, "NULL"),
1730 value_for_print (p->blurb, "NULL"),
1731 value_for_print (p->minimum, "0"),
1732 value_for_print (p->maximum, "G_MAXULONG"),
1733 value_for_print (p->default_value, "0"),
1735 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1736 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1737 "\t\t(\"%s\" /* name */,\n"
1738 "\t\t %s /* nick */,\n"
1739 "\t\t %s /* blurb */,\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->default_value, "0"),
1747 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1748 char *type = make_me_type (p->extra_gtktype,
1750 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1751 "\t\t(\"%s\" /* name */,\n"
1752 "\t\t %s /* nick */,\n"
1753 "\t\t %s /* blurb */,\n"
1754 "\t\t %s /* enum_type */,\n"
1755 "\t\t %s /* default_value */,\n"
1758 value_for_print (p->nick, "NULL"),
1759 value_for_print (p->blurb, "NULL"),
1761 value_for_print (p->default_value, "0"),
1764 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1765 char *type = make_me_type (p->extra_gtktype,
1767 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1768 "\t\t(\"%s\" /* name */,\n"
1769 "\t\t %s /* nick */,\n"
1770 "\t\t %s /* blurb */,\n"
1771 "\t\t %s /* flags_type */,\n"
1772 "\t\t %s /* default_value */,\n"
1775 value_for_print (p->nick, "NULL"),
1776 value_for_print (p->blurb, "NULL"),
1778 value_for_print (p->default_value, "0"),
1781 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1782 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1783 "\t\t(\"%s\" /* name */,\n"
1784 "\t\t %s /* nick */,\n"
1785 "\t\t %s /* blurb */,\n"
1786 "\t\t %s /* minimum */,\n"
1787 "\t\t %s /* maximum */,\n"
1788 "\t\t %s /* default_value */,\n"
1791 value_for_print (p->nick, "NULL"),
1792 value_for_print (p->blurb, "NULL"),
1793 value_for_print (p->minimum, "G_MINFLOAT"),
1794 value_for_print (p->maximum, "G_MAXFLOAT"),
1795 value_for_print (p->default_value, "0.0"),
1797 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1798 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1799 "\t\t(\"%s\" /* name */,\n"
1800 "\t\t %s /* nick */,\n"
1801 "\t\t %s /* blurb */,\n"
1802 "\t\t %s /* minimum */,\n"
1803 "\t\t %s /* maximum */,\n"
1804 "\t\t %s /* default_value */,\n"
1807 value_for_print (p->nick, "NULL"),
1808 value_for_print (p->blurb, "NULL"),
1809 value_for_print (p->minimum, "G_MINDOUBLE"),
1810 value_for_print (p->maximum, "G_MAXDOUBLE"),
1811 value_for_print (p->default_value, "0.0"),
1813 } else if (strcmp (p->gtktype, "STRING") == 0) {
1814 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1815 "\t\t(\"%s\" /* name */,\n"
1816 "\t\t %s /* nick */,\n"
1817 "\t\t %s /* blurb */,\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->default_value, "NULL"),
1825 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1826 char *type = make_me_type (p->extra_gtktype,
1828 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1829 "\t\t(\"%s\" /* name */,\n"
1830 "\t\t %s /* nick */,\n"
1831 "\t\t %s /* blurb */,\n"
1832 "\t\t %s /* param_type */,\n"
1835 value_for_print (p->nick, "NULL"),
1836 value_for_print (p->blurb, "NULL"),
1840 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1841 char *type = make_me_type (p->extra_gtktype,
1843 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1844 "\t\t(\"%s\" /* name */,\n"
1845 "\t\t %s /* nick */,\n"
1846 "\t\t %s /* blurb */,\n"
1847 "\t\t %s /* boxed_type */,\n"
1850 value_for_print (p->nick, "NULL"),
1851 value_for_print (p->blurb, "NULL"),
1855 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1856 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1857 "\t\t(\"%s\" /* name */,\n"
1858 "\t\t %s /* nick */,\n"
1859 "\t\t %s /* blurb */,\n"
1862 value_for_print (p->nick, "NULL"),
1863 value_for_print (p->blurb, "NULL"),
1865 /* FIXME: VALUE_ARRAY */
1866 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1867 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1868 "\t\t(\"%s\" /* name */,\n"
1869 "\t\t %s /* nick */,\n"
1870 "\t\t %s /* blurb */,\n"
1873 value_for_print (p->nick, "NULL"),
1874 value_for_print (p->blurb, "NULL"),
1876 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
1877 char *type = make_me_type (p->extra_gtktype,
1879 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1880 "\t\t(\"%s\" /* name */,\n"
1881 "\t\t %s /* nick */,\n"
1882 "\t\t %s /* blurb */,\n"
1883 "\t\t %s /* object_type */,\n"
1886 value_for_print (p->nick, "NULL"),
1887 value_for_print (p->blurb, "NULL"),
1892 error_printf (GOB_ERROR, p->line_no,
1893 "%s type is not supported by properties",
1897 s = g_strdup (p->name);
1899 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1901 "\t\tparam_spec);\n", s);
1904 g_string_free (flags, TRUE);
1908 make_arguments(Class *c)
1911 if (get_properties > 0)
1912 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1913 if (set_properties > 0)
1914 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1915 out_printf (out, " {\n"
1916 "\tGParamSpec *param_spec;\n\n");
1918 for (li = c->nodes; li != NULL; li = li->next) {
1920 if (n->type == PROPERTY_NODE)
1921 make_property ((Property *)n);
1922 else if (n->type == ARGUMENT_NODE)
1923 make_argument ((Argument *)n);
1925 out_printf(out, " }\n");
1929 print_initializer(Method *m, Variable *v)
1933 if(v->initializer == NULL)
1936 if(v->scope == PRIVATE_SCOPE)
1937 root = g_strconcat(((FuncArg *)m->args->data)->name,
1940 root = g_strdup(((FuncArg *)m->args->data)->name);
1942 if(v->initializer_line > 0)
1943 out_addline_infile(out, v->initializer_line);
1945 out_printf(out, "\t%s->%s = %s;\n",
1946 root, v->id, v->initializer);
1948 if(v->initializer_line > 0)
1949 out_addline_outfile(out);
1955 print_destructor (Variable *v)
1959 if(v->destructor == NULL)
1962 if(v->scope == PRIVATE_SCOPE)
1963 root = "self->_priv";
1967 if(v->destructor_simple) {
1968 if(v->destructor_line > 0)
1969 out_addline_infile(out, v->destructor_line);
1971 out_printf(out, "\tif(%s->%s) { "
1972 "((*(void (*)(void *))%s)) (%s->%s); "
1973 "%s->%s = NULL; }\n",
1974 root, v->id, v->destructor, root, v->id,
1977 if(v->destructor_line > 0)
1978 out_addline_outfile(out);
1980 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
1981 out_printf(out, "#define VAR %s\n", v->id);
1982 out_printf(out, "\t{\n");
1983 if(v->destructor_line > 0)
1984 out_addline_infile(out, v->destructor_line);
1986 out_printf(out, "\t%s}\n", v->destructor);
1988 if(v->destructor_line > 0)
1989 out_addline_outfile(out);
1990 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
1992 out_printf(out, "#undef VAR\n");
1993 out_printf(out, "#undef %s\n", v->id);
1998 add_shutdown (Class *c)
2000 out_printf(out, "\nstatic void\n"
2001 "___shutdown (GObject *obj_self)\n"
2004 "#define __GOB_FUNCTION__ \"%s::shutdown\"\n",
2007 if (unreftors > 0) {
2008 out_printf (out, "\t%s *self = %s (obj_self);\n",
2009 typebase, macrobase);
2012 if (shutdown_handler != NULL) {
2013 /* so we get possible bad argument warning */
2014 if (shutdown_handler->line_no > 0)
2015 out_addline_infile (out, shutdown_handler->line_no);
2016 out_printf (out, "\t___%x_%s_shutdown(obj_self);\n",
2017 (guint)shutdown_handler->unique_id, funcbase);
2018 if (shutdown_handler->line_no > 0)
2019 out_addline_outfile (out);
2022 "\tif (G_OBJECT_CLASS (parent_class)->shutdown) \\\n"
2023 "\t\t(* G_OBJECT_CLASS (parent_class)->shutdown) (obj_self);\n");
2026 if (unreftors > 0) {
2028 for(li = ((Class *)class)->nodes;
2032 Variable *v = (Variable *)n;
2033 if (n->type == VARIABLE_NODE &&
2034 v->scope != CLASS_SCOPE &&
2035 v->destructor_unref)
2036 print_destructor (v);
2040 out_printf (out, "\treturn;\n");
2042 out_printf(out, "\tself = NULL;\n");
2043 out_printf(out, "}\n"
2044 "#undef __GOB_FUNCTION__\n\n");
2048 add_finalize (Class *c)
2052 "___finalize(GObject *obj_self)\n"
2055 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2060 out_printf(out, "\t%s *self = %s (obj_self);\n",
2061 typebase, macrobase);
2064 out_printf(out, "\tgpointer priv = self->_priv;\n");
2067 if(finalize_handler) {
2068 /* so we get possible bad argument warning */
2069 if(finalize_handler->line_no > 0)
2070 out_addline_infile(out, finalize_handler->line_no);
2071 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2072 (guint)finalize_handler->unique_id, funcbase);
2073 if(finalize_handler->line_no > 0)
2074 out_addline_outfile(out);
2077 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2078 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2081 if (destructors > 0) {
2083 for (li = ((Class *)class)->nodes;
2087 Variable *v = (Variable *)n;
2088 if (n->type == VARIABLE_NODE &&
2089 v->scope != CLASS_SCOPE &&
2090 ! v->destructor_unref)
2091 print_destructor (v);
2096 out_printf(out, "\tg_free (priv);\n");
2098 out_printf (out, "\treturn;\n");
2099 if (destructors > 0 ||
2101 out_printf (out, "\tself = NULL;\n");
2103 out_printf(out, "}\n"
2104 "#undef __GOB_FUNCTION__\n\n");
2108 make_bonobo_object_epv (Class *c, const char *classname)
2111 gboolean added_line = FALSE;
2113 for (li = c->nodes; li != NULL; li = li->next) {
2115 Method *m = (Method *)n;
2116 if(n->type != METHOD_NODE ||
2117 m->method == OVERRIDE_METHOD)
2120 if (m->bonobo_object_func) {
2121 if(m->line_no > 0) {
2122 out_addline_infile(out, m->line_no);
2124 } else if (m->line_no == 0 &&
2126 out_addline_outfile(out);
2129 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2130 classname, m->id, m->id);
2134 out_addline_outfile(out);
2141 for(li=c->nodes;li;li=g_list_next(li)) {
2145 gboolean add_unused_class = FALSE;
2147 if(n->type != METHOD_NODE)
2150 if(m->method == INIT_METHOD) {
2152 out_addline_infile(out, m->line_no);
2153 print_method(out, "static ", "\n", "", " ", "", "\n",
2154 m, FALSE, FALSE, TRUE);
2156 out_addline_outfile(out);
2157 out_printf(out, "{\n"
2158 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2161 out_printf(out, "\t%s->_priv = "
2162 "g_new0 (%sPrivate, 1);\n",
2163 ((FuncArg *)m->args->data)->name,
2165 } else if(always_private_struct) {
2166 out_printf(out, "\t%s->_priv = NULL;\n",
2167 ((FuncArg *)m->args->data)->name);
2169 if(initializers > 0) {
2171 for(li = ((Class *)class)->nodes;
2175 Variable *v = (Variable *)n;
2176 if(n->type != VARIABLE_NODE ||
2177 v->scope == CLASS_SCOPE)
2179 print_initializer(m, v);
2182 } else if(m->method == CLASS_INIT_METHOD) {
2183 gboolean did_base_obj = FALSE;
2186 out_addline_infile(out, m->line_no);
2187 print_method(out, "static ", "\n", "", " ", "", "\n",
2188 m, FALSE, FALSE, TRUE);
2190 out_addline_outfile(out);
2191 out_printf(out, "{\n"
2192 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2194 if (set_properties > 0 ||
2195 get_properties > 0 ||
2202 "(GObjectClass*) %s;\n",
2203 ((FuncArg *)m->args->data)->name);
2204 add_unused_class = TRUE;
2205 did_base_obj = TRUE;
2210 ((FuncArg *)m->args->data)->name,
2213 if (initializers > 0) {
2215 for(li = ((Class *)class)->nodes;
2219 Variable *v = (Variable *)n;
2220 if(n->type == VARIABLE_NODE &&
2221 v->scope == CLASS_SCOPE)
2222 print_initializer(m, v);
2226 out_printf(out, "\n\tparent_class = ");
2228 out_printf(out, "(%sClass *)", ptypebase);
2229 out_printf(out, "g_type_class_ref (%s);\n",
2235 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2237 /* if there are no handlers for these things, we
2238 * need to set them up here */
2239 if(need_shutdown && !shutdown_handler)
2240 out_printf(out, "\tg_object_class->shutdown "
2241 "= ___shutdown;\n");
2242 if(need_finalize && !finalize_handler)
2243 out_printf(out, "\tg_object_class->finalize = "
2246 if(get_properties > 0 || set_properties > 0)
2249 if (c->bonobo_object_class != NULL) {
2250 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2256 out_printf(out, " {\n");
2257 out_addline_infile(out, m->ccode_line);
2258 out_printf(out, "%s\n", m->cbuf);
2259 out_addline_outfile(out);
2260 out_printf(out, " }\n");
2262 out_printf(out, "\treturn;\n");
2265 ((FuncArg *)m->args->data)->name);
2266 if(add_unused_class) {
2267 out_printf (out, "\tg_object_class = NULL;\n");
2269 out_printf(out, "}\n"
2270 "#undef __GOB_FUNCTION__\n");
2275 add_argument (Argument *a, gboolean is_set)
2279 char *the_type_lower;
2284 line_no = a->set_line;
2287 line_no = a->get_line;
2291 s = g_strdup(a->name);
2293 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2295 the_type_lower = g_strdup (a->gtktype);
2296 g_strdown (the_type_lower);
2301 if (a->atype != NULL)
2302 cast = get_type (a->atype, TRUE);
2304 cast = g_strdup (get_cast (a->gtktype, FALSE));
2306 out_printf (out, "\t%s ARG = (%s) g_value_get_%s (VAL);\n",
2307 cast, cast, the_type_lower);
2310 } else if ( ! is_set) {
2313 if (a->atype != NULL)
2314 cast = get_type (a->atype, TRUE);
2316 cast = g_strdup (get_cast (a->gtktype, FALSE));
2317 out_printf (out, "\t%s ARG;\n"
2318 "\tmemset (&ARG, 0, sizeof (%s));\n",
2324 out_printf(out, "\t\t{\n");
2326 out_addline_infile (out, line_no);
2327 out_printf (out, "%s\n", cbuf);
2329 out_addline_outfile (out);
2330 out_printf (out, "\t\t}\n");
2332 if (strcmp (a->gtktype, "OBJECT") == 0)
2333 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2336 out_printf (out, "\t\t"
2337 "g_value_set_%s (VAL, ARG);\n",
2340 g_free (the_type_lower);
2343 out_printf (out, "\t\tif (&ARG) ;\n");
2346 out_printf (out, "\t\tbreak;\n");
2348 out_printf (out, "\t}\n");
2352 add_property (Property *p, gboolean is_set)
2355 char *the_type_lower;
2361 line_no = p->set_line;
2364 line_no = p->get_line;
2369 name_upper = g_strdup (p->name);
2370 g_strup (name_upper);
2371 the_type_lower = g_strdup (p->gtktype);
2372 g_strdown (the_type_lower);
2374 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2376 out_printf(out, "\t\t{\n");
2378 out_addline_infile (out, line_no);
2379 out_printf (out, "%s\n", cbuf);
2381 out_addline_outfile (out);
2382 out_printf (out, "\t\t}\n");
2384 g_free (name_upper);
2385 g_free (the_type_lower);
2387 out_printf (out, "\t\tbreak;\n");
2391 add_getset_arg(Class *c, gboolean is_set)
2394 out_printf(out, "\nstatic void\n"
2395 "___object_%s_property (GObject *object,\n"
2396 "\tguint property_id,\n"
2397 "\t%sGValue *VAL,\n"
2398 "\tGParamSpec *pspec)\n"
2399 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2402 "\tself = %s (object);\n\n"
2403 "\tswitch (property_id) {\n",
2404 is_set ? "set" : "get",
2405 is_set ? "const " : "",
2406 c->otype, is_set ? "set" : "get",
2407 typebase, macrobase);
2409 for (li = c->nodes; li != NULL; li = li->next) {
2411 if (n->type == PROPERTY_NODE)
2412 add_property ((Property *)n, is_set);
2413 else if (n->type == ARGUMENT_NODE)
2414 add_argument ((Argument *)n, is_set);
2416 out_printf (out, "\tdefault:\n"
2417 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2418 "#ifndef __PRETTY_FUNCTION__\n"
2419 "# undef G_STRLOC\n"
2420 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2422 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2424 "\treturn;\n\tself = NULL;\n\tVAL = NULL;\n\tpspec = NULL;\n}\n"
2425 "#undef __GOB_FUNCTION__\n");
2429 print_checks (Method *m, FuncArg *fa)
2433 gboolean checked_null = FALSE;
2434 is_void = (strcmp(m->mtype->name, "void")==0 &&
2435 m->mtype->pointer == NULL);
2437 for(li = fa->checks; li != NULL; li = li->next) {
2438 Check *ch = li->data;
2440 /* point to the method prot in .gob for failed checks */
2442 out_addline_infile(out, m->line_no);
2444 out_printf(out, "\tg_return_if_fail (");
2446 out_printf(out, "\tg_return_val_if_fail (");
2447 switch(ch->chtype) {
2449 out_printf(out, "%s != NULL", fa->name);
2450 checked_null = TRUE;
2453 s = make_pre_macro(fa->atype->name, "IS");
2455 out_printf(out, "%s (%s)", s, fa->name);
2457 /* if not check null, null may be valid */
2458 out_printf(out, "!(%s) || %s (%s)", fa->name,
2463 out_printf(out, "%s < %s", fa->name, ch->number);
2466 out_printf(out, "%s > %s", fa->name, ch->number);
2469 out_printf(out, "%s <= %s", fa->name, ch->number);
2472 out_printf(out, "%s >= %s", fa->name, ch->number);
2475 out_printf(out, "%s == %s", fa->name, ch->number);
2478 out_printf(out, "%s != %s", fa->name, ch->number);
2482 out_printf(out, ");\n");
2484 out_printf(out, ", (");
2485 print_type(out, m->mtype, TRUE);
2486 out_printf(out, ")%s);\n",
2487 m->onerror?m->onerror:"0");
2493 print_preconditions(Method *m)
2497 for(li=m->args;li;li=g_list_next(li)) {
2498 FuncArg *fa = li->data;
2500 print_checks(m, fa);
2503 out_addline_outfile(out);
2507 print_method_body(Method *m, int pre)
2510 out_addline_outfile(out);
2511 out_printf(out, "{\n"
2512 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2513 ((Class *)class)->otype,
2516 print_preconditions(m);
2518 /* Note: the trailing }'s are on one line, this is so
2519 that we get the no return warning correctly and point to
2520 the correct line in the .gob file, yes this is slightly
2521 ugly in the .c file, but that is not supposed to be
2522 human readable anyway. */
2524 out_printf(out, "{\n");
2526 out_addline_infile(out, m->ccode_line);
2527 out_printf(out, "\t%s}", m->cbuf);
2530 /* Note, there is no \n between the last } and this } so that
2531 * errors/warnings reported on the end of the body get pointed to the
2532 * right line in the .gob source */
2533 out_printf(out, "}\n");
2536 out_addline_outfile(out);
2537 out_printf(out, "#undef __GOB_FUNCTION__\n");
2541 put_signal_args (Method *m)
2547 if (m->args->next == NULL)
2550 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2551 li != NULL && ali != NULL;
2552 li = li->next, ali = ali->next, i++) {
2553 FuncArg *fa = li->data;
2554 char *cast = g_strdup (get_cast (ali->data, FALSE));
2555 /* FIXME: This code is so fucking ugly it hurts */
2556 gboolean do_static =
2557 (strcmp ((char *)ali->data, "STRING") == 0 ||
2558 strcmp ((char *)ali->data, "BOXED") == 0);
2562 cast = get_type (fa->atype, TRUE);
2564 /* we should have already proved before that
2565 the we know all the types */
2566 g_assert (cast != NULL);
2569 "\t___param_values[%d].g_type = 0;\n"
2570 "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
2571 i, i, (char *)ali->data);
2573 set_func = g_strdup_printf ("g_value_set%s_%s",
2574 do_static ? "_static" : "",
2576 g_strdown (set_func);
2578 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2579 set_func, i, cast, fa->name);
2587 get_arg_names_for_macro(Method *m)
2591 GString *gs = g_string_new(NULL);
2593 for(li=m->args;li;li=g_list_next(li)) {
2594 FuncArg *arg = li->data;
2595 g_string_sprintfa(gs, "%s___%s", p, arg->name);
2599 g_string_free(gs, FALSE);
2604 put_method(Method *m)
2606 char *s, *args, *doc;
2608 is_void = (strcmp(m->mtype->name, "void")==0 &&
2609 m->mtype->pointer == NULL);
2610 out_printf(out, "\n");
2611 if(m->method != OVERRIDE_METHOD) {
2612 doc = get_gtk_doc(m->id);
2614 out_printf(out, "%s", doc);
2619 case REGULAR_METHOD:
2621 out_addline_infile(out, m->line_no);
2622 if(m->scope == PRIVATE_SCOPE)
2623 print_method(out, "static ", "\n", "", " ", "", "\n",
2624 m, FALSE, FALSE, TRUE);
2625 else /* PUBLIC, PROTECTED */
2626 print_method(out, "", "\n", "", " ", "", "\n",
2627 m, FALSE, FALSE, TRUE);
2628 print_method_body(m, TRUE);
2629 /* the outfile line was added above */
2631 case SIGNAL_FIRST_METHOD:
2632 case SIGNAL_LAST_METHOD:
2634 out_addline_infile(out, m->line_no);
2635 if(m->scope == PRIVATE_SCOPE)
2636 print_method(out, "static ", "\n", "", " ", "", "\n",
2637 m, FALSE, FALSE, TRUE);
2638 else /* PUBLIC, PROTECTED */
2639 print_method(out, "", "\n", "", " ", "", "\n",
2640 m, FALSE, FALSE, TRUE);
2641 out_addline_outfile (out);
2643 out_printf (out, "{\n");
2646 "\tGValue ___param_values[%d];\n"
2647 "\tGValue ___return_val = {0};\n\n",
2648 g_list_length (m->args));
2650 print_preconditions (m);
2653 "\n\t___param_values[0].g_type = 0;\n"
2654 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2655 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2656 ((FuncArg *)m->args->data)->name,
2657 ((FuncArg *)m->args->data)->name);
2659 put_signal_args (m);
2661 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2662 const char *defret = NULL;
2664 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2665 (char *)m->gtktypes->data);
2667 if (m->defreturn != NULL)
2668 defret = m->defreturn;
2669 else if (m->onerror != NULL)
2670 defret = m->onerror;
2672 if (defret != NULL) {
2674 /* FIXME: This code is so fucking ugly it hurts */
2675 gboolean do_static =
2676 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2677 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2678 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2680 cast = get_type (m->mtype, TRUE);
2682 set_func = g_strdup_printf ("g_value_set%s_%s",
2683 do_static ? "_static" : "",
2684 (char *)m->gtktypes->data);
2685 g_strdown (set_func);
2687 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2688 set_func, cast, defret);
2693 out_printf (out, "\n");
2696 s = g_strdup (m->id);
2699 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2700 "\t\tobject_signals[%s_SIGNAL],\n"
2701 "\t\t0 /* detail */,\n"
2702 "\t\t&___return_val);\n", s);
2706 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2707 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2708 char *getfunc = g_strdup_printf ("g_value_get_%s",
2709 (char *)m->gtktypes->data);
2710 g_strdown (getfunc);
2713 cast = get_type (m->mtype, TRUE);
2715 out_printf (out, "\n\treturn (%s) %s (&___return_val);\n",
2721 out_printf(out, "}\n");
2726 out_addline_infile(out, m->line_no);
2727 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2728 m, FALSE, FALSE, TRUE);
2729 print_method_body(m, FALSE);
2730 /* the outfile line was added above */
2732 case VIRTUAL_METHOD:
2734 out_addline_infile(out, m->line_no);
2735 if(m->scope==PRIVATE_SCOPE)
2736 print_method(out, "static ", "\n", "", " ", "", "\n",
2737 m, FALSE, FALSE, TRUE);
2738 else /* PUBLIC, PROTECTED */
2739 print_method(out, "", "\n", "", " ", "", "\n",
2740 m, FALSE, FALSE, TRUE);
2741 out_addline_outfile(out);
2742 out_printf(out, "{\n"
2743 "\t%sClass *klass;\n", typebase);
2744 print_preconditions(m);
2745 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2746 "\tif(klass->%s)\n",
2747 macrobase, ((FuncArg *)m->args->data)->name,
2749 if(strcmp(m->mtype->name, "void") == 0 &&
2750 m->mtype->pointer == NULL) {
2752 out_printf(out, "\t\t(*klass->%s)(%s",
2754 ((FuncArg *)m->args->data)->name);
2755 for(li=m->args->next;li;li=g_list_next(li)) {
2756 FuncArg *fa = li->data;
2757 out_printf(out, ",%s", fa->name);
2759 out_printf(out, ");\n}\n");
2762 out_printf(out, "\t\treturn (*klass->%s)(%s",
2764 ((FuncArg *)m->args->data)->name);
2765 for(li=m->args->next;li;li=g_list_next(li)) {
2766 FuncArg *fa = li->data;
2767 out_printf(out, ",%s", fa->name);
2769 out_printf(out, ");\n"
2772 print_type(out, m->mtype, TRUE);
2774 out_printf(out, ")(%s);\n}\n", m->defreturn);
2776 out_printf(out, ")(%s);\n}\n", m->onerror);
2778 out_printf(out, ")(0);\n}\n");
2784 out_addline_infile(out, m->line_no);
2785 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2786 m, FALSE, FALSE, TRUE);
2787 print_method_body(m, FALSE);
2788 /* the outfile line was added above */
2790 case OVERRIDE_METHOD:
2794 out_addline_infile(out, m->line_no);
2795 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2796 print_method(out, "static ", s, "", " ", "", "\n",
2797 m, FALSE, FALSE, FALSE);
2799 out_addline_outfile(out);
2800 s = replace_sep(m->otype, '_');
2802 args = get_arg_names_for_macro(m);
2804 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2805 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2806 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2807 args, s, m->id, s, m->id, args);
2809 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2810 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2811 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2813 args, s, m->id, s, m->id, args);
2814 out_printf(out, "(");
2815 print_type(out, m->mtype, TRUE);
2816 out_printf(out, ")%s))\n",
2817 m->onerror?m->onerror:"0");
2821 print_method_body(m, TRUE);
2822 /* the outfile line was added above */
2823 out_printf(out, "#undef PARENT_HANDLER\n");
2833 char *outfile, *outfileh, *outfileph;
2836 outfile = g_strconcat (filebase, ".c", NULL);
2838 outfile = g_strconcat (filebase, ".cc", NULL);
2839 if (no_touch_headers)
2840 outfileh = g_strconcat ("#gob#", filebase, ".h#gob#", NULL);
2842 outfileh = g_strconcat (filebase, ".h", NULL);
2844 if ((privates > 0 || protecteds > 0 ||
2845 private_header == PRIVATE_HEADER_ALWAYS) &&
2846 private_header != PRIVATE_HEADER_NEVER)
2847 outfileph = g_strconcat (filebase, "-private.h", NULL);
2853 devnull = fopen ("/dev/null", "w");
2854 if (devnull == NULL)
2855 g_error ("Cannot open null device");
2858 if (outfileph != NULL)
2861 out = fopen (outfile, "w");
2863 g_error ("Cannot open outfile: %s", outfile);
2865 outh = fopen (outfileh, "w");
2867 g_error ("Cannot open outfile: %s", outfileh);
2868 if (outfileph != NULL) {
2869 outph = fopen (outfileph, "w");
2871 g_error ("Cannot open outfile: %s", outfileh);
2877 put_argument_nongnu_wrappers (Class *c)
2881 if (get_properties < 0 && set_properties < 0)
2884 for (li = c->nodes; li != NULL; li = li->next) {
2886 const char *name, *gtktype;
2892 if (n->type == ARGUMENT_NODE) {
2893 Argument *a = (Argument *)n;
2895 gtktype = a->gtktype;
2897 get = a->get != NULL;
2898 set = a->set != NULL;
2899 } else if (n->type == PROPERTY_NODE) {
2900 Property *p = (Property *)n;
2902 gtktype = p->gtktype;
2904 get = p->get != NULL;
2905 set = p->set != NULL;
2910 aname = g_strdup (name);
2914 cast = get_type (atype, TRUE);
2916 cast = g_strdup (get_cast (gtktype, TRUE));
2920 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2921 "\"%s\",(%s)(arg)\n",
2922 macrobase, aname, name, cast);
2924 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2925 "\"%s\",(%s*)(arg)\n",
2926 macrobase, aname, name, cast);
2929 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2931 macrobase, aname, name);
2933 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2935 macrobase, aname, name);
2943 put_argument_gnu_wrappers(Class *c)
2947 if(get_properties < 0 && set_properties < 0)
2950 for (li = c->nodes; li != NULL; li = li->next) {
2952 const char *name, *gtktype;
2958 if (n->type == ARGUMENT_NODE) {
2959 Argument *a = (Argument *)n;
2961 gtktype = a->gtktype;
2963 get = a->get != NULL;
2964 set = a->set != NULL;
2965 } else if (n->type == PROPERTY_NODE) {
2966 Property *p = (Property *)n;
2968 gtktype = p->gtktype;
2970 get = p->get != NULL;
2971 set = p->set != NULL;
2976 aname = g_strdup (name);
2980 cast = get_type (atype, TRUE);
2982 cast = g_strdup (get_cast (gtktype, TRUE));
2986 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2987 "\"%s\",({%sz = (arg); z;})\n",
2988 macrobase, aname, name, cast);
2990 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2991 "\"%s\",({%s*z = (arg); z;})\n",
2992 macrobase, aname, name, cast);
2995 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2997 macrobase, aname, name);
2999 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3001 macrobase, aname, name);
3009 print_ccode_block(CCode *cc)
3012 switch(cc->cctype) {
3014 /* HT code is printed exactly like normal header
3015 code but is printed before */
3018 out_printf(fp, "\n");
3021 /* AT code is printed exactly like normal 'all'
3022 code but is printed before */
3025 out_printf(outph, "\n");
3026 out_printf(outph, "%s\n", cc->cbuf);
3027 out_addline_infile(outph, cc->line_no);
3028 out_addline_outfile(outph);
3030 out_printf(outh, "\n");
3031 out_printf(outh, "%s\n", cc->cbuf);
3033 out_printf(fp, "\n");
3034 out_addline_infile(fp, cc->line_no);
3039 out_printf(fp, "\n");
3040 out_addline_infile(fp, cc->line_no);
3047 out_printf(fp, "\n");
3048 out_addline_infile(fp, cc->line_no);
3051 out_printf(fp, "%s\n", cc->cbuf);
3052 if(cc->cctype == C_CCODE ||
3053 cc->cctype == A_CCODE ||
3054 cc->cctype == AT_CCODE ||
3055 cc->cctype == PH_CCODE)
3056 out_addline_outfile(fp);
3060 print_class_block(Class *c)
3064 gboolean printed_private = FALSE;
3067 out_printf(out, "/* utility types we may need */\n");
3068 if(special_array[SPECIAL_2POINTER])
3069 out_printf(out, "typedef struct { "
3070 "gpointer a; gpointer b; "
3071 "} ___twopointertype;\n");
3072 if(special_array[SPECIAL_3POINTER])
3073 out_printf(out, "typedef struct { "
3074 "gpointer a; gpointer b; "
3076 "} ___threepointertype;\n");
3077 if(special_array[SPECIAL_INT_POINTER])
3078 out_printf(out, "typedef struct { "
3079 "gint a; gpointer b; "
3080 "} ___intpointertype;\n");
3081 out_printf(out, "\n");
3084 out_printf(outh, "\n/*\n"
3085 " * Type checking and casting macros\n"
3087 out_printf(outh, "#define %s\t"
3088 "(%s_get_type())\n",
3089 macrotype, funcbase);
3090 out_printf(outh, "#define %s(obj)\t"
3091 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3092 macrobase, funcbase, typebase);
3093 out_printf(outh, "#define %s_CONST(obj)\t"
3094 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3095 macrobase, funcbase, typebase);
3096 out_printf(outh, "#define %s_CLASS(klass)\t"
3097 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3098 macrobase, funcbase, typebase);
3099 out_printf(outh, "#define %s(obj)\t"
3100 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3103 "#define %s_GET_CLASS(obj)\t"
3104 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3105 macrobase, funcbase, typebase);
3107 if ( ! no_self_alias) {
3108 out_printf(out, "/* self casting macros */\n");
3109 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3110 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3111 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3112 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3113 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3115 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3118 out_printf(out, "/* self typedefs */\n");
3119 out_printf(out, "typedef %s Self;\n", typebase);
3120 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3124 always_private_struct) {
3125 out_printf (outh, "\n/* Private structure type */\n");
3126 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3127 typebase, typebase);
3129 out_printf (outh, "/* There are no privates, this "
3130 "structure is thus never defined */\n");
3133 out_printf (outh, "\n/*\n"
3134 " * Main object structure\n"
3136 s = replace_sep (c->otype, '_');
3138 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3139 "#define __TYPEDEF_%s__\n", s, s);
3141 out_printf (outh, "typedef struct _%s %s;\n"
3142 "#endif\n", typebase, typebase);
3143 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3144 typebase, ptypebase);
3145 for (li = c->nodes; li; li=li->next) {
3146 static gboolean printed_public = FALSE;
3148 Variable *v = (Variable *)n;
3149 if(n->type == VARIABLE_NODE &&
3150 v->scope == PUBLIC_SCOPE) {
3151 if( ! printed_public) {
3152 out_printf(outh, "\t/*< public >*/\n");
3153 printed_public = TRUE;
3155 put_variable((Variable *)n, outh);
3158 /* put protecteds always AFTER publics */
3159 for (li = c->nodes; li != NULL; li = li->next) {
3161 Variable *v = (Variable *)n;
3162 if (n->type == VARIABLE_NODE &&
3163 v->scope == PROTECTED_SCOPE) {
3164 if ( ! printed_private) {
3165 out_printf (outh, "\t/*< private >*/\n");
3166 printed_private = TRUE;
3168 put_variable ((Variable *)n, outh);
3172 always_private_struct) {
3173 if ( ! printed_private)
3174 out_printf (outh, "\t/*< private >*/\n");
3175 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3177 out_printf (outh, "};\n");
3182 /* if we are to stick this into the private
3183 header, if not stick it directly into the
3190 out_printf (outfp, "struct _%sPrivate {\n",
3192 for(li=c->nodes; li; li=li->next) {
3194 Variable *v = (Variable *)n;
3195 if(n->type == VARIABLE_NODE &&
3196 v->scope == PRIVATE_SCOPE) {
3197 out_addline_infile(outfp, v->line_no);
3198 put_variable(v, outfp);
3201 out_addline_outfile(outfp);
3202 out_printf(outfp, "};\n");
3205 out_printf(outh, "\n/*\n"
3206 " * Class definition\n"
3208 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3209 typebase, typebase);
3211 "struct _%sClass {\n\t%sClass __parent__;\n",
3212 typebase, ptypebase);
3213 for(li = c->nodes; li != NULL; li = li->next) {
3215 if(n->type == METHOD_NODE)
3216 put_vs_method((Method *)n);
3218 /* If BonoboX type class put down the epv */
3219 if (c->bonobo_object_class != NULL) {
3221 "\t/* Bonobo object epv */\n"
3222 "\tPOA_%s__epv _epv;\n",
3223 c->bonobo_object_class);
3225 /* put class scope variables */
3226 for (li = c->nodes; li != NULL; li = li->next) {
3228 Variable *v = (Variable *)n;
3229 if (n->type == VARIABLE_NODE &&
3230 v->scope == CLASS_SCOPE)
3231 put_variable ((Variable *)n, outh);
3233 out_printf (outh, "};\n\n");
3235 out_printf (out, "/* here are local prototypes */\n");
3236 if (set_properties > 0) {
3237 out_printf (out, "static void ___object_set_property "
3238 "(GObject *object, guint property_id, "
3239 "const GValue *value, GParamSpec *pspec);\n");
3241 if (get_properties > 0) {
3242 out_printf (out, "static void ___object_get_property "
3243 "(GObject *object, guint property_id, "
3244 "GValue *value, GParamSpec *pspec);\n");
3247 out_printf (outh, "\n/*\n"
3248 " * Public methods\n"
3251 if ( ! overrode_get_type) {
3252 out_printf (outh, "GType\t%s_get_type\t(void)", funcbase);
3254 out_printf (outh, " G_GNUC_CONST;\n");
3256 out_printf (outh, ";\n");
3260 for(li = c->nodes; li != NULL; li = li->next) {
3262 if(n->type == METHOD_NODE) {
3263 put_pub_method((Method *)n);
3264 put_prot_method((Method *)n);
3265 put_priv_method_prot((Method *)n);
3269 /* this idea is less and less apealing to me */
3271 out_printf (outh, "\n/*\n"
3272 " * Signal connection wrapper macros\n"
3275 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3276 put_signal_macros (c, TRUE);
3277 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3278 put_signal_macros (c, FALSE);
3279 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3281 put_signal_macros (c, FALSE);
3282 out_printf(outh, "\n");
3285 out_printf (out, "\n/*\n"
3286 " * Signal connection wrapper macro shortcuts\n"
3288 put_local_signal_macros (c);
3289 out_printf(outh, "\n");
3292 /* argument wrapping macros */
3293 if(get_properties > 0 || set_properties > 0) {
3294 out_printf(outh, "\n/*\n"
3295 " * Argument wrapping macros\n"
3298 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3299 put_argument_gnu_wrappers(c);
3300 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3301 put_argument_nongnu_wrappers(c);
3302 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3304 put_argument_nongnu_wrappers(c);
3309 for(li = c->nodes; li != NULL; li = li->next) {
3311 if(n->type == METHOD_NODE)
3312 add_signal_prots((Method *)n);
3318 if(any_method_to_alias(c)) {
3320 out_printf(out, "/* Short form macros */\n");
3321 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3322 make_method_gnu_aliases(c);
3323 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3325 make_method_nongnu_aliases(c);
3328 add_interface_inits (c);
3330 if ( ! overrode_get_type) {
3331 if (c->bonobo_object_class != NULL)
3332 add_bonobo_object_get_type ();
3337 out_printf (out, "/* a macro for creating a new object of our type */\n");
3339 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3340 typebase, funcbase);
3342 out_printf (out, "/* a function for creating a new object of our type */\n");
3343 out_printf (out, "#include <stdarg.h>\n");
3345 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3346 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3347 "{\n\t%s *ret;\n\tva_list ap;\n"
3348 "\tva_start (ap, first);\n"
3349 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3352 "\treturn ret;\n}\n\n",
3354 no_gnu ? "" : " G_GNUC_UNUSED",
3355 typebase, typebase, typebase, funcbase);
3365 if(set_properties > 0) {
3366 add_getset_arg(c, TRUE);
3369 if(get_properties > 0) {
3370 add_getset_arg(c, FALSE);
3373 for(li = c->nodes; li != NULL; li = li->next) {
3375 if(n->type == METHOD_NODE)
3376 put_method((Method *)n);
3379 add_bad_hack_to_avoid_unused_warnings(c);
3383 print_useful_macros(void)
3385 int major = 0, minor = 0, pl = 0;
3388 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3389 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3390 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3391 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3393 /* Useful priv macro thingie */
3394 /* FIXME: this should be done the same way that priv is, as a var,
3396 out_printf (out, "#define selfp (self->_priv)\n\n");
3400 print_file_comments(void)
3404 out_printf(outh, "/* Generated by GOB (v%s)"
3405 " (do not edit directly) */\n\n", VERSION);
3407 out_printf(outph, "/* Generated by GOB (v%s)"
3408 " (do not edit directly) */\n\n", VERSION);
3409 out_printf(out, "/* Generated by GOB (v%s) on %s"
3410 " (do not edit directly) */\n\n",
3411 VERSION, ctime(&curtime));
3413 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3417 print_includes(void)
3419 gboolean found_header;
3422 /* We may need string.h for memset */
3423 if(destructors > 0 &&
3424 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3425 out_printf(out, "#include <string.h> /* memset() */\n\n");
3428 p = g_strconcat(filebase, ".h", NULL);
3429 found_header = TRUE;
3430 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3431 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3432 found_header = FALSE;
3436 /* if we are creating a private header see if it was included */
3438 p = g_strconcat(filebase, "-private.h", NULL);
3439 if( ! g_list_find_custom(include_files, p,
3440 (GCompareFunc)strcmp)) {
3441 out_printf(out, "#include \"%s-private.h\"\n\n",
3444 error_printf(GOB_WARN, 0,
3445 "Implicit private header include "
3447 "\tsource file, while public "
3448 "header is at a custom location, "
3450 "\texplicitly include "
3451 "the private header below the "
3459 print_header_prefixes(void)
3463 p = replace_sep(((Class *)class)->otype, '_');
3465 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3467 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3468 "#define __%s_PRIVATE_H__\n\n"
3469 "#include \"%s.h\"\n\n", p, p, filebase);
3472 if( ! no_extern_c) {
3473 out_printf(outh, "#ifdef __cplusplus\n"
3475 "#endif /* __cplusplus */\n\n");
3477 out_printf(outph, "#ifdef __cplusplus\n"
3479 "#endif /* __cplusplus */\n\n");
3484 print_header_postfixes(void)
3487 out_printf(outh, "\n#ifdef __cplusplus\n"
3489 "#endif /* __cplusplus */\n");
3490 out_printf(outh, "\n#endif\n");
3493 out_printf(outph, "\n#ifdef __cplusplus\n"
3495 "#endif /* __cplusplus */\n");
3496 out_printf(outph, "\n#endif\n");
3505 /* print the AT_CCODE blocks */
3506 for(li = nodes; li != NULL; li = li->next) {
3507 Node *node = li->data;
3508 if(node->type == CCODE_NODE) {
3509 CCode *cc = (CCode *)node;
3510 if(cc->cctype == AT_CCODE)
3511 print_ccode_block((CCode *)node);
3517 print_header_top(void)
3521 /* mandatory includes */
3522 out_printf (outh, "#include <glib.h>\n");
3523 out_printf (outh, "#include <glib-object.h>\n");
3525 /* print the HT_CCODE blocks */
3526 for (li = nodes; li != NULL; li = li->next) {
3527 Node *node = li->data;
3528 if (node->type == CCODE_NODE) {
3529 CCode *cc = (CCode *)node;
3530 if (cc->cctype == HT_CCODE)
3531 print_ccode_block ((CCode *)node);
3537 print_enum (EnumDef *enode)
3544 funcprefix = replace_sep (enode->etype, '_');
3545 g_strdown (funcprefix);
3546 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3548 type = remove_sep (enode->etype);
3550 out_printf (outh, "\ntypedef enum {\n");
3552 for (li = enode->values; li != NULL; li = li->next) {
3553 EnumValue *value = li->data;
3555 char *sname = g_strdown (g_strdup (value->name));
3557 while ((p = strchr (sname, '_')) != NULL)
3560 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3561 if (value->value != NULL)
3562 out_printf (outh, " = %s", value->value);
3563 if (li->next != NULL)
3564 out_printf (outh, ",\n");
3566 out_printf (outh, "\n");
3568 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3569 enode->prefix, value->name,
3570 enode->prefix, value->name,
3576 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3578 out_printf (outh, "} %s;\n", type);
3580 str = make_pre_macro (enode->etype, "TYPE");
3581 out_printf (outh, "#define %s ", str);
3584 out_printf (outh, "%s_get_type()\n", funcprefix);
3585 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3588 "GType\n%s_get_type (void)\n"
3590 "\tstatic GType type = 0;\n"
3591 "\tif (type == 0)\n"
3592 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3595 funcprefix, type, funcprefix);
3597 g_free (funcprefix);
3602 print_flags (Flags *fnode)
3610 funcprefix = replace_sep (fnode->ftype, '_');
3611 g_strdown (funcprefix);
3612 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3614 type = remove_sep (fnode->ftype);
3616 out_printf (outh, "\ntypedef enum {\n");
3618 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3619 const char *name = li->data;
3621 char *sname = g_strdown (g_strdup (name));
3623 while ((p = strchr (sname, '_')) != NULL)
3626 out_printf (outh, "\t%s_%s = 1<<%d",
3627 fnode->prefix, name, i);
3628 if (li->next != NULL)
3629 out_printf (outh, ",\n");
3631 out_printf (outh, "\n");
3633 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3634 fnode->prefix, name,
3635 fnode->prefix, name,
3641 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3643 out_printf (outh, "} %s;\n", type);
3645 str = make_pre_macro (fnode->ftype, "TYPE");
3646 out_printf (outh, "#define %s ", str);
3649 out_printf (outh, "%s_get_type()\n", funcprefix);
3650 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3653 "GType\n%s_get_type (void)\n"
3655 "\tstatic GType type = 0;\n"
3656 "\tif (type == 0)\n"
3657 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3660 funcprefix, type, funcprefix);
3662 g_free (funcprefix);
3667 print_error (Error *enode)
3674 funcprefix = replace_sep (enode->etype, '_');
3675 g_strdown (funcprefix);
3676 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3678 type = remove_sep (enode->etype);
3680 out_printf (outh, "\ntypedef enum {\n");
3682 for (li = enode->values; li != NULL; li = li->next) {
3683 const char *name = li->data;
3685 char *sname = g_strdown (g_strdup (name));
3687 while ((p = strchr (sname, '_')) != NULL)
3690 out_printf (outh, "\t%s_%s", enode->prefix, name);
3691 if (li->next != NULL)
3692 out_printf (outh, ",\n");
3694 out_printf (outh, "\n");
3696 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3697 enode->prefix, name,
3698 enode->prefix, name,
3704 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3706 out_printf (outh, "} %s;\n", type);
3708 str = make_pre_macro (enode->etype, "TYPE");
3709 out_printf (outh, "#define %s ", str);
3712 out_printf (outh, "%s_get_type ()\n", funcprefix);
3713 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3716 "GType\n%s_get_type (void)\n"
3718 "\tstatic GType type = 0;\n"
3719 "\tif (type == 0)\n"
3720 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3723 funcprefix, type, funcprefix);
3725 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3726 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3728 str = replace_sep (enode->etype, '-');
3732 "GQuark\n%s_quark (void)\n"
3734 "\tstatic GQuark q = 0;\n"
3736 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3743 g_free (funcprefix);
3748 generate_outfiles(void)
3752 print_file_comments();
3758 print_header_prefixes();
3760 print_useful_macros();
3764 for (li = nodes; li != NULL; li = li->next) {
3765 Node *node = li->data;
3766 if (node->type == CCODE_NODE) {
3767 CCode *cc = (CCode *)node;
3768 if (cc->cctype != HT_CCODE &&
3769 cc->cctype != AT_CCODE)
3770 print_ccode_block ((CCode *)node);
3771 } else if (node->type == CLASS_NODE) {
3772 print_class_block ((Class *)node);
3773 } else if (node->type == ENUMDEF_NODE) {
3774 print_enum ((EnumDef *)node);
3775 } else if (node->type == FLAGS_NODE) {
3776 print_flags ((Flags *)node);
3777 } else if (node->type == ERROR_NODE) {
3778 print_error ((Error *)node);
3780 g_assert_not_reached();
3784 print_header_postfixes();
3790 fprintf(stderr, "Gob version %s\n\n", VERSION);
3791 fprintf(stderr, "gob [options] file.gob\n\n");
3792 fprintf(stderr, "Options:\n"
3793 "\t--help,-h,-? Display this help\n"
3794 "\t--version Display version\n"
3795 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3796 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3797 "\t--for-cpp Create C++ files\n"
3798 "\t--no-extern-c Never print extern \"C\" into the "
3800 "\t--no-gnu Never use GNU extentions\n"
3801 "\t--no-touch-headers Don't touch headers unless they "
3803 "\t--always-private-header Always create a private header "
3805 "\t even if it would be empty "
3807 "\t--ondemand-private-header Create private header only when "
3809 "\t--no-private-header Don't create a private header, "
3811 "\t structure and protected "
3812 "prototypes inside c file\n"
3813 "\t--always-private-struct Always create a private pointer "
3815 "\t the object structure\n"
3816 "\t--m4 Preprocess source with m4. "
3817 "Following args will\n"
3818 "\t be passed to m4\n"
3819 "\t--m4-dir Print directory that will be "
3822 "\t--no-write,-n Don't write output files, just "
3824 "\t--no-lines Don't print '#line' to output\n"
3825 "\t--no-self-alias Don't create self type and macro "
3827 "\t--no-kill-underscores Ignored for compatibility\n");
3831 parse_options(int argc, char *argv[])
3834 int got_file = FALSE;
3835 int no_opts = FALSE;
3836 int m4_opts = FALSE; /* if we are just passing on args to m4 */
3840 for(i = 1 ; i < argc; i++) {
3842 char *new_commandline;
3843 g_assert(m4_commandline!=NULL);
3845 /* check whether this one looks like the filename */
3846 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
3848 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
3852 /* insert flags before the filename */
3853 new_commandline=g_strconcat(m4_commandline,
3861 /* just an ordinary option */
3863 new_commandline=g_strconcat(m4_commandline,
3868 /* free old commandline */
3869 g_free(m4_commandline);
3870 m4_commandline=new_commandline;
3872 } else if(no_opts ||
3873 argv[i][0] != '-') {
3876 fprintf(stderr, "Specify only one file!\n");
3882 } else if(strcmp(argv[i], "--help")==0) {
3885 } else if(strcmp(argv[i], "--version")==0) {
3886 fprintf(stderr, "Gob version %s\n", VERSION);
3888 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
3889 exit_on_warn = TRUE;
3890 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
3891 exit_on_warn = FALSE;
3892 } else if(strcmp(argv[i], "--for-cpp")==0) {
3894 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
3895 no_touch_headers = TRUE;
3896 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
3897 private_header = PRIVATE_HEADER_ONDEMAND;
3898 } else if(strcmp(argv[i], "--always-private-header")==0) {
3899 private_header = PRIVATE_HEADER_ALWAYS;
3900 } else if(strcmp(argv[i], "--no-private-header")==0) {
3901 private_header = PRIVATE_HEADER_NEVER;
3902 } else if(strcmp(argv[i], "--no-gnu")==0) {
3904 } else if(strcmp(argv[i], "--no-extern-c")==0) {
3906 } else if(strcmp(argv[i], "--no-write")==0) {
3908 } else if(strcmp(argv[i], "--no-lines")==0) {
3910 } else if(strcmp(argv[i], "--no-self-alias")==0) {
3911 no_self_alias = TRUE;
3912 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
3914 } else if(strcmp(argv[i], "--always-private-struct")==0) {
3915 always_private_struct = TRUE;
3916 } else if(strcmp(argv[i], "--m4-dir")==0) {
3917 printf("%s\n",M4_INCLUDE_DIR);
3919 } else if(strcmp(argv[i], "--m4")==0) {
3923 m4_commandline=g_strdup(M4_COMMANDLINE);
3924 } else if(strcmp(argv[i], "--m4-clean")==0) {
3928 m4_commandline=g_strdup(M4_COMMANDLINE);
3929 } else if(strcmp(argv[i], "--")==0) {
3930 /*further arguments are files*/
3932 } else if(strncmp(argv[i], "--", 2)==0) {
3933 /*unknown long option*/
3934 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
3938 /*by now we know we have a string starting with
3939 - which is a short option string*/
3941 for(p = argv[i] + 1; *p; p++) {
3955 "Unknown option '%c'!\n", *p);
3964 /* if we are using m4, and got no filename, append m4 flags now */
3965 if(!got_file && use_m4 && !use_m4_clean) {
3966 char *new_commandline;
3967 new_commandline=g_strconcat(m4_commandline,
3971 g_free(m4_commandline);
3972 m4_commandline=new_commandline;
3977 /* this is a somewhat ugly hack, but it appears to work */
3979 compare_and_move_header(void)
3981 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
3982 char *hf = g_strconcat(filebase, ".h", NULL);
3984 if(stat(hf, &s) == 0) {
3986 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
3987 if(system(s) == 0) {
3988 if(unlink(hfnew) != 0)
3989 error_printf(GOB_ERROR, 0,
3990 "Can't remove new header file");
3998 error_printf(GOB_ERROR, 0,
3999 "Can't remove old header file");
4001 if(rename(hfnew, hf) != 0)
4002 error_printf(GOB_ERROR, 0,
4003 "Can't rename new header file");
4009 main(int argc, char *argv[])
4011 parse_options(argc, argv);
4014 yyin = popen(m4_commandline, "r");
4016 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4020 } else if(filename) {
4021 yyin = fopen(filename, "r");
4023 fprintf(stderr, "Error: can't open file '%s'\n",
4032 /* This is where parsing is done */
4035 g_error("Parsing errors, quitting");
4037 /* close input file */
4038 if(use_m4) pclose(yyin);
4043 error_print(GOB_ERROR, 0, " no class defined");
4046 exit_on_error = FALSE;
4048 signals = count_signals ((Class *)class);
4049 set_properties = count_set_properties ((Class *)class) +
4050 count_set_arguments ((Class *)class);
4051 get_properties = count_get_properties ((Class *)class) +
4052 count_get_arguments ((Class *)class);
4053 overrides = count_overrides ((Class *)class);
4054 privates = count_privates ((Class *)class);
4055 protecteds = count_protecteds ((Class *)class);
4056 unreftors = count_unreftors ((Class *)class);
4057 destructors = count_destructors ((Class *)class);
4058 initializers = count_initializers ((Class *)class);
4059 overrode_get_type = find_get_type ((Class *)class);
4062 make_inits ((Class *)class);
4064 need_shutdown = TRUE;
4065 find_shutdown ((Class *)class);
4067 if (destructors > 0 ||
4069 need_finalize = TRUE;
4070 find_finalize ((Class *)class);
4072 check_bad_symbols ((Class *)class);
4073 check_duplicate_symbols ((Class *)class);
4074 check_duplicate_overrides ((Class *)class);
4075 check_duplicate_signals_args ((Class *)class);
4076 check_public_new ((Class *)class);
4077 check_vararg ((Class *)class);
4078 check_firstarg ((Class *)class);
4079 check_nonvoidempty ((Class *)class);
4080 check_signal_args ((Class *)class);
4081 check_property_types ((Class *)class);
4082 check_argument_types ((Class *)class);
4083 check_func_arg_checks ((Class *)class);
4085 exit_on_error = TRUE;
4090 any_special = setup_special_array ((Class *)class, special_array);
4094 generate_outfiles ();
4105 if (no_touch_headers &&
4107 compare_and_move_header ();