2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2004 George Lebl
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
33 #include "treefuncs.h"
41 char *filename = NULL;
51 extern GList *include_files;
53 extern GHashTable *gtk_doc_hash;
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 gob_strdown (filebase);
125 funcbase = replace_sep (((Class *)class)->otype, '_');
126 gob_strdown (funcbase);
128 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
129 gob_strdown (pfuncbase);
131 macrobase = replace_sep (((Class *)class)->otype, '_');
132 gob_strup (macrobase);
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 gob_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 gob_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, "INT64"))
1542 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1543 "\t\tG_MININT64, G_MAXINT64,\n"
1546 a->name, flags->str);
1547 else if (!strcmp (a->gtktype, "UINT64"))
1548 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1549 "\t\t0, G_MAXUINT64,\n"
1552 a->name, flags->str);
1553 else if (!strcmp (a->gtktype, "FLOAT"))
1554 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1555 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1558 a->name, flags->str);
1559 else if (!strcmp (a->gtktype, "DOUBLE"))
1560 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1561 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1564 a->name, flags->str);
1565 else if (!strcmp (a->gtktype, "POINTER"))
1566 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1568 a->name, flags->str);
1570 error_printf (GOB_ERROR, a->line_no,
1571 "%s type is not supported for arguments, try using properties",
1574 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1575 "\t\tPROP_%s, param_spec);\n", s);
1579 g_string_free(flags, TRUE);
1582 #define value_for_print(str, alt) (str != NULL ? str : alt)
1585 make_me_type (const char *type, const char *alt)
1588 return g_strdup (alt);
1589 /* HACK! just in case someone made this
1590 * work with 2.0.0 by using the TYPE
1592 if ((strstr (type, "_TYPE_") != NULL ||
1593 strstr (type, "TYPE_") == type) &&
1594 strchr (type, ':') == NULL)
1595 return g_strdup (type);
1596 return make_pre_macro (type, "TYPE");
1600 make_property (Property *p)
1605 char *argflags[] = {
1613 flags = g_string_new ("(GParamFlags)(");
1615 if (p->get != NULL && p->set != NULL)
1616 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1617 else if (p->get != NULL)
1618 g_string_append (flags, "G_PARAM_READABLE");
1620 g_string_append (flags, "G_PARAM_WRITABLE");
1622 if (p->get == NULL && p->set == NULL) {
1623 error_print (GOB_ERROR, p->line_no,
1624 "Property has no getter nor setter");
1627 for (l = p->flags; l != NULL; l = l->next) {
1628 char *flag = l->data;
1630 if(strcmp (flag, "READABLE") == 0 ||
1631 strcmp (flag, "WRITABLE") == 0) {
1632 error_print(GOB_WARN, p->line_no,
1634 "WRITABLE argument flags are "
1635 "set automatically");
1638 for(i = 0; argflags[i]; i++) {
1639 if(strcmp(argflags[i], flag)==0)
1642 /* if we haven't found it in our list */
1643 if( ! argflags[i]) {
1644 error_printf(GOB_WARN, p->line_no,
1645 "Unknown flag '%s' used, "
1646 "perhaps it was misspelled", flag);
1648 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1651 g_string_append (flags, ")");
1653 if (strcmp (p->gtktype, "CHAR") == 0) {
1654 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1655 "\t\t(\"%s\" /* name */,\n"
1656 "\t\t %s /* nick */,\n"
1657 "\t\t %s /* blurb */,\n"
1658 "\t\t %s /* minimum */,\n"
1659 "\t\t %s /* maximum */,\n"
1660 "\t\t %s /* default_value */,\n"
1663 value_for_print (p->nick, "NULL"),
1664 value_for_print (p->blurb, "NULL"),
1665 value_for_print (p->minimum, "-128"),
1666 value_for_print (p->maximum, "127"),
1667 value_for_print (p->default_value, "0"),
1669 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1670 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1671 "\t\t(\"%s\" /* name */,\n"
1672 "\t\t %s /* nick */,\n"
1673 "\t\t %s /* blurb */,\n"
1674 "\t\t %s /* minimum */,\n"
1675 "\t\t %s /* maximum */,\n"
1676 "\t\t %s /* default_value */,\n"
1679 value_for_print (p->nick, "NULL"),
1680 value_for_print (p->blurb, "NULL"),
1681 value_for_print (p->minimum, "0"),
1682 value_for_print (p->maximum, "0xFF"),
1683 value_for_print (p->default_value, "0"),
1685 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1686 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1687 "\t\t(\"%s\" /* name */,\n"
1688 "\t\t %s /* nick */,\n"
1689 "\t\t %s /* blurb */,\n"
1690 "\t\t %s /* default_value */,\n"
1693 value_for_print (p->nick, "NULL"),
1694 value_for_print (p->blurb, "NULL"),
1695 value_for_print (p->default_value, "FALSE"),
1697 } else if (strcmp (p->gtktype, "INT") == 0) {
1698 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1699 "\t\t(\"%s\" /* name */,\n"
1700 "\t\t %s /* nick */,\n"
1701 "\t\t %s /* blurb */,\n"
1702 "\t\t %s /* minimum */,\n"
1703 "\t\t %s /* maximum */,\n"
1704 "\t\t %s /* default_value */,\n"
1707 value_for_print (p->nick, "NULL"),
1708 value_for_print (p->blurb, "NULL"),
1709 value_for_print (p->minimum, "G_MININT"),
1710 value_for_print (p->maximum, "G_MAXINT"),
1711 value_for_print (p->default_value, "0"),
1713 } else if (strcmp (p->gtktype, "UINT") == 0) {
1714 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1715 "\t\t(\"%s\" /* name */,\n"
1716 "\t\t %s /* nick */,\n"
1717 "\t\t %s /* blurb */,\n"
1718 "\t\t %s /* minimum */,\n"
1719 "\t\t %s /* maximum */,\n"
1720 "\t\t %s /* default_value */,\n"
1723 value_for_print (p->nick, "NULL"),
1724 value_for_print (p->blurb, "NULL"),
1725 value_for_print (p->minimum, "0"),
1726 value_for_print (p->maximum, "G_MAXUINT"),
1727 value_for_print (p->default_value, "0"),
1729 } else if (strcmp (p->gtktype, "LONG") == 0) {
1730 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1731 "\t\t(\"%s\" /* name */,\n"
1732 "\t\t %s /* nick */,\n"
1733 "\t\t %s /* blurb */,\n"
1734 "\t\t %s /* minimum */,\n"
1735 "\t\t %s /* maximum */,\n"
1736 "\t\t %s /* default_value */,\n"
1739 value_for_print (p->nick, "NULL"),
1740 value_for_print (p->blurb, "NULL"),
1741 value_for_print (p->minimum, "G_MINLONG"),
1742 value_for_print (p->maximum, "G_MAXLONG"),
1743 value_for_print (p->default_value, "0"),
1745 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1746 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1747 "\t\t(\"%s\" /* name */,\n"
1748 "\t\t %s /* nick */,\n"
1749 "\t\t %s /* blurb */,\n"
1750 "\t\t %s /* minimum */,\n"
1751 "\t\t %s /* maximum */,\n"
1752 "\t\t %s /* default_value */,\n"
1755 value_for_print (p->nick, "NULL"),
1756 value_for_print (p->blurb, "NULL"),
1757 value_for_print (p->minimum, "0"),
1758 value_for_print (p->maximum, "G_MAXULONG"),
1759 value_for_print (p->default_value, "0"),
1761 } else if (strcmp (p->gtktype, "INT64") == 0) {
1762 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1763 "\t\t(\"%s\" /* name */,\n"
1764 "\t\t %s /* nick */,\n"
1765 "\t\t %s /* blurb */,\n"
1766 "\t\t %s /* minimum */,\n"
1767 "\t\t %s /* maximum */,\n"
1768 "\t\t %s /* default_value */,\n"
1771 value_for_print (p->nick, "NULL"),
1772 value_for_print (p->blurb, "NULL"),
1773 value_for_print (p->minimum, "G_MININT64"),
1774 value_for_print (p->maximum, "G_MAXINT64"),
1775 value_for_print (p->default_value, "0"),
1777 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1778 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1779 "\t\t(\"%s\" /* name */,\n"
1780 "\t\t %s /* nick */,\n"
1781 "\t\t %s /* blurb */,\n"
1782 "\t\t %s /* minimum */,\n"
1783 "\t\t %s /* maximum */,\n"
1784 "\t\t %s /* default_value */,\n"
1787 value_for_print (p->nick, "NULL"),
1788 value_for_print (p->blurb, "NULL"),
1789 value_for_print (p->minimum, "0"),
1790 value_for_print (p->maximum, "G_MAXUINT64"),
1791 value_for_print (p->default_value, "0"),
1793 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1794 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1795 "\t\t(\"%s\" /* name */,\n"
1796 "\t\t %s /* nick */,\n"
1797 "\t\t %s /* blurb */,\n"
1798 "\t\t %s /* default_value */,\n"
1801 value_for_print (p->nick, "NULL"),
1802 value_for_print (p->blurb, "NULL"),
1803 value_for_print (p->default_value, "0"),
1805 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1806 char *type = make_me_type (p->extra_gtktype,
1808 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1809 "\t\t(\"%s\" /* name */,\n"
1810 "\t\t %s /* nick */,\n"
1811 "\t\t %s /* blurb */,\n"
1812 "\t\t %s /* enum_type */,\n"
1813 "\t\t %s /* default_value */,\n"
1816 value_for_print (p->nick, "NULL"),
1817 value_for_print (p->blurb, "NULL"),
1819 value_for_print (p->default_value, "0"),
1822 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1823 char *type = make_me_type (p->extra_gtktype,
1825 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1826 "\t\t(\"%s\" /* name */,\n"
1827 "\t\t %s /* nick */,\n"
1828 "\t\t %s /* blurb */,\n"
1829 "\t\t %s /* flags_type */,\n"
1830 "\t\t %s /* default_value */,\n"
1833 value_for_print (p->nick, "NULL"),
1834 value_for_print (p->blurb, "NULL"),
1836 value_for_print (p->default_value, "0"),
1839 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1840 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1841 "\t\t(\"%s\" /* name */,\n"
1842 "\t\t %s /* nick */,\n"
1843 "\t\t %s /* blurb */,\n"
1844 "\t\t %s /* minimum */,\n"
1845 "\t\t %s /* maximum */,\n"
1846 "\t\t %s /* default_value */,\n"
1849 value_for_print (p->nick, "NULL"),
1850 value_for_print (p->blurb, "NULL"),
1851 value_for_print (p->minimum, "G_MINFLOAT"),
1852 value_for_print (p->maximum, "G_MAXFLOAT"),
1853 value_for_print (p->default_value, "0.0"),
1855 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1856 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1857 "\t\t(\"%s\" /* name */,\n"
1858 "\t\t %s /* nick */,\n"
1859 "\t\t %s /* blurb */,\n"
1860 "\t\t %s /* minimum */,\n"
1861 "\t\t %s /* maximum */,\n"
1862 "\t\t %s /* default_value */,\n"
1865 value_for_print (p->nick, "NULL"),
1866 value_for_print (p->blurb, "NULL"),
1867 value_for_print (p->minimum, "G_MINDOUBLE"),
1868 value_for_print (p->maximum, "G_MAXDOUBLE"),
1869 value_for_print (p->default_value, "0.0"),
1871 } else if (strcmp (p->gtktype, "STRING") == 0) {
1872 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1873 "\t\t(\"%s\" /* name */,\n"
1874 "\t\t %s /* nick */,\n"
1875 "\t\t %s /* blurb */,\n"
1876 "\t\t %s /* default_value */,\n"
1879 value_for_print (p->nick, "NULL"),
1880 value_for_print (p->blurb, "NULL"),
1881 value_for_print (p->default_value, "NULL"),
1883 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1884 char *type = make_me_type (p->extra_gtktype,
1886 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1887 "\t\t(\"%s\" /* name */,\n"
1888 "\t\t %s /* nick */,\n"
1889 "\t\t %s /* blurb */,\n"
1890 "\t\t %s /* param_type */,\n"
1893 value_for_print (p->nick, "NULL"),
1894 value_for_print (p->blurb, "NULL"),
1898 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1899 char *type = make_me_type (p->extra_gtktype,
1901 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1902 "\t\t(\"%s\" /* name */,\n"
1903 "\t\t %s /* nick */,\n"
1904 "\t\t %s /* blurb */,\n"
1905 "\t\t %s /* boxed_type */,\n"
1908 value_for_print (p->nick, "NULL"),
1909 value_for_print (p->blurb, "NULL"),
1913 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1914 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1915 "\t\t(\"%s\" /* name */,\n"
1916 "\t\t %s /* nick */,\n"
1917 "\t\t %s /* blurb */,\n"
1920 value_for_print (p->nick, "NULL"),
1921 value_for_print (p->blurb, "NULL"),
1923 /* FIXME: VALUE_ARRAY */
1924 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1925 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1926 "\t\t(\"%s\" /* name */,\n"
1927 "\t\t %s /* nick */,\n"
1928 "\t\t %s /* blurb */,\n"
1931 value_for_print (p->nick, "NULL"),
1932 value_for_print (p->blurb, "NULL"),
1934 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
1935 char *type = make_me_type (p->extra_gtktype,
1937 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1938 "\t\t(\"%s\" /* name */,\n"
1939 "\t\t %s /* nick */,\n"
1940 "\t\t %s /* blurb */,\n"
1941 "\t\t %s /* object_type */,\n"
1944 value_for_print (p->nick, "NULL"),
1945 value_for_print (p->blurb, "NULL"),
1950 error_printf (GOB_ERROR, p->line_no,
1951 "%s type is not supported by properties",
1955 s = g_strdup (p->name);
1957 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1959 "\t\tparam_spec);\n", s);
1962 g_string_free (flags, TRUE);
1966 make_arguments(Class *c)
1969 if (get_properties > 0)
1970 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1971 if (set_properties > 0)
1972 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1973 out_printf (out, " {\n"
1974 "\tGParamSpec *param_spec;\n\n");
1976 for (li = c->nodes; li != NULL; li = li->next) {
1978 if (n->type == PROPERTY_NODE)
1979 make_property ((Property *)n);
1980 else if (n->type == ARGUMENT_NODE)
1981 make_argument ((Argument *)n);
1983 out_printf(out, " }\n");
1987 print_initializer(Method *m, Variable *v)
1991 if(v->initializer == NULL)
1994 if(v->scope == PRIVATE_SCOPE)
1995 root = g_strconcat(((FuncArg *)m->args->data)->name,
1998 root = g_strdup(((FuncArg *)m->args->data)->name);
2000 if(v->initializer_line > 0)
2001 out_addline_infile(out, v->initializer_line);
2003 out_printf(out, "\t%s->%s = %s;\n",
2004 root, v->id, v->initializer);
2006 if(v->initializer_line > 0)
2007 out_addline_outfile(out);
2013 print_destructor (Variable *v)
2017 if(v->destructor == NULL)
2020 if(v->scope == PRIVATE_SCOPE)
2021 root = "self->_priv";
2025 if(v->destructor_simple) {
2026 if(v->destructor_line > 0)
2027 out_addline_infile(out, v->destructor_line);
2029 out_printf(out, "\tif(%s->%s) { "
2030 "((*(void (*)(void *))%s)) (%s->%s); "
2031 "%s->%s = NULL; }\n",
2032 root, v->id, v->destructor, root, v->id,
2035 if(v->destructor_line > 0)
2036 out_addline_outfile(out);
2038 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2039 out_printf(out, "#define VAR %s\n", v->id);
2040 out_printf(out, "\t{\n");
2041 if(v->destructor_line > 0)
2042 out_addline_infile(out, v->destructor_line);
2044 out_printf(out, "\t%s}\n", v->destructor);
2046 if(v->destructor_line > 0)
2047 out_addline_outfile(out);
2048 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
2050 out_printf(out, "#undef VAR\n");
2051 out_printf(out, "#undef %s\n", v->id);
2056 add_dispose (Class *c)
2058 out_printf(out, "\nstatic void\n"
2059 "___dispose (GObject *obj_self)\n"
2062 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2065 if (unreftors > 0) {
2066 out_printf (out, "\t%s *self = %s (obj_self);\n",
2067 typebase, macrobase);
2070 if (dispose_handler != NULL) {
2071 /* so we get possible bad argument warning */
2072 if (dispose_handler->line_no > 0)
2073 out_addline_infile (out, dispose_handler->line_no);
2074 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2075 (guint)dispose_handler->unique_id, funcbase);
2076 if (dispose_handler->line_no > 0)
2077 out_addline_outfile (out);
2080 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2081 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2084 if (unreftors > 0) {
2086 for(li = ((Class *)class)->nodes;
2090 Variable *v = (Variable *)n;
2091 if (n->type == VARIABLE_NODE &&
2092 v->scope != CLASS_SCOPE &&
2093 v->destructor_unref)
2094 print_destructor (v);
2098 out_printf (out, "\treturn;\n");
2100 out_printf(out, "\tself = NULL;\n");
2101 out_printf(out, "}\n"
2102 "#undef __GOB_FUNCTION__\n\n");
2106 add_finalize (Class *c)
2110 "___finalize(GObject *obj_self)\n"
2113 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2118 out_printf(out, "\t%s *self = %s (obj_self);\n",
2119 typebase, macrobase);
2122 out_printf(out, "\tgpointer priv = self->_priv;\n");
2125 if(finalize_handler) {
2126 /* so we get possible bad argument warning */
2127 if(finalize_handler->line_no > 0)
2128 out_addline_infile(out, finalize_handler->line_no);
2129 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2130 (guint)finalize_handler->unique_id, funcbase);
2131 if(finalize_handler->line_no > 0)
2132 out_addline_outfile(out);
2135 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2136 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2139 if (destructors > 0) {
2141 for (li = ((Class *)class)->nodes;
2145 Variable *v = (Variable *)n;
2146 if (n->type == VARIABLE_NODE &&
2147 v->scope != CLASS_SCOPE &&
2148 ! v->destructor_unref)
2149 print_destructor (v);
2154 out_printf(out, "\tg_free (priv);\n");
2156 out_printf (out, "\treturn;\n");
2157 if (destructors > 0 ||
2159 out_printf (out, "\tself = NULL;\n");
2161 out_printf(out, "}\n"
2162 "#undef __GOB_FUNCTION__\n\n");
2166 make_bonobo_object_epv (Class *c, const char *classname)
2169 gboolean added_line = FALSE;
2171 for (li = c->nodes; li != NULL; li = li->next) {
2173 Method *m = (Method *)n;
2174 if(n->type != METHOD_NODE ||
2175 m->method == OVERRIDE_METHOD)
2178 if (m->bonobo_object_func) {
2179 if(m->line_no > 0) {
2180 out_addline_infile(out, m->line_no);
2182 } else if (m->line_no == 0 &&
2184 out_addline_outfile(out);
2187 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2188 classname, m->id, m->id);
2192 out_addline_outfile(out);
2199 for(li=c->nodes;li;li=g_list_next(li)) {
2203 gboolean add_unused_class = FALSE;
2205 if(n->type != METHOD_NODE)
2208 if(m->method == INIT_METHOD) {
2210 out_addline_infile(out, m->line_no);
2211 print_method(out, "static ", "\n", "", " ", "", "\n",
2212 m, FALSE, FALSE, TRUE);
2214 out_addline_outfile(out);
2215 out_printf(out, "{\n"
2216 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2219 out_printf(out, "\t%s->_priv = "
2220 "g_new0 (%sPrivate, 1);\n",
2221 ((FuncArg *)m->args->data)->name,
2223 } else if(always_private_struct) {
2224 out_printf(out, "\t%s->_priv = NULL;\n",
2225 ((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)
2237 print_initializer(m, v);
2240 } else if(m->method == CLASS_INIT_METHOD) {
2241 gboolean did_base_obj = FALSE;
2244 out_addline_infile(out, m->line_no);
2245 print_method(out, "static ", "\n", "", " ", "", "\n",
2246 m, FALSE, FALSE, TRUE);
2248 out_addline_outfile(out);
2249 out_printf(out, "{\n"
2250 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2252 if (set_properties > 0 ||
2253 get_properties > 0 ||
2260 "(GObjectClass*) %s;\n",
2261 ((FuncArg *)m->args->data)->name);
2262 add_unused_class = TRUE;
2263 did_base_obj = TRUE;
2268 ((FuncArg *)m->args->data)->name,
2271 if (initializers > 0) {
2273 for(li = ((Class *)class)->nodes;
2277 Variable *v = (Variable *)n;
2278 if(n->type == VARIABLE_NODE &&
2279 v->scope == CLASS_SCOPE)
2280 print_initializer(m, v);
2284 out_printf(out, "\n\tparent_class = ");
2286 out_printf(out, "(%sClass *)", ptypebase);
2287 out_printf(out, "g_type_class_ref (%s);\n",
2293 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2295 /* if there are no handlers for these things, we
2296 * need to set them up here */
2297 if(need_dispose && !dispose_handler)
2298 out_printf(out, "\tg_object_class->dispose "
2300 if(need_finalize && !finalize_handler)
2301 out_printf(out, "\tg_object_class->finalize = "
2304 if(get_properties > 0 || set_properties > 0)
2307 if (c->bonobo_object_class != NULL) {
2308 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2314 out_printf(out, " {\n");
2315 out_addline_infile(out, m->ccode_line);
2316 out_printf(out, "%s\n", m->cbuf);
2317 out_addline_outfile(out);
2318 out_printf(out, " }\n");
2320 out_printf(out, "\treturn;\n");
2323 ((FuncArg *)m->args->data)->name);
2324 if(add_unused_class) {
2325 out_printf (out, "\tg_object_class = NULL;\n");
2327 out_printf(out, "}\n"
2328 "#undef __GOB_FUNCTION__\n");
2333 add_argument (Argument *a, gboolean is_set)
2337 char *the_type_lower;
2342 line_no = a->set_line;
2345 line_no = a->get_line;
2349 s = g_strdup(a->name);
2351 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2353 the_type_lower = g_strdup (a->gtktype);
2354 gob_strdown (the_type_lower);
2356 /* HACK because there is no g_value_set/get for unichar */
2357 if (strcmp (the_type_lower, "unichar") == 0) {
2358 g_free (the_type_lower);
2359 the_type_lower = g_strdup ("uint");
2365 if (a->atype != NULL)
2366 cast = get_type (a->atype, TRUE);
2368 cast = g_strdup (get_cast (a->gtktype, FALSE));
2370 out_printf (out, "\t%s ARG = (%s) g_value_get_%s (VAL);\n",
2371 cast, cast, the_type_lower);
2374 } else if ( ! is_set) {
2377 if (a->atype != NULL)
2378 cast = get_type (a->atype, TRUE);
2380 cast = g_strdup (get_cast (a->gtktype, FALSE));
2381 out_printf (out, "\t%s ARG;\n"
2382 "\tmemset (&ARG, 0, sizeof (%s));\n",
2388 out_printf(out, "\t\t{\n");
2390 out_addline_infile (out, line_no);
2391 out_printf (out, "%s\n", cbuf);
2393 out_addline_outfile (out);
2394 out_printf (out, "\t\t}\n");
2396 if (strcmp (a->gtktype, "OBJECT") == 0)
2397 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2400 out_printf (out, "\t\t"
2401 "g_value_set_%s (VAL, ARG);\n",
2404 g_free (the_type_lower);
2407 out_printf (out, "\t\tif (&ARG) ;\n");
2410 out_printf (out, "\t\tbreak;\n");
2412 out_printf (out, "\t}\n");
2416 add_property (Property *p, gboolean is_set)
2419 char *the_type_lower;
2425 line_no = p->set_line;
2428 line_no = p->get_line;
2433 name_upper = g_strdup (p->name);
2434 gob_strup (name_upper);
2435 the_type_lower = g_strdup (p->gtktype);
2436 gob_strdown (the_type_lower);
2438 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2440 out_printf(out, "\t\t{\n");
2442 out_addline_infile (out, line_no);
2443 out_printf (out, "%s\n", cbuf);
2445 out_addline_outfile (out);
2446 out_printf (out, "\t\t}\n");
2448 g_free (name_upper);
2449 g_free (the_type_lower);
2451 out_printf (out, "\t\tbreak;\n");
2455 add_getset_arg(Class *c, gboolean is_set)
2458 out_printf(out, "\nstatic void\n"
2459 "___object_%s_property (GObject *object,\n"
2460 "\tguint property_id,\n"
2461 "\t%sGValue *VAL,\n"
2462 "\tGParamSpec *pspec)\n"
2463 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2466 "\tself = %s (object);\n\n"
2467 "\tswitch (property_id) {\n",
2468 is_set ? "set" : "get",
2469 is_set ? "const " : "",
2470 c->otype, is_set ? "set" : "get",
2471 typebase, macrobase);
2473 for (li = c->nodes; li != NULL; li = li->next) {
2475 if (n->type == PROPERTY_NODE)
2476 add_property ((Property *)n, is_set);
2477 else if (n->type == ARGUMENT_NODE)
2478 add_argument ((Argument *)n, is_set);
2480 out_printf (out, "\tdefault:\n"
2481 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2482 "#ifndef __PRETTY_FUNCTION__\n"
2483 "# undef G_STRLOC\n"
2484 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2486 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2488 "\treturn;\n\tself = NULL;\n\tVAL = NULL;\n\tpspec = NULL;\n}\n"
2489 "#undef __GOB_FUNCTION__\n");
2493 print_checks (Method *m, FuncArg *fa)
2497 gboolean checked_null = FALSE;
2498 is_void = (strcmp(m->mtype->name, "void")==0 &&
2499 m->mtype->pointer == NULL);
2501 for(li = fa->checks; li != NULL; li = li->next) {
2502 Check *ch = li->data;
2504 /* point to the method prot in .gob for failed checks */
2506 out_addline_infile(out, m->line_no);
2508 out_printf(out, "\tg_return_if_fail (");
2510 out_printf(out, "\tg_return_val_if_fail (");
2511 switch(ch->chtype) {
2513 out_printf(out, "%s != NULL", fa->name);
2514 checked_null = TRUE;
2517 s = make_pre_macro(fa->atype->name, "IS");
2519 out_printf(out, "%s (%s)", s, fa->name);
2521 /* if not check null, null may be valid */
2522 out_printf(out, "!(%s) || %s (%s)", fa->name,
2527 out_printf(out, "%s < %s", fa->name, ch->number);
2530 out_printf(out, "%s > %s", fa->name, ch->number);
2533 out_printf(out, "%s <= %s", fa->name, ch->number);
2536 out_printf(out, "%s >= %s", fa->name, ch->number);
2539 out_printf(out, "%s == %s", fa->name, ch->number);
2542 out_printf(out, "%s != %s", fa->name, ch->number);
2546 out_printf(out, ");\n");
2548 out_printf(out, ", (");
2549 print_type(out, m->mtype, TRUE);
2550 out_printf(out, ")%s);\n",
2551 m->onerror?m->onerror:"0");
2557 print_preconditions(Method *m)
2561 for(li=m->args;li;li=g_list_next(li)) {
2562 FuncArg *fa = li->data;
2564 print_checks(m, fa);
2567 out_addline_outfile(out);
2571 print_method_body(Method *m, int pre)
2574 out_addline_outfile(out);
2575 out_printf(out, "{\n"
2576 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2577 ((Class *)class)->otype,
2580 print_preconditions(m);
2582 /* Note: the trailing }'s are on one line, this is so
2583 that we get the no return warning correctly and point to
2584 the correct line in the .gob file, yes this is slightly
2585 ugly in the .c file, but that is not supposed to be
2586 human readable anyway. */
2588 out_printf(out, "{\n");
2590 out_addline_infile(out, m->ccode_line);
2591 out_printf(out, "\t%s}", m->cbuf);
2594 /* Note, there is no \n between the last } and this } so that
2595 * errors/warnings reported on the end of the body get pointed to the
2596 * right line in the .gob source */
2597 out_printf(out, "}\n");
2600 out_addline_outfile(out);
2601 out_printf(out, "#undef __GOB_FUNCTION__\n");
2605 put_signal_args (Method *m)
2611 if (m->args->next == NULL)
2614 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2615 li != NULL && ali != NULL;
2616 li = li->next, ali = ali->next, i++) {
2617 FuncArg *fa = li->data;
2618 char *cast = g_strdup (get_cast (ali->data, FALSE));
2619 /* FIXME: This code is so fucking ugly it hurts */
2620 gboolean do_static =
2621 (strcmp ((char *)ali->data, "STRING") == 0 ||
2622 strcmp ((char *)ali->data, "BOXED") == 0);
2626 cast = get_type (fa->atype, TRUE);
2628 /* we should have already proved before that
2629 the we know all the types */
2630 g_assert (cast != NULL);
2633 "\t___param_values[%d].g_type = 0;\n"
2634 "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
2635 i, i, (char *)ali->data);
2637 if (strcmp (ali->data, "UNICHAR") == 0)
2638 /* hack because glib is braindamaged */
2639 set_func = g_strdup ("g_value_set_uint");
2641 set_func = g_strdup_printf ("g_value_set%s_%s",
2642 do_static ? "_static" : "",
2644 gob_strdown (set_func);
2646 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2647 set_func, i, cast, fa->name);
2655 clear_signal_args (Method *m)
2660 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2662 if (m->args->next == NULL)
2665 for (li = m->args->next, i = 1;
2667 li = li->next, i++) {
2669 "\tg_value_unset (&___param_values[%d]);\n", i);
2674 get_arg_names_for_macro (Method *m)
2678 GString *gs = g_string_new(NULL);
2680 for(li=m->args;li;li=g_list_next(li)) {
2681 FuncArg *arg = li->data;
2682 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2685 return g_string_free (gs, FALSE);
2689 put_method(Method *m)
2691 char *s, *args, *doc;
2693 is_void = (strcmp(m->mtype->name, "void")==0 &&
2694 m->mtype->pointer == NULL);
2695 out_printf(out, "\n");
2696 if(m->method != OVERRIDE_METHOD) {
2697 doc = get_gtk_doc(m->id);
2699 out_printf(out, "%s", doc);
2704 case REGULAR_METHOD:
2706 out_addline_infile(out, m->line_no);
2707 if(m->scope == PRIVATE_SCOPE)
2708 print_method(out, "static ", "\n", "", " ", "", "\n",
2709 m, FALSE, FALSE, TRUE);
2710 else /* PUBLIC, PROTECTED */
2711 print_method(out, "", "\n", "", " ", "", "\n",
2712 m, FALSE, FALSE, TRUE);
2713 print_method_body(m, TRUE);
2714 /* the outfile line was added above */
2716 case SIGNAL_FIRST_METHOD:
2717 case SIGNAL_LAST_METHOD:
2719 out_addline_infile(out, m->line_no);
2720 if(m->scope == PRIVATE_SCOPE)
2721 print_method(out, "static ", "\n", "", " ", "", "\n",
2722 m, FALSE, FALSE, TRUE);
2723 else /* PUBLIC, PROTECTED */
2724 print_method(out, "", "\n", "", " ", "", "\n",
2725 m, FALSE, FALSE, TRUE);
2726 out_addline_outfile (out);
2728 out_printf (out, "{\n");
2731 "\tGValue ___param_values[%d];\n"
2732 "\tGValue ___return_val = {0};\n\n",
2733 g_list_length (m->args));
2735 print_preconditions (m);
2738 "\n\t___param_values[0].g_type = 0;\n"
2739 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2740 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2741 ((FuncArg *)m->args->data)->name,
2742 ((FuncArg *)m->args->data)->name);
2744 put_signal_args (m);
2746 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2747 const char *defret = NULL;
2749 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2750 (char *)m->gtktypes->data);
2752 if (m->defreturn != NULL)
2753 defret = m->defreturn;
2754 else if (m->onerror != NULL)
2755 defret = m->onerror;
2757 if (defret != NULL) {
2759 /* FIXME: This code is so fucking ugly it hurts */
2760 gboolean do_static =
2761 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2762 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2763 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2765 cast = get_type (m->mtype, TRUE);
2767 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2768 /* hack because glib is braindamaged */
2769 set_func = g_strdup ("g_value_set_uint");
2771 set_func = g_strdup_printf ("g_value_set%s_%s",
2772 do_static ? "_static" : "",
2773 (char *)m->gtktypes->data);
2774 gob_strdown (set_func);
2776 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2777 set_func, cast, defret);
2782 out_printf (out, "\n");
2785 s = g_strdup (m->id);
2788 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2789 "\t\tobject_signals[%s_SIGNAL],\n"
2790 "\t\t0 /* detail */,\n"
2791 "\t\t&___return_val);\n", s);
2795 clear_signal_args (m);
2797 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2798 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2800 /* Hack because glib is very very braindead */
2802 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2803 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
2804 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
2805 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
2807 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2808 /* hack because glib is braindamaged */
2809 getfunc = g_strdup ("g_value_get_uint");
2811 getfunc = g_strdup_printf ("g_value_%s_%s",
2812 do_dup ? "dup" : "get",
2813 (char *)m->gtktypes->data);
2814 gob_strdown (getfunc);
2817 cast = get_type (m->mtype, TRUE);
2822 print_type (out, m->mtype, TRUE);
2824 " ___ret = (%s) %s (&___return_val);\n"
2825 "\t\tg_value_unset (&___return_val);\n"
2826 "\t\treturn ___ret;\n"
2833 out_printf(out, "}\n");
2838 out_addline_infile(out, m->line_no);
2839 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2840 m, FALSE, FALSE, TRUE);
2841 print_method_body(m, FALSE);
2842 /* the outfile line was added above */
2844 case VIRTUAL_METHOD:
2846 out_addline_infile(out, m->line_no);
2847 if(m->scope==PRIVATE_SCOPE)
2848 print_method(out, "static ", "\n", "", " ", "", "\n",
2849 m, FALSE, FALSE, TRUE);
2850 else /* PUBLIC, PROTECTED */
2851 print_method(out, "", "\n", "", " ", "", "\n",
2852 m, FALSE, FALSE, TRUE);
2853 out_addline_outfile(out);
2854 out_printf(out, "{\n"
2855 "\t%sClass *klass;\n", typebase);
2856 print_preconditions(m);
2857 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2858 "\tif(klass->%s)\n",
2859 macrobase, ((FuncArg *)m->args->data)->name,
2861 if(strcmp(m->mtype->name, "void") == 0 &&
2862 m->mtype->pointer == NULL) {
2864 out_printf(out, "\t\t(*klass->%s)(%s",
2866 ((FuncArg *)m->args->data)->name);
2867 for(li=m->args->next;li;li=g_list_next(li)) {
2868 FuncArg *fa = li->data;
2869 out_printf(out, ",%s", fa->name);
2871 out_printf(out, ");\n}\n");
2874 out_printf(out, "\t\treturn (*klass->%s)(%s",
2876 ((FuncArg *)m->args->data)->name);
2877 for(li=m->args->next;li;li=g_list_next(li)) {
2878 FuncArg *fa = li->data;
2879 out_printf(out, ",%s", fa->name);
2881 out_printf(out, ");\n"
2884 print_type(out, m->mtype, TRUE);
2886 out_printf(out, ")(%s);\n}\n", m->defreturn);
2888 out_printf(out, ")(%s);\n}\n", m->onerror);
2890 out_printf(out, ")(0);\n}\n");
2896 out_addline_infile(out, m->line_no);
2897 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2898 m, FALSE, FALSE, TRUE);
2899 print_method_body(m, FALSE);
2900 /* the outfile line was added above */
2902 case OVERRIDE_METHOD:
2906 out_addline_infile(out, m->line_no);
2907 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2908 print_method(out, "static ", s, "", " ", "", "\n",
2909 m, FALSE, FALSE, FALSE);
2911 out_addline_outfile(out);
2912 s = replace_sep(m->otype, '_');
2914 args = get_arg_names_for_macro(m);
2916 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2917 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2918 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2919 args, s, m->id, s, m->id, args);
2921 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2922 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2923 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2925 args, s, m->id, s, m->id, args);
2926 out_printf(out, "(");
2927 print_type(out, m->mtype, TRUE);
2928 out_printf(out, ")%s))\n",
2929 m->onerror?m->onerror:"0");
2933 print_method_body(m, TRUE);
2934 /* the outfile line was added above */
2935 out_printf(out, "#undef PARENT_HANDLER\n");
2945 char *outfile, *outfileh, *outfileph;
2948 outfile = g_strconcat (filebase, ".c", NULL);
2950 outfile = g_strconcat (filebase, ".cc", NULL);
2951 if (no_touch_headers)
2952 outfileh = g_strconcat ("#gob#", filebase, ".h#gob#", NULL);
2954 outfileh = g_strconcat (filebase, ".h", NULL);
2956 if ((privates > 0 || protecteds > 0 ||
2957 private_header == PRIVATE_HEADER_ALWAYS) &&
2958 private_header != PRIVATE_HEADER_NEVER)
2959 outfileph = g_strconcat (filebase, "-private.h", NULL);
2965 devnull = fopen ("/dev/null", "w");
2966 if (devnull == NULL)
2967 error_print (GOB_ERROR, 0, "Cannot open null device");
2970 if (outfileph != NULL)
2973 out = fopen (outfile, "w");
2975 error_printf (GOB_ERROR, 0,
2976 "Cannot open outfile: %s", outfile);
2978 outh = fopen (outfileh, "w");
2980 error_printf (GOB_ERROR, 0,
2981 "Cannot open outfile: %s", outfileh);
2983 if (outfileph != NULL) {
2984 outph = fopen (outfileph, "w");
2985 if (outph == NULL) {
2986 error_printf (GOB_ERROR, 0,
2987 "Cannot open outfile: %s",
2995 put_argument_nongnu_wrappers (Class *c)
2999 if (get_properties < 0 && set_properties < 0)
3002 for (li = c->nodes; li != NULL; li = li->next) {
3004 const char *name, *gtktype;
3010 if (n->type == ARGUMENT_NODE) {
3011 Argument *a = (Argument *)n;
3013 gtktype = a->gtktype;
3015 get = a->get != NULL;
3016 set = a->set != NULL;
3017 } else if (n->type == PROPERTY_NODE) {
3018 Property *p = (Property *)n;
3020 gtktype = p->gtktype;
3022 get = p->get != NULL;
3023 set = p->set != NULL;
3028 aname = g_strdup (name);
3032 cast = get_type (atype, TRUE);
3034 cast = g_strdup (get_cast (gtktype, TRUE));
3038 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3039 "\"%s\",(%s)(arg)\n",
3040 macrobase, aname, name, cast);
3042 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3043 "\"%s\",(%s*)(arg)\n",
3044 macrobase, aname, name, cast);
3047 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3049 macrobase, aname, name);
3051 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3053 macrobase, aname, name);
3061 put_argument_gnu_wrappers(Class *c)
3065 if(get_properties < 0 && set_properties < 0)
3068 for (li = c->nodes; li != NULL; li = li->next) {
3070 const char *name, *gtktype;
3076 if (n->type == ARGUMENT_NODE) {
3077 Argument *a = (Argument *)n;
3079 gtktype = a->gtktype;
3081 get = a->get != NULL;
3082 set = a->set != NULL;
3083 } else if (n->type == PROPERTY_NODE) {
3084 Property *p = (Property *)n;
3086 gtktype = p->gtktype;
3088 get = p->get != NULL;
3089 set = p->set != NULL;
3094 aname = g_strdup (name);
3098 cast = get_type (atype, TRUE);
3100 cast = g_strdup (get_cast (gtktype, TRUE));
3104 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3105 "\"%s\",({%sz = (arg); z;})\n",
3106 macrobase, aname, name, cast);
3108 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3109 "\"%s\",({%s*z = (arg); z;})\n",
3110 macrobase, aname, name, cast);
3113 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3115 macrobase, aname, name);
3117 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3119 macrobase, aname, name);
3127 print_ccode_block(CCode *cc)
3130 switch(cc->cctype) {
3132 /* HT code is printed exactly like normal header
3133 code but is printed before */
3136 out_printf(fp, "\n");
3139 /* AT code is printed exactly like normal 'all'
3140 code but is printed before */
3143 out_printf(outph, "\n");
3144 out_printf(outph, "%s\n", cc->cbuf);
3145 out_addline_infile(outph, cc->line_no);
3146 out_addline_outfile(outph);
3148 out_printf(outh, "\n");
3149 out_printf(outh, "%s\n", cc->cbuf);
3151 out_printf(fp, "\n");
3152 out_addline_infile(fp, cc->line_no);
3157 out_printf(fp, "\n");
3158 out_addline_infile(fp, cc->line_no);
3165 out_printf(fp, "\n");
3166 out_addline_infile(fp, cc->line_no);
3169 out_printf(fp, "%s\n", cc->cbuf);
3170 if(cc->cctype == C_CCODE ||
3171 cc->cctype == A_CCODE ||
3172 cc->cctype == AT_CCODE ||
3173 cc->cctype == PH_CCODE)
3174 out_addline_outfile(fp);
3178 print_class_block(Class *c)
3182 gboolean printed_private = FALSE;
3185 out_printf(out, "/* utility types we may need */\n");
3186 if(special_array[SPECIAL_2POINTER])
3187 out_printf(out, "typedef struct { "
3188 "gpointer a; gpointer b; "
3189 "} ___twopointertype;\n");
3190 if(special_array[SPECIAL_3POINTER])
3191 out_printf(out, "typedef struct { "
3192 "gpointer a; gpointer b; "
3194 "} ___threepointertype;\n");
3195 if(special_array[SPECIAL_INT_POINTER])
3196 out_printf(out, "typedef struct { "
3197 "gint a; gpointer b; "
3198 "} ___intpointertype;\n");
3199 out_printf(out, "\n");
3202 out_printf(outh, "\n/*\n"
3203 " * Type checking and casting macros\n"
3205 out_printf(outh, "#define %s\t"
3206 "(%s_get_type())\n",
3207 macrotype, funcbase);
3208 out_printf(outh, "#define %s(obj)\t"
3209 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3210 macrobase, funcbase, typebase);
3211 out_printf(outh, "#define %s_CONST(obj)\t"
3212 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3213 macrobase, funcbase, typebase);
3214 out_printf(outh, "#define %s_CLASS(klass)\t"
3215 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3216 macrobase, funcbase, typebase);
3217 out_printf(outh, "#define %s(obj)\t"
3218 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3221 "#define %s_GET_CLASS(obj)\t"
3222 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3223 macrobase, funcbase, typebase);
3225 if ( ! no_self_alias) {
3226 out_printf(out, "/* self casting macros */\n");
3227 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3228 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3229 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3230 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3231 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3233 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3236 out_printf(out, "/* self typedefs */\n");
3237 out_printf(out, "typedef %s Self;\n", typebase);
3238 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3242 always_private_struct) {
3243 out_printf (outh, "\n/* Private structure type */\n");
3244 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3245 typebase, typebase);
3247 out_printf (outh, "/* There are no privates, this "
3248 "structure is thus never defined */\n");
3251 out_printf (outh, "\n/*\n"
3252 " * Main object structure\n"
3254 s = replace_sep (c->otype, '_');
3256 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3257 "#define __TYPEDEF_%s__\n", s, s);
3259 out_printf (outh, "typedef struct _%s %s;\n"
3260 "#endif\n", typebase, typebase);
3261 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3262 typebase, ptypebase);
3263 for (li = c->nodes; li; li=li->next) {
3264 static gboolean printed_public = FALSE;
3266 Variable *v = (Variable *)n;
3267 if(n->type == VARIABLE_NODE &&
3268 v->scope == PUBLIC_SCOPE) {
3269 if( ! printed_public) {
3270 out_printf(outh, "\t/*< public >*/\n");
3271 printed_public = TRUE;
3273 put_variable((Variable *)n, outh);
3276 /* put protecteds always AFTER publics */
3277 for (li = c->nodes; li != NULL; li = li->next) {
3279 Variable *v = (Variable *)n;
3280 if (n->type == VARIABLE_NODE &&
3281 v->scope == PROTECTED_SCOPE) {
3282 if ( ! printed_private) {
3283 out_printf (outh, "\t/*< private >*/\n");
3284 printed_private = TRUE;
3286 put_variable ((Variable *)n, outh);
3290 always_private_struct) {
3291 if ( ! printed_private)
3292 out_printf (outh, "\t/*< private >*/\n");
3293 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3295 out_printf (outh, "};\n");
3300 /* if we are to stick this into the private
3301 header, if not stick it directly into the
3308 out_printf (outfp, "struct _%sPrivate {\n",
3310 for(li=c->nodes; li; li=li->next) {
3312 Variable *v = (Variable *)n;
3313 if(n->type == VARIABLE_NODE &&
3314 v->scope == PRIVATE_SCOPE) {
3315 out_addline_infile(outfp, v->line_no);
3316 put_variable(v, outfp);
3319 out_addline_outfile(outfp);
3320 out_printf(outfp, "};\n");
3323 out_printf(outh, "\n/*\n"
3324 " * Class definition\n"
3326 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3327 typebase, typebase);
3329 "struct _%sClass {\n\t%sClass __parent__;\n",
3330 typebase, ptypebase);
3331 for(li = c->nodes; li != NULL; li = li->next) {
3333 if(n->type == METHOD_NODE)
3334 put_vs_method((Method *)n);
3336 /* If BonoboX type class put down the epv */
3337 if (c->bonobo_object_class != NULL) {
3339 "\t/* Bonobo object epv */\n"
3340 "\tPOA_%s__epv _epv;\n",
3341 c->bonobo_object_class);
3343 /* put class scope variables */
3344 for (li = c->nodes; li != NULL; li = li->next) {
3346 Variable *v = (Variable *)n;
3347 if (n->type == VARIABLE_NODE &&
3348 v->scope == CLASS_SCOPE)
3349 put_variable ((Variable *)n, outh);
3351 out_printf (outh, "};\n\n");
3353 out_printf (out, "/* here are local prototypes */\n");
3354 if (set_properties > 0) {
3355 out_printf (out, "static void ___object_set_property "
3356 "(GObject *object, guint property_id, "
3357 "const GValue *value, GParamSpec *pspec);\n");
3359 if (get_properties > 0) {
3360 out_printf (out, "static void ___object_get_property "
3361 "(GObject *object, guint property_id, "
3362 "GValue *value, GParamSpec *pspec);\n");
3365 out_printf (outh, "\n/*\n"
3366 " * Public methods\n"
3369 if ( ! overrode_get_type) {
3370 out_printf (outh, "GType\t%s_get_type\t(void);\n", funcbase);
3373 for(li = c->nodes; li != NULL; li = li->next) {
3375 if(n->type == METHOD_NODE) {
3376 put_pub_method((Method *)n);
3377 put_prot_method((Method *)n);
3378 put_priv_method_prot((Method *)n);
3382 /* this idea is less and less apealing to me */
3384 out_printf (outh, "\n/*\n"
3385 " * Signal connection wrapper macros\n"
3388 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3389 put_signal_macros (c, TRUE);
3390 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3391 put_signal_macros (c, FALSE);
3392 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3394 put_signal_macros (c, FALSE);
3395 out_printf(outh, "\n");
3398 out_printf (out, "\n/*\n"
3399 " * Signal connection wrapper macro shortcuts\n"
3401 put_local_signal_macros (c);
3402 out_printf(outh, "\n");
3405 /* argument wrapping macros */
3406 if(get_properties > 0 || set_properties > 0) {
3407 out_printf(outh, "\n/*\n"
3408 " * Argument wrapping macros\n"
3411 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3412 put_argument_gnu_wrappers(c);
3413 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3414 put_argument_nongnu_wrappers(c);
3415 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3417 put_argument_nongnu_wrappers(c);
3422 for(li = c->nodes; li != NULL; li = li->next) {
3424 if(n->type == METHOD_NODE)
3425 add_signal_prots((Method *)n);
3431 if(any_method_to_alias(c)) {
3433 out_printf(out, "/* Short form macros */\n");
3434 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3435 make_method_gnu_aliases(c);
3436 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3438 make_method_nongnu_aliases(c);
3441 add_interface_inits (c);
3443 if ( ! overrode_get_type) {
3444 if (c->bonobo_object_class != NULL)
3445 add_bonobo_object_get_type ();
3450 out_printf (out, "/* a macro for creating a new object of our type */\n");
3452 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3453 typebase, funcbase);
3455 out_printf (out, "/* a function for creating a new object of our type */\n");
3456 out_printf (out, "#include <stdarg.h>\n");
3458 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3459 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3460 "{\n\t%s *ret;\n\tva_list ap;\n"
3461 "\tva_start (ap, first);\n"
3462 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3465 "\treturn ret;\n}\n\n",
3467 no_gnu ? "" : " G_GNUC_UNUSED",
3468 typebase, typebase, typebase, funcbase);
3478 if(set_properties > 0) {
3479 add_getset_arg(c, TRUE);
3482 if(get_properties > 0) {
3483 add_getset_arg(c, FALSE);
3486 for(li = c->nodes; li != NULL; li = li->next) {
3488 if(n->type == METHOD_NODE)
3489 put_method((Method *)n);
3492 add_bad_hack_to_avoid_unused_warnings(c);
3496 print_useful_macros(void)
3498 int major = 0, minor = 0, pl = 0;
3501 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3502 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3503 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3504 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3506 /* Useful priv macro thingie */
3507 /* FIXME: this should be done the same way that priv is, as a var,
3509 out_printf (out, "#define selfp (self->_priv)\n\n");
3513 print_more_useful_macros (void)
3516 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3517 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3519 out_printf (out, "#ifdef G_LIKELY\n");
3520 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3521 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3522 out_printf (out, "#else /* ! G_LIKELY */\n");
3523 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3524 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3525 out_printf (out, "#endif /* G_LIKELY */\n");
3530 print_file_comments(void)
3534 out_printf(outh, "/* Generated by GOB (v%s)"
3535 " (do not edit directly) */\n\n", VERSION);
3537 out_printf(outph, "/* Generated by GOB (v%s)"
3538 " (do not edit directly) */\n\n", VERSION);
3539 out_printf(out, "/* Generated by GOB (v%s) on %s"
3540 " (do not edit directly) */\n\n",
3541 VERSION, ctime(&curtime));
3543 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3547 print_includes(void)
3549 gboolean found_header;
3552 /* We may need string.h for memset */
3553 if(destructors > 0 &&
3554 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3555 out_printf(out, "#include <string.h> /* memset() */\n\n");
3558 p = g_strconcat(filebase, ".h", NULL);
3559 found_header = TRUE;
3560 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3561 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3562 found_header = FALSE;
3566 /* if we are creating a private header see if it was included */
3568 p = g_strconcat(filebase, "-private.h", NULL);
3569 if( ! g_list_find_custom(include_files, p,
3570 (GCompareFunc)strcmp)) {
3571 out_printf(out, "#include \"%s-private.h\"\n\n",
3574 error_printf(GOB_WARN, 0,
3575 "Implicit private header include "
3577 "\tsource file, while public "
3578 "header is at a custom location, "
3580 "\texplicitly include "
3581 "the private header below the "
3589 print_header_prefixes(void)
3593 p = replace_sep(((Class *)class)->otype, '_');
3595 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3597 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3598 "#define __%s_PRIVATE_H__\n\n"
3599 "#include \"%s.h\"\n\n", p, p, filebase);
3602 if( ! no_extern_c) {
3603 out_printf(outh, "#ifdef __cplusplus\n"
3605 "#endif /* __cplusplus */\n\n");
3607 out_printf(outph, "#ifdef __cplusplus\n"
3609 "#endif /* __cplusplus */\n\n");
3614 print_header_postfixes(void)
3617 out_printf(outh, "\n#ifdef __cplusplus\n"
3619 "#endif /* __cplusplus */\n");
3620 out_printf(outh, "\n#endif\n");
3623 out_printf(outph, "\n#ifdef __cplusplus\n"
3625 "#endif /* __cplusplus */\n");
3626 out_printf(outph, "\n#endif\n");
3635 /* print the AT_CCODE blocks */
3636 for(li = nodes; li != NULL; li = li->next) {
3637 Node *node = li->data;
3638 if(node->type == CCODE_NODE) {
3639 CCode *cc = (CCode *)node;
3640 if(cc->cctype == AT_CCODE)
3641 print_ccode_block((CCode *)node);
3647 print_header_top(void)
3651 /* mandatory includes */
3652 out_printf (outh, "#include <glib.h>\n");
3653 out_printf (outh, "#include <glib-object.h>\n");
3655 /* print the HT_CCODE blocks */
3656 for (li = nodes; li != NULL; li = li->next) {
3657 Node *node = li->data;
3658 if (node->type == CCODE_NODE) {
3659 CCode *cc = (CCode *)node;
3660 if (cc->cctype == HT_CCODE)
3661 print_ccode_block ((CCode *)node);
3667 print_enum (EnumDef *enode)
3674 funcprefix = replace_sep (enode->etype, '_');
3675 gob_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 EnumValue *value = li->data;
3685 char *sname = gob_strdown (g_strdup (value->name));
3687 while ((p = strchr (sname, '_')) != NULL)
3690 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3691 if (value->value != NULL)
3692 out_printf (outh, " = %s", value->value);
3693 if (li->next != NULL)
3694 out_printf (outh, ",\n");
3696 out_printf (outh, "\n");
3698 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3699 enode->prefix, value->name,
3700 enode->prefix, value->name,
3706 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3708 out_printf (outh, "} %s;\n", type);
3710 str = make_pre_macro (enode->etype, "TYPE");
3711 out_printf (outh, "#define %s ", str);
3714 out_printf (outh, "%s_get_type()\n", funcprefix);
3715 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3718 "GType\n%s_get_type (void)\n"
3720 "\tstatic GType type = 0;\n"
3721 "\tif ___GOB_UNLIKELY(type == 0)\n"
3722 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3725 funcprefix, type, funcprefix);
3727 g_free (funcprefix);
3732 print_flags (Flags *fnode)
3740 funcprefix = replace_sep (fnode->ftype, '_');
3741 gob_strdown (funcprefix);
3742 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3744 type = remove_sep (fnode->ftype);
3746 out_printf (outh, "\ntypedef enum {\n");
3748 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3749 const char *name = li->data;
3751 char *sname = gob_strdown (g_strdup (name));
3753 while ((p = strchr (sname, '_')) != NULL)
3756 out_printf (outh, "\t%s_%s = 1<<%d",
3757 fnode->prefix, name, i);
3758 if (li->next != NULL)
3759 out_printf (outh, ",\n");
3761 out_printf (outh, "\n");
3763 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3764 fnode->prefix, name,
3765 fnode->prefix, name,
3771 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3773 out_printf (outh, "} %s;\n", type);
3775 str = make_pre_macro (fnode->ftype, "TYPE");
3776 out_printf (outh, "#define %s ", str);
3779 out_printf (outh, "%s_get_type()\n", funcprefix);
3780 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3783 "GType\n%s_get_type (void)\n"
3785 "\tstatic GType type = 0;\n"
3786 "\tif ___GOB_UNLIKELY(type == 0)\n"
3787 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3790 funcprefix, type, funcprefix);
3792 g_free (funcprefix);
3797 print_error (Error *enode)
3804 funcprefix = replace_sep (enode->etype, '_');
3805 gob_strdown (funcprefix);
3806 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3808 type = remove_sep (enode->etype);
3810 out_printf (outh, "\ntypedef enum {\n");
3812 for (li = enode->values; li != NULL; li = li->next) {
3813 const char *name = li->data;
3815 char *sname = gob_strdown (g_strdup (name));
3817 while ((p = strchr (sname, '_')) != NULL)
3820 out_printf (outh, "\t%s_%s", enode->prefix, name);
3821 if (li->next != NULL)
3822 out_printf (outh, ",\n");
3824 out_printf (outh, "\n");
3826 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3827 enode->prefix, name,
3828 enode->prefix, name,
3834 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3836 out_printf (outh, "} %s;\n", type);
3838 str = make_pre_macro (enode->etype, "TYPE");
3839 out_printf (outh, "#define %s ", str);
3842 out_printf (outh, "%s_get_type ()\n", funcprefix);
3843 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3846 "GType\n%s_get_type (void)\n"
3848 "\tstatic GType type = 0;\n"
3849 "\tif ___GOB_UNLIKELY(type == 0)\n"
3850 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3853 funcprefix, type, funcprefix);
3855 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3856 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3858 str = replace_sep (enode->etype, '-');
3862 "GQuark\n%s_quark (void)\n"
3864 "\tstatic GQuark q = 0;\n"
3866 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3873 g_free (funcprefix);
3878 generate_outfiles(void)
3882 print_file_comments();
3888 print_header_prefixes();
3890 print_useful_macros();
3894 print_more_useful_macros ();
3896 for (li = nodes; li != NULL; li = li->next) {
3897 Node *node = li->data;
3898 if (node->type == CCODE_NODE) {
3899 CCode *cc = (CCode *)node;
3900 if (cc->cctype != HT_CCODE &&
3901 cc->cctype != AT_CCODE)
3902 print_ccode_block ((CCode *)node);
3903 } else if (node->type == CLASS_NODE) {
3904 print_class_block ((Class *)node);
3905 } else if (node->type == ENUMDEF_NODE) {
3906 print_enum ((EnumDef *)node);
3907 } else if (node->type == FLAGS_NODE) {
3908 print_flags ((Flags *)node);
3909 } else if (node->type == ERROR_NODE) {
3910 print_error ((Error *)node);
3912 g_assert_not_reached();
3916 print_header_postfixes();
3922 fprintf(stderr, "Gob version %s\n\n", VERSION);
3923 fprintf(stderr, "gob [options] file.gob\n\n");
3924 fprintf(stderr, "Options:\n"
3925 "\t--help,-h,-? Display this help\n"
3926 "\t--version Display version\n"
3927 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3928 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3929 "\t--for-cpp Create C++ files\n"
3930 "\t--no-extern-c Never print extern \"C\" into the "
3932 "\t--no-gnu Never use GNU extentions\n"
3933 "\t--no-touch-headers Don't touch headers unless they "
3935 "\t--always-private-header Always create a private header "
3937 "\t even if it would be empty "
3939 "\t--ondemand-private-header Create private header only when "
3941 "\t--no-private-header Don't create a private header, "
3943 "\t structure and protected "
3944 "prototypes inside c file\n"
3945 "\t--always-private-struct Always create a private pointer "
3947 "\t the object structure\n"
3948 "\t--m4 Preprocess source with m4. "
3949 "Following args will\n"
3950 "\t be passed to m4\n"
3951 "\t--m4-dir Print directory that will be "
3954 "\t--no-write,-n Don't write output files, just "
3956 "\t--no-lines Don't print '#line' to output\n"
3957 "\t--no-self-alias Don't create self type and macro "
3959 "\t--no-kill-underscores Ignored for compatibility\n");
3963 parse_options(int argc, char *argv[])
3966 int got_file = FALSE;
3967 int no_opts = FALSE;
3968 int m4_opts = FALSE; /* if we are just passing on args to m4 */
3972 for(i = 1 ; i < argc; i++) {
3974 char *new_commandline;
3975 g_assert(m4_commandline!=NULL);
3977 /* check whether this one looks like the filename */
3978 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
3980 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
3984 /* insert flags before the filename */
3985 new_commandline=g_strconcat(m4_commandline,
3993 /* just an ordinary option */
3995 new_commandline=g_strconcat(m4_commandline,
4000 /* free old commandline */
4001 g_free(m4_commandline);
4002 m4_commandline=new_commandline;
4004 } else if(no_opts ||
4005 argv[i][0] != '-') {
4008 fprintf(stderr, "Specify only one file!\n");
4014 } else if(strcmp(argv[i], "--help")==0) {
4017 } else if(strcmp(argv[i], "--version")==0) {
4018 fprintf(stderr, "Gob version %s\n", VERSION);
4020 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4021 exit_on_warn = TRUE;
4022 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4023 exit_on_warn = FALSE;
4024 } else if(strcmp(argv[i], "--for-cpp")==0) {
4026 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4027 no_touch_headers = TRUE;
4028 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4029 private_header = PRIVATE_HEADER_ONDEMAND;
4030 } else if(strcmp(argv[i], "--always-private-header")==0) {
4031 private_header = PRIVATE_HEADER_ALWAYS;
4032 } else if(strcmp(argv[i], "--no-private-header")==0) {
4033 private_header = PRIVATE_HEADER_NEVER;
4034 } else if(strcmp(argv[i], "--no-gnu")==0) {
4036 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4038 } else if(strcmp(argv[i], "--no-write")==0) {
4040 } else if(strcmp(argv[i], "--no-lines")==0) {
4042 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4043 no_self_alias = TRUE;
4044 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4046 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4047 always_private_struct = TRUE;
4048 } else if(strcmp(argv[i], "--m4-dir")==0) {
4049 printf("%s\n",M4_INCLUDE_DIR);
4051 } else if(strcmp(argv[i], "--m4")==0) {
4055 m4_commandline=g_strdup(M4_COMMANDLINE);
4056 } else if(strcmp(argv[i], "--m4-clean")==0) {
4060 m4_commandline=g_strdup(M4_COMMANDLINE);
4061 } else if(strcmp(argv[i], "--")==0) {
4062 /*further arguments are files*/
4064 } else if(strncmp(argv[i], "--", 2)==0) {
4065 /*unknown long option*/
4066 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4070 /*by now we know we have a string starting with
4071 - which is a short option string*/
4073 for(p = argv[i] + 1; *p; p++) {
4087 "Unknown option '%c'!\n", *p);
4096 /* if we are using m4, and got no filename, append m4 flags now */
4097 if(!got_file && use_m4 && !use_m4_clean) {
4098 char *new_commandline;
4099 new_commandline=g_strconcat(m4_commandline,
4103 g_free(m4_commandline);
4104 m4_commandline=new_commandline;
4109 /* this is a somewhat ugly hack, but it appears to work */
4111 compare_and_move_header(void)
4113 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
4114 char *hf = g_strconcat(filebase, ".h", NULL);
4116 if(stat(hf, &s) == 0) {
4118 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
4119 if(system(s) == 0) {
4120 if(unlink(hfnew) != 0)
4121 error_printf(GOB_ERROR, 0,
4122 "Can't remove new header file");
4130 error_printf(GOB_ERROR, 0,
4131 "Can't remove old header file");
4133 if(rename(hfnew, hf) != 0)
4134 error_printf(GOB_ERROR, 0,
4135 "Can't rename new header file");
4141 main(int argc, char *argv[])
4143 parse_options(argc, argv);
4146 yyin = popen(m4_commandline, "r");
4148 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4152 } else if(filename) {
4153 yyin = fopen(filename, "r");
4155 fprintf(stderr, "Error: can't open file '%s'\n",
4164 /* This is where parsing is done */
4167 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4169 /* close input file */
4170 if(use_m4) pclose(yyin);
4175 error_print (GOB_ERROR, 0, "no class defined");
4178 exit_on_error = FALSE;
4180 signals = count_signals ((Class *)class);
4181 set_properties = count_set_properties ((Class *)class) +
4182 count_set_arguments ((Class *)class);
4183 get_properties = count_get_properties ((Class *)class) +
4184 count_get_arguments ((Class *)class);
4185 overrides = count_overrides ((Class *)class);
4186 privates = count_privates ((Class *)class);
4187 protecteds = count_protecteds ((Class *)class);
4188 unreftors = count_unreftors ((Class *)class);
4189 destructors = count_destructors ((Class *)class);
4190 initializers = count_initializers ((Class *)class);
4191 overrode_get_type = find_get_type ((Class *)class);
4194 make_inits ((Class *)class);
4196 need_dispose = TRUE;
4197 find_dispose ((Class *)class);
4199 if (destructors > 0 ||
4201 need_finalize = TRUE;
4202 find_finalize ((Class *)class);
4204 check_bad_symbols ((Class *)class);
4205 check_duplicate_symbols ((Class *)class);
4206 check_duplicate_overrides ((Class *)class);
4207 check_duplicate_signals_args ((Class *)class);
4208 check_public_new ((Class *)class);
4209 check_vararg ((Class *)class);
4210 check_firstarg ((Class *)class);
4211 check_nonvoidempty ((Class *)class);
4212 check_signal_args ((Class *)class);
4213 check_property_types ((Class *)class);
4214 check_argument_types ((Class *)class);
4215 check_func_arg_checks ((Class *)class);
4216 check_for_class_destructors ((Class *)class);
4218 exit_on_error = TRUE;
4223 any_special = setup_special_array ((Class *)class, special_array);
4227 generate_outfiles ();
4238 if (no_touch_headers &&
4240 compare_and_move_header ();