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),(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), (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;
1004 char *name = replace_sep (interface, '_');
1005 char *type = remove_sep (interface);
1007 out_printf (out, "\nstatic void\n"
1008 "___%s_init (%sIface *iface)\n"
1012 add_interface_methods (c, interface);
1014 out_printf (out, "}\n\n");
1022 add_interface_infos (void)
1025 for (li = ((Class *)class)->interfaces;
1028 char *name = replace_sep (li->data, '_');
1030 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1031 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1041 add_interfaces (void)
1044 for (li = ((Class *)class)->interfaces;
1047 char *name = replace_sep (li->data, '_');
1048 char *type = make_pre_macro (li->data, "TYPE");
1051 "\t\tg_type_add_interface_static (type,\n"
1053 "\t\t\t&%s_info);\n",
1065 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1069 "%s_get_type (void)\n"
1071 "\tstatic GType type = 0;\n\n"
1072 "\tif (type == 0) {\n"
1073 "\t\tstatic const GTypeInfo info = {\n"
1074 "\t\t\tsizeof (%sClass),\n"
1075 "\t\t\t(GBaseInitFunc) NULL,\n"
1076 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1077 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1078 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1079 "\t\t\tNULL /* class_data */,\n"
1080 "\t\t\tsizeof (%s),\n"
1081 "\t\t\t0 /* n_preallocs */,\n"
1082 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1084 funcbase, typebase, funcbase, typebase, funcbase);
1086 add_interface_infos ();
1089 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)0);\n",
1090 pmacrotype, typebase);
1098 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1100 chunk_size, chunk_size);
1110 add_bonobo_object_get_type (void)
1112 /* char *chunk_size = ((Class*)class)->chunk_size; */
1113 /* _vicious_ spanks seth with a rusty nail
1115 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1116 "gob2 doesn't officially support it yet. It'd be safer "
1117 "and a lot more fun to blow goats.\"\n");
1122 "%s_get_type (void)\n" /* 1 */
1124 "\tstatic GType type = 0;\n\n"
1125 "\tif (type == 0) {\n"
1126 "\t\tstatic const GTypeInfo info = {\n"
1127 "\t\t\tsizeof (%sClass),\n" /* 2 */
1128 "\t\t\t(GBaseInitFunc) NULL,\n"
1129 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1130 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1131 "\t\t\tNULL, /* class_finalize */\n"
1132 "\t\t\tNULL, /* class_data */\n"
1133 "\t\t\tsizeof (%s),\n" /* 4 */
1134 "\t\t\t0, /* n_preallocs */\n"
1135 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1144 add_interface_infos ();
1147 "\t\ttype = bonobo_type_unique (\n"
1148 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1149 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1150 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1151 "\t\t\t&info, \"%s\");\n", /* 3 */
1152 ((Class*)class)->bonobo_object_class /* 1 */,
1161 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1163 chunk_size, chunk_size);
1172 add_overrides(Class *c, const char *oname,
1173 gboolean did_base_obj)
1179 done = g_hash_table_new (g_str_hash, g_str_equal);
1181 s = g_strdup ("GObject");
1182 g_hash_table_insert (done, s, s);
1184 for (li = c->nodes; li != NULL; li = li->next) {
1187 Method *m = (Method *)n;
1188 if(n->type != METHOD_NODE ||
1189 m->method != OVERRIDE_METHOD)
1192 s = remove_sep(m->otype);
1194 if(g_hash_table_lookup(done, s)) {
1198 g_hash_table_insert(done, s, s);
1200 f = replace_sep(m->otype, '_');
1203 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1208 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1209 g_hash_table_destroy (done);
1213 make_run_signal_flags(Method *m, gboolean last)
1228 gs = g_string_new(NULL);
1231 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1233 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1235 if(m->scope == PUBLIC_SCOPE)
1236 g_string_append(gs, " | G_SIGNAL_ACTION");
1238 for(li = m->flags; li; li = li->next) {
1239 char *flag = li->data;
1241 for(i=0;flags[i];i++) {
1242 if(strcmp(flags[i], flag)==0)
1245 /* if we haven't found it in our list */
1247 error_printf(GOB_WARN, m->line_no,
1248 "Unknown flag '%s' used, "
1249 "perhaps it was misspelled",
1252 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1256 char *ret = gs->str;
1257 g_string_free(gs, FALSE);
1264 add_signals(Class *c)
1268 out_printf(out, "\n");
1269 for(li=c->nodes;li;li=g_list_next(li)) {
1271 char *mar, *sig, *flags;
1272 gboolean is_none, last = FALSE;
1273 Method *m = (Method *)n;
1275 if(n->type != METHOD_NODE ||
1276 (m->method != SIGNAL_FIRST_METHOD &&
1277 m->method != SIGNAL_LAST_METHOD))
1280 if(m->method == SIGNAL_FIRST_METHOD)
1285 if(g_hash_table_lookup(marsh, m))
1286 mar = g_strconcat("___marshal_",
1287 (char *)g_hash_table_lookup(marsh, m),
1290 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1292 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1294 sig = g_strdup (m->id);
1296 flags = make_run_signal_flags (m, last);
1297 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1298 "\t\tg_signal_new (\"%s\",\n"
1299 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1300 "\t\t\t(GSignalFlags)(%s),\n"
1301 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1302 "\t\t\tNULL, NULL,\n"
1304 "\t\t\tG_TYPE_%s, %d",
1307 typebase, m->id, mar,
1308 (char *)m->gtktypes->data,
1309 is_none ? 0 : g_list_length(m->gtktypes->next));
1316 for(l = m->gtktypes->next; l != NULL; l = l->next)
1317 out_printf(out, ",\n\t\t\tG_TYPE_%s",
1321 out_printf(out, ");\n");
1323 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1327 out_printf(out, "\tif(");
1328 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1329 out_printf(out, "%s sizeof(", sep);
1330 print_type(out, m->mtype, FALSE);
1331 out_printf(out, "%s",
1333 m->mtype->postfix : "");
1334 out_printf(out, ") != sizeof(%s)",
1335 get_cast(m->gtktypes->data, FALSE));
1340 for(al = m->args->next, gl = m->gtktypes->next;
1341 al != NULL && gl != NULL;
1342 al = al->next, gl = gl->next) {
1343 FuncArg *arg = al->data;
1344 char *gtkarg = gl->data;
1346 out_printf(out, "%ssizeof(", sep);
1347 print_type(out, arg->atype, FALSE);
1348 out_printf(out, "%s",
1349 arg->atype->postfix ?
1350 arg->atype->postfix : "");
1351 out_printf(out, ") != sizeof(%s)",
1352 get_cast(gtkarg, FALSE));
1356 out_printf(out, ") {\n"
1357 "\t\tg_error(\"%s line %d: Type mismatch "
1358 "of \\\"%s\\\" signal signature\");\n"
1360 filename, m->line_no, m->id);
1367 set_def_handlers(Class *c, const char *oname)
1370 gboolean set_line = FALSE;
1372 out_printf(out, "\n");
1373 for(li = c->nodes; li; li = g_list_next(li)) {
1375 Method *m = (Method *)n;
1377 if(n->type != METHOD_NODE ||
1378 (m->method != SIGNAL_FIRST_METHOD &&
1379 m->method != SIGNAL_LAST_METHOD &&
1380 m->method != VIRTUAL_METHOD &&
1381 m->method != OVERRIDE_METHOD))
1384 if(m->line_no > 0 && m->cbuf) {
1385 out_addline_infile(out, m->line_no);
1387 } else if(set_line) {
1388 out_addline_outfile(out);
1393 if (m->method == OVERRIDE_METHOD) {
1395 s = replace_sep (m->otype, '_');
1398 if (need_shutdown &&
1399 shutdown_handler != NULL &&
1400 strcmp (m->id, "shutdown") == 0)
1401 out_printf (out, "\tg_object_class->shutdown "
1402 "= ___shutdown;\n");
1403 else if (need_finalize &&
1405 strcmp(m->id, "finalize") == 0)
1407 "\tg_object_class->finalize = ___finalize;\n");
1408 else if (m->cbuf != NULL)
1410 "\t%s_class->%s = ___%x_%s_%s;\n",
1411 s, m->id, (guint)m->unique_id,
1414 out_printf(out, "\t%s_class->%s = NULL;\n",
1418 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1422 out_printf(out, "\t%s->%s = NULL;\n",
1427 out_addline_outfile(out);
1431 make_argument (Argument *a)
1436 char *argflags[] = {
1444 flags = g_string_new ("(GParamFlags)(");
1446 if(a->get && a->set)
1447 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1449 g_string_append (flags, "G_PARAM_READABLE");
1451 g_string_append (flags, "G_PARAM_WRITABLE");
1453 g_assert(a->get || a->set);
1455 for (l = a->flags; l != NULL; l = l->next) {
1456 char *flag = l->data;
1458 if(strcmp (flag, "READABLE") == 0 ||
1459 strcmp (flag, "WRITABLE") == 0) {
1460 error_print(GOB_WARN, a->line_no,
1462 "WRITABLE argument flags are "
1463 "set automatically");
1466 for(i = 0; argflags[i]; i++) {
1467 if(strcmp(argflags[i], flag)==0)
1470 /* if we haven't found it in our list */
1471 if( ! argflags[i]) {
1472 error_printf(GOB_WARN, a->line_no,
1473 "Unknown flag '%s' used, "
1474 "perhaps it was misspelled", flag);
1476 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1479 g_string_append (flags, ")");
1481 s = g_strdup(a->name);
1483 if (!strcmp (a->gtktype, "ENUM"))
1484 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1485 "\t\tG_TYPE_ENUM, 0,\n"
1487 a->name, flags->str);
1488 if (!strcmp (a->gtktype, "FLAGS"))
1489 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1490 "\t\tG_TYPE_FLAGS, 0,\n"
1492 a->name, flags->str);
1493 else if (!strcmp (a->gtktype, "OBJECT"))
1494 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1495 "\t\tG_TYPE_OBJECT,\n"
1497 a->name, flags->str);
1498 else if (!strcmp (a->gtktype, "STRING"))
1499 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1502 a->name, flags->str);
1503 else if (!strcmp (a->gtktype, "INT"))
1504 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1505 "\t\tG_MININT, G_MAXINT,\n"
1508 a->name, flags->str);
1509 else if (!strcmp (a->gtktype, "UINT"))
1510 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1511 "\t\t0, G_MAXUINT,\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, "CHAR"))
1522 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1526 a->name, flags->str);
1527 else if (!strcmp (a->gtktype, "UCHAR"))
1528 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1532 a->name, flags->str);
1533 else if (!strcmp (a->gtktype, "BOOL") ||
1534 !strcmp (a->gtktype, "BOOLEAN"))
1535 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1538 a->name, flags->str);
1539 else if (!strcmp (a->gtktype, "LONG"))
1540 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1541 "\t\tG_MINLONG, G_MAXLONG,\n"
1544 a->name, flags->str);
1545 else if (!strcmp (a->gtktype, "ULONG"))
1546 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1547 "\t\t0, G_MAXULONG,\n"
1550 a->name, flags->str);
1551 else if (!strcmp (a->gtktype, "FLOAT"))
1552 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1553 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1556 a->name, flags->str);
1557 else if (!strcmp (a->gtktype, "DOUBLE"))
1558 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1559 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1562 a->name, flags->str);
1563 else if (!strcmp (a->gtktype, "POINTER"))
1564 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1566 a->name, flags->str);
1568 error_printf (GOB_ERROR, a->line_no,
1569 "%s type is not supported for arguments, try using properties",
1572 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1573 "\t\tPROP_%s, param_spec);\n", s);
1577 g_string_free(flags, TRUE);
1580 #define value_for_print(str, alt) (str != NULL ? str : alt)
1583 make_property (Property *p)
1588 char *argflags[] = {
1596 flags = g_string_new ("(GParamFlags)(");
1598 if (p->get != NULL && p->set != NULL)
1599 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1600 else if (p->get != NULL)
1601 g_string_append (flags, "G_PARAM_READABLE");
1603 g_string_append (flags, "G_PARAM_WRITABLE");
1605 if (p->get == NULL && p->set == NULL) {
1606 error_print (GOB_ERROR, p->line_no,
1607 "Property has no getter nor setter");
1610 for (l = p->flags; l != NULL; l = l->next) {
1611 char *flag = l->data;
1613 if(strcmp (flag, "READABLE") == 0 ||
1614 strcmp (flag, "WRITABLE") == 0) {
1615 error_print(GOB_WARN, p->line_no,
1617 "WRITABLE argument flags are "
1618 "set automatically");
1621 for(i = 0; argflags[i]; i++) {
1622 if(strcmp(argflags[i], flag)==0)
1625 /* if we haven't found it in our list */
1626 if( ! argflags[i]) {
1627 error_printf(GOB_WARN, p->line_no,
1628 "Unknown flag '%s' used, "
1629 "perhaps it was misspelled", flag);
1631 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1634 g_string_append (flags, ")");
1636 if (strcmp (p->gtktype, "CHAR") == 0)
1637 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1638 "\t\t(\"%s\" /* name */,\n"
1639 "\t\t %s /* nick */,\n"
1640 "\t\t %s /* blurb */,\n"
1641 "\t\t %s /* minimum */,\n"
1642 "\t\t %s /* maximum */,\n"
1643 "\t\t %s /* default_value */,\n"
1646 value_for_print (p->nick, "NULL"),
1647 value_for_print (p->blurb, "NULL"),
1648 value_for_print (p->minimum, "-128"),
1649 value_for_print (p->maximum, "127"),
1650 value_for_print (p->default_value, "0"),
1652 else if (strcmp (p->gtktype, "UCHAR") == 0)
1653 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1654 "\t\t(\"%s\" /* name */,\n"
1655 "\t\t %s /* nick */,\n"
1656 "\t\t %s /* blurb */,\n"
1657 "\t\t %s /* minimum */,\n"
1658 "\t\t %s /* maximum */,\n"
1659 "\t\t %s /* default_value */,\n"
1662 value_for_print (p->nick, "NULL"),
1663 value_for_print (p->blurb, "NULL"),
1664 value_for_print (p->minimum, "0"),
1665 value_for_print (p->maximum, "0xFF"),
1666 value_for_print (p->default_value, "0"),
1668 else if (strcmp (p->gtktype, "BOOLEAN") == 0)
1669 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1670 "\t\t(\"%s\" /* name */,\n"
1671 "\t\t %s /* nick */,\n"
1672 "\t\t %s /* blurb */,\n"
1673 "\t\t %s /* default_value */,\n"
1676 value_for_print (p->nick, "NULL"),
1677 value_for_print (p->blurb, "NULL"),
1678 value_for_print (p->default_value, "FALSE"),
1680 else if (strcmp (p->gtktype, "INT") == 0)
1681 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1682 "\t\t(\"%s\" /* name */,\n"
1683 "\t\t %s /* nick */,\n"
1684 "\t\t %s /* blurb */,\n"
1685 "\t\t %s /* minimum */,\n"
1686 "\t\t %s /* maximum */,\n"
1687 "\t\t %s /* default_value */,\n"
1690 value_for_print (p->nick, "NULL"),
1691 value_for_print (p->blurb, "NULL"),
1692 value_for_print (p->minimum, "G_MININT"),
1693 value_for_print (p->maximum, "G_MAXINT"),
1694 value_for_print (p->default_value, "0"),
1696 else if (strcmp (p->gtktype, "UINT") == 0)
1697 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1698 "\t\t(\"%s\" /* name */,\n"
1699 "\t\t %s /* nick */,\n"
1700 "\t\t %s /* blurb */,\n"
1701 "\t\t %s /* minimum */,\n"
1702 "\t\t %s /* maximum */,\n"
1703 "\t\t %s /* default_value */,\n"
1706 value_for_print (p->nick, "NULL"),
1707 value_for_print (p->blurb, "NULL"),
1708 value_for_print (p->minimum, "0"),
1709 value_for_print (p->maximum, "G_MAXUINT"),
1710 value_for_print (p->default_value, "0"),
1712 else if (strcmp (p->gtktype, "LONG") == 0)
1713 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1714 "\t\t(\"%s\" /* name */,\n"
1715 "\t\t %s /* nick */,\n"
1716 "\t\t %s /* blurb */,\n"
1717 "\t\t %s /* minimum */,\n"
1718 "\t\t %s /* maximum */,\n"
1719 "\t\t %s /* default_value */,\n"
1722 value_for_print (p->nick, "NULL"),
1723 value_for_print (p->blurb, "NULL"),
1724 value_for_print (p->minimum, "G_MINLONG"),
1725 value_for_print (p->maximum, "G_MAXLONG"),
1726 value_for_print (p->default_value, "0"),
1728 else if (strcmp (p->gtktype, "ULONG") == 0)
1729 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1730 "\t\t(\"%s\" /* name */,\n"
1731 "\t\t %s /* nick */,\n"
1732 "\t\t %s /* blurb */,\n"
1733 "\t\t %s /* minimum */,\n"
1734 "\t\t %s /* maximum */,\n"
1735 "\t\t %s /* default_value */,\n"
1738 value_for_print (p->nick, "NULL"),
1739 value_for_print (p->blurb, "NULL"),
1740 value_for_print (p->minimum, "0"),
1741 value_for_print (p->maximum, "G_MAXULONG"),
1742 value_for_print (p->default_value, "0"),
1744 else if (strcmp (p->gtktype, "UNICHAR") == 0)
1745 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1746 "\t\t(\"%s\" /* name */,\n"
1747 "\t\t %s /* nick */,\n"
1748 "\t\t %s /* blurb */,\n"
1749 "\t\t %s /* default_value */,\n"
1752 value_for_print (p->nick, "NULL"),
1753 value_for_print (p->blurb, "NULL"),
1754 value_for_print (p->default_value, "0"),
1756 else if (strcmp (p->gtktype, "ENUM") == 0)
1757 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1758 "\t\t(\"%s\" /* name */,\n"
1759 "\t\t %s /* nick */,\n"
1760 "\t\t %s /* blurb */,\n"
1761 "\t\t %s /* enum_type */,\n"
1762 "\t\t %s /* default_value */,\n"
1765 value_for_print (p->nick, "NULL"),
1766 value_for_print (p->blurb, "NULL"),
1767 value_for_print (p->extra_gtktype, "G_TYPE_ENUM"),
1768 value_for_print (p->default_value, "0"),
1770 else if (strcmp (p->gtktype, "FLAGS") == 0)
1771 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1772 "\t\t(\"%s\" /* name */,\n"
1773 "\t\t %s /* nick */,\n"
1774 "\t\t %s /* blurb */,\n"
1775 "\t\t %s /* flags_type */,\n"
1776 "\t\t %s /* default_value */,\n"
1779 value_for_print (p->nick, "NULL"),
1780 value_for_print (p->blurb, "NULL"),
1781 value_for_print (p->extra_gtktype, "G_TYPE_FLAGS"),
1782 value_for_print (p->default_value, "0"),
1784 else if (strcmp (p->gtktype, "FLOAT") == 0)
1785 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1786 "\t\t(\"%s\" /* name */,\n"
1787 "\t\t %s /* nick */,\n"
1788 "\t\t %s /* blurb */,\n"
1789 "\t\t %s /* minimum */,\n"
1790 "\t\t %s /* maximum */,\n"
1791 "\t\t %s /* default_value */,\n"
1794 value_for_print (p->nick, "NULL"),
1795 value_for_print (p->blurb, "NULL"),
1796 value_for_print (p->minimum, "G_MINFLOAT"),
1797 value_for_print (p->maximum, "G_MAXFLOAT"),
1798 value_for_print (p->default_value, "0.0"),
1800 else if (strcmp (p->gtktype, "DOUBLE") == 0)
1801 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1802 "\t\t(\"%s\" /* name */,\n"
1803 "\t\t %s /* nick */,\n"
1804 "\t\t %s /* blurb */,\n"
1805 "\t\t %s /* minimum */,\n"
1806 "\t\t %s /* maximum */,\n"
1807 "\t\t %s /* default_value */,\n"
1810 value_for_print (p->nick, "NULL"),
1811 value_for_print (p->blurb, "NULL"),
1812 value_for_print (p->minimum, "G_MINDOUBLE"),
1813 value_for_print (p->maximum, "G_MAXDOUBLE"),
1814 value_for_print (p->default_value, "0.0"),
1816 else if (strcmp (p->gtktype, "STRING") == 0)
1817 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1818 "\t\t(\"%s\" /* name */,\n"
1819 "\t\t %s /* nick */,\n"
1820 "\t\t %s /* blurb */,\n"
1821 "\t\t %s /* default_value */,\n"
1824 value_for_print (p->nick, "NULL"),
1825 value_for_print (p->blurb, "NULL"),
1826 value_for_print (p->default_value, "NULL"),
1828 else if (strcmp (p->gtktype, "PARAM") == 0)
1829 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1830 "\t\t(\"%s\" /* name */,\n"
1831 "\t\t %s /* nick */,\n"
1832 "\t\t %s /* blurb */,\n"
1833 "\t\t %s /* param_type */,\n"
1836 value_for_print (p->nick, "NULL"),
1837 value_for_print (p->blurb, "NULL"),
1838 value_for_print (p->extra_gtktype, "G_TYPE_PARAM"),
1840 else if (strcmp (p->gtktype, "BOXED") == 0)
1841 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1842 "\t\t(\"%s\" /* name */,\n"
1843 "\t\t %s /* nick */,\n"
1844 "\t\t %s /* blurb */,\n"
1845 "\t\t %s /* boxed_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_BOXED"),
1852 else if (strcmp (p->gtktype, "POINTER") == 0)
1853 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1854 "\t\t(\"%s\" /* name */,\n"
1855 "\t\t %s /* nick */,\n"
1856 "\t\t %s /* blurb */,\n"
1859 value_for_print (p->nick, "NULL"),
1860 value_for_print (p->blurb, "NULL"),
1862 /* FIXME: VALUE_ARRAY */
1863 else if (strcmp (p->gtktype, "CLOSURE") == 0)
1864 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1865 "\t\t(\"%s\" /* name */,\n"
1866 "\t\t %s /* nick */,\n"
1867 "\t\t %s /* blurb */,\n"
1870 value_for_print (p->nick, "NULL"),
1871 value_for_print (p->blurb, "NULL"),
1873 else if (strcmp (p->gtktype, "OBJECT") == 0)
1874 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1875 "\t\t(\"%s\" /* name */,\n"
1876 "\t\t %s /* nick */,\n"
1877 "\t\t %s /* blurb */,\n"
1878 "\t\t %s /* object_type */,\n"
1881 value_for_print (p->nick, "NULL"),
1882 value_for_print (p->blurb, "NULL"),
1883 value_for_print (p->extra_gtktype, "G_TYPE_OBJECT"),
1886 error_printf (GOB_ERROR, p->line_no,
1887 "%s type is not supported by properties",
1890 s = g_strdup (p->name);
1892 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1894 "\t\tparam_spec);\n", s);
1897 g_string_free (flags, TRUE);
1901 make_arguments(Class *c)
1904 if (get_properties > 0)
1905 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1906 if (set_properties > 0)
1907 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1908 out_printf (out, " {\n"
1909 "\tGParamSpec *param_spec;\n\n");
1911 for (li = c->nodes; li != NULL; li = li->next) {
1913 if (n->type == PROPERTY_NODE)
1914 make_property ((Property *)n);
1915 else if (n->type == ARGUMENT_NODE)
1916 make_argument ((Argument *)n);
1918 out_printf(out, " }\n");
1922 print_initializer(Method *m, Variable *v)
1926 if(v->initializer == NULL)
1929 if(v->scope == PRIVATE_SCOPE)
1930 root = g_strconcat(((FuncArg *)m->args->data)->name,
1933 root = g_strdup(((FuncArg *)m->args->data)->name);
1935 if(v->initializer_line > 0)
1936 out_addline_infile(out, v->initializer_line);
1938 out_printf(out, "\t%s->%s = %s;\n",
1939 root, v->id, v->initializer);
1941 if(v->initializer_line > 0)
1942 out_addline_outfile(out);
1948 print_destructor (Variable *v)
1952 if(v->destructor == NULL)
1955 if(v->scope == PRIVATE_SCOPE)
1956 root = "self->_priv";
1960 if(v->destructor_simple) {
1961 if(v->destructor_line > 0)
1962 out_addline_infile(out, v->destructor_line);
1964 out_printf(out, "\tif(%s->%s) { "
1965 "((*(void (*)(void *))%s)) (%s->%s); "
1966 "%s->%s = NULL; }\n",
1967 root, v->id, v->destructor, root, v->id,
1970 if(v->destructor_line > 0)
1971 out_addline_outfile(out);
1973 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
1974 out_printf(out, "#define VAR %s\n", v->id);
1975 out_printf(out, "\t{\n");
1976 if(v->destructor_line > 0)
1977 out_addline_infile(out, v->destructor_line);
1979 out_printf(out, "\t%s}\n", v->destructor);
1981 if(v->destructor_line > 0)
1982 out_addline_outfile(out);
1983 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
1985 out_printf(out, "#undef VAR\n");
1986 out_printf(out, "#undef %s\n", v->id);
1991 add_shutdown (Class *c)
1993 out_printf(out, "\nstatic void\n"
1994 "___shutdown (GObject *obj_self)\n"
1997 "#define __GOB_FUNCTION__ \"%s::shutdown\"\n",
2000 if (unreftors > 0) {
2001 out_printf (out, "\t%s *self = %s (obj_self);\n",
2002 typebase, macrobase);
2005 if (shutdown_handler != NULL) {
2006 /* so we get possible bad argument warning */
2007 if (shutdown_handler->line_no > 0)
2008 out_addline_infile (out, shutdown_handler->line_no);
2009 out_printf (out, "\t___%x_%s_shutdown(obj_self);\n",
2010 (guint)shutdown_handler->unique_id, funcbase);
2011 if (shutdown_handler->line_no > 0)
2012 out_addline_outfile (out);
2015 "\tif (G_OBJECT_CLASS (parent_class)->shutdown) \\\n"
2016 "\t\t(* G_OBJECT_CLASS (parent_class)->shutdown) (obj_self);\n");
2019 if (unreftors > 0) {
2021 for(li = ((Class *)class)->nodes;
2025 Variable *v = (Variable *)n;
2026 if (n->type == VARIABLE_NODE &&
2027 v->scope != CLASS_SCOPE &&
2028 v->destructor_unref)
2029 print_destructor (v);
2033 out_printf (out, "\treturn;\n");
2035 out_printf(out, "\tself = NULL;\n");
2036 out_printf(out, "}\n"
2037 "#undef __GOB_FUNCTION__\n\n");
2041 add_finalize (Class *c)
2045 "___finalize(GObject *obj_self)\n"
2048 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2053 out_printf(out, "\t%s *self = %s (obj_self);\n",
2054 typebase, macrobase);
2057 out_printf(out, "\tgpointer priv = self->_priv;\n");
2060 if(finalize_handler) {
2061 /* so we get possible bad argument warning */
2062 if(finalize_handler->line_no > 0)
2063 out_addline_infile(out, finalize_handler->line_no);
2064 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2065 (guint)finalize_handler->unique_id, funcbase);
2066 if(finalize_handler->line_no > 0)
2067 out_addline_outfile(out);
2070 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2071 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2074 if (destructors > 0) {
2076 for (li = ((Class *)class)->nodes;
2080 Variable *v = (Variable *)n;
2081 if (n->type == VARIABLE_NODE &&
2082 v->scope != CLASS_SCOPE &&
2083 ! v->destructor_unref)
2084 print_destructor (v);
2089 out_printf(out, "\tg_free (priv);\n");
2091 out_printf (out, "\treturn;\n");
2092 if (destructors > 0 ||
2094 out_printf (out, "\tself = NULL;\n");
2096 out_printf(out, "}\n"
2097 "#undef __GOB_FUNCTION__\n\n");
2101 make_bonobo_object_epv (Class *c, const char *classname)
2104 gboolean added_line = FALSE;
2106 for (li = c->nodes; li != NULL; li = li->next) {
2108 Method *m = (Method *)n;
2109 if(n->type != METHOD_NODE ||
2110 m->method == OVERRIDE_METHOD)
2113 if (m->bonobo_object_func) {
2114 if(m->line_no > 0) {
2115 out_addline_infile(out, m->line_no);
2117 } else if (m->line_no == 0 &&
2119 out_addline_outfile(out);
2122 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2123 classname, m->id, m->id);
2127 out_addline_outfile(out);
2134 for(li=c->nodes;li;li=g_list_next(li)) {
2138 gboolean add_unused_class = FALSE;
2140 if(n->type != METHOD_NODE)
2143 if(m->method == INIT_METHOD) {
2145 out_addline_infile(out, m->line_no);
2146 print_method(out, "static ", "\n", "", " ", "", "\n",
2147 m, FALSE, FALSE, TRUE);
2149 out_addline_outfile(out);
2150 out_printf(out, "{\n"
2151 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2154 out_printf(out, "\t%s->_priv = "
2155 "g_new0 (%sPrivate, 1);\n",
2156 ((FuncArg *)m->args->data)->name,
2158 } else if(always_private_struct) {
2159 out_printf(out, "\t%s->_priv = NULL;\n",
2160 ((FuncArg *)m->args->data)->name);
2162 if(initializers > 0) {
2164 for(li = ((Class *)class)->nodes;
2168 Variable *v = (Variable *)n;
2169 if(n->type != VARIABLE_NODE ||
2170 v->scope == CLASS_SCOPE)
2172 print_initializer(m, v);
2175 } else if(m->method == CLASS_INIT_METHOD) {
2176 gboolean did_base_obj = FALSE;
2179 out_addline_infile(out, m->line_no);
2180 print_method(out, "static ", "\n", "", " ", "", "\n",
2181 m, FALSE, FALSE, TRUE);
2183 out_addline_outfile(out);
2184 out_printf(out, "{\n"
2185 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2187 if (set_properties > 0 ||
2188 get_properties > 0 ||
2195 "(GObjectClass*) %s;\n",
2196 ((FuncArg *)m->args->data)->name);
2197 add_unused_class = TRUE;
2198 did_base_obj = TRUE;
2203 ((FuncArg *)m->args->data)->name,
2206 if (initializers > 0) {
2208 for(li = ((Class *)class)->nodes;
2212 Variable *v = (Variable *)n;
2213 if(n->type == VARIABLE_NODE &&
2214 v->scope == CLASS_SCOPE)
2215 print_initializer(m, v);
2219 out_printf(out, "\n\tparent_class = ");
2221 out_printf(out, "(%sClass *)", ptypebase);
2222 out_printf(out, "g_type_class_ref (%s);\n",
2228 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2230 /* if there are no handlers for these things, we
2231 * need to set them up here */
2232 if(need_shutdown && !shutdown_handler)
2233 out_printf(out, "\tg_object_class->shutdown "
2234 "= ___shutdown;\n");
2235 if(need_finalize && !finalize_handler)
2236 out_printf(out, "\tg_object_class->finalize = "
2239 if(get_properties > 0 || set_properties > 0)
2242 if (c->bonobo_object_class != NULL) {
2243 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2249 out_printf(out, " {\n");
2250 out_addline_infile(out, m->ccode_line);
2251 out_printf(out, "%s\n", m->cbuf);
2252 out_addline_outfile(out);
2253 out_printf(out, " }\n");
2255 out_printf(out, "\treturn;\n");
2258 ((FuncArg *)m->args->data)->name);
2259 if(add_unused_class) {
2260 out_printf (out, "\tg_object_class = NULL;\n");
2262 out_printf(out, "}\n"
2263 "#undef __GOB_FUNCTION__\n");
2268 add_argument (Argument *a, gboolean is_set)
2272 char *the_type_lower;
2277 line_no = a->set_line;
2280 line_no = a->get_line;
2284 s = g_strdup(a->name);
2286 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2288 the_type_lower = g_strdup (a->gtktype);
2289 g_strdown (the_type_lower);
2294 if (a->atype != NULL)
2295 cast = get_type (a->atype, TRUE);
2297 cast = g_strdup (get_cast (a->gtktype, FALSE));
2299 out_printf (out, "\t%s ARG = (%s) g_value_get_%s (VAL);\n",
2300 cast, cast, the_type_lower);
2303 } else if ( ! is_set) {
2306 if (a->atype != NULL)
2307 cast = get_type (a->atype, TRUE);
2309 cast = g_strdup (get_cast (a->gtktype, FALSE));
2310 out_printf (out, "\t%s ARG;\n"
2311 "\tmemset (&ARG, 0, sizeof (%s));\n",
2317 out_printf(out, "\t\t{\n");
2319 out_addline_infile (out, line_no);
2320 out_printf (out, "%s\n", cbuf);
2322 out_addline_outfile (out);
2323 out_printf (out, "\t\t}\n");
2325 if (strcmp (a->gtktype, "OBJECT") == 0)
2326 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2329 out_printf (out, "\t\t"
2330 "g_value_set_%s (VAL, ARG);\n",
2333 g_free (the_type_lower);
2336 out_printf (out, "\t\tif (&ARG) ;\n");
2339 out_printf (out, "\t\tbreak;\n");
2341 out_printf (out, "\t}\n");
2345 add_property (Property *p, gboolean is_set)
2348 char *the_type_lower;
2354 line_no = p->set_line;
2357 line_no = p->get_line;
2362 name_upper = g_strdup (p->name);
2363 g_strup (name_upper);
2364 the_type_lower = g_strdup (p->gtktype);
2365 g_strdown (the_type_lower);
2367 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2369 out_printf(out, "\t\t{\n");
2371 out_addline_infile (out, line_no);
2372 out_printf (out, "%s\n", cbuf);
2374 out_addline_outfile (out);
2375 out_printf (out, "\t\t}\n");
2377 g_free (name_upper);
2378 g_free (the_type_lower);
2380 out_printf (out, "\t\tbreak;\n");
2384 add_getset_arg(Class *c, gboolean is_set)
2387 out_printf(out, "\nstatic void\n"
2388 "___object_%s_property (GObject *object,\n"
2389 "\tguint property_id,\n"
2390 "\t%sGValue *VAL,\n"
2391 "\tGParamSpec *pspec)\n"
2392 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2395 "\tself = %s (object);\n\n"
2396 "\tswitch (property_id) {\n",
2397 is_set ? "set" : "get",
2398 is_set ? "const " : "",
2399 c->otype, is_set ? "set" : "get",
2400 typebase, macrobase);
2402 for (li = c->nodes; li != NULL; li = li->next) {
2404 if (n->type == PROPERTY_NODE)
2405 add_property ((Property *)n, is_set);
2406 else if (n->type == ARGUMENT_NODE)
2407 add_argument ((Argument *)n, is_set);
2409 out_printf (out, "\tdefault:\n"
2410 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2411 "#ifndef __PRETTY_FUNCTION__\n"
2412 "# undef G_STRLOC\n"
2413 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2415 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2417 "\treturn;\n\tself = NULL;\n\tVAL = NULL;\n\tpspec = NULL;\n}\n"
2418 "#undef __GOB_FUNCTION__\n");
2422 print_checks (Method *m, FuncArg *fa)
2426 gboolean checked_null = FALSE;
2427 is_void = (strcmp(m->mtype->name, "void")==0 &&
2428 m->mtype->pointer == NULL);
2430 for(li = fa->checks; li != NULL; li = li->next) {
2431 Check *ch = li->data;
2433 /* point to the method prot in .gob for failed checks */
2435 out_addline_infile(out, m->line_no);
2437 out_printf(out, "\tg_return_if_fail (");
2439 out_printf(out, "\tg_return_val_if_fail (");
2440 switch(ch->chtype) {
2442 out_printf(out, "%s != NULL", fa->name);
2443 checked_null = TRUE;
2446 s = make_pre_macro(fa->atype->name, "IS");
2448 out_printf(out, "%s (%s)", s, fa->name);
2450 /* if not check null, null may be valid */
2451 out_printf(out, "!(%s) || %s (%s)", fa->name,
2456 out_printf(out, "%s < %s", fa->name, ch->number);
2459 out_printf(out, "%s > %s", fa->name, ch->number);
2462 out_printf(out, "%s <= %s", fa->name, ch->number);
2465 out_printf(out, "%s >= %s", fa->name, ch->number);
2468 out_printf(out, "%s == %s", fa->name, ch->number);
2471 out_printf(out, "%s != %s", fa->name, ch->number);
2475 out_printf(out, ");\n");
2477 out_printf(out, ", (");
2478 print_type(out, m->mtype, TRUE);
2479 out_printf(out, ")%s);\n",
2480 m->onerror?m->onerror:"0");
2486 print_preconditions(Method *m)
2490 for(li=m->args;li;li=g_list_next(li)) {
2491 FuncArg *fa = li->data;
2493 print_checks(m, fa);
2496 out_addline_outfile(out);
2500 print_method_body(Method *m, int pre)
2503 out_addline_outfile(out);
2504 out_printf(out, "{\n"
2505 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2506 ((Class *)class)->otype,
2509 print_preconditions(m);
2511 /* Note: the trailing }'s are on one line, this is so
2512 that we get the no return warning correctly and point to
2513 the correct line in the .gob file, yes this is slightly
2514 ugly in the .c file, but that is not supposed to be
2515 human readable anyway. */
2517 out_printf(out, "{\n");
2519 out_addline_infile(out, m->ccode_line);
2520 out_printf(out, "\t%s}", m->cbuf);
2523 /* Note, there is no \n between the last } and this } so that
2524 * errors/warnings reported on the end of the body get pointed to the
2525 * right line in the .gob source */
2526 out_printf(out, "}\n");
2529 out_addline_outfile(out);
2530 out_printf(out, "#undef __GOB_FUNCTION__\n");
2534 put_signal_args (Method *m)
2538 for (ali = m->gtktypes->next, li=m->args->next;
2539 li != NULL && ali != NULL;
2540 li = li->next, ali = ali->next) {
2541 FuncArg *fa = li->data;
2542 char *cast = g_strdup (get_cast (ali->data, FALSE));
2545 cast = get_type (fa->atype, TRUE);
2547 /* we should have already proved before that
2548 the we know all the types */
2549 g_assert (cast != NULL);
2551 out_printf (out, ",\n\t\t(%s)%s", cast,
2559 get_arg_names_for_macro(Method *m)
2563 GString *gs = g_string_new(NULL);
2565 for(li=m->args;li;li=g_list_next(li)) {
2566 FuncArg *arg = li->data;
2567 g_string_sprintfa(gs, "%s___%s", p, arg->name);
2571 g_string_free(gs, FALSE);
2576 put_method(Method *m)
2578 char *s, *args, *doc;
2580 is_void = (strcmp(m->mtype->name, "void")==0 &&
2581 m->mtype->pointer == NULL);
2582 out_printf(out, "\n");
2583 if(m->method != OVERRIDE_METHOD) {
2584 doc = get_gtk_doc(m->id);
2586 out_printf(out, "%s", doc);
2591 case REGULAR_METHOD:
2593 out_addline_infile(out, m->line_no);
2594 if(m->scope == PRIVATE_SCOPE)
2595 print_method(out, "static ", "\n", "", " ", "", "\n",
2596 m, FALSE, FALSE, TRUE);
2597 else /* PUBLIC, PROTECTED */
2598 print_method(out, "", "\n", "", " ", "", "\n",
2599 m, FALSE, FALSE, TRUE);
2600 print_method_body(m, TRUE);
2601 /* the outfile line was added above */
2603 case SIGNAL_FIRST_METHOD:
2604 case SIGNAL_LAST_METHOD:
2606 out_addline_infile(out, m->line_no);
2607 if(m->scope == PRIVATE_SCOPE)
2608 print_method(out, "static ", "\n", "", " ", "", "\n",
2609 m, FALSE, FALSE, TRUE);
2610 else /* PUBLIC, PROTECTED */
2611 print_method(out, "", "\n", "", " ", "", "\n",
2612 m, FALSE, FALSE, TRUE);
2613 out_addline_outfile(out);
2614 out_printf(out, "{\n");
2615 s = g_strdup(m->id);
2617 if(strcmp(m->mtype->name, "void") == 0 &&
2618 m->mtype->pointer == NULL) {
2619 print_preconditions(m);
2620 if(((FuncArg *)m->args->data)->name)
2621 out_printf(out, "\tg_signal_emit (G_OBJECT (%s),\n"
2622 "\t\tobject_signals[%s_SIGNAL], 0",
2623 ((FuncArg *)m->args->data)->name, s);
2624 put_signal_args (m);
2625 out_printf(out, ");\n}\n");
2627 out_printf(out, "\t");
2628 print_type(out, m->mtype, TRUE);
2629 out_printf(out, "return_val = (");
2630 print_type(out, m->mtype, TRUE);
2632 out_printf(out, ")(%s);\n", m->defreturn);
2634 out_printf(out, ")(%s);\n", m->onerror);
2636 out_printf(out, ")(0);\n");
2637 print_preconditions(m);
2638 out_printf(out, "\tg_signal_emit (G_OBJECT (%s),\n"
2639 "\t\tobject_signals[%s_SIGNAL], 0",
2640 ((FuncArg *)m->args->data)->name, s);
2642 out_printf(out, ",\n\t\t&return_val);\n"
2643 "\treturn return_val;\n}\n");
2649 out_addline_infile(out, m->line_no);
2650 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2651 m, FALSE, FALSE, TRUE);
2652 print_method_body(m, FALSE);
2653 /* the outfile line was added above */
2655 case VIRTUAL_METHOD:
2657 out_addline_infile(out, m->line_no);
2658 if(m->scope==PRIVATE_SCOPE)
2659 print_method(out, "static ", "\n", "", " ", "", "\n",
2660 m, FALSE, FALSE, TRUE);
2661 else /* PUBLIC, PROTECTED */
2662 print_method(out, "", "\n", "", " ", "", "\n",
2663 m, FALSE, FALSE, TRUE);
2664 out_addline_outfile(out);
2665 out_printf(out, "{\n"
2666 "\t%sClass *klass;\n", typebase);
2667 print_preconditions(m);
2668 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2669 "\tif(klass->%s)\n",
2670 macrobase, ((FuncArg *)m->args->data)->name,
2672 if(strcmp(m->mtype->name, "void") == 0 &&
2673 m->mtype->pointer == NULL) {
2675 out_printf(out, "\t\t(*klass->%s)(%s",
2677 ((FuncArg *)m->args->data)->name);
2678 for(li=m->args->next;li;li=g_list_next(li)) {
2679 FuncArg *fa = li->data;
2680 out_printf(out, ",%s", fa->name);
2682 out_printf(out, ");\n}\n");
2685 out_printf(out, "\t\treturn (*klass->%s)(%s",
2687 ((FuncArg *)m->args->data)->name);
2688 for(li=m->args->next;li;li=g_list_next(li)) {
2689 FuncArg *fa = li->data;
2690 out_printf(out, ",%s", fa->name);
2692 out_printf(out, ");\n"
2695 print_type(out, m->mtype, TRUE);
2697 out_printf(out, ")(%s);\n}\n", m->defreturn);
2699 out_printf(out, ")(%s);\n}\n", m->onerror);
2701 out_printf(out, ")(0);\n}\n");
2707 out_addline_infile(out, m->line_no);
2708 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2709 m, FALSE, FALSE, TRUE);
2710 print_method_body(m, FALSE);
2711 /* the outfile line was added above */
2713 case OVERRIDE_METHOD:
2717 out_addline_infile(out, m->line_no);
2718 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2719 print_method(out, "static ", s, "", " ", "", "\n",
2720 m, FALSE, FALSE, FALSE);
2722 out_addline_outfile(out);
2723 s = replace_sep(m->otype, '_');
2725 args = get_arg_names_for_macro(m);
2727 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2728 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2729 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2730 args, s, m->id, s, m->id, args);
2732 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2733 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2734 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2736 args, s, m->id, s, m->id, args);
2737 out_printf(out, "(");
2738 print_type(out, m->mtype, TRUE);
2739 out_printf(out, ")%s))\n",
2740 m->onerror?m->onerror:"0");
2744 print_method_body(m, TRUE);
2745 /* the outfile line was added above */
2746 out_printf(out, "#undef PARENT_HANDLER\n");
2756 char *outfile, *outfileh, *outfileph;
2759 outfile = g_strconcat (filebase, ".c", NULL);
2761 outfile = g_strconcat (filebase, ".cc", NULL);
2762 if (no_touch_headers)
2763 outfileh = g_strconcat ("#gob#", filebase, ".h#gob#", NULL);
2765 outfileh = g_strconcat (filebase, ".h", NULL);
2767 if ((privates > 0 || protecteds > 0 ||
2768 private_header == PRIVATE_HEADER_ALWAYS) &&
2769 private_header != PRIVATE_HEADER_NEVER)
2770 outfileph = g_strconcat (filebase, "-private.h", NULL);
2776 devnull = fopen ("/dev/null", "w");
2777 if (devnull == NULL)
2778 g_error ("Cannot open null device");
2781 if (outfileph != NULL)
2784 out = fopen (outfile, "w");
2786 g_error ("Cannot open outfile: %s", outfile);
2788 outh = fopen (outfileh, "w");
2790 g_error ("Cannot open outfile: %s", outfileh);
2791 if (outfileph != NULL) {
2792 outph = fopen (outfileph, "w");
2794 g_error ("Cannot open outfile: %s", outfileh);
2800 put_argument_nongnu_wrappers (Class *c)
2804 if (get_properties < 0 && set_properties < 0)
2807 for (li = c->nodes; li != NULL; li = li->next) {
2809 const char *name, *gtktype;
2815 if (n->type == ARGUMENT_NODE) {
2816 Argument *a = (Argument *)n;
2818 gtktype = a->gtktype;
2820 get = a->get != NULL;
2821 set = a->set != NULL;
2822 } else if (n->type == PROPERTY_NODE) {
2823 Property *p = (Property *)n;
2825 gtktype = p->gtktype;
2827 get = p->get != NULL;
2828 set = p->set != NULL;
2833 aname = g_strdup (name);
2837 cast = get_type (atype, TRUE);
2839 cast = g_strdup (get_cast (gtktype, TRUE));
2843 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2844 "\"%s\",(%s)(arg)\n",
2845 macrobase, aname, name, cast);
2847 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2848 "\"%s\",(%s*)(arg)\n",
2849 macrobase, aname, name, cast);
2852 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2854 macrobase, aname, name);
2856 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2858 macrobase, aname, name);
2866 put_argument_gnu_wrappers(Class *c)
2870 if(get_properties < 0 && set_properties < 0)
2873 for (li = c->nodes; li != NULL; li = li->next) {
2875 const char *name, *gtktype;
2881 if (n->type == ARGUMENT_NODE) {
2882 Argument *a = (Argument *)n;
2884 gtktype = a->gtktype;
2886 get = a->get != NULL;
2887 set = a->set != NULL;
2888 } else if (n->type == PROPERTY_NODE) {
2889 Property *p = (Property *)n;
2891 gtktype = p->gtktype;
2893 get = p->get != NULL;
2894 set = p->set != NULL;
2899 aname = g_strdup (name);
2903 cast = get_type (atype, TRUE);
2905 cast = g_strdup (get_cast (gtktype, TRUE));
2909 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2910 "\"%s\",({%sz = (arg); z;})\n",
2911 macrobase, aname, name, cast);
2913 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2914 "\"%s\",({%s*z = (arg); z;})\n",
2915 macrobase, aname, name, cast);
2918 out_printf (outh, "#define %s_PROP_%s(arg) \t"
2920 macrobase, aname, name);
2922 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
2924 macrobase, aname, name);
2932 print_ccode_block(CCode *cc)
2935 switch(cc->cctype) {
2937 /* HT code is printed exactly like normal header
2938 code but is printed before */
2941 out_printf(fp, "\n");
2944 /* AT code is printed exactly like normal 'all'
2945 code but is printed before */
2948 out_printf(outph, "\n");
2949 out_printf(outph, "%s\n", cc->cbuf);
2950 out_addline_infile(outph, cc->line_no);
2951 out_addline_outfile(outph);
2953 out_printf(outh, "\n");
2954 out_printf(outh, "%s\n", cc->cbuf);
2956 out_printf(fp, "\n");
2957 out_addline_infile(fp, cc->line_no);
2962 out_printf(fp, "\n");
2963 out_addline_infile(fp, cc->line_no);
2970 out_printf(fp, "\n");
2971 out_addline_infile(fp, cc->line_no);
2974 out_printf(fp, "%s\n", cc->cbuf);
2975 if(cc->cctype == C_CCODE ||
2976 cc->cctype == A_CCODE ||
2977 cc->cctype == AT_CCODE ||
2978 cc->cctype == PH_CCODE)
2979 out_addline_outfile(fp);
2983 print_class_block(Class *c)
2987 gboolean printed_private = FALSE;
2990 out_printf(out, "/* utility types we may need */\n");
2991 if(special_array[SPECIAL_2POINTER])
2992 out_printf(out, "typedef struct { "
2993 "gpointer a; gpointer b; "
2994 "} ___twopointertype;\n");
2995 if(special_array[SPECIAL_3POINTER])
2996 out_printf(out, "typedef struct { "
2997 "gpointer a; gpointer b; "
2999 "} ___threepointertype;\n");
3000 if(special_array[SPECIAL_INT_POINTER])
3001 out_printf(out, "typedef struct { "
3002 "gint a; gpointer b; "
3003 "} ___intpointertype;\n");
3004 out_printf(out, "\n");
3007 out_printf(outh, "\n/*\n"
3008 " * Type checking and casting macros\n"
3010 out_printf(outh, "#define %s\t"
3011 "(%s_get_type())\n",
3012 macrotype, funcbase);
3013 out_printf(outh, "#define %s(obj)\t"
3014 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3015 macrobase, funcbase, typebase);
3016 out_printf(outh, "#define %s_CONST(obj)\t"
3017 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3018 macrobase, funcbase, typebase);
3019 out_printf(outh, "#define %s_CLASS(klass)\t"
3020 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3021 macrobase, funcbase, typebase);
3022 out_printf(outh, "#define %s(obj)\t"
3023 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3026 "#define %s_GET_CLASS(obj)\t"
3027 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3028 macrobase, funcbase, typebase);
3030 if ( ! no_self_alias) {
3031 out_printf(out, "/* self casting macros */\n");
3032 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3033 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3034 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3035 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3036 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3038 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3041 out_printf(out, "/* self typedefs */\n");
3042 out_printf(out, "typedef %s Self;\n", typebase);
3043 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3047 always_private_struct) {
3048 out_printf (outh, "\n/* Private structure type */\n");
3049 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3050 typebase, typebase);
3052 out_printf (outh, "/* There are no privates, this "
3053 "structure is thus never defined */\n");
3056 out_printf (outh, "\n/*\n"
3057 " * Main object structure\n"
3059 s = replace_sep (c->otype, '_');
3061 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3062 "#define __TYPEDEF_%s__\n", s, s);
3064 out_printf (outh, "typedef struct _%s %s;\n"
3065 "#endif\n", typebase, typebase);
3066 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3067 typebase, ptypebase);
3068 for (li = c->nodes; li; li=li->next) {
3069 static gboolean printed_public = FALSE;
3071 Variable *v = (Variable *)n;
3072 if(n->type == VARIABLE_NODE &&
3073 v->scope == PUBLIC_SCOPE) {
3074 if( ! printed_public) {
3075 out_printf(outh, "\t/*< public >*/\n");
3076 printed_public = TRUE;
3078 put_variable((Variable *)n, outh);
3081 /* put protecteds always AFTER publics */
3082 for (li = c->nodes; li != NULL; li = li->next) {
3084 Variable *v = (Variable *)n;
3085 if (n->type == VARIABLE_NODE &&
3086 v->scope == PROTECTED_SCOPE) {
3087 if ( ! printed_private) {
3088 out_printf (outh, "\t/*< private >*/\n");
3089 printed_private = TRUE;
3091 put_variable ((Variable *)n, outh);
3095 always_private_struct) {
3096 if ( ! printed_private)
3097 out_printf (outh, "\t/*< private >*/\n");
3098 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3100 out_printf (outh, "};\n");
3105 /* if we are to stick this into the private
3106 header, if not stick it directly into the
3113 out_printf (outfp, "struct _%sPrivate {\n",
3115 for(li=c->nodes; li; li=li->next) {
3117 Variable *v = (Variable *)n;
3118 if(n->type == VARIABLE_NODE &&
3119 v->scope == PRIVATE_SCOPE) {
3120 out_addline_infile(outfp, v->line_no);
3121 put_variable(v, outfp);
3124 out_addline_outfile(outfp);
3125 out_printf(outfp, "};\n");
3128 out_printf(outh, "\n/*\n"
3129 " * Class definition\n"
3131 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3132 typebase, typebase);
3134 "struct _%sClass {\n\t%sClass __parent__;\n",
3135 typebase, ptypebase);
3136 for(li = c->nodes; li != NULL; li = li->next) {
3138 if(n->type == METHOD_NODE)
3139 put_vs_method((Method *)n);
3141 /* If BonoboX type class put down the epv */
3142 if (c->bonobo_object_class != NULL) {
3144 "\t/* Bonobo object epv */\n"
3145 "\tPOA_%s__epv _epv;\n",
3146 c->bonobo_object_class);
3148 /* put class scope variables */
3149 for (li = c->nodes; li != NULL; li = li->next) {
3151 Variable *v = (Variable *)n;
3152 if (n->type == VARIABLE_NODE &&
3153 v->scope == CLASS_SCOPE)
3154 put_variable ((Variable *)n, outh);
3156 out_printf (outh, "};\n\n");
3158 out_printf (out, "/* here are local prototypes */\n");
3159 if (set_properties > 0) {
3160 out_printf (out, "static void ___object_set_property "
3161 "(GObject *object, guint property_id, "
3162 "const GValue *value, GParamSpec *pspec);\n");
3164 if (get_properties > 0) {
3165 out_printf (out, "static void ___object_get_property "
3166 "(GObject *object, guint property_id, "
3167 "GValue *value, GParamSpec *pspec);\n");
3170 out_printf (outh, "\n/*\n"
3171 " * Public methods\n"
3174 if ( ! overrode_get_type) {
3175 out_printf (outh, "GType\t%s_get_type\t(void)", funcbase);
3177 out_printf (outh, " G_GNUC_CONST;\n");
3179 out_printf (outh, ";\n");
3183 for(li = c->nodes; li != NULL; li = li->next) {
3185 if(n->type == METHOD_NODE) {
3186 put_pub_method((Method *)n);
3187 put_prot_method((Method *)n);
3188 put_priv_method_prot((Method *)n);
3192 /* this idea is less and less apealing to me */
3194 out_printf (outh, "\n/*\n"
3195 " * Signal connection wrapper macros\n"
3198 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3199 put_signal_macros (c, TRUE);
3200 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3201 put_signal_macros (c, FALSE);
3202 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3204 put_signal_macros (c, FALSE);
3205 out_printf(outh, "\n");
3208 out_printf (out, "\n/*\n"
3209 " * Signal connection wrapper macro shortcuts\n"
3211 put_local_signal_macros (c);
3212 out_printf(outh, "\n");
3215 /* argument wrapping macros */
3216 if(get_properties > 0 || set_properties > 0) {
3217 out_printf(outh, "\n/*\n"
3218 " * Argument wrapping macros\n"
3221 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3222 put_argument_gnu_wrappers(c);
3223 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3224 put_argument_nongnu_wrappers(c);
3225 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3227 put_argument_nongnu_wrappers(c);
3232 for(li = c->nodes; li != NULL; li = li->next) {
3234 if(n->type == METHOD_NODE)
3235 add_signal_prots((Method *)n);
3241 if(any_method_to_alias(c)) {
3243 out_printf(out, "/* Short form macros */\n");
3244 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3245 make_method_gnu_aliases(c);
3246 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3248 make_method_nongnu_aliases(c);
3251 add_interface_inits (c);
3253 if ( ! overrode_get_type) {
3254 if (c->bonobo_object_class != NULL)
3255 add_bonobo_object_get_type ();
3260 out_printf (out, "/* a macro for creating a new object of our type */\n");
3262 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3263 typebase, funcbase);
3265 out_printf (out, "/* a function for creating a new object of our type */\n");
3266 out_printf (out, "#include <stdarg.h>\n");
3268 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3269 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3270 "{\n\t%s *ret;\n\tva_list ap;\n"
3271 "\tva_start (ap, first);\n"
3272 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3275 "\treturn ret;\n}\n\n",
3277 no_gnu ? "" : " G_GNUC_UNUSED",
3278 typebase, typebase, typebase, funcbase);
3288 if(set_properties > 0) {
3289 add_getset_arg(c, TRUE);
3292 if(get_properties > 0) {
3293 add_getset_arg(c, FALSE);
3296 for(li = c->nodes; li != NULL; li = li->next) {
3298 if(n->type == METHOD_NODE)
3299 put_method((Method *)n);
3302 add_bad_hack_to_avoid_unused_warnings(c);
3306 print_useful_macros(void)
3308 int major = 0, minor = 0, pl = 0;
3311 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3312 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3313 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3314 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3316 /* Useful priv macro thingie */
3317 /* FIXME: this should be done the same way that priv is, as a var,
3319 out_printf (out, "#define selfp (self->_priv)\n\n");
3323 print_file_comments(void)
3327 out_printf(outh, "/* Generated by GOB (v%s)"
3328 " (do not edit directly) */\n\n", VERSION);
3330 out_printf(outph, "/* Generated by GOB (v%s)"
3331 " (do not edit directly) */\n\n", VERSION);
3332 out_printf(out, "/* Generated by GOB (v%s) on %s"
3333 " (do not edit directly) */\n\n",
3334 VERSION, ctime(&curtime));
3336 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3340 print_includes(void)
3342 gboolean found_header;
3345 /* We may need string.h for memset */
3346 if(destructors > 0 &&
3347 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3348 out_printf(out, "#include <string.h> /* memset() */\n\n");
3351 p = g_strconcat(filebase, ".h", NULL);
3352 found_header = TRUE;
3353 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3354 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3355 found_header = FALSE;
3359 /* if we are creating a private header see if it was included */
3361 p = g_strconcat(filebase, "-private.h", NULL);
3362 if( ! g_list_find_custom(include_files, p,
3363 (GCompareFunc)strcmp)) {
3364 out_printf(out, "#include \"%s-private.h\"\n\n",
3367 error_printf(GOB_WARN, 0,
3368 "Implicit private header include "
3370 "\tsource file, while public "
3371 "header is at a custom location, "
3373 "\texplicitly include "
3374 "the private header below the "
3382 print_header_prefixes(void)
3386 p = replace_sep(((Class *)class)->otype, '_');
3388 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3390 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3391 "#define __%s_PRIVATE_H__\n\n"
3392 "#include \"%s.h\"\n\n", p, p, filebase);
3395 if( ! no_extern_c) {
3396 out_printf(outh, "#ifdef __cplusplus\n"
3398 "#endif /* __cplusplus */\n\n");
3400 out_printf(outph, "#ifdef __cplusplus\n"
3402 "#endif /* __cplusplus */\n\n");
3407 print_header_postfixes(void)
3410 out_printf(outh, "\n#ifdef __cplusplus\n"
3412 "#endif /* __cplusplus */\n");
3413 out_printf(outh, "\n#endif\n");
3416 out_printf(outph, "\n#ifdef __cplusplus\n"
3418 "#endif /* __cplusplus */\n");
3419 out_printf(outph, "\n#endif\n");
3428 /* print the AT_CCODE blocks */
3429 for(li = nodes; li != NULL; li = li->next) {
3430 Node *node = li->data;
3431 if(node->type == CCODE_NODE) {
3432 CCode *cc = (CCode *)node;
3433 if(cc->cctype == AT_CCODE)
3434 print_ccode_block((CCode *)node);
3440 print_header_top(void)
3444 /* mandatory includes */
3445 out_printf (outh, "#include <glib.h>\n");
3446 out_printf (outh, "#include <glib-object.h>\n");
3448 /* print the HT_CCODE blocks */
3449 for (li = nodes; li != NULL; li = li->next) {
3450 Node *node = li->data;
3451 if (node->type == CCODE_NODE) {
3452 CCode *cc = (CCode *)node;
3453 if (cc->cctype == HT_CCODE)
3454 print_ccode_block ((CCode *)node);
3460 print_enum (EnumDef *enode)
3467 funcprefix = replace_sep (enode->etype, '_');
3468 g_strdown (funcprefix);
3469 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3471 type = remove_sep (enode->etype);
3473 out_printf (outh, "\ntypedef enum {\n");
3475 for (li = enode->values; li != NULL; li = li->next) {
3476 EnumValue *value = li->data;
3478 char *sname = g_strdown (g_strdup (value->name));
3480 while ((p = strchr (sname, '_')) != NULL)
3483 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3484 if (value->value != NULL)
3485 out_printf (outh, " = %s", value->value);
3486 if (li->next != NULL)
3487 out_printf (outh, ",\n");
3489 out_printf (outh, "\n");
3491 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3492 enode->prefix, value->name,
3493 enode->prefix, value->name,
3499 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3501 out_printf (outh, "} %s;\n", type);
3503 str = make_pre_macro (enode->etype, "TYPE");
3504 out_printf (outh, "#define %s ", str);
3507 out_printf (outh, "%s_get_type()\n", funcprefix);
3508 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3511 "GType\n%s_get_type (void)\n"
3513 "\tstatic GType type = 0;\n"
3514 "\tif (type == 0)\n"
3515 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3518 funcprefix, type, funcprefix);
3520 g_free (funcprefix);
3525 print_flags (Flags *fnode)
3533 funcprefix = replace_sep (fnode->ftype, '_');
3534 g_strdown (funcprefix);
3535 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3537 type = remove_sep (fnode->ftype);
3539 out_printf (outh, "\ntypedef enum {\n");
3541 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3542 const char *name = li->data;
3544 char *sname = g_strdown (g_strdup (name));
3546 while ((p = strchr (sname, '_')) != NULL)
3549 out_printf (outh, "\t%s_%s = 1<<%d",
3550 fnode->prefix, name, i);
3551 if (li->next != NULL)
3552 out_printf (outh, ",\n");
3554 out_printf (outh, "\n");
3556 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3557 fnode->prefix, name,
3558 fnode->prefix, name,
3564 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3566 out_printf (outh, "} %s;\n", type);
3568 str = make_pre_macro (fnode->ftype, "TYPE");
3569 out_printf (outh, "#define %s ", str);
3572 out_printf (outh, "%s_get_type()\n", funcprefix);
3573 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3576 "GType\n%s_get_type (void)\n"
3578 "\tstatic GType type = 0;\n"
3579 "\tif (type == 0)\n"
3580 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3583 funcprefix, type, funcprefix);
3585 g_free (funcprefix);
3590 print_error (Error *enode)
3597 funcprefix = replace_sep (enode->etype, '_');
3598 g_strdown (funcprefix);
3599 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3601 type = remove_sep (enode->etype);
3603 out_printf (outh, "\ntypedef enum {\n");
3605 for (li = enode->values; li != NULL; li = li->next) {
3606 const char *name = li->data;
3608 char *sname = g_strdown (g_strdup (name));
3610 while ((p = strchr (sname, '_')) != NULL)
3613 out_printf (outh, "\t%s_%s", enode->prefix, name);
3614 if (li->next != NULL)
3615 out_printf (outh, ",\n");
3617 out_printf (outh, "\n");
3619 out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n",
3620 enode->prefix, name,
3621 enode->prefix, name,
3627 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3629 out_printf (outh, "} %s;\n", type);
3631 str = make_pre_macro (enode->etype, "TYPE");
3632 out_printf (outh, "#define %s ", str);
3635 out_printf (outh, "%s_get_type ()\n", funcprefix);
3636 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3639 "GType\n%s_get_type (void)\n"
3641 "\tstatic GType type = 0;\n"
3642 "\tif (type == 0)\n"
3643 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3646 funcprefix, type, funcprefix);
3648 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3649 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3651 str = replace_sep (enode->etype, '-');
3655 "GQuark\n%s_quark (void)\n"
3657 "\tstatic GQuark q = 0;\n"
3659 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3666 g_free (funcprefix);
3671 generate_outfiles(void)
3675 print_file_comments();
3681 print_header_prefixes();
3683 print_useful_macros();
3687 for (li = nodes; li != NULL; li = li->next) {
3688 Node *node = li->data;
3689 if (node->type == CCODE_NODE) {
3690 CCode *cc = (CCode *)node;
3691 if (cc->cctype != HT_CCODE &&
3692 cc->cctype != AT_CCODE)
3693 print_ccode_block ((CCode *)node);
3694 } else if (node->type == CLASS_NODE) {
3695 print_class_block ((Class *)node);
3696 } else if (node->type == ENUMDEF_NODE) {
3697 print_enum ((EnumDef *)node);
3698 } else if (node->type == FLAGS_NODE) {
3699 print_flags ((Flags *)node);
3700 } else if (node->type == ERROR_NODE) {
3701 print_error ((Error *)node);
3703 g_assert_not_reached();
3707 print_header_postfixes();
3713 fprintf(stderr, "Gob version %s\n\n", VERSION);
3714 fprintf(stderr, "gob [options] file.gob\n\n");
3715 fprintf(stderr, "Options:\n"
3716 "\t--help,-h,-? Display this help\n"
3717 "\t--version Display version\n"
3718 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3719 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3720 "\t--for-cpp Create C++ files\n"
3721 "\t--no-extern-c Never print extern \"C\" into the "
3723 "\t--no-gnu Never use GNU extentions\n"
3724 "\t--no-touch-headers Don't touch headers unless they "
3726 "\t--always-private-header Always create a private header "
3728 "\t even if it would be empty "
3730 "\t--ondemand-private-header Create private header only when "
3732 "\t--no-private-header Don't create a private header, "
3734 "\t structure and protected "
3735 "prototypes inside c file\n"
3736 "\t--always-private-struct Always create a private pointer "
3738 "\t the object structure\n"
3739 "\t--m4 Preprocess source with m4. "
3740 "Following args will\n"
3741 "\t be passed to m4\n"
3742 "\t--m4-dir Print directory that will be "
3745 "\t--no-write,-n Don't write output files, just "
3747 "\t--no-lines Don't print '#line' to output\n"
3748 "\t--no-self-alias Don't create self type and macro "
3750 "\t--no-kill-underscores Ignored for compatibility\n");
3754 parse_options(int argc, char *argv[])
3757 int got_file = FALSE;
3758 int no_opts = FALSE;
3759 int m4_opts = FALSE; /* if we are just passing on args to m4 */
3763 for(i = 1 ; i < argc; i++) {
3765 char *new_commandline;
3766 g_assert(m4_commandline!=NULL);
3768 /* check whether this one looks like the filename */
3769 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
3771 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
3775 /* insert flags before the filename */
3776 new_commandline=g_strconcat(m4_commandline,
3784 /* just an ordinary option */
3786 new_commandline=g_strconcat(m4_commandline,
3791 /* free old commandline */
3792 g_free(m4_commandline);
3793 m4_commandline=new_commandline;
3795 } else if(no_opts ||
3796 argv[i][0] != '-') {
3799 fprintf(stderr, "Specify only one file!\n");
3805 } else if(strcmp(argv[i], "--help")==0) {
3808 } else if(strcmp(argv[i], "--version")==0) {
3809 fprintf(stderr, "Gob version %s\n", VERSION);
3811 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
3812 exit_on_warn = TRUE;
3813 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
3814 exit_on_warn = FALSE;
3815 } else if(strcmp(argv[i], "--for-cpp")==0) {
3817 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
3818 no_touch_headers = TRUE;
3819 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
3820 private_header = PRIVATE_HEADER_ONDEMAND;
3821 } else if(strcmp(argv[i], "--always-private-header")==0) {
3822 private_header = PRIVATE_HEADER_ALWAYS;
3823 } else if(strcmp(argv[i], "--no-private-header")==0) {
3824 private_header = PRIVATE_HEADER_NEVER;
3825 } else if(strcmp(argv[i], "--no-gnu")==0) {
3827 } else if(strcmp(argv[i], "--no-extern-c")==0) {
3829 } else if(strcmp(argv[i], "--no-write")==0) {
3831 } else if(strcmp(argv[i], "--no-lines")==0) {
3833 } else if(strcmp(argv[i], "--no-self-alias")==0) {
3834 no_self_alias = TRUE;
3835 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
3837 } else if(strcmp(argv[i], "--always-private-struct")==0) {
3838 always_private_struct = TRUE;
3839 } else if(strcmp(argv[i], "--m4-dir")==0) {
3840 printf("%s\n",M4_INCLUDE_DIR);
3842 } else if(strcmp(argv[i], "--m4")==0) {
3846 m4_commandline=g_strdup(M4_COMMANDLINE);
3847 } else if(strcmp(argv[i], "--m4-clean")==0) {
3851 m4_commandline=g_strdup(M4_COMMANDLINE);
3852 } else if(strcmp(argv[i], "--")==0) {
3853 /*further arguments are files*/
3855 } else if(strncmp(argv[i], "--", 2)==0) {
3856 /*unknown long option*/
3857 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
3861 /*by now we know we have a string starting with
3862 - which is a short option string*/
3864 for(p = argv[i] + 1; *p; p++) {
3878 "Unknown option '%c'!\n", *p);
3887 /* if we are using m4, and got no filename, append m4 flags now */
3888 if(!got_file && use_m4 && !use_m4_clean) {
3889 char *new_commandline;
3890 new_commandline=g_strconcat(m4_commandline,
3894 g_free(m4_commandline);
3895 m4_commandline=new_commandline;
3900 /* this is a somewhat ugly hack, but it appears to work */
3902 compare_and_move_header(void)
3904 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
3905 char *hf = g_strconcat(filebase, ".h", NULL);
3907 if(stat(hf, &s) == 0) {
3909 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
3910 if(system(s) == 0) {
3911 if(unlink(hfnew) != 0)
3912 error_printf(GOB_ERROR, 0,
3913 "Can't remove new header file");
3921 error_printf(GOB_ERROR, 0,
3922 "Can't remove old header file");
3924 if(rename(hfnew, hf) != 0)
3925 error_printf(GOB_ERROR, 0,
3926 "Can't rename new header file");
3932 main(int argc, char *argv[])
3934 parse_options(argc, argv);
3937 yyin = popen(m4_commandline, "r");
3939 fprintf(stderr, "Error: can't open pipe from '%s'\n",
3943 } else if(filename) {
3944 yyin = fopen(filename, "r");
3946 fprintf(stderr, "Error: can't open file '%s'\n",
3955 /* This is where parsing is done */
3958 g_error("Parsing errors, quitting");
3960 /* close input file */
3961 if(use_m4) pclose(yyin);
3966 error_print(GOB_ERROR, 0, " no class defined");
3969 exit_on_error = FALSE;
3971 signals = count_signals ((Class *)class);
3972 set_properties = count_set_properties ((Class *)class) +
3973 count_set_arguments ((Class *)class);
3974 get_properties = count_get_properties ((Class *)class) +
3975 count_get_arguments ((Class *)class);
3976 overrides = count_overrides ((Class *)class);
3977 privates = count_privates ((Class *)class);
3978 protecteds = count_protecteds ((Class *)class);
3979 unreftors = count_unreftors ((Class *)class);
3980 destructors = count_destructors ((Class *)class);
3981 initializers = count_initializers ((Class *)class);
3982 overrode_get_type = find_get_type ((Class *)class);
3985 make_inits ((Class *)class);
3987 need_shutdown = TRUE;
3988 find_shutdown ((Class *)class);
3990 if (destructors > 0 ||
3992 need_finalize = TRUE;
3993 find_finalize ((Class *)class);
3995 check_bad_symbols ((Class *)class);
3996 check_duplicate_symbols ((Class *)class);
3997 check_duplicate_overrides ((Class *)class);
3998 check_duplicate_signals_args ((Class *)class);
3999 check_public_new ((Class *)class);
4000 check_vararg ((Class *)class);
4001 check_firstarg ((Class *)class);
4002 check_nonvoidempty ((Class *)class);
4003 check_signal_args ((Class *)class);
4004 check_property_types ((Class *)class);
4005 check_argument_types ((Class *)class);
4006 check_func_arg_checks ((Class *)class);
4008 exit_on_error = TRUE;
4013 any_special = setup_special_array ((Class *)class, special_array);
4017 generate_outfiles ();
4028 if (no_touch_headers &&
4030 compare_and_move_header ();