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 ___GOB_UNLIKELY(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 ___GOB_UNLIKELY(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 ___GOB_UNLIKELY(");
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 clear_signal_args (Method *m)
2616 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2618 if (m->args->next == NULL)
2621 for (li = m->args->next, i = 1;
2623 li = li->next, i++) {
2625 "\tg_value_unset (&___param_values[%d]);\n", i);
2630 get_arg_names_for_macro (Method *m)
2634 GString *gs = g_string_new(NULL);
2636 for(li=m->args;li;li=g_list_next(li)) {
2637 FuncArg *arg = li->data;
2638 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2641 return g_string_free (gs, FALSE);
2645 put_method(Method *m)
2647 char *s, *args, *doc;
2649 is_void = (strcmp(m->mtype->name, "void")==0 &&
2650 m->mtype->pointer == NULL);
2651 out_printf(out, "\n");
2652 if(m->method != OVERRIDE_METHOD) {
2653 doc = get_gtk_doc(m->id);
2655 out_printf(out, "%s", doc);
2660 case REGULAR_METHOD:
2662 out_addline_infile(out, m->line_no);
2663 if(m->scope == PRIVATE_SCOPE)
2664 print_method(out, "static ", "\n", "", " ", "", "\n",
2665 m, FALSE, FALSE, TRUE);
2666 else /* PUBLIC, PROTECTED */
2667 print_method(out, "", "\n", "", " ", "", "\n",
2668 m, FALSE, FALSE, TRUE);
2669 print_method_body(m, TRUE);
2670 /* the outfile line was added above */
2672 case SIGNAL_FIRST_METHOD:
2673 case SIGNAL_LAST_METHOD:
2675 out_addline_infile(out, m->line_no);
2676 if(m->scope == PRIVATE_SCOPE)
2677 print_method(out, "static ", "\n", "", " ", "", "\n",
2678 m, FALSE, FALSE, TRUE);
2679 else /* PUBLIC, PROTECTED */
2680 print_method(out, "", "\n", "", " ", "", "\n",
2681 m, FALSE, FALSE, TRUE);
2682 out_addline_outfile (out);
2684 out_printf (out, "{\n");
2687 "\tGValue ___param_values[%d];\n"
2688 "\tGValue ___return_val = {0};\n\n",
2689 g_list_length (m->args));
2691 print_preconditions (m);
2694 "\n\t___param_values[0].g_type = 0;\n"
2695 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2696 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2697 ((FuncArg *)m->args->data)->name,
2698 ((FuncArg *)m->args->data)->name);
2700 put_signal_args (m);
2702 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2703 const char *defret = NULL;
2705 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2706 (char *)m->gtktypes->data);
2708 if (m->defreturn != NULL)
2709 defret = m->defreturn;
2710 else if (m->onerror != NULL)
2711 defret = m->onerror;
2713 if (defret != NULL) {
2715 /* FIXME: This code is so fucking ugly it hurts */
2716 gboolean do_static =
2717 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2718 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2719 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2721 cast = get_type (m->mtype, TRUE);
2723 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2724 /* hack because glib is braindamaged */
2725 set_func = g_strdup ("g_value_set_uint");
2727 set_func = g_strdup_printf ("g_value_set%s_%s",
2728 do_static ? "_static" : "",
2729 (char *)m->gtktypes->data);
2730 g_strdown (set_func);
2732 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2733 set_func, cast, defret);
2738 out_printf (out, "\n");
2741 s = g_strdup (m->id);
2744 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2745 "\t\tobject_signals[%s_SIGNAL],\n"
2746 "\t\t0 /* detail */,\n"
2747 "\t\t&___return_val);\n", s);
2751 clear_signal_args (m);
2753 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2754 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2756 /* Hack because glib is very very braindead */
2758 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2759 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
2760 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
2761 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
2763 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2764 /* hack because glib is braindamaged */
2765 getfunc = g_strdup ("g_value_get_uint");
2767 getfunc = g_strdup_printf ("g_value_%s_%s",
2768 do_dup ? "dup" : "get",
2769 (char *)m->gtktypes->data);
2770 g_strdown (getfunc);
2773 cast = get_type (m->mtype, TRUE);
2778 print_type (out, m->mtype, TRUE);
2780 " ___ret = (%s) %s (&___return_val);\n"
2781 "\t\tg_value_unset (&___return_val);\n"
2782 "\t\treturn ___ret;\n"
2789 out_printf(out, "}\n");
2794 out_addline_infile(out, m->line_no);
2795 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2796 m, FALSE, FALSE, TRUE);
2797 print_method_body(m, FALSE);
2798 /* the outfile line was added above */
2800 case VIRTUAL_METHOD:
2802 out_addline_infile(out, m->line_no);
2803 if(m->scope==PRIVATE_SCOPE)
2804 print_method(out, "static ", "\n", "", " ", "", "\n",
2805 m, FALSE, FALSE, TRUE);
2806 else /* PUBLIC, PROTECTED */
2807 print_method(out, "", "\n", "", " ", "", "\n",
2808 m, FALSE, FALSE, TRUE);
2809 out_addline_outfile(out);
2810 out_printf(out, "{\n"
2811 "\t%sClass *klass;\n", typebase);
2812 print_preconditions(m);
2813 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2814 "\tif(klass->%s)\n",
2815 macrobase, ((FuncArg *)m->args->data)->name,
2817 if(strcmp(m->mtype->name, "void") == 0 &&
2818 m->mtype->pointer == NULL) {
2820 out_printf(out, "\t\t(*klass->%s)(%s",
2822 ((FuncArg *)m->args->data)->name);
2823 for(li=m->args->next;li;li=g_list_next(li)) {
2824 FuncArg *fa = li->data;
2825 out_printf(out, ",%s", fa->name);
2827 out_printf(out, ");\n}\n");
2830 out_printf(out, "\t\treturn (*klass->%s)(%s",
2832 ((FuncArg *)m->args->data)->name);
2833 for(li=m->args->next;li;li=g_list_next(li)) {
2834 FuncArg *fa = li->data;
2835 out_printf(out, ",%s", fa->name);
2837 out_printf(out, ");\n"
2840 print_type(out, m->mtype, TRUE);
2842 out_printf(out, ")(%s);\n}\n", m->defreturn);
2844 out_printf(out, ")(%s);\n}\n", m->onerror);
2846 out_printf(out, ")(0);\n}\n");
2852 out_addline_infile(out, m->line_no);
2853 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2854 m, FALSE, FALSE, TRUE);
2855 print_method_body(m, FALSE);
2856 /* the outfile line was added above */
2858 case OVERRIDE_METHOD:
2862 out_addline_infile(out, m->line_no);
2863 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2864 print_method(out, "static ", s, "", " ", "", "\n",
2865 m, FALSE, FALSE, FALSE);
2867 out_addline_outfile(out);
2868 s = replace_sep(m->otype, '_');
2870 args = get_arg_names_for_macro(m);
2872 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2873 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2874 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2875 args, s, m->id, s, m->id, args);
2877 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2878 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2879 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2881 args, s, m->id, s, m->id, args);
2882 out_printf(out, "(");
2883 print_type(out, m->mtype, TRUE);
2884 out_printf(out, ")%s))\n",
2885 m->onerror?m->onerror:"0");
2889 print_method_body(m, TRUE);
2890 /* the outfile line was added above */
2891 out_printf(out, "#undef PARENT_HANDLER\n");
2901 char *outfile, *outfileh, *outfileph;
2904 outfile = g_strconcat (filebase, ".c", NULL);
2906 outfile = g_strconcat (filebase, ".cc", NULL);
2907 if (no_touch_headers)
2908 outfileh = g_strconcat ("#gob#", filebase, ".h#gob#", NULL);
2910 outfileh = g_strconcat (filebase, ".h", NULL);
2912 if ((privates > 0 || protecteds > 0 ||
2913 private_header == PRIVATE_HEADER_ALWAYS) &&
2914 private_header != PRIVATE_HEADER_NEVER)
2915 outfileph = g_strconcat (filebase, "-private.h", NULL);
2921 devnull = fopen ("/dev/null", "w");
2922 if (devnull == NULL)
2923 g_error ("Cannot open null device");
2926 if (outfileph != NULL)
2929 out = fopen (outfile, "w");
2931 g_error ("Cannot open outfile: %s", outfile);
2933 outh = fopen (outfileh, "w");
2935 g_error ("Cannot open outfile: %s", outfileh);
2936 if (outfileph != NULL) {
2937 outph = fopen (outfileph, "w");
2939 g_error ("Cannot open outfile: %s", outfileh);
2945 put_argument_nongnu_wrappers (Class *c)
2949 if (get_properties < 0 && set_properties < 0)
2952 for (li = c->nodes; li != NULL; li = li->next) {
2954 const char *name, *gtktype;
2960 if (n->type == ARGUMENT_NODE) {
2961 Argument *a = (Argument *)n;
2963 gtktype = a->gtktype;
2965 get = a->get != NULL;
2966 set = a->set != NULL;
2967 } else if (n->type == PROPERTY_NODE) {
2968 Property *p = (Property *)n;
2970 gtktype = p->gtktype;
2972 get = p->get != NULL;
2973 set = p->set != NULL;
2978 aname = g_strdup (name);
2982 cast = get_type (atype, TRUE);
2984 cast = g_strdup (get_cast (gtktype, TRUE));
2988 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2989 "\"%s\",(%s)(arg)\n",
2990 macrobase, aname, name, cast);
2992 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2993 "\"%s\",(%s*)(arg)\n",
2994 macrobase, aname, name, cast);
2997 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2999 macrobase, aname, name);
3001 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3003 macrobase, aname, name);
3011 put_argument_gnu_wrappers(Class *c)
3015 if(get_properties < 0 && set_properties < 0)
3018 for (li = c->nodes; li != NULL; li = li->next) {
3020 const char *name, *gtktype;
3026 if (n->type == ARGUMENT_NODE) {
3027 Argument *a = (Argument *)n;
3029 gtktype = a->gtktype;
3031 get = a->get != NULL;
3032 set = a->set != NULL;
3033 } else if (n->type == PROPERTY_NODE) {
3034 Property *p = (Property *)n;
3036 gtktype = p->gtktype;
3038 get = p->get != NULL;
3039 set = p->set != NULL;
3044 aname = g_strdup (name);
3048 cast = get_type (atype, TRUE);
3050 cast = g_strdup (get_cast (gtktype, TRUE));
3054 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3055 "\"%s\",({%sz = (arg); z;})\n",
3056 macrobase, aname, name, cast);
3058 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3059 "\"%s\",({%s*z = (arg); z;})\n",
3060 macrobase, aname, name, cast);
3063 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3065 macrobase, aname, name);
3067 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3069 macrobase, aname, name);
3077 print_ccode_block(CCode *cc)
3080 switch(cc->cctype) {
3082 /* HT code is printed exactly like normal header
3083 code but is printed before */
3086 out_printf(fp, "\n");
3089 /* AT code is printed exactly like normal 'all'
3090 code but is printed before */
3093 out_printf(outph, "\n");
3094 out_printf(outph, "%s\n", cc->cbuf);
3095 out_addline_infile(outph, cc->line_no);
3096 out_addline_outfile(outph);
3098 out_printf(outh, "\n");
3099 out_printf(outh, "%s\n", cc->cbuf);
3101 out_printf(fp, "\n");
3102 out_addline_infile(fp, cc->line_no);
3107 out_printf(fp, "\n");
3108 out_addline_infile(fp, cc->line_no);
3115 out_printf(fp, "\n");
3116 out_addline_infile(fp, cc->line_no);
3119 out_printf(fp, "%s\n", cc->cbuf);
3120 if(cc->cctype == C_CCODE ||
3121 cc->cctype == A_CCODE ||
3122 cc->cctype == AT_CCODE ||
3123 cc->cctype == PH_CCODE)
3124 out_addline_outfile(fp);
3128 print_class_block(Class *c)
3132 gboolean printed_private = FALSE;
3135 out_printf(out, "/* utility types we may need */\n");
3136 if(special_array[SPECIAL_2POINTER])
3137 out_printf(out, "typedef struct { "
3138 "gpointer a; gpointer b; "
3139 "} ___twopointertype;\n");
3140 if(special_array[SPECIAL_3POINTER])
3141 out_printf(out, "typedef struct { "
3142 "gpointer a; gpointer b; "
3144 "} ___threepointertype;\n");
3145 if(special_array[SPECIAL_INT_POINTER])
3146 out_printf(out, "typedef struct { "
3147 "gint a; gpointer b; "
3148 "} ___intpointertype;\n");
3149 out_printf(out, "\n");
3152 out_printf(outh, "\n/*\n"
3153 " * Type checking and casting macros\n"
3155 out_printf(outh, "#define %s\t"
3156 "(%s_get_type())\n",
3157 macrotype, funcbase);
3158 out_printf(outh, "#define %s(obj)\t"
3159 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3160 macrobase, funcbase, typebase);
3161 out_printf(outh, "#define %s_CONST(obj)\t"
3162 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3163 macrobase, funcbase, typebase);
3164 out_printf(outh, "#define %s_CLASS(klass)\t"
3165 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3166 macrobase, funcbase, typebase);
3167 out_printf(outh, "#define %s(obj)\t"
3168 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3171 "#define %s_GET_CLASS(obj)\t"
3172 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3173 macrobase, funcbase, typebase);
3175 if ( ! no_self_alias) {
3176 out_printf(out, "/* self casting macros */\n");
3177 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3178 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3179 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3180 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3181 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3183 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3186 out_printf(out, "/* self typedefs */\n");
3187 out_printf(out, "typedef %s Self;\n", typebase);
3188 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3192 always_private_struct) {
3193 out_printf (outh, "\n/* Private structure type */\n");
3194 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3195 typebase, typebase);
3197 out_printf (outh, "/* There are no privates, this "
3198 "structure is thus never defined */\n");
3201 out_printf (outh, "\n/*\n"
3202 " * Main object structure\n"
3204 s = replace_sep (c->otype, '_');
3206 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3207 "#define __TYPEDEF_%s__\n", s, s);
3209 out_printf (outh, "typedef struct _%s %s;\n"
3210 "#endif\n", typebase, typebase);
3211 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3212 typebase, ptypebase);
3213 for (li = c->nodes; li; li=li->next) {
3214 static gboolean printed_public = FALSE;
3216 Variable *v = (Variable *)n;
3217 if(n->type == VARIABLE_NODE &&
3218 v->scope == PUBLIC_SCOPE) {
3219 if( ! printed_public) {
3220 out_printf(outh, "\t/*< public >*/\n");
3221 printed_public = TRUE;
3223 put_variable((Variable *)n, outh);
3226 /* put protecteds always AFTER publics */
3227 for (li = c->nodes; li != NULL; li = li->next) {
3229 Variable *v = (Variable *)n;
3230 if (n->type == VARIABLE_NODE &&
3231 v->scope == PROTECTED_SCOPE) {
3232 if ( ! printed_private) {
3233 out_printf (outh, "\t/*< private >*/\n");
3234 printed_private = TRUE;
3236 put_variable ((Variable *)n, outh);
3240 always_private_struct) {
3241 if ( ! printed_private)
3242 out_printf (outh, "\t/*< private >*/\n");
3243 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3245 out_printf (outh, "};\n");
3250 /* if we are to stick this into the private
3251 header, if not stick it directly into the
3258 out_printf (outfp, "struct _%sPrivate {\n",
3260 for(li=c->nodes; li; li=li->next) {
3262 Variable *v = (Variable *)n;
3263 if(n->type == VARIABLE_NODE &&
3264 v->scope == PRIVATE_SCOPE) {
3265 out_addline_infile(outfp, v->line_no);
3266 put_variable(v, outfp);
3269 out_addline_outfile(outfp);
3270 out_printf(outfp, "};\n");
3273 out_printf(outh, "\n/*\n"
3274 " * Class definition\n"
3276 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3277 typebase, typebase);
3279 "struct _%sClass {\n\t%sClass __parent__;\n",
3280 typebase, ptypebase);
3281 for(li = c->nodes; li != NULL; li = li->next) {
3283 if(n->type == METHOD_NODE)
3284 put_vs_method((Method *)n);
3286 /* If BonoboX type class put down the epv */
3287 if (c->bonobo_object_class != NULL) {
3289 "\t/* Bonobo object epv */\n"
3290 "\tPOA_%s__epv _epv;\n",
3291 c->bonobo_object_class);
3293 /* put class scope variables */
3294 for (li = c->nodes; li != NULL; li = li->next) {
3296 Variable *v = (Variable *)n;
3297 if (n->type == VARIABLE_NODE &&
3298 v->scope == CLASS_SCOPE)
3299 put_variable ((Variable *)n, outh);
3301 out_printf (outh, "};\n\n");
3303 out_printf (out, "/* here are local prototypes */\n");
3304 if (set_properties > 0) {
3305 out_printf (out, "static void ___object_set_property "
3306 "(GObject *object, guint property_id, "
3307 "const GValue *value, GParamSpec *pspec);\n");
3309 if (get_properties > 0) {
3310 out_printf (out, "static void ___object_get_property "
3311 "(GObject *object, guint property_id, "
3312 "GValue *value, GParamSpec *pspec);\n");
3315 out_printf (outh, "\n/*\n"
3316 " * Public methods\n"
3319 if ( ! overrode_get_type) {
3320 out_printf (outh, "GType\t%s_get_type\t(void);\n", funcbase);
3323 for(li = c->nodes; li != NULL; li = li->next) {
3325 if(n->type == METHOD_NODE) {
3326 put_pub_method((Method *)n);
3327 put_prot_method((Method *)n);
3328 put_priv_method_prot((Method *)n);
3332 /* this idea is less and less apealing to me */
3334 out_printf (outh, "\n/*\n"
3335 " * Signal connection wrapper macros\n"
3338 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3339 put_signal_macros (c, TRUE);
3340 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3341 put_signal_macros (c, FALSE);
3342 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3344 put_signal_macros (c, FALSE);
3345 out_printf(outh, "\n");
3348 out_printf (out, "\n/*\n"
3349 " * Signal connection wrapper macro shortcuts\n"
3351 put_local_signal_macros (c);
3352 out_printf(outh, "\n");
3355 /* argument wrapping macros */
3356 if(get_properties > 0 || set_properties > 0) {
3357 out_printf(outh, "\n/*\n"
3358 " * Argument wrapping macros\n"
3361 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3362 put_argument_gnu_wrappers(c);
3363 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3364 put_argument_nongnu_wrappers(c);
3365 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3367 put_argument_nongnu_wrappers(c);
3372 for(li = c->nodes; li != NULL; li = li->next) {
3374 if(n->type == METHOD_NODE)
3375 add_signal_prots((Method *)n);
3381 if(any_method_to_alias(c)) {
3383 out_printf(out, "/* Short form macros */\n");
3384 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3385 make_method_gnu_aliases(c);
3386 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3388 make_method_nongnu_aliases(c);
3391 add_interface_inits (c);
3393 if ( ! overrode_get_type) {
3394 if (c->bonobo_object_class != NULL)
3395 add_bonobo_object_get_type ();
3400 out_printf (out, "/* a macro for creating a new object of our type */\n");
3402 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3403 typebase, funcbase);
3405 out_printf (out, "/* a function for creating a new object of our type */\n");
3406 out_printf (out, "#include <stdarg.h>\n");
3408 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3409 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3410 "{\n\t%s *ret;\n\tva_list ap;\n"
3411 "\tva_start (ap, first);\n"
3412 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3415 "\treturn ret;\n}\n\n",
3417 no_gnu ? "" : " G_GNUC_UNUSED",
3418 typebase, typebase, typebase, funcbase);
3428 if(set_properties > 0) {
3429 add_getset_arg(c, TRUE);
3432 if(get_properties > 0) {
3433 add_getset_arg(c, FALSE);
3436 for(li = c->nodes; li != NULL; li = li->next) {
3438 if(n->type == METHOD_NODE)
3439 put_method((Method *)n);
3442 add_bad_hack_to_avoid_unused_warnings(c);
3446 print_useful_macros(void)
3448 int major = 0, minor = 0, pl = 0;
3451 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3452 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3453 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3454 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3456 /* Useful priv macro thingie */
3457 /* FIXME: this should be done the same way that priv is, as a var,
3459 out_printf (out, "#define selfp (self->_priv)\n\n");
3463 print_more_useful_macros (void)
3466 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3467 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3469 out_printf (out, "#ifdef G_LIKELY\n");
3470 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3471 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3472 out_printf (out, "#else /* ! G_LIKELY */\n");
3473 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3474 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3475 out_printf (out, "#endif /* G_LIKELY */\n");
3480 print_file_comments(void)
3484 out_printf(outh, "/* Generated by GOB (v%s)"
3485 " (do not edit directly) */\n\n", VERSION);
3487 out_printf(outph, "/* Generated by GOB (v%s)"
3488 " (do not edit directly) */\n\n", VERSION);
3489 out_printf(out, "/* Generated by GOB (v%s) on %s"
3490 " (do not edit directly) */\n\n",
3491 VERSION, ctime(&curtime));
3493 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3497 print_includes(void)
3499 gboolean found_header;
3502 /* We may need string.h for memset */
3503 if(destructors > 0 &&
3504 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3505 out_printf(out, "#include <string.h> /* memset() */\n\n");
3508 p = g_strconcat(filebase, ".h", NULL);
3509 found_header = TRUE;
3510 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3511 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3512 found_header = FALSE;
3516 /* if we are creating a private header see if it was included */
3518 p = g_strconcat(filebase, "-private.h", NULL);
3519 if( ! g_list_find_custom(include_files, p,
3520 (GCompareFunc)strcmp)) {
3521 out_printf(out, "#include \"%s-private.h\"\n\n",
3524 error_printf(GOB_WARN, 0,
3525 "Implicit private header include "
3527 "\tsource file, while public "
3528 "header is at a custom location, "
3530 "\texplicitly include "
3531 "the private header below the "
3539 print_header_prefixes(void)
3543 p = replace_sep(((Class *)class)->otype, '_');
3545 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3547 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3548 "#define __%s_PRIVATE_H__\n\n"
3549 "#include \"%s.h\"\n\n", p, p, filebase);
3552 if( ! no_extern_c) {
3553 out_printf(outh, "#ifdef __cplusplus\n"
3555 "#endif /* __cplusplus */\n\n");
3557 out_printf(outph, "#ifdef __cplusplus\n"
3559 "#endif /* __cplusplus */\n\n");
3564 print_header_postfixes(void)
3567 out_printf(outh, "\n#ifdef __cplusplus\n"
3569 "#endif /* __cplusplus */\n");
3570 out_printf(outh, "\n#endif\n");
3573 out_printf(outph, "\n#ifdef __cplusplus\n"
3575 "#endif /* __cplusplus */\n");
3576 out_printf(outph, "\n#endif\n");
3585 /* print the AT_CCODE blocks */
3586 for(li = nodes; li != NULL; li = li->next) {
3587 Node *node = li->data;
3588 if(node->type == CCODE_NODE) {
3589 CCode *cc = (CCode *)node;
3590 if(cc->cctype == AT_CCODE)
3591 print_ccode_block((CCode *)node);
3597 print_header_top(void)
3601 /* mandatory includes */
3602 out_printf (outh, "#include <glib.h>\n");
3603 out_printf (outh, "#include <glib-object.h>\n");
3605 /* print the HT_CCODE blocks */
3606 for (li = nodes; li != NULL; li = li->next) {
3607 Node *node = li->data;
3608 if (node->type == CCODE_NODE) {
3609 CCode *cc = (CCode *)node;
3610 if (cc->cctype == HT_CCODE)
3611 print_ccode_block ((CCode *)node);
3617 print_enum (EnumDef *enode)
3624 funcprefix = replace_sep (enode->etype, '_');
3625 g_strdown (funcprefix);
3626 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3628 type = remove_sep (enode->etype);
3630 out_printf (outh, "\ntypedef enum {\n");
3632 for (li = enode->values; li != NULL; li = li->next) {
3633 EnumValue *value = li->data;
3635 char *sname = g_strdown (g_strdup (value->name));
3637 while ((p = strchr (sname, '_')) != NULL)
3640 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3641 if (value->value != NULL)
3642 out_printf (outh, " = %s", value->value);
3643 if (li->next != NULL)
3644 out_printf (outh, ",\n");
3646 out_printf (outh, "\n");
3648 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3649 enode->prefix, value->name,
3650 enode->prefix, value->name,
3656 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3658 out_printf (outh, "} %s;\n", type);
3660 str = make_pre_macro (enode->etype, "TYPE");
3661 out_printf (outh, "#define %s ", str);
3664 out_printf (outh, "%s_get_type()\n", funcprefix);
3665 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3668 "GType\n%s_get_type (void)\n"
3670 "\tstatic GType type = 0;\n"
3671 "\tif ___GOB_UNLIKELY(type == 0)\n"
3672 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3675 funcprefix, type, funcprefix);
3677 g_free (funcprefix);
3682 print_flags (Flags *fnode)
3690 funcprefix = replace_sep (fnode->ftype, '_');
3691 g_strdown (funcprefix);
3692 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3694 type = remove_sep (fnode->ftype);
3696 out_printf (outh, "\ntypedef enum {\n");
3698 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3699 const char *name = li->data;
3701 char *sname = g_strdown (g_strdup (name));
3703 while ((p = strchr (sname, '_')) != NULL)
3706 out_printf (outh, "\t%s_%s = 1<<%d",
3707 fnode->prefix, name, i);
3708 if (li->next != NULL)
3709 out_printf (outh, ",\n");
3711 out_printf (outh, "\n");
3713 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3714 fnode->prefix, name,
3715 fnode->prefix, name,
3721 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3723 out_printf (outh, "} %s;\n", type);
3725 str = make_pre_macro (fnode->ftype, "TYPE");
3726 out_printf (outh, "#define %s ", str);
3729 out_printf (outh, "%s_get_type()\n", funcprefix);
3730 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3733 "GType\n%s_get_type (void)\n"
3735 "\tstatic GType type = 0;\n"
3736 "\tif ___GOB_UNLIKELY(type == 0)\n"
3737 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3740 funcprefix, type, funcprefix);
3742 g_free (funcprefix);
3747 print_error (Error *enode)
3754 funcprefix = replace_sep (enode->etype, '_');
3755 g_strdown (funcprefix);
3756 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3758 type = remove_sep (enode->etype);
3760 out_printf (outh, "\ntypedef enum {\n");
3762 for (li = enode->values; li != NULL; li = li->next) {
3763 const char *name = li->data;
3765 char *sname = g_strdown (g_strdup (name));
3767 while ((p = strchr (sname, '_')) != NULL)
3770 out_printf (outh, "\t%s_%s", enode->prefix, name);
3771 if (li->next != NULL)
3772 out_printf (outh, ",\n");
3774 out_printf (outh, "\n");
3776 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3777 enode->prefix, name,
3778 enode->prefix, name,
3784 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3786 out_printf (outh, "} %s;\n", type);
3788 str = make_pre_macro (enode->etype, "TYPE");
3789 out_printf (outh, "#define %s ", str);
3792 out_printf (outh, "%s_get_type ()\n", funcprefix);
3793 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3796 "GType\n%s_get_type (void)\n"
3798 "\tstatic GType type = 0;\n"
3799 "\tif ___GOB_UNLIKELY(type == 0)\n"
3800 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3803 funcprefix, type, funcprefix);
3805 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3806 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3808 str = replace_sep (enode->etype, '-');
3812 "GQuark\n%s_quark (void)\n"
3814 "\tstatic GQuark q = 0;\n"
3816 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3823 g_free (funcprefix);
3828 generate_outfiles(void)
3832 print_file_comments();
3838 print_header_prefixes();
3840 print_useful_macros();
3844 print_more_useful_macros ();
3846 for (li = nodes; li != NULL; li = li->next) {
3847 Node *node = li->data;
3848 if (node->type == CCODE_NODE) {
3849 CCode *cc = (CCode *)node;
3850 if (cc->cctype != HT_CCODE &&
3851 cc->cctype != AT_CCODE)
3852 print_ccode_block ((CCode *)node);
3853 } else if (node->type == CLASS_NODE) {
3854 print_class_block ((Class *)node);
3855 } else if (node->type == ENUMDEF_NODE) {
3856 print_enum ((EnumDef *)node);
3857 } else if (node->type == FLAGS_NODE) {
3858 print_flags ((Flags *)node);
3859 } else if (node->type == ERROR_NODE) {
3860 print_error ((Error *)node);
3862 g_assert_not_reached();
3866 print_header_postfixes();
3872 fprintf(stderr, "Gob version %s\n\n", VERSION);
3873 fprintf(stderr, "gob [options] file.gob\n\n");
3874 fprintf(stderr, "Options:\n"
3875 "\t--help,-h,-? Display this help\n"
3876 "\t--version Display version\n"
3877 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3878 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3879 "\t--for-cpp Create C++ files\n"
3880 "\t--no-extern-c Never print extern \"C\" into the "
3882 "\t--no-gnu Never use GNU extentions\n"
3883 "\t--no-touch-headers Don't touch headers unless they "
3885 "\t--always-private-header Always create a private header "
3887 "\t even if it would be empty "
3889 "\t--ondemand-private-header Create private header only when "
3891 "\t--no-private-header Don't create a private header, "
3893 "\t structure and protected "
3894 "prototypes inside c file\n"
3895 "\t--always-private-struct Always create a private pointer "
3897 "\t the object structure\n"
3898 "\t--m4 Preprocess source with m4. "
3899 "Following args will\n"
3900 "\t be passed to m4\n"
3901 "\t--m4-dir Print directory that will be "
3904 "\t--no-write,-n Don't write output files, just "
3906 "\t--no-lines Don't print '#line' to output\n"
3907 "\t--no-self-alias Don't create self type and macro "
3909 "\t--no-kill-underscores Ignored for compatibility\n");
3913 parse_options(int argc, char *argv[])
3916 int got_file = FALSE;
3917 int no_opts = FALSE;
3918 int m4_opts = FALSE; /* if we are just passing on args to m4 */
3922 for(i = 1 ; i < argc; i++) {
3924 char *new_commandline;
3925 g_assert(m4_commandline!=NULL);
3927 /* check whether this one looks like the filename */
3928 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
3930 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
3934 /* insert flags before the filename */
3935 new_commandline=g_strconcat(m4_commandline,
3943 /* just an ordinary option */
3945 new_commandline=g_strconcat(m4_commandline,
3950 /* free old commandline */
3951 g_free(m4_commandline);
3952 m4_commandline=new_commandline;
3954 } else if(no_opts ||
3955 argv[i][0] != '-') {
3958 fprintf(stderr, "Specify only one file!\n");
3964 } else if(strcmp(argv[i], "--help")==0) {
3967 } else if(strcmp(argv[i], "--version")==0) {
3968 fprintf(stderr, "Gob version %s\n", VERSION);
3970 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
3971 exit_on_warn = TRUE;
3972 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
3973 exit_on_warn = FALSE;
3974 } else if(strcmp(argv[i], "--for-cpp")==0) {
3976 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
3977 no_touch_headers = TRUE;
3978 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
3979 private_header = PRIVATE_HEADER_ONDEMAND;
3980 } else if(strcmp(argv[i], "--always-private-header")==0) {
3981 private_header = PRIVATE_HEADER_ALWAYS;
3982 } else if(strcmp(argv[i], "--no-private-header")==0) {
3983 private_header = PRIVATE_HEADER_NEVER;
3984 } else if(strcmp(argv[i], "--no-gnu")==0) {
3986 } else if(strcmp(argv[i], "--no-extern-c")==0) {
3988 } else if(strcmp(argv[i], "--no-write")==0) {
3990 } else if(strcmp(argv[i], "--no-lines")==0) {
3992 } else if(strcmp(argv[i], "--no-self-alias")==0) {
3993 no_self_alias = TRUE;
3994 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
3996 } else if(strcmp(argv[i], "--always-private-struct")==0) {
3997 always_private_struct = TRUE;
3998 } else if(strcmp(argv[i], "--m4-dir")==0) {
3999 printf("%s\n",M4_INCLUDE_DIR);
4001 } else if(strcmp(argv[i], "--m4")==0) {
4005 m4_commandline=g_strdup(M4_COMMANDLINE);
4006 } else if(strcmp(argv[i], "--m4-clean")==0) {
4010 m4_commandline=g_strdup(M4_COMMANDLINE);
4011 } else if(strcmp(argv[i], "--")==0) {
4012 /*further arguments are files*/
4014 } else if(strncmp(argv[i], "--", 2)==0) {
4015 /*unknown long option*/
4016 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4020 /*by now we know we have a string starting with
4021 - which is a short option string*/
4023 for(p = argv[i] + 1; *p; p++) {
4037 "Unknown option '%c'!\n", *p);
4046 /* if we are using m4, and got no filename, append m4 flags now */
4047 if(!got_file && use_m4 && !use_m4_clean) {
4048 char *new_commandline;
4049 new_commandline=g_strconcat(m4_commandline,
4053 g_free(m4_commandline);
4054 m4_commandline=new_commandline;
4059 /* this is a somewhat ugly hack, but it appears to work */
4061 compare_and_move_header(void)
4063 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
4064 char *hf = g_strconcat(filebase, ".h", NULL);
4066 if(stat(hf, &s) == 0) {
4068 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
4069 if(system(s) == 0) {
4070 if(unlink(hfnew) != 0)
4071 error_printf(GOB_ERROR, 0,
4072 "Can't remove new header file");
4080 error_printf(GOB_ERROR, 0,
4081 "Can't remove old header file");
4083 if(rename(hfnew, hf) != 0)
4084 error_printf(GOB_ERROR, 0,
4085 "Can't rename new header file");
4091 main(int argc, char *argv[])
4093 parse_options(argc, argv);
4096 yyin = popen(m4_commandline, "r");
4098 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4102 } else if(filename) {
4103 yyin = fopen(filename, "r");
4105 fprintf(stderr, "Error: can't open file '%s'\n",
4114 /* This is where parsing is done */
4117 g_error("Parsing errors, quitting");
4119 /* close input file */
4120 if(use_m4) pclose(yyin);
4125 error_print(GOB_ERROR, 0, " no class defined");
4128 exit_on_error = FALSE;
4130 signals = count_signals ((Class *)class);
4131 set_properties = count_set_properties ((Class *)class) +
4132 count_set_arguments ((Class *)class);
4133 get_properties = count_get_properties ((Class *)class) +
4134 count_get_arguments ((Class *)class);
4135 overrides = count_overrides ((Class *)class);
4136 privates = count_privates ((Class *)class);
4137 protecteds = count_protecteds ((Class *)class);
4138 unreftors = count_unreftors ((Class *)class);
4139 destructors = count_destructors ((Class *)class);
4140 initializers = count_initializers ((Class *)class);
4141 overrode_get_type = find_get_type ((Class *)class);
4144 make_inits ((Class *)class);
4146 need_dispose = TRUE;
4147 find_dispose ((Class *)class);
4149 if (destructors > 0 ||
4151 need_finalize = TRUE;
4152 find_finalize ((Class *)class);
4154 check_bad_symbols ((Class *)class);
4155 check_duplicate_symbols ((Class *)class);
4156 check_duplicate_overrides ((Class *)class);
4157 check_duplicate_signals_args ((Class *)class);
4158 check_public_new ((Class *)class);
4159 check_vararg ((Class *)class);
4160 check_firstarg ((Class *)class);
4161 check_nonvoidempty ((Class *)class);
4162 check_signal_args ((Class *)class);
4163 check_property_types ((Class *)class);
4164 check_argument_types ((Class *)class);
4165 check_func_arg_checks ((Class *)class);
4167 exit_on_error = TRUE;
4172 any_special = setup_special_array ((Class *)class, special_array);
4176 generate_outfiles ();
4187 if (no_touch_headers &&
4189 compare_and_move_header ();