2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001 George Lebl
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
33 #include "treefuncs.h"
41 char *filename = NULL;
51 extern GList *include_files;
53 extern GHashTable *gtk_doc_hash;
56 static char *funcbase;
57 static char *pfuncbase;
58 static char *macrobase;
60 static char *pmacrois;
61 static char *macrotype;
62 static char *pmacrotype;
63 static char *typebase;
64 static char *ptypebase;
66 static int signals = 0; /* number of signals */
67 static int set_properties = 0; /* number of named (set) properties */
68 static int get_properties = 0; /* number of named (get) properties */
69 static int overrides = 0; /* number of override methods */
70 static int privates = 0; /* number of private data members */
71 static int protecteds = 0; /* number of protected methods */
72 static int unreftors = 0; /* number of variable unreffing destructors */
73 static int destructors = 0; /* number of variable non-unreffing destructors */
74 static int initializers = 0; /* number of variable initializers */
75 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
77 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
78 and need the REALLY UGLY HACK to
81 /* the special variable types we need to define */
82 static gboolean special_array[SPECIAL_LAST] = {0};
83 static gboolean any_special = FALSE;
85 static gboolean need_shutdown = FALSE;
86 static Method * shutdown_handler = NULL;
88 static gboolean need_finalize = FALSE;
89 static Method * finalize_handler = NULL;
96 gboolean no_touch_headers = FALSE;
97 gboolean for_cpp = FALSE;
98 gboolean no_gnu = FALSE;
99 gboolean exit_on_warn = FALSE;
100 gboolean exit_on_error = TRUE;
101 gboolean got_error = FALSE;
102 gint private_header = PRIVATE_HEADER_ONDEMAND;
103 gboolean no_extern_c = FALSE;
104 gboolean no_write = FALSE;
105 gboolean no_lines = FALSE;
106 gboolean no_self_alias = FALSE;
107 gboolean always_private_struct = FALSE;
109 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
110 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
111 char *m4_commandline = NULL;
112 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
113 #define M4_BASE_FILENAME "gobm4.m4"
114 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
115 #define M4_COMMANDLINE "m4"
117 int method_unique_id = 1;
122 filebase = replace_sep (((Class *)class)->otype, '-');
123 g_strdown (filebase);
125 funcbase = replace_sep (((Class *)class)->otype, '_');
126 g_strdown (funcbase);
128 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
129 g_strdown (pfuncbase);
131 macrobase = replace_sep (((Class *)class)->otype, '_');
134 macrois = make_pre_macro (((Class *)class)->otype, "IS");
135 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
137 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
138 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
140 typebase = remove_sep (((Class *)class)->otype);
142 ptypebase = remove_sep (((Class *)class)->ptype);
146 get_type (const Type *t, gboolean postfix_to_stars)
153 s = remove_sep(t->name);
154 gs = g_string_new(s);
158 if (postfix_to_stars) {
160 /*XXX: this is ugly perhaps we can do this whole postfix thing
161 in a nicer way, we just count the number of '[' s and from
162 that we deduce the number of dimensions, so that we can print
164 for (p = t->postfix; p && *p; p++)
165 if(*p == '[') extra++;
167 g_string_append_c(gs, ' ');
169 if (t->pointer != NULL) {
170 g_string_append (gs, t->pointer);
171 for (i=0; i < extra; i++)
172 g_string_append_c (gs, '*');
173 g_string_append_c (gs, ' ');
177 g_string_free (gs, FALSE);
182 get_gtk_doc (const char *id)
189 val = g_hash_table_lookup(gtk_doc_hash, id);
191 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
193 val = g_hash_table_lookup(gtk_doc_hash, id);
195 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
201 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
205 s = get_type(t, postfix_to_stars);
206 out_printf(fp, "%s", s);
212 print_method (FILE *fp,
213 const char *typeprefix,
214 const char *nameprefix,
215 const char *subnameprefix,
216 const char *namepostfix,
217 const char *afterargs,
220 gboolean one_arg_per_line,
221 gboolean no_funcbase,
222 gboolean kill_underscore)
227 out_printf(fp, "%s", typeprefix);
228 print_type(fp, m->mtype, TRUE);
233 out_printf(fp, "%s%s%s%s(",
234 nameprefix, subnameprefix, id, namepostfix);
236 out_printf(fp, "%s%s_%s%s%s(",
237 nameprefix, funcbase, subnameprefix, id,
241 for(li=m->args; li; li=g_list_next(li)) {
242 FuncArg *arg = li->data;
243 print_type(fp, arg->atype, FALSE);
245 out_printf(fp, "%s%s,%s", arg->name,
246 arg->atype->postfix ?
247 arg->atype->postfix : "",
248 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
250 out_printf(fp, "%s%s", arg->name,
251 arg->atype->postfix ?
252 arg->atype->postfix : "");
255 out_printf(fp, ",%s...",
256 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
258 out_printf(fp, "void");
260 out_printf(fp, "%s)%s", afterargs, postfix);
264 any_method_to_alias(Class *c)
268 for(li=c->nodes;li;li=g_list_next(li)) {
269 Node *node = li->data;
270 if(node->type == METHOD_NODE) {
271 Method *m = (Method *)node;
273 if(m->method == INIT_METHOD ||
274 m->method == CLASS_INIT_METHOD ||
275 m->method == OVERRIDE_METHOD)
285 /* just the vararg macros, we use the same func pointers for these as in non-gnu */
287 make_method_gnu_aliases(Class *c)
291 for(li = c->nodes; li != NULL; li = li->next) {
292 Node *node = li->data;
293 if(node->type == METHOD_NODE) {
294 Method *m = (Method *)node;
296 if(m->method == INIT_METHOD ||
297 m->method == CLASS_INIT_METHOD ||
298 m->method == OVERRIDE_METHOD)
302 out_printf(out, "#define self_%s(args...) "
303 "%s_%s(args)\n", m->id,
306 out_printf(out, "#define self_%s() "
314 make_method_nongnu_aliases(Class *c)
318 gboolean local_made_aliases = FALSE;
320 for(li=c->nodes; li; li=g_list_next(li)) {
321 Node *node = li->data;
322 if(node->type == METHOD_NODE) {
323 Method *m = (Method *)node;
325 if(m->method == INIT_METHOD ||
326 m->method == CLASS_INIT_METHOD ||
327 m->method == OVERRIDE_METHOD)
330 if( ! local_made_aliases)
331 out_printf(out, "\n/* Short form pointers */\n");
333 print_method(out, "static ", "(* const self_", "", ") ",
335 m, FALSE, TRUE, FALSE);
336 out_printf(out, " = %s_%s;\n", funcbase,
339 local_made_aliases = TRUE;
342 if(local_made_aliases) {
343 out_printf(out, "\n");
349 add_bad_hack_to_avoid_unused_warnings(Class *c)
353 /* if we haven't had any methods, just return */
358 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
360 "/*REALLY BAD HACK\n"
361 " This is to avoid unused warnings if you don't call\n"
362 " some method. I need to find a better way to do\n"
363 " this, not needed in GCC since we use some gcc\n"
364 " extentions to make saner, faster code */\n"
366 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
368 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
369 for(li=c->nodes;li;li=g_list_next(li)) {
370 Node *node = li->data;
371 if(node->type == METHOD_NODE) {
372 Method *m = (Method *)node;
374 if(m->method == INIT_METHOD ||
375 m->method == CLASS_INIT_METHOD ||
376 m->method == OVERRIDE_METHOD)
379 /* in C++ mode we don't alias new */
380 if(for_cpp && strcmp(m->id, "new")==0)
383 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
386 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
389 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
391 out_printf(out, "}\n\n");
395 put_variable(Variable *v, FILE *fp)
397 out_printf(fp, "\t");
398 print_type(fp, v->vtype, FALSE);
399 out_printf(fp, "%s%s;", v->id,
401 v->vtype->postfix:"");
402 if(v->scope == PROTECTED_SCOPE)
403 out_printf(fp, " /* protected */");
404 out_printf(fp, "\n");
408 put_vs_method(const Method *m)
410 if(m->method != SIGNAL_LAST_METHOD &&
411 m->method != SIGNAL_FIRST_METHOD &&
412 m->method != VIRTUAL_METHOD)
415 /* if a signal mark it as such */
416 if(m->method != VIRTUAL_METHOD)
417 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
418 m, FALSE, TRUE, TRUE);
420 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
421 m, FALSE, TRUE, TRUE);
425 put_pub_method(const Method *m)
427 if(m->scope != PUBLIC_SCOPE)
430 print_method(outh, "", "\t", "", "\t", "", ";\n", m, TRUE, FALSE, TRUE);
434 put_signal_macro (const Method *m, gboolean gnu)
436 if(m->method != SIGNAL_LAST_METHOD &&
437 m->method != SIGNAL_FIRST_METHOD)
442 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
443 "g_signal_connect(%s(object),\"%s\","
444 "(GCallback)(func),(data))\n",
445 funcbase, m->id, macrobase, m->id);
448 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
449 "g_signal_connect_after(%s(object),\"%s\","
450 "(GCallback)(func),(data))\n",
451 funcbase, m->id, macrobase, m->id);
454 out_printf (outh, "#define %s_connect_data__%s"
455 "(object,func,data,destroy_data,flags)\t"
456 "g_signal_connect_data(%s(object),\"%s\","
457 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
458 funcbase, m->id, macrobase, m->id);
461 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
463 "%s(({%s *___object = (object); ___object; })),"
466 funcbase, m->id, macrobase, typebase, m->id);
467 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
468 " = (func); ", m, FALSE, TRUE, TRUE);
469 out_printf (outh, "___%s; }), (data))\n", m->id);
472 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
473 "g_signal_connect_after("
474 "%s(({%s *___object = (object); ___object; })),"
477 funcbase, m->id, macrobase, typebase, m->id);
478 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
479 " = (func); ", m, FALSE, TRUE, TRUE);
480 out_printf (outh, "___%s; }), (data))\n", m->id);
483 out_printf (outh, "#define %s_connect_data__%s"
484 "(object,func,data,destroy_data,flags)\t"
485 "g_signal_connect_data("
486 "%s(({%s *___object = (object); ___object; })),"
489 funcbase, m->id, macrobase, typebase, m->id);
490 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
491 " = (func); ", m, FALSE, TRUE, TRUE);
492 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
497 put_signal_macros (const Class *c, gboolean gnu)
504 for (li = c->nodes; li != NULL; li = li->next) {
505 const Node *n = li->data;
506 if (n->type == METHOD_NODE)
507 put_signal_macro ((Method *)n, gnu);
512 put_local_signal_macro (const Method *m)
514 if(m->method != SIGNAL_LAST_METHOD &&
515 m->method != SIGNAL_FIRST_METHOD)
519 out_printf (out, "#define self_connect__%s(object,func,data)\t"
520 "%s_connect__%s((object),(func),(data))\n",
521 m->id, funcbase, m->id);
524 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
525 "%s_connect_after__%s((object),(func),(data))\n",
526 m->id, funcbase, m->id);
529 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
530 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
531 m->id, funcbase, m->id);
535 put_local_signal_macros (const Class *c)
542 for (li = c->nodes; li != NULL; li = li->next) {
543 const Node *n = li->data;
544 if (n->type == METHOD_NODE)
545 put_local_signal_macro ((Method *)n);
551 put_prot_method(const Method *m)
553 if(m->scope != PROTECTED_SCOPE)
557 print_method(outph, "", "\t", "", "\t", "", ";\n",
558 m, FALSE, FALSE, TRUE);
560 print_method(out, "", "\t", "", "\t", "", ";\n",
561 m, FALSE, FALSE, TRUE);
565 put_priv_method_prot(Method *m)
567 if(m->method == SIGNAL_LAST_METHOD ||
568 m->method == SIGNAL_FIRST_METHOD ||
569 m->method == VIRTUAL_METHOD) {
572 "static ", "___real_", "", " ", "", ";\n",
573 m, FALSE, FALSE, TRUE);
575 /* no else, here, it might still have a private prototype, it's not
578 if((m->method == OVERRIDE_METHOD &&
581 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
582 print_method(out, "static ", s, "", " ", "",
583 no_gnu?";\n":" G_GNUC_UNUSED;\n",
584 m, FALSE, FALSE, FALSE);
586 } else if(m->scope == PRIVATE_SCOPE ||
587 m->method == INIT_METHOD ||
588 m->method == CLASS_INIT_METHOD) {
589 print_method(out, "static ", "", "", " ", "",
590 no_gnu?";\n":" G_GNUC_UNUSED;\n",
591 m, FALSE, FALSE, TRUE);
596 make_func_arg (const char *typename, gboolean is_class, const char *name)
603 tn = g_strconcat (typename, ":Class", NULL);
605 tn = g_strdup (typename);
607 type = node_new (TYPE_NODE,
611 node = node_new (FUNCARG_NODE,
612 "atype:steal", (Type *)type,
615 return g_list_prepend (NULL, node);
619 make_inits(Class *cl)
621 int got_class_init = FALSE;
622 int got_init = FALSE;
625 for(li=cl->nodes;li;li=g_list_next(li)) {
627 if(n->type == METHOD_NODE) {
628 Method *m = (Method *)n;
629 if(m->method == INIT_METHOD) {
631 error_print(GOB_ERROR, m->line_no, "init defined more then once");
633 } else if(m->method == CLASS_INIT_METHOD) {
635 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
636 got_class_init = TRUE;
640 if(!got_class_init) {
641 Type *type = (Type *)node_new (TYPE_NODE,
644 node = node_new (METHOD_NODE,
646 "method", CLASS_INIT_METHOD,
649 "args:steal", make_func_arg (cl->otype,
652 "unique_id", method_unique_id++,
654 cl->nodes = g_list_prepend(cl->nodes, node);
657 Type *type = (Type *)node_new (TYPE_NODE,
660 node = node_new (METHOD_NODE,
662 "method", INIT_METHOD,
665 "args:steal", make_func_arg (cl->otype,
666 FALSE /* is_class */,
668 "unique_id", method_unique_id++,
670 cl->nodes = g_list_prepend(cl->nodes, node);
675 find_shutdown(Class *cl)
679 shutdown_handler = NULL;
680 for(li=cl->nodes;li;li=g_list_next(li)) {
682 if(n->type == METHOD_NODE) {
683 Method *m = (Method *)n;
684 if(m->method == OVERRIDE_METHOD &&
685 strcmp(m->id, "shutdown")==0) {
686 if(strcmp(m->otype, "G:Object") != 0) {
687 error_print(GOB_ERROR, m->line_no,
688 "shutdown method override "
689 "of class other then "
692 if(g_list_length(m->args) != 1) {
693 error_print(GOB_ERROR, m->line_no,
694 "shutdown method override "
695 "with more then one "
698 shutdown_handler = m;
706 find_finalize(Class *cl)
710 finalize_handler = NULL;
711 for(li=cl->nodes;li;li=g_list_next(li)) {
713 if(n->type == METHOD_NODE) {
714 Method *m = (Method *)n;
715 if(m->method == OVERRIDE_METHOD &&
716 strcmp(m->id, "finalize")==0) {
717 if(strcmp(m->otype, "G:Object") != 0) {
718 error_print(GOB_ERROR, m->line_no,
719 "finalize method override "
720 "of class other then "
723 if(g_list_length(m->args) != 1) {
724 error_print(GOB_ERROR, m->line_no,
725 "finalize method override "
726 "with more then one "
729 finalize_handler = m;
737 /* hash of method -> name of signal prototype */
738 static GHashTable *marsh = NULL;
740 /* list of methods with different signal prototypes,
741 we check this list if we can use a signal prototype of a
742 previous signal method, there are only uniques here */
743 static GList *eq_signal_methods = NULL;
745 /* compare a list of strings */
747 is_list_equal(GList *a, GList *b)
749 for(;a && b; a=a->next, b=b->next) {
750 if(strcmp(a->data, b->data)!=0) {
754 /* the the lists were different length */
761 find_same_type_signal(Method *m)
764 for(li=eq_signal_methods;li;li=li->next) {
765 Method *mm = li->data;
766 if(is_list_equal(mm->gtktypes, m->gtktypes))
773 print_signal_marsal_args (Method *m)
775 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
778 for (i = 0, li = m->gtktypes->next;
780 i++, li = li->next) {
781 char *get_func = g_strdup_printf
782 ("g_value_get_%s", (char *)li->data);
783 g_strdown (get_func);
784 out_printf (out, ",\n\t\t(%s) "
785 "%s (param_values + %d)",
786 get_cast (li->data, FALSE),
791 out_printf (out, ",\n\t\tdata2);\n");
796 add_signal_prots(Method *m)
802 gboolean ret_none = FALSE;
803 gboolean arglist_none = FALSE;
806 if (m->method != SIGNAL_LAST_METHOD &&
807 m->method != SIGNAL_FIRST_METHOD)
811 marsh = g_hash_table_new(NULL, NULL);
813 g_assert (m->gtktypes->next != NULL);
815 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
816 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
818 if (ret_none && arglist_none)
821 /* if we already did a signal prototype just use that */
822 mm = find_same_type_signal (m);
824 s = g_hash_table_lookup (marsh, mm);
825 g_hash_table_insert (marsh, m, s);
832 retcast = get_cast (m->gtktypes->data, FALSE);
834 s = g_strdup_printf("Sig%d", sig++);
836 g_hash_table_insert(marsh, m, s);
837 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
839 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
840 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
841 get_cast(m->gtktypes->data, FALSE), s, typebase);
843 if ( ! arglist_none) {
844 for (li = m->gtktypes->next; li != NULL; li = li->next)
845 out_printf (out, "%s, ", get_cast (li->data, FALSE));
847 out_printf (out, "gpointer);\n");
849 out_printf (out, "\nstatic void\n"
850 "___marshal_%s (GClosure *closure,\n"
851 "\tGValue *return_value,\n"
852 "\tguint n_param_values,\n"
853 "\tconst GValue *param_values,\n"
854 "\tgpointer invocation_hint,\n"
855 "\tgpointer marshal_data)\n"
859 out_printf (out, "\t%s v_return;\n", retcast);
861 out_printf (out, "\tregister ___%s callback;\n"
862 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
863 "\tregister gpointer data1, data2;\n\n",
866 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
867 arglist_none ? 1 : g_list_length (m->gtktypes));
870 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
871 "\t\tdata1 = closure->data;\n"
872 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
874 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
875 "\t\tdata2 = closure->data;\n"
878 out_printf (out, "\tcallback = (___%s) "
879 "(marshal_data != NULL ? marshal_data : cc->callback);"
883 out_printf (out, "\tcallback ((%s *)data1", typebase);
885 out_printf (out, "\tv_return = callback ((%s *)data1",
889 print_signal_marsal_args (m);
892 /* FIXME: This code is so fucking ugly it hurts */
893 gboolean take_ownership =
894 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
895 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
896 char *set_func = g_strdup_printf ("g_value_set_%s%s",
897 (char *)m->gtktypes->data,
899 "_take_ownership" : "");
900 g_strdown (set_func);
902 out_printf (out, "\n\t%s (return_value, v_return);\n",
907 out_printf (out, "}\n\n");
914 out_printf(out, "\n");
916 out_printf(out, "enum {\n");
917 for(li=c->nodes;li;li=g_list_next(li)) {
919 if(n->type == METHOD_NODE) {
920 Method *m = (Method *)n;
921 if(m->method == SIGNAL_LAST_METHOD ||
922 m->method == SIGNAL_FIRST_METHOD) {
923 char *s = g_strdup(m->id);
925 out_printf(out, "\t%s_SIGNAL,\n", s);
930 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
932 if (set_properties > 0 ||
933 get_properties > 0) {
934 out_printf(out, "enum {\n\tPROP_0");
935 for(li=c->nodes;li;li=g_list_next(li)) {
937 if (n->type == PROPERTY_NODE) {
938 Property *p = (Property *)n;
939 char *s = g_strdup (p->name);
941 out_printf (out, ",\n\tPROP_%s", s);
943 } else if (n->type == ARGUMENT_NODE) {
944 Argument *a = (Argument *)n;
945 char *s = g_strdup(a->name);
947 out_printf(out, ",\n\tPROP_%s", s);
951 out_printf(out, "\n};\n\n");
956 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
958 out_printf(out, "/* pointer to the class of our parent */\n");
959 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
963 add_interface_methods (Class *c, const char *interface)
966 gboolean added_line = FALSE;
968 for (li = c->nodes; li != NULL; li = li->next) {
970 Method *m = (Method *)n;
971 if (n->type != METHOD_NODE ||
972 m->method == OVERRIDE_METHOD ||
973 m->interface == NULL ||
974 strcmp (m->interface, interface) != 0)
977 if (m->line_no > 0) {
978 out_addline_infile (out, m->line_no);
980 } else if (m->line_no == 0 &&
982 out_addline_outfile (out);
985 out_printf (out, "\tiface->%s = self_%s;\n",
989 out_addline_outfile (out);
993 add_interface_inits (Class *c)
997 if (c->interfaces == NULL)
1000 out_printf(out, "\n");
1002 for (li = c->interfaces; li != NULL; li = li->next) {
1003 const char *interface = li->data;
1005 char *name = replace_sep (interface, '_');
1006 char *type = remove_sep (interface);
1008 /* EEEK! evil, we should have some sort of option
1009 * to force this for arbitrary interfaces, since
1010 * some are Class and some are Iface. Glib is shite
1011 * in consistency. */
1012 if (strcmp (type, "GtkEditable") == 0 ||
1013 strcmp (type, "GTypePlugin") == 0)
1016 /* We'll assume Iface is the standard ending */
1019 out_printf (out, "\nstatic void\n"
1020 "___%s_init (%s%s *iface)\n"
1024 add_interface_methods (c, interface);
1026 out_printf (out, "}\n\n");
1034 add_interface_infos (void)
1037 for (li = ((Class *)class)->interfaces;
1040 char *name = replace_sep (li->data, '_');
1042 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1043 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1053 add_interfaces (void)
1056 for (li = ((Class *)class)->interfaces;
1059 char *name = replace_sep (li->data, '_');
1060 char *type = make_pre_macro (li->data, "TYPE");
1063 "\t\tg_type_add_interface_static (type,\n"
1065 "\t\t\t&%s_info);\n",
1077 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1081 "%s_get_type (void)\n"
1083 "\tstatic GType type = 0;\n\n"
1084 "\tif (type == 0) {\n"
1085 "\t\tstatic const GTypeInfo info = {\n"
1086 "\t\t\tsizeof (%sClass),\n"
1087 "\t\t\t(GBaseInitFunc) NULL,\n"
1088 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1089 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1090 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1091 "\t\t\tNULL /* class_data */,\n"
1092 "\t\t\tsizeof (%s),\n"
1093 "\t\t\t0 /* n_preallocs */,\n"
1094 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1096 funcbase, typebase, funcbase, typebase, funcbase);
1098 add_interface_infos ();
1101 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)0);\n",
1102 pmacrotype, typebase);
1110 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1112 chunk_size, chunk_size);
1122 add_bonobo_object_get_type (void)
1124 /* char *chunk_size = ((Class*)class)->chunk_size; */
1125 /* _vicious_ spanks seth with a rusty nail
1127 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1128 "gob2 doesn't officially support it yet. It'd be safer "
1129 "and a lot more fun to blow goats.\"\n");
1134 "%s_get_type (void)\n" /* 1 */
1136 "\tstatic GType type = 0;\n\n"
1137 "\tif (type == 0) {\n"
1138 "\t\tstatic const GTypeInfo info = {\n"
1139 "\t\t\tsizeof (%sClass),\n" /* 2 */
1140 "\t\t\t(GBaseInitFunc) NULL,\n"
1141 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1142 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1143 "\t\t\tNULL, /* class_finalize */\n"
1144 "\t\t\tNULL, /* class_data */\n"
1145 "\t\t\tsizeof (%s),\n" /* 4 */
1146 "\t\t\t0, /* n_preallocs */\n"
1147 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1156 add_interface_infos ();
1159 "\t\ttype = bonobo_type_unique (\n"
1160 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1161 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1162 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1163 "\t\t\t&info, \"%s\");\n", /* 3 */
1164 ((Class*)class)->bonobo_object_class /* 1 */,
1173 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1175 chunk_size, chunk_size);
1184 add_overrides(Class *c, const char *oname,
1185 gboolean did_base_obj)
1191 done = g_hash_table_new (g_str_hash, g_str_equal);
1193 s = g_strdup ("GObject");
1194 g_hash_table_insert (done, s, s);
1196 for (li = c->nodes; li != NULL; li = li->next) {
1199 Method *m = (Method *)n;
1200 if(n->type != METHOD_NODE ||
1201 m->method != OVERRIDE_METHOD)
1204 s = remove_sep(m->otype);
1206 if(g_hash_table_lookup(done, s)) {
1210 g_hash_table_insert(done, s, s);
1212 f = replace_sep(m->otype, '_');
1215 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1220 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1221 g_hash_table_destroy (done);
1225 make_run_signal_flags(Method *m, gboolean last)
1240 gs = g_string_new(NULL);
1243 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1245 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1247 if(m->scope == PUBLIC_SCOPE)
1248 g_string_append(gs, " | G_SIGNAL_ACTION");
1250 for(li = m->flags; li; li = li->next) {
1251 char *flag = li->data;
1253 for(i=0;flags[i];i++) {
1254 if(strcmp(flags[i], flag)==0)
1257 /* if we haven't found it in our list */
1259 error_printf(GOB_WARN, m->line_no,
1260 "Unknown flag '%s' used, "
1261 "perhaps it was misspelled",
1264 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1268 char *ret = gs->str;
1269 g_string_free(gs, FALSE);
1276 add_signals(Class *c)
1280 out_printf(out, "\n");
1281 for(li=c->nodes;li;li=g_list_next(li)) {
1283 char *mar, *sig, *flags;
1284 gboolean is_none, last = FALSE;
1285 Method *m = (Method *)n;
1287 if(n->type != METHOD_NODE ||
1288 (m->method != SIGNAL_FIRST_METHOD &&
1289 m->method != SIGNAL_LAST_METHOD))
1292 if(m->method == SIGNAL_FIRST_METHOD)
1297 if(g_hash_table_lookup(marsh, m))
1298 mar = g_strconcat("___marshal_",
1299 (char *)g_hash_table_lookup(marsh, m),
1302 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1304 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1306 sig = g_strdup (m->id);
1308 flags = make_run_signal_flags (m, last);
1309 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1310 "\t\tg_signal_new (\"%s\",\n"
1311 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1312 "\t\t\t(GSignalFlags)(%s),\n"
1313 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1314 "\t\t\tNULL, NULL,\n"
1316 "\t\t\tG_TYPE_%s, %d",
1319 typebase, m->id, mar,
1320 (char *)m->gtktypes->data,
1321 is_none ? 0 : g_list_length(m->gtktypes->next));
1328 for(l = m->gtktypes->next; l != NULL; l = l->next)
1329 out_printf(out, ",\n\t\t\tG_TYPE_%s",
1333 out_printf(out, ");\n");
1335 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1339 out_printf(out, "\tif(");
1340 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1341 out_printf(out, "%s sizeof(", sep);
1342 print_type(out, m->mtype, FALSE);
1343 out_printf(out, "%s",
1345 m->mtype->postfix : "");
1346 out_printf(out, ") != sizeof(%s)",
1347 get_cast(m->gtktypes->data, FALSE));
1352 for(al = m->args->next, gl = m->gtktypes->next;
1353 al != NULL && gl != NULL;
1354 al = al->next, gl = gl->next) {
1355 FuncArg *arg = al->data;
1356 char *gtkarg = gl->data;
1358 out_printf(out, "%ssizeof(", sep);
1359 print_type(out, arg->atype, FALSE);
1360 out_printf(out, "%s",
1361 arg->atype->postfix ?
1362 arg->atype->postfix : "");
1363 out_printf(out, ") != sizeof(%s)",
1364 get_cast(gtkarg, FALSE));
1368 out_printf(out, ") {\n"
1369 "\t\tg_error(\"%s line %d: Type mismatch "
1370 "of \\\"%s\\\" signal signature\");\n"
1372 filename, m->line_no, m->id);
1379 set_def_handlers(Class *c, const char *oname)
1382 gboolean set_line = FALSE;
1384 out_printf(out, "\n");
1385 for(li = c->nodes; li; li = g_list_next(li)) {
1387 Method *m = (Method *)n;
1389 if(n->type != METHOD_NODE ||
1390 (m->method != SIGNAL_FIRST_METHOD &&
1391 m->method != SIGNAL_LAST_METHOD &&
1392 m->method != VIRTUAL_METHOD &&
1393 m->method != OVERRIDE_METHOD))
1396 if(m->line_no > 0 && m->cbuf) {
1397 out_addline_infile(out, m->line_no);
1399 } else if(set_line) {
1400 out_addline_outfile(out);
1405 if (m->method == OVERRIDE_METHOD) {
1407 s = replace_sep (m->otype, '_');
1410 if (need_shutdown &&
1411 shutdown_handler != NULL &&
1412 strcmp (m->id, "shutdown") == 0)
1413 out_printf (out, "\tg_object_class->shutdown "
1414 "= ___shutdown;\n");
1415 else if (need_finalize &&
1417 strcmp(m->id, "finalize") == 0)
1419 "\tg_object_class->finalize = ___finalize;\n");
1420 else if (m->cbuf != NULL)
1422 "\t%s_class->%s = ___%x_%s_%s;\n",
1423 s, m->id, (guint)m->unique_id,
1426 out_printf(out, "\t%s_class->%s = NULL;\n",
1430 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1434 out_printf(out, "\t%s->%s = NULL;\n",
1439 out_addline_outfile(out);
1443 make_argument (Argument *a)
1448 char *argflags[] = {
1456 flags = g_string_new ("(GParamFlags)(");
1458 if(a->get && a->set)
1459 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1461 g_string_append (flags, "G_PARAM_READABLE");
1463 g_string_append (flags, "G_PARAM_WRITABLE");
1465 g_assert(a->get || a->set);
1467 for (l = a->flags; l != NULL; l = l->next) {
1468 char *flag = l->data;
1470 if(strcmp (flag, "READABLE") == 0 ||
1471 strcmp (flag, "WRITABLE") == 0) {
1472 error_print(GOB_WARN, a->line_no,
1474 "WRITABLE argument flags are "
1475 "set automatically");
1478 for(i = 0; argflags[i]; i++) {
1479 if(strcmp(argflags[i], flag)==0)
1482 /* if we haven't found it in our list */
1483 if( ! argflags[i]) {
1484 error_printf(GOB_WARN, a->line_no,
1485 "Unknown flag '%s' used, "
1486 "perhaps it was misspelled", flag);
1488 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1491 g_string_append (flags, ")");
1493 s = g_strdup(a->name);
1495 if (!strcmp (a->gtktype, "ENUM"))
1496 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1497 "\t\tG_TYPE_ENUM, 0,\n"
1499 a->name, flags->str);
1500 if (!strcmp (a->gtktype, "FLAGS"))
1501 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1502 "\t\tG_TYPE_FLAGS, 0,\n"
1504 a->name, flags->str);
1505 else if (!strcmp (a->gtktype, "OBJECT"))
1506 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1507 "\t\tG_TYPE_OBJECT,\n"
1509 a->name, flags->str);
1510 else if (!strcmp (a->gtktype, "STRING"))
1511 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1514 a->name, flags->str);
1515 else if (!strcmp (a->gtktype, "INT"))
1516 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1517 "\t\tG_MININT, G_MAXINT,\n"
1520 a->name, flags->str);
1521 else if (!strcmp (a->gtktype, "UINT"))
1522 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1523 "\t\t0, G_MAXUINT,\n"
1526 a->name, flags->str);
1527 else if (!strcmp (a->gtktype, "INT"))
1528 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1529 "\t\tG_MININT, G_MAXINT,\n"
1532 a->name, flags->str);
1533 else if (!strcmp (a->gtktype, "CHAR"))
1534 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1538 a->name, flags->str);
1539 else if (!strcmp (a->gtktype, "UCHAR"))
1540 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1544 a->name, flags->str);
1545 else if (!strcmp (a->gtktype, "BOOL") ||
1546 !strcmp (a->gtktype, "BOOLEAN"))
1547 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1550 a->name, flags->str);
1551 else if (!strcmp (a->gtktype, "LONG"))
1552 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1553 "\t\tG_MINLONG, G_MAXLONG,\n"
1556 a->name, flags->str);
1557 else if (!strcmp (a->gtktype, "ULONG"))
1558 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1559 "\t\t0, G_MAXULONG,\n"
1562 a->name, flags->str);
1563 else if (!strcmp (a->gtktype, "FLOAT"))
1564 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1565 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1568 a->name, flags->str);
1569 else if (!strcmp (a->gtktype, "DOUBLE"))
1570 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1571 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1574 a->name, flags->str);
1575 else if (!strcmp (a->gtktype, "POINTER"))
1576 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1578 a->name, flags->str);
1580 error_printf (GOB_ERROR, a->line_no,
1581 "%s type is not supported for arguments, try using properties",
1584 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1585 "\t\tPROP_%s, param_spec);\n", s);
1589 g_string_free(flags, TRUE);
1592 #define value_for_print(str, alt) (str != NULL ? str : alt)
1595 make_property (Property *p)
1600 char *argflags[] = {
1608 flags = g_string_new ("(GParamFlags)(");
1610 if (p->get != NULL && p->set != NULL)
1611 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1612 else if (p->get != NULL)
1613 g_string_append (flags, "G_PARAM_READABLE");
1615 g_string_append (flags, "G_PARAM_WRITABLE");
1617 if (p->get == NULL && p->set == NULL) {
1618 error_print (GOB_ERROR, p->line_no,
1619 "Property has no getter nor setter");
1622 for (l = p->flags; l != NULL; l = l->next) {
1623 char *flag = l->data;
1625 if(strcmp (flag, "READABLE") == 0 ||
1626 strcmp (flag, "WRITABLE") == 0) {
1627 error_print(GOB_WARN, p->line_no,
1629 "WRITABLE argument flags are "
1630 "set automatically");
1633 for(i = 0; argflags[i]; i++) {
1634 if(strcmp(argflags[i], flag)==0)
1637 /* if we haven't found it in our list */
1638 if( ! argflags[i]) {
1639 error_printf(GOB_WARN, p->line_no,
1640 "Unknown flag '%s' used, "
1641 "perhaps it was misspelled", flag);
1643 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1646 g_string_append (flags, ")");
1648 if (strcmp (p->gtktype, "CHAR") == 0)
1649 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1650 "\t\t(\"%s\" /* name */,\n"
1651 "\t\t %s /* nick */,\n"
1652 "\t\t %s /* blurb */,\n"
1653 "\t\t %s /* minimum */,\n"
1654 "\t\t %s /* maximum */,\n"
1655 "\t\t %s /* default_value */,\n"
1658 value_for_print (p->nick, "NULL"),
1659 value_for_print (p->blurb, "NULL"),
1660 value_for_print (p->minimum, "-128"),
1661 value_for_print (p->maximum, "127"),
1662 value_for_print (p->default_value, "0"),
1664 else if (strcmp (p->gtktype, "UCHAR") == 0)
1665 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1666 "\t\t(\"%s\" /* name */,\n"
1667 "\t\t %s /* nick */,\n"
1668 "\t\t %s /* blurb */,\n"
1669 "\t\t %s /* minimum */,\n"
1670 "\t\t %s /* maximum */,\n"
1671 "\t\t %s /* default_value */,\n"
1674 value_for_print (p->nick, "NULL"),
1675 value_for_print (p->blurb, "NULL"),
1676 value_for_print (p->minimum, "0"),
1677 value_for_print (p->maximum, "0xFF"),
1678 value_for_print (p->default_value, "0"),
1680 else if (strcmp (p->gtktype, "BOOLEAN") == 0)
1681 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1682 "\t\t(\"%s\" /* name */,\n"
1683 "\t\t %s /* nick */,\n"
1684 "\t\t %s /* blurb */,\n"
1685 "\t\t %s /* default_value */,\n"
1688 value_for_print (p->nick, "NULL"),
1689 value_for_print (p->blurb, "NULL"),
1690 value_for_print (p->default_value, "FALSE"),
1692 else if (strcmp (p->gtktype, "INT") == 0)
1693 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1694 "\t\t(\"%s\" /* name */,\n"
1695 "\t\t %s /* nick */,\n"
1696 "\t\t %s /* blurb */,\n"
1697 "\t\t %s /* minimum */,\n"
1698 "\t\t %s /* maximum */,\n"
1699 "\t\t %s /* default_value */,\n"
1702 value_for_print (p->nick, "NULL"),
1703 value_for_print (p->blurb, "NULL"),
1704 value_for_print (p->minimum, "G_MININT"),
1705 value_for_print (p->maximum, "G_MAXINT"),
1706 value_for_print (p->default_value, "0"),
1708 else if (strcmp (p->gtktype, "UINT") == 0)
1709 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1710 "\t\t(\"%s\" /* name */,\n"
1711 "\t\t %s /* nick */,\n"
1712 "\t\t %s /* blurb */,\n"
1713 "\t\t %s /* minimum */,\n"
1714 "\t\t %s /* maximum */,\n"
1715 "\t\t %s /* default_value */,\n"
1718 value_for_print (p->nick, "NULL"),
1719 value_for_print (p->blurb, "NULL"),
1720 value_for_print (p->minimum, "0"),
1721 value_for_print (p->maximum, "G_MAXUINT"),
1722 value_for_print (p->default_value, "0"),
1724 else if (strcmp (p->gtktype, "LONG") == 0)
1725 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1726 "\t\t(\"%s\" /* name */,\n"
1727 "\t\t %s /* nick */,\n"
1728 "\t\t %s /* blurb */,\n"
1729 "\t\t %s /* minimum */,\n"
1730 "\t\t %s /* maximum */,\n"
1731 "\t\t %s /* default_value */,\n"
1734 value_for_print (p->nick, "NULL"),
1735 value_for_print (p->blurb, "NULL"),
1736 value_for_print (p->minimum, "G_MINLONG"),
1737 value_for_print (p->maximum, "G_MAXLONG"),
1738 value_for_print (p->default_value, "0"),
1740 else if (strcmp (p->gtktype, "ULONG") == 0)
1741 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1742 "\t\t(\"%s\" /* name */,\n"
1743 "\t\t %s /* nick */,\n"
1744 "\t\t %s /* blurb */,\n"
1745 "\t\t %s /* minimum */,\n"
1746 "\t\t %s /* maximum */,\n"
1747 "\t\t %s /* default_value */,\n"
1750 value_for_print (p->nick, "NULL"),
1751 value_for_print (p->blurb, "NULL"),
1752 value_for_print (p->minimum, "0"),
1753 value_for_print (p->maximum, "G_MAXULONG"),
1754 value_for_print (p->default_value, "0"),
1756 else if (strcmp (p->gtktype, "UNICHAR") == 0)
1757 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1758 "\t\t(\"%s\" /* name */,\n"
1759 "\t\t %s /* nick */,\n"
1760 "\t\t %s /* blurb */,\n"
1761 "\t\t %s /* default_value */,\n"
1764 value_for_print (p->nick, "NULL"),
1765 value_for_print (p->blurb, "NULL"),
1766 value_for_print (p->default_value, "0"),
1768 else if (strcmp (p->gtktype, "ENUM") == 0)
1769 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1770 "\t\t(\"%s\" /* name */,\n"
1771 "\t\t %s /* nick */,\n"
1772 "\t\t %s /* blurb */,\n"
1773 "\t\t %s /* enum_type */,\n"
1774 "\t\t %s /* default_value */,\n"
1777 value_for_print (p->nick, "NULL"),
1778 value_for_print (p->blurb, "NULL"),
1779 value_for_print (p->extra_gtktype, "G_TYPE_ENUM"),
1780 value_for_print (p->default_value, "0"),
1782 else if (strcmp (p->gtktype, "FLAGS") == 0)
1783 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1784 "\t\t(\"%s\" /* name */,\n"
1785 "\t\t %s /* nick */,\n"
1786 "\t\t %s /* blurb */,\n"
1787 "\t\t %s /* flags_type */,\n"
1788 "\t\t %s /* default_value */,\n"
1791 value_for_print (p->nick, "NULL"),
1792 value_for_print (p->blurb, "NULL"),
1793 value_for_print (p->extra_gtktype, "G_TYPE_FLAGS"),
1794 value_for_print (p->default_value, "0"),
1796 else if (strcmp (p->gtktype, "FLOAT") == 0)
1797 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1798 "\t\t(\"%s\" /* name */,\n"
1799 "\t\t %s /* nick */,\n"
1800 "\t\t %s /* blurb */,\n"
1801 "\t\t %s /* minimum */,\n"
1802 "\t\t %s /* maximum */,\n"
1803 "\t\t %s /* default_value */,\n"
1806 value_for_print (p->nick, "NULL"),
1807 value_for_print (p->blurb, "NULL"),
1808 value_for_print (p->minimum, "G_MINFLOAT"),
1809 value_for_print (p->maximum, "G_MAXFLOAT"),
1810 value_for_print (p->default_value, "0.0"),
1812 else if (strcmp (p->gtktype, "DOUBLE") == 0)
1813 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1814 "\t\t(\"%s\" /* name */,\n"
1815 "\t\t %s /* nick */,\n"
1816 "\t\t %s /* blurb */,\n"
1817 "\t\t %s /* minimum */,\n"
1818 "\t\t %s /* maximum */,\n"
1819 "\t\t %s /* default_value */,\n"
1822 value_for_print (p->nick, "NULL"),
1823 value_for_print (p->blurb, "NULL"),
1824 value_for_print (p->minimum, "G_MINDOUBLE"),
1825 value_for_print (p->maximum, "G_MAXDOUBLE"),
1826 value_for_print (p->default_value, "0.0"),
1828 else if (strcmp (p->gtktype, "STRING") == 0)
1829 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1830 "\t\t(\"%s\" /* name */,\n"
1831 "\t\t %s /* nick */,\n"
1832 "\t\t %s /* blurb */,\n"
1833 "\t\t %s /* default_value */,\n"
1836 value_for_print (p->nick, "NULL"),
1837 value_for_print (p->blurb, "NULL"),
1838 value_for_print (p->default_value, "NULL"),
1840 else if (strcmp (p->gtktype, "PARAM") == 0)
1841 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1842 "\t\t(\"%s\" /* name */,\n"
1843 "\t\t %s /* nick */,\n"
1844 "\t\t %s /* blurb */,\n"
1845 "\t\t %s /* param_type */,\n"
1848 value_for_print (p->nick, "NULL"),
1849 value_for_print (p->blurb, "NULL"),
1850 value_for_print (p->extra_gtktype, "G_TYPE_PARAM"),
1852 else if (strcmp (p->gtktype, "BOXED") == 0)
1853 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1854 "\t\t(\"%s\" /* name */,\n"
1855 "\t\t %s /* nick */,\n"
1856 "\t\t %s /* blurb */,\n"
1857 "\t\t %s /* boxed_type */,\n"
1860 value_for_print (p->nick, "NULL"),
1861 value_for_print (p->blurb, "NULL"),
1862 value_for_print (p->extra_gtktype, "G_TYPE_BOXED"),
1864 else if (strcmp (p->gtktype, "POINTER") == 0)
1865 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1866 "\t\t(\"%s\" /* name */,\n"
1867 "\t\t %s /* nick */,\n"
1868 "\t\t %s /* blurb */,\n"
1871 value_for_print (p->nick, "NULL"),
1872 value_for_print (p->blurb, "NULL"),
1874 /* FIXME: VALUE_ARRAY */
1875 else if (strcmp (p->gtktype, "CLOSURE") == 0)
1876 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1877 "\t\t(\"%s\" /* name */,\n"
1878 "\t\t %s /* nick */,\n"
1879 "\t\t %s /* blurb */,\n"
1882 value_for_print (p->nick, "NULL"),
1883 value_for_print (p->blurb, "NULL"),
1885 else if (strcmp (p->gtktype, "OBJECT") == 0)
1886 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1887 "\t\t(\"%s\" /* name */,\n"
1888 "\t\t %s /* nick */,\n"
1889 "\t\t %s /* blurb */,\n"
1890 "\t\t %s /* object_type */,\n"
1893 value_for_print (p->nick, "NULL"),
1894 value_for_print (p->blurb, "NULL"),
1895 value_for_print (p->extra_gtktype, "G_TYPE_OBJECT"),
1898 error_printf (GOB_ERROR, p->line_no,
1899 "%s type is not supported by properties",
1902 s = g_strdup (p->name);
1904 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1906 "\t\tparam_spec);\n", s);
1909 g_string_free (flags, TRUE);
1913 make_arguments(Class *c)
1916 if (get_properties > 0)
1917 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1918 if (set_properties > 0)
1919 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1920 out_printf (out, " {\n"
1921 "\tGParamSpec *param_spec;\n\n");
1923 for (li = c->nodes; li != NULL; li = li->next) {
1925 if (n->type == PROPERTY_NODE)
1926 make_property ((Property *)n);
1927 else if (n->type == ARGUMENT_NODE)
1928 make_argument ((Argument *)n);
1930 out_printf(out, " }\n");
1934 print_initializer(Method *m, Variable *v)
1938 if(v->initializer == NULL)
1941 if(v->scope == PRIVATE_SCOPE)
1942 root = g_strconcat(((FuncArg *)m->args->data)->name,
1945 root = g_strdup(((FuncArg *)m->args->data)->name);
1947 if(v->initializer_line > 0)
1948 out_addline_infile(out, v->initializer_line);
1950 out_printf(out, "\t%s->%s = %s;\n",
1951 root, v->id, v->initializer);
1953 if(v->initializer_line > 0)
1954 out_addline_outfile(out);
1960 print_destructor (Variable *v)
1964 if(v->destructor == NULL)
1967 if(v->scope == PRIVATE_SCOPE)
1968 root = "self->_priv";
1972 if(v->destructor_simple) {
1973 if(v->destructor_line > 0)
1974 out_addline_infile(out, v->destructor_line);
1976 out_printf(out, "\tif(%s->%s) { "
1977 "((*(void (*)(void *))%s)) (%s->%s); "
1978 "%s->%s = NULL; }\n",
1979 root, v->id, v->destructor, root, v->id,
1982 if(v->destructor_line > 0)
1983 out_addline_outfile(out);
1985 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
1986 out_printf(out, "#define VAR %s\n", v->id);
1987 out_printf(out, "\t{\n");
1988 if(v->destructor_line > 0)
1989 out_addline_infile(out, v->destructor_line);
1991 out_printf(out, "\t%s}\n", v->destructor);
1993 if(v->destructor_line > 0)
1994 out_addline_outfile(out);
1995 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
1997 out_printf(out, "#undef VAR\n");
1998 out_printf(out, "#undef %s\n", v->id);
2003 add_shutdown (Class *c)
2005 out_printf(out, "\nstatic void\n"
2006 "___shutdown (GObject *obj_self)\n"
2009 "#define __GOB_FUNCTION__ \"%s::shutdown\"\n",
2012 if (unreftors > 0) {
2013 out_printf (out, "\t%s *self = %s (obj_self);\n",
2014 typebase, macrobase);
2017 if (shutdown_handler != NULL) {
2018 /* so we get possible bad argument warning */
2019 if (shutdown_handler->line_no > 0)
2020 out_addline_infile (out, shutdown_handler->line_no);
2021 out_printf (out, "\t___%x_%s_shutdown(obj_self);\n",
2022 (guint)shutdown_handler->unique_id, funcbase);
2023 if (shutdown_handler->line_no > 0)
2024 out_addline_outfile (out);
2027 "\tif (G_OBJECT_CLASS (parent_class)->shutdown) \\\n"
2028 "\t\t(* G_OBJECT_CLASS (parent_class)->shutdown) (obj_self);\n");
2031 if (unreftors > 0) {
2033 for(li = ((Class *)class)->nodes;
2037 Variable *v = (Variable *)n;
2038 if (n->type == VARIABLE_NODE &&
2039 v->scope != CLASS_SCOPE &&
2040 v->destructor_unref)
2041 print_destructor (v);
2045 out_printf (out, "\treturn;\n");
2047 out_printf(out, "\tself = NULL;\n");
2048 out_printf(out, "}\n"
2049 "#undef __GOB_FUNCTION__\n\n");
2053 add_finalize (Class *c)
2057 "___finalize(GObject *obj_self)\n"
2060 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2065 out_printf(out, "\t%s *self = %s (obj_self);\n",
2066 typebase, macrobase);
2069 out_printf(out, "\tgpointer priv = self->_priv;\n");
2072 if(finalize_handler) {
2073 /* so we get possible bad argument warning */
2074 if(finalize_handler->line_no > 0)
2075 out_addline_infile(out, finalize_handler->line_no);
2076 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2077 (guint)finalize_handler->unique_id, funcbase);
2078 if(finalize_handler->line_no > 0)
2079 out_addline_outfile(out);
2082 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2083 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2086 if (destructors > 0) {
2088 for (li = ((Class *)class)->nodes;
2092 Variable *v = (Variable *)n;
2093 if (n->type == VARIABLE_NODE &&
2094 v->scope != CLASS_SCOPE &&
2095 ! v->destructor_unref)
2096 print_destructor (v);
2101 out_printf(out, "\tg_free (priv);\n");
2103 out_printf (out, "\treturn;\n");
2104 if (destructors > 0 ||
2106 out_printf (out, "\tself = NULL;\n");
2108 out_printf(out, "}\n"
2109 "#undef __GOB_FUNCTION__\n\n");
2113 make_bonobo_object_epv (Class *c, const char *classname)
2116 gboolean added_line = FALSE;
2118 for (li = c->nodes; li != NULL; li = li->next) {
2120 Method *m = (Method *)n;
2121 if(n->type != METHOD_NODE ||
2122 m->method == OVERRIDE_METHOD)
2125 if (m->bonobo_object_func) {
2126 if(m->line_no > 0) {
2127 out_addline_infile(out, m->line_no);
2129 } else if (m->line_no == 0 &&
2131 out_addline_outfile(out);
2134 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2135 classname, m->id, m->id);
2139 out_addline_outfile(out);
2146 for(li=c->nodes;li;li=g_list_next(li)) {
2150 gboolean add_unused_class = FALSE;
2152 if(n->type != METHOD_NODE)
2155 if(m->method == INIT_METHOD) {
2157 out_addline_infile(out, m->line_no);
2158 print_method(out, "static ", "\n", "", " ", "", "\n",
2159 m, FALSE, FALSE, TRUE);
2161 out_addline_outfile(out);
2162 out_printf(out, "{\n"
2163 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2166 out_printf(out, "\t%s->_priv = "
2167 "g_new0 (%sPrivate, 1);\n",
2168 ((FuncArg *)m->args->data)->name,
2170 } else if(always_private_struct) {
2171 out_printf(out, "\t%s->_priv = NULL;\n",
2172 ((FuncArg *)m->args->data)->name);
2174 if(initializers > 0) {
2176 for(li = ((Class *)class)->nodes;
2180 Variable *v = (Variable *)n;
2181 if(n->type != VARIABLE_NODE ||
2182 v->scope == CLASS_SCOPE)
2184 print_initializer(m, v);
2187 } else if(m->method == CLASS_INIT_METHOD) {
2188 gboolean did_base_obj = FALSE;
2191 out_addline_infile(out, m->line_no);
2192 print_method(out, "static ", "\n", "", " ", "", "\n",
2193 m, FALSE, FALSE, TRUE);
2195 out_addline_outfile(out);
2196 out_printf(out, "{\n"
2197 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2199 if (set_properties > 0 ||
2200 get_properties > 0 ||
2207 "(GObjectClass*) %s;\n",
2208 ((FuncArg *)m->args->data)->name);
2209 add_unused_class = TRUE;
2210 did_base_obj = TRUE;
2215 ((FuncArg *)m->args->data)->name,
2218 if (initializers > 0) {
2220 for(li = ((Class *)class)->nodes;
2224 Variable *v = (Variable *)n;
2225 if(n->type == VARIABLE_NODE &&
2226 v->scope == CLASS_SCOPE)
2227 print_initializer(m, v);
2231 out_printf(out, "\n\tparent_class = ");
2233 out_printf(out, "(%sClass *)", ptypebase);
2234 out_printf(out, "g_type_class_ref (%s);\n",
2240 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2242 /* if there are no handlers for these things, we
2243 * need to set them up here */
2244 if(need_shutdown && !shutdown_handler)
2245 out_printf(out, "\tg_object_class->shutdown "
2246 "= ___shutdown;\n");
2247 if(need_finalize && !finalize_handler)
2248 out_printf(out, "\tg_object_class->finalize = "
2251 if(get_properties > 0 || set_properties > 0)
2254 if (c->bonobo_object_class != NULL) {
2255 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2261 out_printf(out, " {\n");
2262 out_addline_infile(out, m->ccode_line);
2263 out_printf(out, "%s\n", m->cbuf);
2264 out_addline_outfile(out);
2265 out_printf(out, " }\n");
2267 out_printf(out, "\treturn;\n");
2270 ((FuncArg *)m->args->data)->name);
2271 if(add_unused_class) {
2272 out_printf (out, "\tg_object_class = NULL;\n");
2274 out_printf(out, "}\n"
2275 "#undef __GOB_FUNCTION__\n");
2280 add_argument (Argument *a, gboolean is_set)
2284 char *the_type_lower;
2289 line_no = a->set_line;
2292 line_no = a->get_line;
2296 s = g_strdup(a->name);
2298 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2300 the_type_lower = g_strdup (a->gtktype);
2301 g_strdown (the_type_lower);
2306 if (a->atype != NULL)
2307 cast = get_type (a->atype, TRUE);
2309 cast = g_strdup (get_cast (a->gtktype, FALSE));
2311 out_printf (out, "\t%s ARG = (%s) g_value_get_%s (VAL);\n",
2312 cast, cast, the_type_lower);
2315 } else if ( ! is_set) {
2318 if (a->atype != NULL)
2319 cast = get_type (a->atype, TRUE);
2321 cast = g_strdup (get_cast (a->gtktype, FALSE));
2322 out_printf (out, "\t%s ARG;\n"
2323 "\tmemset (&ARG, 0, sizeof (%s));\n",
2329 out_printf(out, "\t\t{\n");
2331 out_addline_infile (out, line_no);
2332 out_printf (out, "%s\n", cbuf);
2334 out_addline_outfile (out);
2335 out_printf (out, "\t\t}\n");
2337 if (strcmp (a->gtktype, "OBJECT") == 0)
2338 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2341 out_printf (out, "\t\t"
2342 "g_value_set_%s (VAL, ARG);\n",
2345 g_free (the_type_lower);
2348 out_printf (out, "\t\tif (&ARG) ;\n");
2351 out_printf (out, "\t\tbreak;\n");
2353 out_printf (out, "\t}\n");
2357 add_property (Property *p, gboolean is_set)
2360 char *the_type_lower;
2366 line_no = p->set_line;
2369 line_no = p->get_line;
2374 name_upper = g_strdup (p->name);
2375 g_strup (name_upper);
2376 the_type_lower = g_strdup (p->gtktype);
2377 g_strdown (the_type_lower);
2379 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2381 out_printf(out, "\t\t{\n");
2383 out_addline_infile (out, line_no);
2384 out_printf (out, "%s\n", cbuf);
2386 out_addline_outfile (out);
2387 out_printf (out, "\t\t}\n");
2389 g_free (name_upper);
2390 g_free (the_type_lower);
2392 out_printf (out, "\t\tbreak;\n");
2396 add_getset_arg(Class *c, gboolean is_set)
2399 out_printf(out, "\nstatic void\n"
2400 "___object_%s_property (GObject *object,\n"
2401 "\tguint property_id,\n"
2402 "\t%sGValue *VAL,\n"
2403 "\tGParamSpec *pspec)\n"
2404 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2407 "\tself = %s (object);\n\n"
2408 "\tswitch (property_id) {\n",
2409 is_set ? "set" : "get",
2410 is_set ? "const " : "",
2411 c->otype, is_set ? "set" : "get",
2412 typebase, macrobase);
2414 for (li = c->nodes; li != NULL; li = li->next) {
2416 if (n->type == PROPERTY_NODE)
2417 add_property ((Property *)n, is_set);
2418 else if (n->type == ARGUMENT_NODE)
2419 add_argument ((Argument *)n, is_set);
2421 out_printf (out, "\tdefault:\n"
2422 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2423 "#ifndef __PRETTY_FUNCTION__\n"
2424 "# undef G_STRLOC\n"
2425 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2427 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2429 "\treturn;\n\tself = NULL;\n\tVAL = NULL;\n\tpspec = NULL;\n}\n"
2430 "#undef __GOB_FUNCTION__\n");
2434 print_checks (Method *m, FuncArg *fa)
2438 gboolean checked_null = FALSE;
2439 is_void = (strcmp(m->mtype->name, "void")==0 &&
2440 m->mtype->pointer == NULL);
2442 for(li = fa->checks; li != NULL; li = li->next) {
2443 Check *ch = li->data;
2445 /* point to the method prot in .gob for failed checks */
2447 out_addline_infile(out, m->line_no);
2449 out_printf(out, "\tg_return_if_fail (");
2451 out_printf(out, "\tg_return_val_if_fail (");
2452 switch(ch->chtype) {
2454 out_printf(out, "%s != NULL", fa->name);
2455 checked_null = TRUE;
2458 s = make_pre_macro(fa->atype->name, "IS");
2460 out_printf(out, "%s (%s)", s, fa->name);
2462 /* if not check null, null may be valid */
2463 out_printf(out, "!(%s) || %s (%s)", fa->name,
2468 out_printf(out, "%s < %s", fa->name, ch->number);
2471 out_printf(out, "%s > %s", fa->name, ch->number);
2474 out_printf(out, "%s <= %s", fa->name, ch->number);
2477 out_printf(out, "%s >= %s", fa->name, ch->number);
2480 out_printf(out, "%s == %s", fa->name, ch->number);
2483 out_printf(out, "%s != %s", fa->name, ch->number);
2487 out_printf(out, ");\n");
2489 out_printf(out, ", (");
2490 print_type(out, m->mtype, TRUE);
2491 out_printf(out, ")%s);\n",
2492 m->onerror?m->onerror:"0");
2498 print_preconditions(Method *m)
2502 for(li=m->args;li;li=g_list_next(li)) {
2503 FuncArg *fa = li->data;
2505 print_checks(m, fa);
2508 out_addline_outfile(out);
2512 print_method_body(Method *m, int pre)
2515 out_addline_outfile(out);
2516 out_printf(out, "{\n"
2517 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2518 ((Class *)class)->otype,
2521 print_preconditions(m);
2523 /* Note: the trailing }'s are on one line, this is so
2524 that we get the no return warning correctly and point to
2525 the correct line in the .gob file, yes this is slightly
2526 ugly in the .c file, but that is not supposed to be
2527 human readable anyway. */
2529 out_printf(out, "{\n");
2531 out_addline_infile(out, m->ccode_line);
2532 out_printf(out, "\t%s}", m->cbuf);
2535 /* Note, there is no \n between the last } and this } so that
2536 * errors/warnings reported on the end of the body get pointed to the
2537 * right line in the .gob source */
2538 out_printf(out, "}\n");
2541 out_addline_outfile(out);
2542 out_printf(out, "#undef __GOB_FUNCTION__\n");
2546 put_signal_args (Method *m)
2552 if (m->args->next == NULL)
2555 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2556 li != NULL && ali != NULL;
2557 li = li->next, ali = ali->next, i++) {
2558 FuncArg *fa = li->data;
2559 char *cast = g_strdup (get_cast (ali->data, FALSE));
2560 /* FIXME: This code is so fucking ugly it hurts */
2561 gboolean do_static =
2562 (strcmp ((char *)ali->data, "STRING") == 0 ||
2563 strcmp ((char *)ali->data, "BOXED") == 0);
2567 cast = get_type (fa->atype, TRUE);
2569 /* we should have already proved before that
2570 the we know all the types */
2571 g_assert (cast != NULL);
2574 "\t___param_values[%d].g_type = 0;\n"
2575 "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
2576 i, i, (char *)ali->data);
2578 set_func = g_strdup_printf ("g_value_set%s_%s",
2579 do_static ? "_static" : "",
2581 g_strdown (set_func);
2583 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2584 set_func, i, cast, fa->name);
2592 get_arg_names_for_macro(Method *m)
2596 GString *gs = g_string_new(NULL);
2598 for(li=m->args;li;li=g_list_next(li)) {
2599 FuncArg *arg = li->data;
2600 g_string_sprintfa(gs, "%s___%s", p, arg->name);
2604 g_string_free(gs, FALSE);
2609 put_method(Method *m)
2611 char *s, *args, *doc;
2613 is_void = (strcmp(m->mtype->name, "void")==0 &&
2614 m->mtype->pointer == NULL);
2615 out_printf(out, "\n");
2616 if(m->method != OVERRIDE_METHOD) {
2617 doc = get_gtk_doc(m->id);
2619 out_printf(out, "%s", doc);
2624 case REGULAR_METHOD:
2626 out_addline_infile(out, m->line_no);
2627 if(m->scope == PRIVATE_SCOPE)
2628 print_method(out, "static ", "\n", "", " ", "", "\n",
2629 m, FALSE, FALSE, TRUE);
2630 else /* PUBLIC, PROTECTED */
2631 print_method(out, "", "\n", "", " ", "", "\n",
2632 m, FALSE, FALSE, TRUE);
2633 print_method_body(m, TRUE);
2634 /* the outfile line was added above */
2636 case SIGNAL_FIRST_METHOD:
2637 case SIGNAL_LAST_METHOD:
2639 out_addline_infile(out, m->line_no);
2640 if(m->scope == PRIVATE_SCOPE)
2641 print_method(out, "static ", "\n", "", " ", "", "\n",
2642 m, FALSE, FALSE, TRUE);
2643 else /* PUBLIC, PROTECTED */
2644 print_method(out, "", "\n", "", " ", "", "\n",
2645 m, FALSE, FALSE, TRUE);
2646 out_addline_outfile (out);
2648 out_printf (out, "{\n");
2651 "\tGValue ___param_values[%d];\n"
2652 "\tGValue ___return_val = {0};\n\n",
2653 g_list_length (m->args));
2655 print_preconditions (m);
2658 "\n\t___param_values[0].g_type = 0;\n"
2659 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2660 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2661 ((FuncArg *)m->args->data)->name,
2662 ((FuncArg *)m->args->data)->name);
2664 put_signal_args (m);
2666 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2667 const char *defret = NULL;
2669 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2670 (char *)m->gtktypes->data);
2672 if (m->defreturn != NULL)
2673 defret = m->defreturn;
2674 else if (m->onerror != NULL)
2675 defret = m->onerror;
2677 if (defret != NULL) {
2679 /* FIXME: This code is so fucking ugly it hurts */
2680 gboolean do_static =
2681 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2682 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2683 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2685 cast = get_type (m->mtype, TRUE);
2687 set_func = g_strdup_printf ("g_value_set%s_%s",
2688 do_static ? "_static" : "",
2689 (char *)m->gtktypes->data);
2690 g_strdown (set_func);
2692 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2693 set_func, cast, defret);
2698 out_printf (out, "\n");
2701 s = g_strdup (m->id);
2704 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2705 "\t\tobject_signals[%s_SIGNAL],\n"
2706 "\t\t0 /* detail */,\n"
2707 "\t\t&___return_val);\n", s);
2711 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2712 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2713 char *getfunc = g_strdup_printf ("g_value_get_%s",
2714 (char *)m->gtktypes->data);
2715 g_strdown (getfunc);
2718 cast = get_type (m->mtype, TRUE);
2720 out_printf (out, "\n\treturn (%s) %s (&___return_val);\n",
2726 out_printf(out, "}\n");
2731 out_addline_infile(out, m->line_no);
2732 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2733 m, FALSE, FALSE, TRUE);
2734 print_method_body(m, FALSE);
2735 /* the outfile line was added above */
2737 case VIRTUAL_METHOD:
2739 out_addline_infile(out, m->line_no);
2740 if(m->scope==PRIVATE_SCOPE)
2741 print_method(out, "static ", "\n", "", " ", "", "\n",
2742 m, FALSE, FALSE, TRUE);
2743 else /* PUBLIC, PROTECTED */
2744 print_method(out, "", "\n", "", " ", "", "\n",
2745 m, FALSE, FALSE, TRUE);
2746 out_addline_outfile(out);
2747 out_printf(out, "{\n"
2748 "\t%sClass *klass;\n", typebase);
2749 print_preconditions(m);
2750 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2751 "\tif(klass->%s)\n",
2752 macrobase, ((FuncArg *)m->args->data)->name,
2754 if(strcmp(m->mtype->name, "void") == 0 &&
2755 m->mtype->pointer == NULL) {
2757 out_printf(out, "\t\t(*klass->%s)(%s",
2759 ((FuncArg *)m->args->data)->name);
2760 for(li=m->args->next;li;li=g_list_next(li)) {
2761 FuncArg *fa = li->data;
2762 out_printf(out, ",%s", fa->name);
2764 out_printf(out, ");\n}\n");
2767 out_printf(out, "\t\treturn (*klass->%s)(%s",
2769 ((FuncArg *)m->args->data)->name);
2770 for(li=m->args->next;li;li=g_list_next(li)) {
2771 FuncArg *fa = li->data;
2772 out_printf(out, ",%s", fa->name);
2774 out_printf(out, ");\n"
2777 print_type(out, m->mtype, TRUE);
2779 out_printf(out, ")(%s);\n}\n", m->defreturn);
2781 out_printf(out, ")(%s);\n}\n", m->onerror);
2783 out_printf(out, ")(0);\n}\n");
2789 out_addline_infile(out, m->line_no);
2790 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2791 m, FALSE, FALSE, TRUE);
2792 print_method_body(m, FALSE);
2793 /* the outfile line was added above */
2795 case OVERRIDE_METHOD:
2799 out_addline_infile(out, m->line_no);
2800 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2801 print_method(out, "static ", s, "", " ", "", "\n",
2802 m, FALSE, FALSE, FALSE);
2804 out_addline_outfile(out);
2805 s = replace_sep(m->otype, '_');
2807 args = get_arg_names_for_macro(m);
2809 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2810 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2811 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2812 args, s, m->id, s, m->id, args);
2814 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2815 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2816 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2818 args, s, m->id, s, m->id, args);
2819 out_printf(out, "(");
2820 print_type(out, m->mtype, TRUE);
2821 out_printf(out, ")%s))\n",
2822 m->onerror?m->onerror:"0");
2826 print_method_body(m, TRUE);
2827 /* the outfile line was added above */
2828 out_printf(out, "#undef PARENT_HANDLER\n");
2838 char *outfile, *outfileh, *outfileph;
2841 outfile = g_strconcat (filebase, ".c", NULL);
2843 outfile = g_strconcat (filebase, ".cc", NULL);
2844 if (no_touch_headers)
2845 outfileh = g_strconcat ("#gob#", filebase, ".h#gob#", NULL);
2847 outfileh = g_strconcat (filebase, ".h", NULL);
2849 if ((privates > 0 || protecteds > 0 ||
2850 private_header == PRIVATE_HEADER_ALWAYS) &&
2851 private_header != PRIVATE_HEADER_NEVER)
2852 outfileph = g_strconcat (filebase, "-private.h", NULL);
2858 devnull = fopen ("/dev/null", "w");
2859 if (devnull == NULL)
2860 g_error ("Cannot open null device");
2863 if (outfileph != NULL)
2866 out = fopen (outfile, "w");
2868 g_error ("Cannot open outfile: %s", outfile);
2870 outh = fopen (outfileh, "w");
2872 g_error ("Cannot open outfile: %s", outfileh);
2873 if (outfileph != NULL) {
2874 outph = fopen (outfileph, "w");
2876 g_error ("Cannot open outfile: %s", outfileh);
2882 put_argument_nongnu_wrappers (Class *c)
2886 if (get_properties < 0 && set_properties < 0)
2889 for (li = c->nodes; li != NULL; li = li->next) {
2891 const char *name, *gtktype;
2897 if (n->type == ARGUMENT_NODE) {
2898 Argument *a = (Argument *)n;
2900 gtktype = a->gtktype;
2902 get = a->get != NULL;
2903 set = a->set != NULL;
2904 } else if (n->type == PROPERTY_NODE) {
2905 Property *p = (Property *)n;
2907 gtktype = p->gtktype;
2909 get = p->get != NULL;
2910 set = p->set != NULL;
2915 aname = g_strdup (name);
2919 cast = get_type (atype, TRUE);
2921 cast = g_strdup (get_cast (gtktype, TRUE));
2925 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2926 "\"%s\",(%s)(arg)\n",
2927 macrobase, aname, name, cast);
2929 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2930 "\"%s\",(%s*)(arg)\n",
2931 macrobase, aname, name, cast);
2934 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2936 macrobase, aname, name);
2938 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2940 macrobase, aname, name);
2948 put_argument_gnu_wrappers(Class *c)
2952 if(get_properties < 0 && set_properties < 0)
2955 for (li = c->nodes; li != NULL; li = li->next) {
2957 const char *name, *gtktype;
2963 if (n->type == ARGUMENT_NODE) {
2964 Argument *a = (Argument *)n;
2966 gtktype = a->gtktype;
2968 get = a->get != NULL;
2969 set = a->set != NULL;
2970 } else if (n->type == PROPERTY_NODE) {
2971 Property *p = (Property *)n;
2973 gtktype = p->gtktype;
2975 get = p->get != NULL;
2976 set = p->set != NULL;
2981 aname = g_strdup (name);
2985 cast = get_type (atype, TRUE);
2987 cast = g_strdup (get_cast (gtktype, TRUE));
2991 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2992 "\"%s\",({%sz = (arg); z;})\n",
2993 macrobase, aname, name, cast);
2995 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2996 "\"%s\",({%s*z = (arg); z;})\n",
2997 macrobase, aname, name, cast);
3000 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3002 macrobase, aname, name);
3004 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3006 macrobase, aname, name);
3014 print_ccode_block(CCode *cc)
3017 switch(cc->cctype) {
3019 /* HT code is printed exactly like normal header
3020 code but is printed before */
3023 out_printf(fp, "\n");
3026 /* AT code is printed exactly like normal 'all'
3027 code but is printed before */
3030 out_printf(outph, "\n");
3031 out_printf(outph, "%s\n", cc->cbuf);
3032 out_addline_infile(outph, cc->line_no);
3033 out_addline_outfile(outph);
3035 out_printf(outh, "\n");
3036 out_printf(outh, "%s\n", cc->cbuf);
3038 out_printf(fp, "\n");
3039 out_addline_infile(fp, cc->line_no);
3044 out_printf(fp, "\n");
3045 out_addline_infile(fp, cc->line_no);
3052 out_printf(fp, "\n");
3053 out_addline_infile(fp, cc->line_no);
3056 out_printf(fp, "%s\n", cc->cbuf);
3057 if(cc->cctype == C_CCODE ||
3058 cc->cctype == A_CCODE ||
3059 cc->cctype == AT_CCODE ||
3060 cc->cctype == PH_CCODE)
3061 out_addline_outfile(fp);
3065 print_class_block(Class *c)
3069 gboolean printed_private = FALSE;
3072 out_printf(out, "/* utility types we may need */\n");
3073 if(special_array[SPECIAL_2POINTER])
3074 out_printf(out, "typedef struct { "
3075 "gpointer a; gpointer b; "
3076 "} ___twopointertype;\n");
3077 if(special_array[SPECIAL_3POINTER])
3078 out_printf(out, "typedef struct { "
3079 "gpointer a; gpointer b; "
3081 "} ___threepointertype;\n");
3082 if(special_array[SPECIAL_INT_POINTER])
3083 out_printf(out, "typedef struct { "
3084 "gint a; gpointer b; "
3085 "} ___intpointertype;\n");
3086 out_printf(out, "\n");
3089 out_printf(outh, "\n/*\n"
3090 " * Type checking and casting macros\n"
3092 out_printf(outh, "#define %s\t"
3093 "(%s_get_type())\n",
3094 macrotype, funcbase);
3095 out_printf(outh, "#define %s(obj)\t"
3096 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3097 macrobase, funcbase, typebase);
3098 out_printf(outh, "#define %s_CONST(obj)\t"
3099 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3100 macrobase, funcbase, typebase);
3101 out_printf(outh, "#define %s_CLASS(klass)\t"
3102 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3103 macrobase, funcbase, typebase);
3104 out_printf(outh, "#define %s(obj)\t"
3105 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3108 "#define %s_GET_CLASS(obj)\t"
3109 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3110 macrobase, funcbase, typebase);
3112 if ( ! no_self_alias) {
3113 out_printf(out, "/* self casting macros */\n");
3114 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3115 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3116 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3117 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3118 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3120 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3123 out_printf(out, "/* self typedefs */\n");
3124 out_printf(out, "typedef %s Self;\n", typebase);
3125 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3129 always_private_struct) {
3130 out_printf (outh, "\n/* Private structure type */\n");
3131 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3132 typebase, typebase);
3134 out_printf (outh, "/* There are no privates, this "
3135 "structure is thus never defined */\n");
3138 out_printf (outh, "\n/*\n"
3139 " * Main object structure\n"
3141 s = replace_sep (c->otype, '_');
3143 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3144 "#define __TYPEDEF_%s__\n", s, s);
3146 out_printf (outh, "typedef struct _%s %s;\n"
3147 "#endif\n", typebase, typebase);
3148 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3149 typebase, ptypebase);
3150 for (li = c->nodes; li; li=li->next) {
3151 static gboolean printed_public = FALSE;
3153 Variable *v = (Variable *)n;
3154 if(n->type == VARIABLE_NODE &&
3155 v->scope == PUBLIC_SCOPE) {
3156 if( ! printed_public) {
3157 out_printf(outh, "\t/*< public >*/\n");
3158 printed_public = TRUE;
3160 put_variable((Variable *)n, outh);
3163 /* put protecteds always AFTER publics */
3164 for (li = c->nodes; li != NULL; li = li->next) {
3166 Variable *v = (Variable *)n;
3167 if (n->type == VARIABLE_NODE &&
3168 v->scope == PROTECTED_SCOPE) {
3169 if ( ! printed_private) {
3170 out_printf (outh, "\t/*< private >*/\n");
3171 printed_private = TRUE;
3173 put_variable ((Variable *)n, outh);
3177 always_private_struct) {
3178 if ( ! printed_private)
3179 out_printf (outh, "\t/*< private >*/\n");
3180 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3182 out_printf (outh, "};\n");
3187 /* if we are to stick this into the private
3188 header, if not stick it directly into the
3195 out_printf (outfp, "struct _%sPrivate {\n",
3197 for(li=c->nodes; li; li=li->next) {
3199 Variable *v = (Variable *)n;
3200 if(n->type == VARIABLE_NODE &&
3201 v->scope == PRIVATE_SCOPE) {
3202 out_addline_infile(outfp, v->line_no);
3203 put_variable(v, outfp);
3206 out_addline_outfile(outfp);
3207 out_printf(outfp, "};\n");
3210 out_printf(outh, "\n/*\n"
3211 " * Class definition\n"
3213 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3214 typebase, typebase);
3216 "struct _%sClass {\n\t%sClass __parent__;\n",
3217 typebase, ptypebase);
3218 for(li = c->nodes; li != NULL; li = li->next) {
3220 if(n->type == METHOD_NODE)
3221 put_vs_method((Method *)n);
3223 /* If BonoboX type class put down the epv */
3224 if (c->bonobo_object_class != NULL) {
3226 "\t/* Bonobo object epv */\n"
3227 "\tPOA_%s__epv _epv;\n",
3228 c->bonobo_object_class);
3230 /* put class scope variables */
3231 for (li = c->nodes; li != NULL; li = li->next) {
3233 Variable *v = (Variable *)n;
3234 if (n->type == VARIABLE_NODE &&
3235 v->scope == CLASS_SCOPE)
3236 put_variable ((Variable *)n, outh);
3238 out_printf (outh, "};\n\n");
3240 out_printf (out, "/* here are local prototypes */\n");
3241 if (set_properties > 0) {
3242 out_printf (out, "static void ___object_set_property "
3243 "(GObject *object, guint property_id, "
3244 "const GValue *value, GParamSpec *pspec);\n");
3246 if (get_properties > 0) {
3247 out_printf (out, "static void ___object_get_property "
3248 "(GObject *object, guint property_id, "
3249 "GValue *value, GParamSpec *pspec);\n");
3252 out_printf (outh, "\n/*\n"
3253 " * Public methods\n"
3256 if ( ! overrode_get_type) {
3257 out_printf (outh, "GType\t%s_get_type\t(void)", funcbase);
3259 out_printf (outh, " G_GNUC_CONST;\n");
3261 out_printf (outh, ";\n");
3265 for(li = c->nodes; li != NULL; li = li->next) {
3267 if(n->type == METHOD_NODE) {
3268 put_pub_method((Method *)n);
3269 put_prot_method((Method *)n);
3270 put_priv_method_prot((Method *)n);
3274 /* this idea is less and less apealing to me */
3276 out_printf (outh, "\n/*\n"
3277 " * Signal connection wrapper macros\n"
3280 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3281 put_signal_macros (c, TRUE);
3282 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3283 put_signal_macros (c, FALSE);
3284 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3286 put_signal_macros (c, FALSE);
3287 out_printf(outh, "\n");
3290 out_printf (out, "\n/*\n"
3291 " * Signal connection wrapper macro shortcuts\n"
3293 put_local_signal_macros (c);
3294 out_printf(outh, "\n");
3297 /* argument wrapping macros */
3298 if(get_properties > 0 || set_properties > 0) {
3299 out_printf(outh, "\n/*\n"
3300 " * Argument wrapping macros\n"
3303 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3304 put_argument_gnu_wrappers(c);
3305 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3306 put_argument_nongnu_wrappers(c);
3307 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3309 put_argument_nongnu_wrappers(c);
3314 for(li = c->nodes; li != NULL; li = li->next) {
3316 if(n->type == METHOD_NODE)
3317 add_signal_prots((Method *)n);
3323 if(any_method_to_alias(c)) {
3325 out_printf(out, "/* Short form macros */\n");
3326 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3327 make_method_gnu_aliases(c);
3328 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3330 make_method_nongnu_aliases(c);
3333 add_interface_inits (c);
3335 if ( ! overrode_get_type) {
3336 if (c->bonobo_object_class != NULL)
3337 add_bonobo_object_get_type ();
3342 out_printf (out, "/* a macro for creating a new object of our type */\n");
3344 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3345 typebase, funcbase);
3347 out_printf (out, "/* a function for creating a new object of our type */\n");
3348 out_printf (out, "#include <stdarg.h>\n");
3350 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3351 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3352 "{\n\t%s *ret;\n\tva_list ap;\n"
3353 "\tva_start (ap, first);\n"
3354 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3357 "\treturn ret;\n}\n\n",
3359 no_gnu ? "" : " G_GNUC_UNUSED",
3360 typebase, typebase, typebase, funcbase);
3370 if(set_properties > 0) {
3371 add_getset_arg(c, TRUE);
3374 if(get_properties > 0) {
3375 add_getset_arg(c, FALSE);
3378 for(li = c->nodes; li != NULL; li = li->next) {
3380 if(n->type == METHOD_NODE)
3381 put_method((Method *)n);
3384 add_bad_hack_to_avoid_unused_warnings(c);
3388 print_useful_macros(void)
3390 int major = 0, minor = 0, pl = 0;
3393 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3394 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3395 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3396 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3398 /* Useful priv macro thingie */
3399 /* FIXME: this should be done the same way that priv is, as a var,
3401 out_printf (out, "#define selfp (self->_priv)\n\n");
3405 print_file_comments(void)
3409 out_printf(outh, "/* Generated by GOB (v%s)"
3410 " (do not edit directly) */\n\n", VERSION);
3412 out_printf(outph, "/* Generated by GOB (v%s)"
3413 " (do not edit directly) */\n\n", VERSION);
3414 out_printf(out, "/* Generated by GOB (v%s) on %s"
3415 " (do not edit directly) */\n\n",
3416 VERSION, ctime(&curtime));
3418 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3422 print_includes(void)
3424 gboolean found_header;
3427 /* We may need string.h for memset */
3428 if(destructors > 0 &&
3429 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3430 out_printf(out, "#include <string.h> /* memset() */\n\n");
3433 p = g_strconcat(filebase, ".h", NULL);
3434 found_header = TRUE;
3435 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3436 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3437 found_header = FALSE;
3441 /* if we are creating a private header see if it was included */
3443 p = g_strconcat(filebase, "-private.h", NULL);
3444 if( ! g_list_find_custom(include_files, p,
3445 (GCompareFunc)strcmp)) {
3446 out_printf(out, "#include \"%s-private.h\"\n\n",
3449 error_printf(GOB_WARN, 0,
3450 "Implicit private header include "
3452 "\tsource file, while public "
3453 "header is at a custom location, "
3455 "\texplicitly include "
3456 "the private header below the "
3464 print_header_prefixes(void)
3468 p = replace_sep(((Class *)class)->otype, '_');
3470 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3472 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3473 "#define __%s_PRIVATE_H__\n\n"
3474 "#include \"%s.h\"\n\n", p, p, filebase);
3477 if( ! no_extern_c) {
3478 out_printf(outh, "#ifdef __cplusplus\n"
3480 "#endif /* __cplusplus */\n\n");
3482 out_printf(outph, "#ifdef __cplusplus\n"
3484 "#endif /* __cplusplus */\n\n");
3489 print_header_postfixes(void)
3492 out_printf(outh, "\n#ifdef __cplusplus\n"
3494 "#endif /* __cplusplus */\n");
3495 out_printf(outh, "\n#endif\n");
3498 out_printf(outph, "\n#ifdef __cplusplus\n"
3500 "#endif /* __cplusplus */\n");
3501 out_printf(outph, "\n#endif\n");
3510 /* print the AT_CCODE blocks */
3511 for(li = nodes; li != NULL; li = li->next) {
3512 Node *node = li->data;
3513 if(node->type == CCODE_NODE) {
3514 CCode *cc = (CCode *)node;
3515 if(cc->cctype == AT_CCODE)
3516 print_ccode_block((CCode *)node);
3522 print_header_top(void)
3526 /* mandatory includes */
3527 out_printf (outh, "#include <glib.h>\n");
3528 out_printf (outh, "#include <glib-object.h>\n");
3530 /* print the HT_CCODE blocks */
3531 for (li = nodes; li != NULL; li = li->next) {
3532 Node *node = li->data;
3533 if (node->type == CCODE_NODE) {
3534 CCode *cc = (CCode *)node;
3535 if (cc->cctype == HT_CCODE)
3536 print_ccode_block ((CCode *)node);
3542 print_enum (EnumDef *enode)
3549 funcprefix = replace_sep (enode->etype, '_');
3550 g_strdown (funcprefix);
3551 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3553 type = remove_sep (enode->etype);
3555 out_printf (outh, "\ntypedef enum {\n");
3557 for (li = enode->values; li != NULL; li = li->next) {
3558 EnumValue *value = li->data;
3560 char *sname = g_strdown (g_strdup (value->name));
3562 while ((p = strchr (sname, '_')) != NULL)
3565 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3566 if (value->value != NULL)
3567 out_printf (outh, " = %s", value->value);
3568 if (li->next != NULL)
3569 out_printf (outh, ",\n");
3571 out_printf (outh, "\n");
3573 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3574 enode->prefix, value->name,
3575 enode->prefix, value->name,
3581 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3583 out_printf (outh, "} %s;\n", type);
3585 str = make_pre_macro (enode->etype, "TYPE");
3586 out_printf (outh, "#define %s ", str);
3589 out_printf (outh, "%s_get_type()\n", funcprefix);
3590 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3593 "GType\n%s_get_type (void)\n"
3595 "\tstatic GType type = 0;\n"
3596 "\tif (type == 0)\n"
3597 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3600 funcprefix, type, funcprefix);
3602 g_free (funcprefix);
3607 print_flags (Flags *fnode)
3615 funcprefix = replace_sep (fnode->ftype, '_');
3616 g_strdown (funcprefix);
3617 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3619 type = remove_sep (fnode->ftype);
3621 out_printf (outh, "\ntypedef enum {\n");
3623 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3624 const char *name = li->data;
3626 char *sname = g_strdown (g_strdup (name));
3628 while ((p = strchr (sname, '_')) != NULL)
3631 out_printf (outh, "\t%s_%s = 1<<%d",
3632 fnode->prefix, name, i);
3633 if (li->next != NULL)
3634 out_printf (outh, ",\n");
3636 out_printf (outh, "\n");
3638 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3639 fnode->prefix, name,
3640 fnode->prefix, name,
3646 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3648 out_printf (outh, "} %s;\n", type);
3650 str = make_pre_macro (fnode->ftype, "TYPE");
3651 out_printf (outh, "#define %s ", str);
3654 out_printf (outh, "%s_get_type()\n", funcprefix);
3655 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3658 "GType\n%s_get_type (void)\n"
3660 "\tstatic GType type = 0;\n"
3661 "\tif (type == 0)\n"
3662 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3665 funcprefix, type, funcprefix);
3667 g_free (funcprefix);
3672 print_error (Error *enode)
3679 funcprefix = replace_sep (enode->etype, '_');
3680 g_strdown (funcprefix);
3681 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3683 type = remove_sep (enode->etype);
3685 out_printf (outh, "\ntypedef enum {\n");
3687 for (li = enode->values; li != NULL; li = li->next) {
3688 const char *name = li->data;
3690 char *sname = g_strdown (g_strdup (name));
3692 while ((p = strchr (sname, '_')) != NULL)
3695 out_printf (outh, "\t%s_%s", enode->prefix, name);
3696 if (li->next != NULL)
3697 out_printf (outh, ",\n");
3699 out_printf (outh, "\n");
3701 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3702 enode->prefix, name,
3703 enode->prefix, name,
3709 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3711 out_printf (outh, "} %s;\n", type);
3713 str = make_pre_macro (enode->etype, "TYPE");
3714 out_printf (outh, "#define %s ", str);
3717 out_printf (outh, "%s_get_type ()\n", funcprefix);
3718 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3721 "GType\n%s_get_type (void)\n"
3723 "\tstatic GType type = 0;\n"
3724 "\tif (type == 0)\n"
3725 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3728 funcprefix, type, funcprefix);
3730 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3731 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3733 str = replace_sep (enode->etype, '-');
3737 "GQuark\n%s_quark (void)\n"
3739 "\tstatic GQuark q = 0;\n"
3741 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3748 g_free (funcprefix);
3753 generate_outfiles(void)
3757 print_file_comments();
3763 print_header_prefixes();
3765 print_useful_macros();
3769 for (li = nodes; li != NULL; li = li->next) {
3770 Node *node = li->data;
3771 if (node->type == CCODE_NODE) {
3772 CCode *cc = (CCode *)node;
3773 if (cc->cctype != HT_CCODE &&
3774 cc->cctype != AT_CCODE)
3775 print_ccode_block ((CCode *)node);
3776 } else if (node->type == CLASS_NODE) {
3777 print_class_block ((Class *)node);
3778 } else if (node->type == ENUMDEF_NODE) {
3779 print_enum ((EnumDef *)node);
3780 } else if (node->type == FLAGS_NODE) {
3781 print_flags ((Flags *)node);
3782 } else if (node->type == ERROR_NODE) {
3783 print_error ((Error *)node);
3785 g_assert_not_reached();
3789 print_header_postfixes();
3795 fprintf(stderr, "Gob version %s\n\n", VERSION);
3796 fprintf(stderr, "gob [options] file.gob\n\n");
3797 fprintf(stderr, "Options:\n"
3798 "\t--help,-h,-? Display this help\n"
3799 "\t--version Display version\n"
3800 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3801 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3802 "\t--for-cpp Create C++ files\n"
3803 "\t--no-extern-c Never print extern \"C\" into the "
3805 "\t--no-gnu Never use GNU extentions\n"
3806 "\t--no-touch-headers Don't touch headers unless they "
3808 "\t--always-private-header Always create a private header "
3810 "\t even if it would be empty "
3812 "\t--ondemand-private-header Create private header only when "
3814 "\t--no-private-header Don't create a private header, "
3816 "\t structure and protected "
3817 "prototypes inside c file\n"
3818 "\t--always-private-struct Always create a private pointer "
3820 "\t the object structure\n"
3821 "\t--m4 Preprocess source with m4. "
3822 "Following args will\n"
3823 "\t be passed to m4\n"
3824 "\t--m4-dir Print directory that will be "
3827 "\t--no-write,-n Don't write output files, just "
3829 "\t--no-lines Don't print '#line' to output\n"
3830 "\t--no-self-alias Don't create self type and macro "
3832 "\t--no-kill-underscores Ignored for compatibility\n");
3836 parse_options(int argc, char *argv[])
3839 int got_file = FALSE;
3840 int no_opts = FALSE;
3841 int m4_opts = FALSE; /* if we are just passing on args to m4 */
3845 for(i = 1 ; i < argc; i++) {
3847 char *new_commandline;
3848 g_assert(m4_commandline!=NULL);
3850 /* check whether this one looks like the filename */
3851 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
3853 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
3857 /* insert flags before the filename */
3858 new_commandline=g_strconcat(m4_commandline,
3866 /* just an ordinary option */
3868 new_commandline=g_strconcat(m4_commandline,
3873 /* free old commandline */
3874 g_free(m4_commandline);
3875 m4_commandline=new_commandline;
3877 } else if(no_opts ||
3878 argv[i][0] != '-') {
3881 fprintf(stderr, "Specify only one file!\n");
3887 } else if(strcmp(argv[i], "--help")==0) {
3890 } else if(strcmp(argv[i], "--version")==0) {
3891 fprintf(stderr, "Gob version %s\n", VERSION);
3893 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
3894 exit_on_warn = TRUE;
3895 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
3896 exit_on_warn = FALSE;
3897 } else if(strcmp(argv[i], "--for-cpp")==0) {
3899 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
3900 no_touch_headers = TRUE;
3901 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
3902 private_header = PRIVATE_HEADER_ONDEMAND;
3903 } else if(strcmp(argv[i], "--always-private-header")==0) {
3904 private_header = PRIVATE_HEADER_ALWAYS;
3905 } else if(strcmp(argv[i], "--no-private-header")==0) {
3906 private_header = PRIVATE_HEADER_NEVER;
3907 } else if(strcmp(argv[i], "--no-gnu")==0) {
3909 } else if(strcmp(argv[i], "--no-extern-c")==0) {
3911 } else if(strcmp(argv[i], "--no-write")==0) {
3913 } else if(strcmp(argv[i], "--no-lines")==0) {
3915 } else if(strcmp(argv[i], "--no-self-alias")==0) {
3916 no_self_alias = TRUE;
3917 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
3919 } else if(strcmp(argv[i], "--always-private-struct")==0) {
3920 always_private_struct = TRUE;
3921 } else if(strcmp(argv[i], "--m4-dir")==0) {
3922 printf("%s\n",M4_INCLUDE_DIR);
3924 } else if(strcmp(argv[i], "--m4")==0) {
3928 m4_commandline=g_strdup(M4_COMMANDLINE);
3929 } else if(strcmp(argv[i], "--m4-clean")==0) {
3933 m4_commandline=g_strdup(M4_COMMANDLINE);
3934 } else if(strcmp(argv[i], "--")==0) {
3935 /*further arguments are files*/
3937 } else if(strncmp(argv[i], "--", 2)==0) {
3938 /*unknown long option*/
3939 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
3943 /*by now we know we have a string starting with
3944 - which is a short option string*/
3946 for(p = argv[i] + 1; *p; p++) {
3960 "Unknown option '%c'!\n", *p);
3969 /* if we are using m4, and got no filename, append m4 flags now */
3970 if(!got_file && use_m4 && !use_m4_clean) {
3971 char *new_commandline;
3972 new_commandline=g_strconcat(m4_commandline,
3976 g_free(m4_commandline);
3977 m4_commandline=new_commandline;
3982 /* this is a somewhat ugly hack, but it appears to work */
3984 compare_and_move_header(void)
3986 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
3987 char *hf = g_strconcat(filebase, ".h", NULL);
3989 if(stat(hf, &s) == 0) {
3991 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
3992 if(system(s) == 0) {
3993 if(unlink(hfnew) != 0)
3994 error_printf(GOB_ERROR, 0,
3995 "Can't remove new header file");
4003 error_printf(GOB_ERROR, 0,
4004 "Can't remove old header file");
4006 if(rename(hfnew, hf) != 0)
4007 error_printf(GOB_ERROR, 0,
4008 "Can't rename new header file");
4014 main(int argc, char *argv[])
4016 parse_options(argc, argv);
4019 yyin = popen(m4_commandline, "r");
4021 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4025 } else if(filename) {
4026 yyin = fopen(filename, "r");
4028 fprintf(stderr, "Error: can't open file '%s'\n",
4037 /* This is where parsing is done */
4040 g_error("Parsing errors, quitting");
4042 /* close input file */
4043 if(use_m4) pclose(yyin);
4048 error_print(GOB_ERROR, 0, " no class defined");
4051 exit_on_error = FALSE;
4053 signals = count_signals ((Class *)class);
4054 set_properties = count_set_properties ((Class *)class) +
4055 count_set_arguments ((Class *)class);
4056 get_properties = count_get_properties ((Class *)class) +
4057 count_get_arguments ((Class *)class);
4058 overrides = count_overrides ((Class *)class);
4059 privates = count_privates ((Class *)class);
4060 protecteds = count_protecteds ((Class *)class);
4061 unreftors = count_unreftors ((Class *)class);
4062 destructors = count_destructors ((Class *)class);
4063 initializers = count_initializers ((Class *)class);
4064 overrode_get_type = find_get_type ((Class *)class);
4067 make_inits ((Class *)class);
4069 need_shutdown = TRUE;
4070 find_shutdown ((Class *)class);
4072 if (destructors > 0 ||
4074 need_finalize = TRUE;
4075 find_finalize ((Class *)class);
4077 check_bad_symbols ((Class *)class);
4078 check_duplicate_symbols ((Class *)class);
4079 check_duplicate_overrides ((Class *)class);
4080 check_duplicate_signals_args ((Class *)class);
4081 check_public_new ((Class *)class);
4082 check_vararg ((Class *)class);
4083 check_firstarg ((Class *)class);
4084 check_nonvoidempty ((Class *)class);
4085 check_signal_args ((Class *)class);
4086 check_property_types ((Class *)class);
4087 check_argument_types ((Class *)class);
4088 check_func_arg_checks ((Class *)class);
4090 exit_on_error = TRUE;
4095 any_special = setup_special_array ((Class *)class, special_array);
4099 generate_outfiles ();
4110 if (no_touch_headers &&
4112 compare_and_move_header ();