2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2004 George (Jiri) Lebl
6 * Author: George (Jiri) 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;
57 static char *funcbase;
58 static char *pfuncbase;
59 static char *macrobase;
61 static char *pmacrois;
62 static char *macrotype;
63 static char *pmacrotype;
64 static char *typebase;
65 static char *ptypebase;
67 char *output_dir = NULL;
69 static int signals = 0; /* number of signals */
70 static int set_properties = 0; /* number of named (set) properties */
71 static int get_properties = 0; /* number of named (get) properties */
72 static int overrides = 0; /* number of override methods */
73 static int privates = 0; /* number of private data members */
74 static int protecteds = 0; /* number of protected methods */
75 static int unreftors = 0; /* number of variable unreffing destructors */
76 static int destructors = 0; /* number of variable non-unreffing destructors */
77 static int initializers = 0; /* number of variable initializers */
78 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
80 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
81 and need the REALLY UGLY HACK to
84 /* the special variable types we need to define */
85 static gboolean special_array[SPECIAL_LAST] = {0};
86 static gboolean any_special = FALSE;
88 static gboolean need_dispose = FALSE;
89 static Method * dispose_handler = NULL;
91 static gboolean need_finalize = FALSE;
92 static Method * finalize_handler = NULL;
99 gboolean no_touch_headers = FALSE;
100 gboolean for_cpp = FALSE;
101 gboolean no_gnu = FALSE;
102 gboolean exit_on_warn = FALSE;
103 gboolean exit_on_error = TRUE;
104 gboolean got_error = FALSE;
105 gint private_header = PRIVATE_HEADER_ONDEMAND;
106 gboolean no_extern_c = FALSE;
107 gboolean no_write = FALSE;
108 gboolean no_lines = FALSE;
109 gboolean no_self_alias = FALSE;
110 gboolean always_private_struct = FALSE;
112 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
113 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
114 char *m4_commandline = NULL;
115 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
116 #define M4_BASE_FILENAME "gobm4.m4"
117 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
118 #define M4_COMMANDLINE "m4"
120 int method_unique_id = 1;
125 filebase = replace_sep (((Class *)class)->otype, '-');
126 gob_strdown (filebase);
128 if (output_dir != NULL &&
129 output_dir[0] != '\0') {
130 fullfilebase = g_build_filename (output_dir, filebase, NULL);
132 fullfilebase = g_strdup (filebase);
135 funcbase = replace_sep (((Class *)class)->otype, '_');
136 gob_strdown (funcbase);
138 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
139 gob_strdown (pfuncbase);
141 macrobase = replace_sep (((Class *)class)->otype, '_');
142 gob_strup (macrobase);
144 macrois = make_pre_macro (((Class *)class)->otype, "IS");
145 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
147 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
148 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
150 typebase = remove_sep (((Class *)class)->otype);
152 ptypebase = remove_sep (((Class *)class)->ptype);
156 get_gtk_doc (const char *id)
163 val = g_hash_table_lookup(gtk_doc_hash, id);
165 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
167 val = g_hash_table_lookup(gtk_doc_hash, id);
169 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
175 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
179 s = get_type(t, postfix_to_stars);
180 out_printf(fp, "%s", s);
186 print_method (FILE *fp,
187 const char *typeprefix,
188 const char *nameprefix,
189 const char *subnameprefix,
190 const char *namepostfix,
191 const char *afterargs,
194 gboolean one_arg_per_line,
195 gboolean no_funcbase,
196 gboolean kill_underscore,
197 gboolean first_unused,
203 out_printf(fp, "%s", typeprefix);
204 print_type(fp, m->mtype, TRUE);
209 out_printf(fp, "%s%s%s%s(",
210 nameprefix, subnameprefix, id, namepostfix);
212 out_printf(fp, "%s%s_%s%s%s(",
213 nameprefix, funcbase, subnameprefix, id,
217 for(li=m->args; li; li=g_list_next(li)) {
218 FuncArg *arg = li->data;
219 const char *unused = "";
222 ! for_cpp && /* g++ has a cow with this */
225 unused = " G_GNUC_UNUSED";
228 print_type(fp, arg->atype, FALSE);
230 out_printf (fp, "___fake___");
232 out_printf(fp, "%s%s%s,%s", arg->name,
233 arg->atype->postfix ?
234 arg->atype->postfix : "",
236 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
238 out_printf(fp, "%s%s%s", arg->name,
239 arg->atype->postfix ?
240 arg->atype->postfix : "",
244 out_printf(fp, ",%s...",
245 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
247 out_printf(fp, "void");
249 out_printf(fp, "%s)%s", afterargs, postfix);
253 any_method_to_alias(Class *c)
257 for(li=c->nodes;li;li=g_list_next(li)) {
258 Node *node = li->data;
259 if(node->type == METHOD_NODE) {
260 Method *m = (Method *)node;
262 if(m->method == INIT_METHOD ||
263 m->method == CLASS_INIT_METHOD ||
264 m->method == OVERRIDE_METHOD)
275 make_method_aliases (Class *c)
279 for(li = c->nodes; li != NULL; li = li->next) {
280 Node *node = li->data;
281 if(node->type == METHOD_NODE) {
282 Method *m = (Method *)node;
284 if(m->method == INIT_METHOD ||
285 m->method == CLASS_INIT_METHOD ||
286 m->method == OVERRIDE_METHOD)
289 out_printf (out, "#define self_%s %s_%s\n",
298 add_bad_hack_to_avoid_unused_warnings(const Class *c)
302 /* if we haven't had any methods, just return */
307 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
309 "/*REALLY BAD HACK\n"
310 " This is to avoid unused warnings if you don't call\n"
311 " some method. I need to find a better way to do\n"
312 " this, not needed in GCC since we use some gcc\n"
313 " extentions to make saner, faster code */\n"
315 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
317 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
318 for(li=c->nodes;li;li=g_list_next(li)) {
319 Node *node = li->data;
320 if(node->type == METHOD_NODE) {
321 Method *m = (Method *)node;
323 if(m->method == INIT_METHOD ||
324 m->method == CLASS_INIT_METHOD ||
325 m->method == OVERRIDE_METHOD)
328 /* in C++ mode we don't alias new */
329 if(for_cpp && strcmp(m->id, "new")==0)
332 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
335 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
338 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
340 out_printf(out, "}\n\n");
344 put_variable(const Variable *v, FILE *fp)
346 out_printf(fp, "\t");
347 print_type(fp, v->vtype, FALSE);
348 out_printf(fp, "%s%s;", v->id,
350 v->vtype->postfix:"");
351 if(v->scope == PROTECTED_SCOPE)
352 out_printf(fp, " /* protected */");
353 out_printf(fp, "\n");
357 put_vs_method(const Method *m)
359 if(m->method != SIGNAL_LAST_METHOD &&
360 m->method != SIGNAL_FIRST_METHOD &&
361 m->method != VIRTUAL_METHOD)
364 /* if a signal mark it as such */
365 if(m->method != VIRTUAL_METHOD)
366 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
367 m, FALSE, TRUE, TRUE, FALSE, FALSE);
369 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
370 m, FALSE, TRUE, TRUE, FALSE, FALSE);
374 put_pub_method(const Method *m)
376 if(m->scope != PUBLIC_SCOPE)
379 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
380 TRUE, FALSE, TRUE, FALSE, FALSE);
384 put_signal_macro (const Method *m, gboolean gnu)
386 if(m->method != SIGNAL_LAST_METHOD &&
387 m->method != SIGNAL_FIRST_METHOD)
392 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
393 "g_signal_connect(%s(object),\"%s\","
394 "(GCallback)(func),(data))\n",
395 funcbase, m->id, macrobase, m->id);
398 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
399 "g_signal_connect_after(%s(object),\"%s\","
400 "(GCallback)(func),(data))\n",
401 funcbase, m->id, macrobase, m->id);
404 out_printf (outh, "#define %s_connect_data__%s"
405 "(object,func,data,destroy_data,flags)\t"
406 "g_signal_connect_data(%s(object),\"%s\","
407 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
408 funcbase, m->id, macrobase, m->id);
411 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
413 "%s(__extension__ ({%s *___object = (object); ___object; })),"
415 "(GCallback) __extension__ ({",
416 funcbase, m->id, macrobase, typebase, m->id);
417 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
418 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
419 out_printf (outh, "___%s; }), (data))\n", m->id);
422 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
423 "g_signal_connect_after("
424 "%s(__extension__ ({%s *___object = (object); ___object; })),"
426 "(GCallback) __extension__ ({",
427 funcbase, m->id, macrobase, typebase, m->id);
428 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
429 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
430 out_printf (outh, "___%s; }), (data))\n", m->id);
433 out_printf (outh, "#define %s_connect_data__%s"
434 "(object,func,data,destroy_data,flags)\t"
435 "g_signal_connect_data("
436 "%s(__extension__ ({%s *___object = (object); ___object; })),"
438 "(GCallback) __extension__ ({",
439 funcbase, m->id, macrobase, typebase, m->id);
440 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
441 " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
442 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
447 put_signal_macros (const Class *c, gboolean gnu)
454 for (li = c->nodes; li != NULL; li = li->next) {
455 const Node *n = li->data;
456 if (n->type == METHOD_NODE)
457 put_signal_macro ((Method *)n, gnu);
462 put_local_signal_macro (const Method *m)
464 if(m->method != SIGNAL_LAST_METHOD &&
465 m->method != SIGNAL_FIRST_METHOD)
469 out_printf (out, "#define self_connect__%s(object,func,data)\t"
470 "%s_connect__%s((object),(func),(data))\n",
471 m->id, funcbase, m->id);
474 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
475 "%s_connect_after__%s((object),(func),(data))\n",
476 m->id, funcbase, m->id);
479 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
480 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
481 m->id, funcbase, m->id);
485 put_local_signal_macros (const Class *c)
492 for (li = c->nodes; li != NULL; li = li->next) {
493 const Node *n = li->data;
494 if (n->type == METHOD_NODE)
495 put_local_signal_macro ((Method *)n);
501 put_prot_method(const Method *m)
503 if(m->scope != PROTECTED_SCOPE)
507 print_method(outph, "", "\t", "", "\t", "", ";\n",
508 m, FALSE, FALSE, TRUE, FALSE, FALSE);
510 print_method(out, "", "\t", "", "\t", "", ";\n",
511 m, FALSE, FALSE, TRUE, FALSE, FALSE);
515 put_priv_method_prot(const Method *m)
517 if(m->method == SIGNAL_LAST_METHOD ||
518 m->method == SIGNAL_FIRST_METHOD ||
519 m->method == VIRTUAL_METHOD) {
522 "static ", "___real_", "", " ", "", ";\n",
523 m, FALSE, FALSE, TRUE, FALSE, FALSE);
525 /* no else, here, it might still have a private prototype, it's not
528 if((m->method == OVERRIDE_METHOD &&
531 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
532 print_method(out, "static ", s, "", " ", "",
533 no_gnu?";\n":" G_GNUC_UNUSED;\n",
534 m, FALSE, FALSE, FALSE, FALSE, FALSE);
536 } else if(m->scope == PRIVATE_SCOPE ||
537 m->method == INIT_METHOD ||
538 m->method == CLASS_INIT_METHOD) {
539 print_method(out, "static ", "", "", " ", "",
540 no_gnu?";\n":" G_GNUC_UNUSED;\n",
541 m, FALSE, FALSE, TRUE, FALSE, FALSE);
546 make_func_arg (const char *typename, gboolean is_class, const char *name)
553 tn = g_strconcat (typename, ":Class", NULL);
555 tn = g_strdup (typename);
557 type = node_new (TYPE_NODE,
561 node = node_new (FUNCARG_NODE,
562 "atype:steal", (Type *)type,
565 return g_list_prepend (NULL, node);
569 make_inits(Class *cl)
571 int got_class_init = FALSE;
572 int got_init = FALSE;
575 for(li=cl->nodes;li;li=g_list_next(li)) {
577 if(n->type == METHOD_NODE) {
578 Method *m = (Method *)n;
579 if(m->method == INIT_METHOD) {
581 error_print(GOB_ERROR, m->line_no, "init defined more then once");
583 } else if(m->method == CLASS_INIT_METHOD) {
585 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
586 got_class_init = TRUE;
590 if(!got_class_init) {
591 Type *type = (Type *)node_new (TYPE_NODE,
594 node = node_new (METHOD_NODE,
596 "method", CLASS_INIT_METHOD,
599 "args:steal", make_func_arg (cl->otype,
602 "unique_id", method_unique_id++,
604 cl->nodes = g_list_prepend(cl->nodes, node);
607 Type *type = (Type *)node_new (TYPE_NODE,
610 node = node_new (METHOD_NODE,
612 "method", INIT_METHOD,
615 "args:steal", make_func_arg (cl->otype,
616 FALSE /* is_class */,
618 "unique_id", method_unique_id++,
620 cl->nodes = g_list_prepend(cl->nodes, node);
625 find_dispose(const Class *cl)
629 dispose_handler = NULL;
630 for(li=cl->nodes;li;li=g_list_next(li)) {
632 if(n->type == METHOD_NODE) {
633 Method *m = (Method *)n;
634 if(m->method == OVERRIDE_METHOD &&
635 strcmp(m->id, "dispose")==0) {
636 if(strcmp(m->otype, "G:Object") != 0) {
637 error_print(GOB_ERROR, m->line_no,
638 "dispose method override "
639 "of class other then "
642 if(g_list_length(m->args) != 1) {
643 error_print(GOB_ERROR, m->line_no,
644 "dispose method override "
645 "with more then one "
656 find_finalize(const Class *cl)
660 finalize_handler = NULL;
661 for(li=cl->nodes;li;li=g_list_next(li)) {
663 if(n->type == METHOD_NODE) {
664 Method *m = (Method *)n;
665 if(m->method == OVERRIDE_METHOD &&
666 strcmp(m->id, "finalize")==0) {
667 if(strcmp(m->otype, "G:Object") != 0) {
668 error_print(GOB_ERROR, m->line_no,
669 "finalize method override "
670 "of class other then "
673 if(g_list_length(m->args) != 1) {
674 error_print(GOB_ERROR, m->line_no,
675 "finalize method override "
676 "with more then one "
679 finalize_handler = m;
687 /* hash of method -> name of signal prototype */
688 static GHashTable *marsh = NULL;
690 /* list of methods with different signal prototypes,
691 we check this list if we can use a signal prototype of a
692 previous signal method, there are only uniques here */
693 static GList *eq_signal_methods = NULL;
695 /* compare a list of strings */
697 is_list_equal(const GList *a, const GList *b)
699 for(;a && b; a=a->next, b=b->next) {
700 if(strcmp(a->data, b->data)!=0) {
704 /* the the lists were different length */
711 find_same_type_signal(const Method *m)
714 for(li=eq_signal_methods;li;li=li->next) {
715 Method *mm = li->data;
716 if(is_list_equal(mm->gtktypes, m->gtktypes))
723 print_signal_marsal_args (const Method *m)
725 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
728 for (i = 0, li = m->gtktypes->next;
730 i++, li = li->next) {
733 if (strcmp (li->data, "UNICHAR") == 0)
734 /* hack because glib is braindamaged */
735 get_func = g_strdup ("g_value_get_uint");
737 get_func = g_strdup_printf
738 ("g_value_get_%s", (char *)li->data);
740 gob_strdown (get_func);
741 out_printf (out, ",\n\t\t(%s) "
742 "%s (param_values + %d)",
743 get_cast (li->data, FALSE),
748 out_printf (out, ",\n\t\tdata2);\n");
753 add_signal_prots(Method *m)
759 gboolean ret_none = FALSE;
760 gboolean arglist_none = FALSE;
762 const char *unused = "";
764 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
765 unused = " G_GNUC_UNUSED";
768 if (m->method != SIGNAL_LAST_METHOD &&
769 m->method != SIGNAL_FIRST_METHOD)
773 marsh = g_hash_table_new(NULL, NULL);
775 g_assert (m->gtktypes->next != NULL);
777 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
778 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
780 if (ret_none && arglist_none)
783 /* if we already did a signal prototype just use that */
784 mm = find_same_type_signal (m);
786 s = g_hash_table_lookup (marsh, mm);
787 g_hash_table_insert (marsh, m, s);
794 retcast = get_cast (m->gtktypes->data, FALSE);
796 s = g_strdup_printf("Sig%d", sig++);
798 g_hash_table_insert(marsh, m, s);
799 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
801 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
802 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
803 get_cast(m->gtktypes->data, FALSE), s, typebase);
805 if ( ! arglist_none) {
806 for (li = m->gtktypes->next; li != NULL; li = li->next)
807 out_printf (out, "%s, ", get_cast (li->data, FALSE));
809 out_printf (out, "gpointer);\n");
811 out_printf (out, "\nstatic void\n"
812 "___marshal_%s (GClosure *closure,\n"
813 "\tGValue *return_value%s,\n"
814 "\tguint n_param_values,\n"
815 "\tconst GValue *param_values,\n"
816 "\tgpointer invocation_hint%s,\n"
817 "\tgpointer marshal_data)\n"
824 out_printf (out, "\t%s v_return;\n", retcast);
826 out_printf (out, "\tregister ___%s callback;\n"
827 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
828 "\tregister gpointer data1, data2;\n\n",
831 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
832 arglist_none ? 1 : g_list_length (m->gtktypes));
835 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
836 "\t\tdata1 = closure->data;\n"
837 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
839 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
840 "\t\tdata2 = closure->data;\n"
843 out_printf (out, "\tcallback = (___%s) "
844 "(marshal_data != NULL ? marshal_data : cc->callback);"
848 out_printf (out, "\tcallback ((%s *)data1", typebase);
850 out_printf (out, "\tv_return = callback ((%s *)data1",
854 print_signal_marsal_args (m);
857 /* FIXME: This code is so fucking ugly it hurts */
858 gboolean take_ownership =
859 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
860 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
864 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
865 /* hack because glib is braindamaged */
866 set_func = g_strdup ("g_value_set_uint");
868 set_func = g_strdup_printf ("g_value_set_%s%s",
869 (char *)m->gtktypes->data,
871 "_take_ownership" : "");
872 gob_strdown (set_func);
874 out_printf (out, "\n\t%s (return_value, v_return);\n",
879 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
881 out_printf (out, "\n\treturn_value = NULL;\n");
882 out_printf (out, "\tinvocation_hint = NULL;\n");
885 out_printf (out, "}\n\n");
892 out_printf(out, "\n");
894 out_printf(out, "enum {\n");
895 for(li=c->nodes;li;li=g_list_next(li)) {
897 if(n->type == METHOD_NODE) {
898 Method *m = (Method *)n;
899 if(m->method == SIGNAL_LAST_METHOD ||
900 m->method == SIGNAL_FIRST_METHOD) {
901 char *s = g_strdup(m->id);
903 out_printf(out, "\t%s_SIGNAL,\n", s);
908 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
910 if (set_properties > 0 ||
911 get_properties > 0) {
912 out_printf(out, "enum {\n\tPROP_0");
913 for(li=c->nodes;li;li=g_list_next(li)) {
915 if (n->type == PROPERTY_NODE) {
916 Property *p = (Property *)n;
917 char *s = g_strdup (p->name);
919 out_printf (out, ",\n\tPROP_%s", s);
921 } else if (n->type == ARGUMENT_NODE) {
922 Argument *a = (Argument *)n;
923 char *s = g_strdup(a->name);
925 out_printf(out, ",\n\tPROP_%s", s);
929 out_printf(out, "\n};\n\n");
934 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
936 out_printf(out, "/* pointer to the class of our parent */\n");
937 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
941 add_interface_methods (Class *c, const char *interface)
944 gboolean added_line = FALSE;
946 for (li = c->nodes; li != NULL; li = li->next) {
948 Method *m = (Method *)n;
949 if (n->type != METHOD_NODE ||
950 m->method == OVERRIDE_METHOD ||
951 m->interface == NULL ||
952 strcmp (m->interface, interface) != 0)
955 if (m->line_no > 0) {
956 out_addline_infile (out, m->line_no);
958 } else if (m->line_no == 0 &&
960 out_addline_outfile (out);
963 out_printf (out, "\tiface->%s = self_%s;\n",
967 out_addline_outfile (out);
971 add_interface_inits (Class *c)
975 if (c->interfaces == NULL)
978 out_printf(out, "\n");
980 for (li = c->interfaces; li != NULL; li = li->next) {
981 const char *interface = li->data;
983 char *name = replace_sep (interface, '_');
984 char *type = remove_sep (interface);
986 /* EEEK! evil, we should have some sort of option
987 * to force this for arbitrary interfaces, since
988 * some are Class and some are Iface. Glib is shite
990 if (strcmp (type, "GtkEditable") == 0 ||
991 strcmp (type, "GTypePlugin") == 0)
994 /* We'll assume Iface is the standard ending */
997 out_printf (out, "\nstatic void\n"
998 "___%s_init (%s%s *iface)\n"
1002 add_interface_methods (c, interface);
1004 out_printf (out, "}\n\n");
1012 add_interface_infos (void)
1015 for (li = ((Class *)class)->interfaces;
1018 char *name = replace_sep (li->data, '_');
1020 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1021 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1031 add_interfaces (void)
1034 for (li = ((Class *)class)->interfaces;
1037 char *name = replace_sep (li->data, '_');
1038 char *type = make_pre_macro (li->data, "TYPE");
1041 "\t\tg_type_add_interface_static (type,\n"
1043 "\t\t\t&%s_info);\n",
1055 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1059 "%s_get_type (void)\n"
1061 "\tstatic GType type = 0;\n\n"
1062 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1063 "\t\tstatic const GTypeInfo info = {\n"
1064 "\t\t\tsizeof (%sClass),\n"
1065 "\t\t\t(GBaseInitFunc) NULL,\n"
1066 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1067 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1068 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1069 "\t\t\tNULL /* class_data */,\n"
1070 "\t\t\tsizeof (%s),\n"
1071 "\t\t\t0 /* n_preallocs */,\n"
1072 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1075 funcbase, typebase, funcbase, typebase, funcbase);
1077 add_interface_infos ();
1080 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)0);\n",
1081 pmacrotype, typebase);
1089 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1091 chunk_size, chunk_size);
1101 add_bonobo_object_get_type (void)
1103 /* char *chunk_size = ((Class*)class)->chunk_size; */
1104 /* _vicious_ spanks seth with a rusty nail
1106 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1107 "gob2 doesn't officially support it yet. It'd be safer "
1108 "and a lot more fun to blow goats.\"\n");
1113 "%s_get_type (void)\n" /* 1 */
1115 "\tstatic GType type = 0;\n\n"
1116 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1117 "\t\tstatic const GTypeInfo info = {\n"
1118 "\t\t\tsizeof (%sClass),\n" /* 2 */
1119 "\t\t\t(GBaseInitFunc) NULL,\n"
1120 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1121 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1122 "\t\t\tNULL, /* class_finalize */\n"
1123 "\t\t\tNULL, /* class_data */\n"
1124 "\t\t\tsizeof (%s),\n" /* 4 */
1125 "\t\t\t0, /* n_preallocs */\n"
1126 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1135 add_interface_infos ();
1138 "\t\ttype = bonobo_type_unique (\n"
1139 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1140 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1141 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1142 "\t\t\t&info, \"%s\");\n", /* 3 */
1143 ((Class*)class)->bonobo_object_class /* 1 */,
1152 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1154 chunk_size, chunk_size);
1163 add_overrides(Class *c, const char *oname,
1164 gboolean did_base_obj)
1170 done = g_hash_table_new (g_str_hash, g_str_equal);
1172 s = g_strdup ("GObject");
1173 g_hash_table_insert (done, s, s);
1175 for (li = c->nodes; li != NULL; li = li->next) {
1178 Method *m = (Method *)n;
1179 if(n->type != METHOD_NODE ||
1180 m->method != OVERRIDE_METHOD)
1183 s = remove_sep(m->otype);
1185 if(g_hash_table_lookup(done, s)) {
1189 g_hash_table_insert(done, s, s);
1191 f = replace_sep(m->otype, '_');
1194 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1199 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1200 g_hash_table_destroy (done);
1204 make_run_signal_flags(Method *m, gboolean last)
1219 gs = g_string_new(NULL);
1222 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1224 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1226 if(m->scope == PUBLIC_SCOPE)
1227 g_string_append(gs, " | G_SIGNAL_ACTION");
1229 for(li = m->flags; li; li = li->next) {
1230 char *flag = li->data;
1232 for(i=0;flags[i];i++) {
1233 if(strcmp(flags[i], flag)==0)
1236 /* if we haven't found it in our list */
1238 error_printf(GOB_WARN, m->line_no,
1239 "Unknown flag '%s' used, "
1240 "perhaps it was misspelled",
1243 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1247 char *ret = gs->str;
1248 g_string_free(gs, FALSE);
1255 add_signals(Class *c)
1259 out_printf(out, "\n");
1260 for(li=c->nodes;li;li=g_list_next(li)) {
1262 char *mar, *sig, *flags;
1263 gboolean is_none, last = FALSE;
1264 Method *m = (Method *)n;
1266 if(n->type != METHOD_NODE ||
1267 (m->method != SIGNAL_FIRST_METHOD &&
1268 m->method != SIGNAL_LAST_METHOD))
1271 if(m->method == SIGNAL_FIRST_METHOD)
1276 if(g_hash_table_lookup(marsh, m))
1277 mar = g_strconcat("___marshal_",
1278 (char *)g_hash_table_lookup(marsh, m),
1281 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1283 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1285 sig = g_strdup (m->id);
1287 flags = make_run_signal_flags (m, last);
1288 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1289 "\t\tg_signal_new (\"%s\",\n"
1290 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1291 "\t\t\t(GSignalFlags)(%s),\n"
1292 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1293 "\t\t\tNULL, NULL,\n"
1295 "\t\t\tG_TYPE_%s, %d",
1298 typebase, m->id, mar,
1299 (char *)m->gtktypes->data,
1300 is_none ? 0 : g_list_length(m->gtktypes->next));
1307 for(l = m->gtktypes->next; l != NULL; l = l->next)
1308 out_printf(out, ",\n\t\t\tG_TYPE_%s",
1312 out_printf(out, ");\n");
1314 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1317 out_printf(out, "\tif ___GOB_UNLIKELY(");
1318 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1319 out_printf(out, "sizeof(");
1320 print_type(out, m->mtype, FALSE);
1321 out_printf(out, "%s",
1323 m->mtype->postfix : "");
1324 out_printf(out, ") != sizeof(%s) || ",
1325 get_cast(m->gtktypes->data, FALSE));
1328 for(al = m->args->next, gl = m->gtktypes->next;
1329 al != NULL && gl != NULL;
1330 al = al->next, gl = gl->next) {
1331 FuncArg *arg = al->data;
1332 char *gtkarg = gl->data;
1334 out_printf(out, "sizeof(");
1335 print_type(out, arg->atype, FALSE);
1336 out_printf(out, "%s",
1337 arg->atype->postfix ?
1338 arg->atype->postfix : "");
1339 out_printf(out, ") != sizeof(%s) || ",
1340 get_cast(gtkarg, FALSE));
1344 "parent_class == NULL /* avoid warning */");
1346 out_printf(out, ") {\n"
1347 "\t\tg_error(\"%s line %d: Type mismatch "
1348 "of \\\"%s\\\" signal signature\");\n"
1350 filename, m->line_no, m->id);
1357 set_def_handlers(Class *c, const char *oname)
1360 gboolean set_line = FALSE;
1362 out_printf(out, "\n");
1363 for(li = c->nodes; li; li = g_list_next(li)) {
1365 Method *m = (Method *)n;
1367 if(n->type != METHOD_NODE ||
1368 (m->method != SIGNAL_FIRST_METHOD &&
1369 m->method != SIGNAL_LAST_METHOD &&
1370 m->method != VIRTUAL_METHOD &&
1371 m->method != OVERRIDE_METHOD))
1374 if(m->line_no > 0 && m->cbuf) {
1375 out_addline_infile(out, m->line_no);
1377 } else if(set_line) {
1378 out_addline_outfile(out);
1383 if (m->method == OVERRIDE_METHOD) {
1385 s = replace_sep (m->otype, '_');
1389 dispose_handler != NULL &&
1390 strcmp (m->id, "dispose") == 0)
1391 out_printf (out, "\tg_object_class->dispose "
1393 else if (need_finalize &&
1395 strcmp(m->id, "finalize") == 0)
1397 "\tg_object_class->finalize = ___finalize;\n");
1398 else if (m->cbuf != NULL)
1400 "\t%s_class->%s = ___%x_%s_%s;\n",
1401 s, m->id, (guint)m->unique_id,
1404 out_printf(out, "\t%s_class->%s = NULL;\n",
1408 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1412 out_printf(out, "\t%s->%s = NULL;\n",
1417 out_addline_outfile(out);
1421 make_argument (Argument *a)
1426 char *argflags[] = {
1434 flags = g_string_new ("(GParamFlags)(");
1436 if(a->get && a->set)
1437 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1439 g_string_append (flags, "G_PARAM_READABLE");
1441 g_string_append (flags, "G_PARAM_WRITABLE");
1443 g_assert(a->get || a->set);
1445 for (l = a->flags; l != NULL; l = l->next) {
1446 char *flag = l->data;
1448 if(strcmp (flag, "READABLE") == 0 ||
1449 strcmp (flag, "WRITABLE") == 0) {
1450 error_print(GOB_WARN, a->line_no,
1452 "WRITABLE argument flags are "
1453 "set automatically");
1456 for(i = 0; argflags[i]; i++) {
1457 if(strcmp(argflags[i], flag)==0)
1460 /* if we haven't found it in our list */
1461 if( ! argflags[i]) {
1462 error_printf(GOB_WARN, a->line_no,
1463 "Unknown flag '%s' used, "
1464 "perhaps it was misspelled", flag);
1466 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1469 g_string_append (flags, ")");
1471 s = g_strdup(a->name);
1473 if (!strcmp (a->gtktype, "ENUM"))
1474 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1475 "\t\tG_TYPE_ENUM, 0,\n"
1477 a->name, flags->str);
1478 if (!strcmp (a->gtktype, "FLAGS"))
1479 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1480 "\t\tG_TYPE_FLAGS, 0,\n"
1482 a->name, flags->str);
1483 else if (!strcmp (a->gtktype, "OBJECT"))
1484 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1485 "\t\tG_TYPE_OBJECT,\n"
1487 a->name, flags->str);
1488 else if (!strcmp (a->gtktype, "STRING"))
1489 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1492 a->name, flags->str);
1493 else if (!strcmp (a->gtktype, "INT"))
1494 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1495 "\t\tG_MININT, G_MAXINT,\n"
1498 a->name, flags->str);
1499 else if (!strcmp (a->gtktype, "UINT"))
1500 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1501 "\t\t0, G_MAXUINT,\n"
1504 a->name, flags->str);
1505 else if (!strcmp (a->gtktype, "INT"))
1506 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1507 "\t\tG_MININT, G_MAXINT,\n"
1510 a->name, flags->str);
1511 else if (!strcmp (a->gtktype, "CHAR"))
1512 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1516 a->name, flags->str);
1517 else if (!strcmp (a->gtktype, "UCHAR"))
1518 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1522 a->name, flags->str);
1523 else if (!strcmp (a->gtktype, "BOOL") ||
1524 !strcmp (a->gtktype, "BOOLEAN"))
1525 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1528 a->name, flags->str);
1529 else if (!strcmp (a->gtktype, "LONG"))
1530 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1531 "\t\tG_MINLONG, G_MAXLONG,\n"
1534 a->name, flags->str);
1535 else if (!strcmp (a->gtktype, "ULONG"))
1536 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1537 "\t\t0, G_MAXULONG,\n"
1540 a->name, flags->str);
1541 else if (!strcmp (a->gtktype, "INT64"))
1542 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1543 "\t\tG_MININT64, G_MAXINT64,\n"
1546 a->name, flags->str);
1547 else if (!strcmp (a->gtktype, "UINT64"))
1548 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1549 "\t\t0, G_MAXUINT64,\n"
1552 a->name, flags->str);
1553 else if (!strcmp (a->gtktype, "FLOAT"))
1554 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1555 "\t\tG_MINFLOAT, G_MAXFLOAT,\n"
1558 a->name, flags->str);
1559 else if (!strcmp (a->gtktype, "DOUBLE"))
1560 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1561 "\t\tG_MINDOUBLE, G_MAXDOUBLE,\n"
1564 a->name, flags->str);
1565 else if (!strcmp (a->gtktype, "POINTER"))
1566 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1568 a->name, flags->str);
1570 error_printf (GOB_ERROR, a->line_no,
1571 "%s type is not supported for arguments, try using properties",
1574 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1575 "\t\tPROP_%s, param_spec);\n", s);
1579 g_string_free(flags, TRUE);
1582 #define value_for_print(str, alt) (str != NULL ? str : alt)
1585 make_property (Property *p)
1590 char *argflags[] = {
1598 flags = g_string_new ("(GParamFlags)(");
1600 if (p->get != NULL && p->set != NULL)
1601 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1602 else if (p->get != NULL)
1603 g_string_append (flags, "G_PARAM_READABLE");
1605 g_string_append (flags, "G_PARAM_WRITABLE");
1607 if (p->get == NULL && p->set == NULL) {
1608 error_print (GOB_ERROR, p->line_no,
1609 "Property has no getter nor setter");
1612 for (l = p->flags; l != NULL; l = l->next) {
1613 char *flag = l->data;
1615 if(strcmp (flag, "READABLE") == 0 ||
1616 strcmp (flag, "WRITABLE") == 0) {
1617 error_print(GOB_WARN, p->line_no,
1619 "WRITABLE argument flags are "
1620 "set automatically");
1623 for(i = 0; argflags[i]; i++) {
1624 if(strcmp(argflags[i], flag)==0)
1627 /* if we haven't found it in our list */
1628 if( ! argflags[i]) {
1629 error_printf(GOB_WARN, p->line_no,
1630 "Unknown flag '%s' used, "
1631 "perhaps it was misspelled", flag);
1633 g_string_sprintfa(flags, " | G_PARAM_%s", flag);
1636 g_string_append (flags, ")");
1638 if (strcmp (p->gtktype, "CHAR") == 0) {
1639 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1640 "\t\t(\"%s\" /* name */,\n"
1641 "\t\t %s /* nick */,\n"
1642 "\t\t %s /* blurb */,\n"
1643 "\t\t %s /* minimum */,\n"
1644 "\t\t %s /* maximum */,\n"
1645 "\t\t %s /* default_value */,\n"
1648 value_for_print (p->nick, "NULL"),
1649 value_for_print (p->blurb, "NULL"),
1650 value_for_print (p->minimum, "-128"),
1651 value_for_print (p->maximum, "127"),
1652 value_for_print (p->default_value, "0"),
1654 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1655 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1656 "\t\t(\"%s\" /* name */,\n"
1657 "\t\t %s /* nick */,\n"
1658 "\t\t %s /* blurb */,\n"
1659 "\t\t %s /* minimum */,\n"
1660 "\t\t %s /* maximum */,\n"
1661 "\t\t %s /* default_value */,\n"
1664 value_for_print (p->nick, "NULL"),
1665 value_for_print (p->blurb, "NULL"),
1666 value_for_print (p->minimum, "0"),
1667 value_for_print (p->maximum, "0xFF"),
1668 value_for_print (p->default_value, "0"),
1670 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1671 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1672 "\t\t(\"%s\" /* name */,\n"
1673 "\t\t %s /* nick */,\n"
1674 "\t\t %s /* blurb */,\n"
1675 "\t\t %s /* default_value */,\n"
1678 value_for_print (p->nick, "NULL"),
1679 value_for_print (p->blurb, "NULL"),
1680 value_for_print (p->default_value, "FALSE"),
1682 } else if (strcmp (p->gtktype, "INT") == 0) {
1683 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1684 "\t\t(\"%s\" /* name */,\n"
1685 "\t\t %s /* nick */,\n"
1686 "\t\t %s /* blurb */,\n"
1687 "\t\t %s /* minimum */,\n"
1688 "\t\t %s /* maximum */,\n"
1689 "\t\t %s /* default_value */,\n"
1692 value_for_print (p->nick, "NULL"),
1693 value_for_print (p->blurb, "NULL"),
1694 value_for_print (p->minimum, "G_MININT"),
1695 value_for_print (p->maximum, "G_MAXINT"),
1696 value_for_print (p->default_value, "0"),
1698 } else if (strcmp (p->gtktype, "UINT") == 0) {
1699 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1700 "\t\t(\"%s\" /* name */,\n"
1701 "\t\t %s /* nick */,\n"
1702 "\t\t %s /* blurb */,\n"
1703 "\t\t %s /* minimum */,\n"
1704 "\t\t %s /* maximum */,\n"
1705 "\t\t %s /* default_value */,\n"
1708 value_for_print (p->nick, "NULL"),
1709 value_for_print (p->blurb, "NULL"),
1710 value_for_print (p->minimum, "0"),
1711 value_for_print (p->maximum, "G_MAXUINT"),
1712 value_for_print (p->default_value, "0"),
1714 } else if (strcmp (p->gtktype, "LONG") == 0) {
1715 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1716 "\t\t(\"%s\" /* name */,\n"
1717 "\t\t %s /* nick */,\n"
1718 "\t\t %s /* blurb */,\n"
1719 "\t\t %s /* minimum */,\n"
1720 "\t\t %s /* maximum */,\n"
1721 "\t\t %s /* default_value */,\n"
1724 value_for_print (p->nick, "NULL"),
1725 value_for_print (p->blurb, "NULL"),
1726 value_for_print (p->minimum, "G_MINLONG"),
1727 value_for_print (p->maximum, "G_MAXLONG"),
1728 value_for_print (p->default_value, "0"),
1730 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1731 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1732 "\t\t(\"%s\" /* name */,\n"
1733 "\t\t %s /* nick */,\n"
1734 "\t\t %s /* blurb */,\n"
1735 "\t\t %s /* minimum */,\n"
1736 "\t\t %s /* maximum */,\n"
1737 "\t\t %s /* default_value */,\n"
1740 value_for_print (p->nick, "NULL"),
1741 value_for_print (p->blurb, "NULL"),
1742 value_for_print (p->minimum, "0"),
1743 value_for_print (p->maximum, "G_MAXULONG"),
1744 value_for_print (p->default_value, "0"),
1746 } else if (strcmp (p->gtktype, "INT64") == 0) {
1747 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1748 "\t\t(\"%s\" /* name */,\n"
1749 "\t\t %s /* nick */,\n"
1750 "\t\t %s /* blurb */,\n"
1751 "\t\t %s /* minimum */,\n"
1752 "\t\t %s /* maximum */,\n"
1753 "\t\t %s /* default_value */,\n"
1756 value_for_print (p->nick, "NULL"),
1757 value_for_print (p->blurb, "NULL"),
1758 value_for_print (p->minimum, "G_MININT64"),
1759 value_for_print (p->maximum, "G_MAXINT64"),
1760 value_for_print (p->default_value, "0"),
1762 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1763 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1764 "\t\t(\"%s\" /* name */,\n"
1765 "\t\t %s /* nick */,\n"
1766 "\t\t %s /* blurb */,\n"
1767 "\t\t %s /* minimum */,\n"
1768 "\t\t %s /* maximum */,\n"
1769 "\t\t %s /* default_value */,\n"
1772 value_for_print (p->nick, "NULL"),
1773 value_for_print (p->blurb, "NULL"),
1774 value_for_print (p->minimum, "0"),
1775 value_for_print (p->maximum, "G_MAXUINT64"),
1776 value_for_print (p->default_value, "0"),
1778 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1779 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1780 "\t\t(\"%s\" /* name */,\n"
1781 "\t\t %s /* nick */,\n"
1782 "\t\t %s /* blurb */,\n"
1783 "\t\t %s /* default_value */,\n"
1786 value_for_print (p->nick, "NULL"),
1787 value_for_print (p->blurb, "NULL"),
1788 value_for_print (p->default_value, "0"),
1790 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1791 char *type = make_me_type (p->extra_gtktype,
1793 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1794 "\t\t(\"%s\" /* name */,\n"
1795 "\t\t %s /* nick */,\n"
1796 "\t\t %s /* blurb */,\n"
1797 "\t\t %s /* enum_type */,\n"
1798 "\t\t %s /* default_value */,\n"
1801 value_for_print (p->nick, "NULL"),
1802 value_for_print (p->blurb, "NULL"),
1804 value_for_print (p->default_value, "0"),
1807 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1808 char *type = make_me_type (p->extra_gtktype,
1810 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1811 "\t\t(\"%s\" /* name */,\n"
1812 "\t\t %s /* nick */,\n"
1813 "\t\t %s /* blurb */,\n"
1814 "\t\t %s /* flags_type */,\n"
1815 "\t\t %s /* default_value */,\n"
1818 value_for_print (p->nick, "NULL"),
1819 value_for_print (p->blurb, "NULL"),
1821 value_for_print (p->default_value, "0"),
1824 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1825 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1826 "\t\t(\"%s\" /* name */,\n"
1827 "\t\t %s /* nick */,\n"
1828 "\t\t %s /* blurb */,\n"
1829 "\t\t %s /* minimum */,\n"
1830 "\t\t %s /* maximum */,\n"
1831 "\t\t %s /* default_value */,\n"
1834 value_for_print (p->nick, "NULL"),
1835 value_for_print (p->blurb, "NULL"),
1836 value_for_print (p->minimum, "G_MINFLOAT"),
1837 value_for_print (p->maximum, "G_MAXFLOAT"),
1838 value_for_print (p->default_value, "0.0"),
1840 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1841 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1842 "\t\t(\"%s\" /* name */,\n"
1843 "\t\t %s /* nick */,\n"
1844 "\t\t %s /* blurb */,\n"
1845 "\t\t %s /* minimum */,\n"
1846 "\t\t %s /* maximum */,\n"
1847 "\t\t %s /* default_value */,\n"
1850 value_for_print (p->nick, "NULL"),
1851 value_for_print (p->blurb, "NULL"),
1852 value_for_print (p->minimum, "G_MINDOUBLE"),
1853 value_for_print (p->maximum, "G_MAXDOUBLE"),
1854 value_for_print (p->default_value, "0.0"),
1856 } else if (strcmp (p->gtktype, "STRING") == 0) {
1857 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1858 "\t\t(\"%s\" /* name */,\n"
1859 "\t\t %s /* nick */,\n"
1860 "\t\t %s /* blurb */,\n"
1861 "\t\t %s /* default_value */,\n"
1864 value_for_print (p->nick, "NULL"),
1865 value_for_print (p->blurb, "NULL"),
1866 value_for_print (p->default_value, "NULL"),
1868 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1869 char *type = make_me_type (p->extra_gtktype,
1871 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1872 "\t\t(\"%s\" /* name */,\n"
1873 "\t\t %s /* nick */,\n"
1874 "\t\t %s /* blurb */,\n"
1875 "\t\t %s /* param_type */,\n"
1878 value_for_print (p->nick, "NULL"),
1879 value_for_print (p->blurb, "NULL"),
1883 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1884 char *type = make_me_type (p->extra_gtktype,
1886 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1887 "\t\t(\"%s\" /* name */,\n"
1888 "\t\t %s /* nick */,\n"
1889 "\t\t %s /* blurb */,\n"
1890 "\t\t %s /* boxed_type */,\n"
1893 value_for_print (p->nick, "NULL"),
1894 value_for_print (p->blurb, "NULL"),
1898 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1899 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1900 "\t\t(\"%s\" /* name */,\n"
1901 "\t\t %s /* nick */,\n"
1902 "\t\t %s /* blurb */,\n"
1905 value_for_print (p->nick, "NULL"),
1906 value_for_print (p->blurb, "NULL"),
1908 /* FIXME: VALUE_ARRAY */
1909 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1910 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1911 "\t\t(\"%s\" /* name */,\n"
1912 "\t\t %s /* nick */,\n"
1913 "\t\t %s /* blurb */,\n"
1916 value_for_print (p->nick, "NULL"),
1917 value_for_print (p->blurb, "NULL"),
1919 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
1920 char *type = make_me_type (p->extra_gtktype,
1922 out_printf (out, "\tparam_spec = g_param_spec_object\n"
1923 "\t\t(\"%s\" /* name */,\n"
1924 "\t\t %s /* nick */,\n"
1925 "\t\t %s /* blurb */,\n"
1926 "\t\t %s /* object_type */,\n"
1929 value_for_print (p->nick, "NULL"),
1930 value_for_print (p->blurb, "NULL"),
1935 error_printf (GOB_ERROR, p->line_no,
1936 "%s type is not supported by properties",
1940 s = g_strdup (p->name);
1942 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
1944 "\t\tparam_spec);\n", s);
1947 g_string_free (flags, TRUE);
1951 make_arguments(Class *c)
1954 if (get_properties > 0)
1955 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
1956 if (set_properties > 0)
1957 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
1958 out_printf (out, " {\n"
1959 "\tGParamSpec *param_spec;\n\n");
1961 for (li = c->nodes; li != NULL; li = li->next) {
1963 if (n->type == PROPERTY_NODE)
1964 make_property ((Property *)n);
1965 else if (n->type == ARGUMENT_NODE)
1966 make_argument ((Argument *)n);
1968 out_printf(out, " }\n");
1972 print_initializer(Method *m, Variable *v)
1976 if(v->initializer == NULL)
1979 if(v->scope == PRIVATE_SCOPE)
1980 root = g_strconcat(((FuncArg *)m->args->data)->name,
1983 root = g_strdup(((FuncArg *)m->args->data)->name);
1985 if(v->initializer_line > 0)
1986 out_addline_infile(out, v->initializer_line);
1988 out_printf(out, "\t%s->%s = %s;\n",
1989 root, v->id, v->initializer);
1991 if(v->initializer_line > 0)
1992 out_addline_outfile(out);
1998 print_destructor (Variable *v)
2002 if(v->destructor == NULL)
2005 if(v->scope == PRIVATE_SCOPE)
2006 root = "self->_priv";
2010 if(v->destructor_simple) {
2011 if(v->destructor_line > 0)
2012 out_addline_infile(out, v->destructor_line);
2014 out_printf(out, "\tif(%s->%s) { "
2015 "((*(void (*)(void *))%s)) (%s->%s); "
2016 "%s->%s = NULL; }\n",
2017 root, v->id, v->destructor, root, v->id,
2020 if(v->destructor_line > 0)
2021 out_addline_outfile(out);
2023 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2024 out_printf(out, "#define VAR %s\n", v->id);
2025 out_printf(out, "\t{\n");
2026 if(v->destructor_line > 0)
2027 out_addline_infile(out, v->destructor_line);
2029 out_printf(out, "\t%s}\n", v->destructor);
2031 if(v->destructor_line > 0)
2032 out_addline_outfile(out);
2033 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
2035 out_printf(out, "#undef VAR\n");
2036 out_printf(out, "#undef %s\n", v->id);
2041 add_dispose (Class *c)
2043 out_printf(out, "\nstatic void\n"
2044 "___dispose (GObject *obj_self)\n"
2047 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2050 if (unreftors > 0) {
2051 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2053 ! no_gnu ? " G_GNUC_UNUSED" : "",
2057 if (dispose_handler != NULL) {
2058 /* so we get possible bad argument warning */
2059 if (dispose_handler->line_no > 0)
2060 out_addline_infile (out, dispose_handler->line_no);
2061 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2062 (guint)dispose_handler->unique_id, funcbase);
2063 if (dispose_handler->line_no > 0)
2064 out_addline_outfile (out);
2067 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2068 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2071 if (unreftors > 0) {
2073 for(li = ((Class *)class)->nodes;
2077 Variable *v = (Variable *)n;
2078 if (n->type == VARIABLE_NODE &&
2079 v->scope != CLASS_SCOPE &&
2080 v->destructor_unref)
2081 print_destructor (v);
2085 out_printf(out, "}\n"
2086 "#undef __GOB_FUNCTION__\n\n");
2090 add_finalize (Class *c)
2094 "___finalize(GObject *obj_self)\n"
2097 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2102 const char *unused = "";
2104 unused = " G_GNUC_UNUSED";
2105 out_printf(out, "\t%s *self %s = %s (obj_self);\n",
2106 typebase, unused, macrobase);
2109 out_printf(out, "\tgpointer priv = self->_priv;\n");
2112 if(finalize_handler) {
2113 /* so we get possible bad argument warning */
2114 if(finalize_handler->line_no > 0)
2115 out_addline_infile(out, finalize_handler->line_no);
2116 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2117 (guint)finalize_handler->unique_id, funcbase);
2118 if(finalize_handler->line_no > 0)
2119 out_addline_outfile(out);
2122 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2123 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2126 if (destructors > 0) {
2128 for (li = ((Class *)class)->nodes;
2132 Variable *v = (Variable *)n;
2133 if (n->type == VARIABLE_NODE &&
2134 v->scope != CLASS_SCOPE &&
2135 ! v->destructor_unref)
2136 print_destructor (v);
2141 out_printf(out, "\tg_free (priv);\n");
2144 out_printf(out, "}\n"
2145 "#undef __GOB_FUNCTION__\n\n");
2149 make_bonobo_object_epv (Class *c, const char *classname)
2152 gboolean added_line = FALSE;
2154 for (li = c->nodes; li != NULL; li = li->next) {
2156 Method *m = (Method *)n;
2157 if(n->type != METHOD_NODE ||
2158 m->method == OVERRIDE_METHOD)
2161 if (m->bonobo_object_func) {
2162 if(m->line_no > 0) {
2163 out_addline_infile(out, m->line_no);
2165 } else if (m->line_no == 0 &&
2167 out_addline_outfile(out);
2170 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2171 classname, m->id, m->id);
2175 out_addline_outfile(out);
2181 const char *unused = "";
2185 unused = " G_GNUC_UNUSED";
2187 for(li=c->nodes;li;li=g_list_next(li)) {
2191 if(n->type != METHOD_NODE)
2194 if(m->method == INIT_METHOD) {
2196 out_addline_infile(out, m->line_no);
2197 print_method(out, "static ", "\n", "", " ", "", "\n",
2198 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2200 out_addline_outfile(out);
2201 out_printf(out, "{\n"
2202 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2205 out_printf(out, "\t%s->_priv = "
2206 "g_new0 (%sPrivate, 1);\n",
2207 ((FuncArg *)m->args->data)->name,
2209 } else if(always_private_struct) {
2210 out_printf(out, "\t%s->_priv = NULL;\n",
2211 ((FuncArg *)m->args->data)->name);
2213 if(initializers > 0) {
2215 for(li = ((Class *)class)->nodes;
2219 Variable *v = (Variable *)n;
2220 if(n->type != VARIABLE_NODE ||
2221 v->scope == CLASS_SCOPE)
2223 print_initializer(m, v);
2226 } else if(m->method == CLASS_INIT_METHOD) {
2227 gboolean did_base_obj = FALSE;
2230 out_addline_infile(out, m->line_no);
2231 print_method(out, "static ", "\n", "", " ", "", "\n",
2232 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2234 out_addline_outfile(out);
2235 out_printf(out, "{\n"
2236 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2238 if (set_properties > 0 ||
2239 get_properties > 0 ||
2245 "g_object_class%s = "
2246 "(GObjectClass*) %s;\n",
2248 ((FuncArg *)m->args->data)->name);
2249 did_base_obj = TRUE;
2254 ((FuncArg *)m->args->data)->name,
2257 if (initializers > 0) {
2259 for(li = ((Class *)class)->nodes;
2263 Variable *v = (Variable *)n;
2264 if(n->type == VARIABLE_NODE &&
2265 v->scope == CLASS_SCOPE)
2266 print_initializer(m, v);
2270 out_printf(out, "\n\tparent_class = ");
2272 out_printf(out, "(%sClass *)", ptypebase);
2273 out_printf(out, "g_type_class_ref (%s);\n",
2279 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2281 /* if there are no handlers for these things, we
2282 * need to set them up here */
2283 if(need_dispose && !dispose_handler)
2284 out_printf(out, "\tg_object_class->dispose "
2286 if(need_finalize && !finalize_handler)
2287 out_printf(out, "\tg_object_class->finalize = "
2290 if(get_properties > 0 || set_properties > 0)
2293 if (c->bonobo_object_class != NULL) {
2294 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2300 out_printf(out, " {\n");
2301 out_addline_infile(out, m->ccode_line);
2302 out_printf(out, "%s\n", m->cbuf);
2303 out_addline_outfile(out);
2304 out_printf(out, " }\n");
2306 out_printf(out, "}\n"
2307 "#undef __GOB_FUNCTION__\n");
2312 add_argument (Argument *a, gboolean is_set)
2316 char *the_type_lower;
2321 line_no = a->set_line;
2324 line_no = a->get_line;
2328 s = g_strdup(a->name);
2330 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2332 the_type_lower = g_strdup (a->gtktype);
2333 gob_strdown (the_type_lower);
2335 /* HACK because there is no g_value_set/get for unichar */
2336 if (strcmp (the_type_lower, "unichar") == 0) {
2337 g_free (the_type_lower);
2338 the_type_lower = g_strdup ("uint");
2343 const char *unused = "";
2345 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2346 unused = " G_GNUC_UNUSED";
2349 if (a->atype != NULL &&
2350 /* gcc -Wbad-function-cast is wanking stupid, moronic
2351 and otherwise evil so we should just use a (gint)
2352 or (guint) cast, not the specific type cast */
2354 (strcmp (a->gtktype, "ENUM") != 0 &&
2355 strcmp (a->gtktype, "FLAGS") != 0)))
2356 cast = get_type (a->atype, TRUE);
2358 cast = g_strdup (get_cast (a->gtktype, FALSE));
2360 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2361 cast, unused, cast, the_type_lower);
2364 } else if ( ! is_set) {
2367 if (a->atype != NULL)
2368 cast = get_type (a->atype, TRUE);
2370 cast = g_strdup (get_cast (a->gtktype, FALSE));
2371 out_printf (out, "\t%s ARG;\n"
2372 "\tmemset (&ARG, 0, sizeof (%s));\n",
2378 out_printf(out, "\t\t{\n");
2380 out_addline_infile (out, line_no);
2381 out_printf (out, "%s\n", cbuf);
2383 out_addline_outfile (out);
2384 out_printf (out, "\t\t}\n");
2386 if (strcmp (a->gtktype, "OBJECT") == 0)
2387 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2390 out_printf (out, "\t\t"
2391 "g_value_set_%s (VAL, ARG);\n",
2394 g_free (the_type_lower);
2397 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2398 out_printf (out, "\t\tif (&ARG) break;\n");
2401 out_printf (out, "\t\tbreak;\n");
2403 out_printf (out, "\t}\n");
2407 add_property (Property *p, gboolean is_set)
2410 char *the_type_lower;
2416 line_no = p->set_line;
2419 line_no = p->get_line;
2424 name_upper = g_strdup (p->name);
2425 gob_strup (name_upper);
2426 the_type_lower = g_strdup (p->gtktype);
2427 gob_strdown (the_type_lower);
2429 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2431 out_printf(out, "\t\t{\n");
2433 out_addline_infile (out, line_no);
2434 out_printf (out, "%s\n", cbuf);
2436 out_addline_outfile (out);
2437 out_printf (out, "\t\t}\n");
2439 g_free (name_upper);
2440 g_free (the_type_lower);
2442 out_printf (out, "\t\tbreak;\n");
2446 add_getset_arg(Class *c, gboolean is_set)
2449 const char *unused = "";
2450 const char *hack_unused = "";
2452 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2453 unused = " G_GNUC_UNUSED";
2455 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2458 out_printf(out, "\nstatic void\n"
2459 "___object_%s_property (GObject *object,\n"
2460 "\tguint property_id,\n"
2461 "\t%sGValue *VAL%s,\n"
2462 "\tGParamSpec *pspec%s)\n"
2463 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2466 "\tself = %s (object);\n\n"
2467 "\tswitch (property_id) {\n",
2468 is_set ? "set" : "get",
2469 is_set ? "const " : "",
2473 is_set ? "set" : "get",
2478 for (li = c->nodes; li != NULL; li = li->next) {
2480 if (n->type == PROPERTY_NODE)
2481 add_property ((Property *)n, is_set);
2482 else if (n->type == ARGUMENT_NODE)
2483 add_argument ((Argument *)n, is_set);
2485 out_printf (out, "\tdefault:\n"
2486 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2487 "#ifndef __PRETTY_FUNCTION__\n"
2488 "# undef G_STRLOC\n"
2489 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2491 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2492 "\t\t%sbreak;\n\t}\n"
2494 "#undef __GOB_FUNCTION__\n", hack_unused);
2498 print_checks (Method *m, FuncArg *fa)
2502 gboolean checked_null = FALSE;
2503 is_void = (strcmp(m->mtype->name, "void")==0 &&
2504 m->mtype->pointer == NULL);
2506 for(li = fa->checks; li != NULL; li = li->next) {
2507 Check *ch = li->data;
2509 /* point to the method prot in .gob for failed checks */
2511 out_addline_infile(out, m->line_no);
2513 out_printf(out, "\tg_return_if_fail (");
2515 out_printf(out, "\tg_return_val_if_fail (");
2516 switch(ch->chtype) {
2518 out_printf(out, "%s != NULL", fa->name);
2519 checked_null = TRUE;
2522 s = make_pre_macro(fa->atype->name, "IS");
2524 out_printf(out, "%s (%s)", s, fa->name);
2526 /* if not check null, null may be valid */
2527 out_printf(out, "!(%s) || %s (%s)", fa->name,
2532 out_printf(out, "%s < %s", fa->name, ch->number);
2535 out_printf(out, "%s > %s", fa->name, ch->number);
2538 out_printf(out, "%s <= %s", fa->name, ch->number);
2541 out_printf(out, "%s >= %s", fa->name, ch->number);
2544 out_printf(out, "%s == %s", fa->name, ch->number);
2547 out_printf(out, "%s != %s", fa->name, ch->number);
2551 out_printf(out, ");\n");
2553 out_printf(out, ", (");
2554 print_type(out, m->mtype, TRUE);
2555 out_printf(out, ")%s);\n",
2556 m->onerror?m->onerror:"0");
2562 print_preconditions(Method *m)
2566 for(li=m->args;li;li=g_list_next(li)) {
2567 FuncArg *fa = li->data;
2569 print_checks(m, fa);
2572 out_addline_outfile(out);
2576 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2579 out_addline_outfile(out);
2580 out_printf(out, "{\n"
2581 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2582 ((Class *)class)->otype,
2585 print_preconditions(m);
2589 (no_gnu || for_cpp) &&
2591 ((FuncArg *)(m->args->data))->name != NULL &&
2592 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2593 out_printf (out, "\tif (&self) { ; }\n");
2596 /* Note: the trailing }'s are on one line, this is so
2597 that we get the no return warning correctly and point to
2598 the correct line in the .gob file, yes this is slightly
2599 ugly in the .c file, but that is not supposed to be
2600 human readable anyway. */
2602 out_printf(out, "{\n");
2604 out_addline_infile(out, m->ccode_line);
2605 out_printf(out, "\t%s}", m->cbuf);
2608 /* Note, there is no \n between the last } and this } so that
2609 * errors/warnings reported on the end of the body get pointed to the
2610 * right line in the .gob source */
2611 out_printf(out, "}\n");
2614 out_addline_outfile(out);
2615 out_printf(out, "#undef __GOB_FUNCTION__\n");
2619 put_signal_args (Method *m)
2625 if (m->args->next == NULL)
2628 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2629 li != NULL && ali != NULL;
2630 li = li->next, ali = ali->next, i++) {
2631 FuncArg *fa = li->data;
2632 char *cast = g_strdup (get_cast (ali->data, FALSE));
2633 /* FIXME: This code is so fucking ugly it hurts */
2634 gboolean do_static =
2635 (strcmp ((char *)ali->data, "STRING") == 0 ||
2636 strcmp ((char *)ali->data, "BOXED") == 0);
2640 cast = get_type (fa->atype, TRUE);
2642 /* we should have already proved before that
2643 the we know all the types */
2644 g_assert (cast != NULL);
2647 "\t___param_values[%d].g_type = 0;\n"
2648 "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
2649 i, i, (char *)ali->data);
2651 if (strcmp (ali->data, "UNICHAR") == 0)
2652 /* hack because glib is braindamaged */
2653 set_func = g_strdup ("g_value_set_uint");
2655 set_func = g_strdup_printf ("g_value_set%s_%s",
2656 do_static ? "_static" : "",
2658 gob_strdown (set_func);
2660 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2661 set_func, i, cast, fa->name);
2669 clear_signal_args (Method *m)
2674 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2676 if (m->args->next == NULL)
2679 for (li = m->args->next, i = 1;
2681 li = li->next, i++) {
2683 "\tg_value_unset (&___param_values[%d]);\n", i);
2688 get_arg_names_for_macro (Method *m)
2692 GString *gs = g_string_new(NULL);
2694 for(li=m->args;li;li=g_list_next(li)) {
2695 FuncArg *arg = li->data;
2696 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2699 return g_string_free (gs, FALSE);
2703 put_method(Method *m)
2705 char *s, *args, *doc;
2707 is_void = (strcmp(m->mtype->name, "void")==0 &&
2708 m->mtype->pointer == NULL);
2709 out_printf(out, "\n");
2710 if(m->method != OVERRIDE_METHOD) {
2711 doc = get_gtk_doc(m->id);
2713 out_printf(out, "%s", doc);
2718 case REGULAR_METHOD:
2720 out_addline_infile(out, m->line_no);
2721 if(m->scope == PRIVATE_SCOPE)
2722 print_method(out, "static ", "\n", "", " ", "", "\n",
2723 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2724 else /* PUBLIC, PROTECTED */
2725 print_method(out, "", "\n", "", " ", "", "\n",
2726 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2727 print_method_body(m, TRUE, TRUE);
2728 /* the outfile line was added above */
2730 case SIGNAL_FIRST_METHOD:
2731 case SIGNAL_LAST_METHOD:
2733 out_addline_infile(out, m->line_no);
2734 if(m->scope == PRIVATE_SCOPE)
2735 print_method(out, "static ", "\n", "", " ", "", "\n",
2736 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2737 else /* PUBLIC, PROTECTED */
2738 print_method(out, "", "\n", "", " ", "", "\n",
2739 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2740 out_addline_outfile (out);
2742 out_printf (out, "{\n");
2745 "\tGValue ___param_values[%d];\n"
2746 "\tGValue ___return_val;\n\n"
2747 "memset (&___return_val, 0, "
2748 "sizeof (___return_val));\n"
2749 "memset (&___param_values, 0, "
2750 "sizeof (___param_values));\n\n",
2751 g_list_length (m->args));
2753 print_preconditions (m);
2756 "\n\t___param_values[0].g_type = 0;\n"
2757 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2758 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2759 ((FuncArg *)m->args->data)->name,
2760 ((FuncArg *)m->args->data)->name);
2762 put_signal_args (m);
2764 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2765 const char *defret = NULL;
2767 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2768 (char *)m->gtktypes->data);
2770 if (m->defreturn != NULL)
2771 defret = m->defreturn;
2772 else if (m->onerror != NULL)
2773 defret = m->onerror;
2775 if (defret != NULL) {
2777 /* FIXME: This code is so fucking ugly it hurts */
2778 gboolean do_static =
2779 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2780 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2781 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2783 cast = get_type (m->mtype, TRUE);
2785 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2786 /* hack because glib is braindamaged */
2787 set_func = g_strdup ("g_value_set_uint");
2789 set_func = g_strdup_printf ("g_value_set%s_%s",
2790 do_static ? "_static" : "",
2791 (char *)m->gtktypes->data);
2792 gob_strdown (set_func);
2794 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
2795 set_func, cast, defret);
2800 out_printf (out, "\n");
2803 s = g_strdup (m->id);
2806 out_printf(out, "\tg_signal_emitv (___param_values,\n"
2807 "\t\tobject_signals[%s_SIGNAL],\n"
2808 "\t\t0 /* detail */,\n"
2809 "\t\t&___return_val);\n", s);
2813 clear_signal_args (m);
2815 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2816 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2818 /* Hack because glib is very very braindead */
2820 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2821 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
2822 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
2823 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
2825 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
2826 /* hack because glib is braindamaged */
2827 getfunc = g_strdup ("g_value_get_uint");
2829 getfunc = g_strdup_printf ("g_value_%s_%s",
2830 do_dup ? "dup" : "get",
2831 (char *)m->gtktypes->data);
2832 gob_strdown (getfunc);
2835 cast = get_type (m->mtype, TRUE);
2840 print_type (out, m->mtype, TRUE);
2842 " ___ret = (%s) %s (&___return_val);\n"
2843 "\t\tg_value_unset (&___return_val);\n"
2844 "\t\treturn ___ret;\n"
2851 out_printf(out, "}\n");
2856 out_addline_infile(out, m->line_no);
2857 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2858 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2859 print_method_body(m, FALSE, TRUE);
2860 /* the outfile line was added above */
2862 case VIRTUAL_METHOD:
2864 out_addline_infile(out, m->line_no);
2865 if(m->scope==PRIVATE_SCOPE)
2866 print_method(out, "static ", "\n", "", " ", "", "\n",
2867 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2868 else /* PUBLIC, PROTECTED */
2869 print_method(out, "", "\n", "", " ", "", "\n",
2870 m, FALSE, FALSE, TRUE, FALSE, FALSE);
2871 out_addline_outfile(out);
2872 out_printf(out, "{\n"
2873 "\t%sClass *klass;\n", typebase);
2874 print_preconditions(m);
2875 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2876 "\tif(klass->%s)\n",
2877 macrobase, ((FuncArg *)m->args->data)->name,
2879 if(strcmp(m->mtype->name, "void") == 0 &&
2880 m->mtype->pointer == NULL) {
2882 out_printf(out, "\t\t(*klass->%s)(%s",
2884 ((FuncArg *)m->args->data)->name);
2885 for(li=m->args->next;li;li=g_list_next(li)) {
2886 FuncArg *fa = li->data;
2887 out_printf(out, ",%s", fa->name);
2889 out_printf(out, ");\n}\n");
2892 out_printf(out, "\t\treturn (*klass->%s)(%s",
2894 ((FuncArg *)m->args->data)->name);
2895 for(li=m->args->next;li;li=g_list_next(li)) {
2896 FuncArg *fa = li->data;
2897 out_printf(out, ",%s", fa->name);
2899 out_printf(out, ");\n"
2902 print_type(out, m->mtype, TRUE);
2904 out_printf(out, ")(%s);\n}\n", m->defreturn);
2906 out_printf(out, ")(%s);\n}\n", m->onerror);
2908 out_printf(out, ")(0);\n}\n");
2914 out_addline_infile(out, m->line_no);
2915 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2916 m, FALSE, FALSE, TRUE, TRUE, FALSE);
2917 print_method_body(m, FALSE, TRUE);
2918 /* the outfile line was added above */
2920 case OVERRIDE_METHOD:
2924 out_addline_infile(out, m->line_no);
2925 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2926 print_method(out, "static ", s, "", " ", "", "\n",
2927 m, FALSE, FALSE, FALSE, TRUE, FALSE);
2929 out_addline_outfile(out);
2930 s = replace_sep(m->otype, '_');
2932 args = get_arg_names_for_macro(m);
2934 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2935 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2936 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2937 args, s, m->id, s, m->id, args);
2939 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2940 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2941 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2943 args, s, m->id, s, m->id, args);
2944 out_printf(out, "(");
2945 print_type(out, m->mtype, TRUE);
2946 out_printf(out, ")%s))\n",
2947 m->onerror?m->onerror:"0");
2951 print_method_body(m, TRUE, TRUE);
2952 /* the outfile line was added above */
2953 out_printf(out, "#undef PARENT_HANDLER\n");
2963 char *outfile, *outfileh, *outfileph;
2966 outfile = g_strconcat (fullfilebase, ".c", NULL);
2968 outfile = g_strconcat (fullfilebase, ".cc", NULL);
2969 if (no_touch_headers)
2970 outfileh = g_strconcat (fullfilebase, ".h#gob#", NULL);
2972 outfileh = g_strconcat (fullfilebase, ".h", NULL);
2974 if ((privates > 0 || protecteds > 0 ||
2975 private_header == PRIVATE_HEADER_ALWAYS) &&
2976 private_header != PRIVATE_HEADER_NEVER)
2977 outfileph = g_strconcat (fullfilebase, "-private.h", NULL);
2983 devnull = fopen ("/dev/null", "w");
2984 if (devnull == NULL)
2985 error_print (GOB_ERROR, 0, "Cannot open null device");
2988 if (outfileph != NULL)
2991 out = fopen (outfile, "w");
2993 error_printf (GOB_ERROR, 0,
2994 "Cannot open outfile: %s", outfile);
2996 outh = fopen (outfileh, "w");
2998 error_printf (GOB_ERROR, 0,
2999 "Cannot open outfile: %s", outfileh);
3001 if (outfileph != NULL) {
3002 outph = fopen (outfileph, "w");
3003 if (outph == NULL) {
3004 error_printf (GOB_ERROR, 0,
3005 "Cannot open outfile: %s",
3013 put_argument_nongnu_wrappers (Class *c)
3017 if (get_properties < 0 && set_properties < 0)
3020 for (li = c->nodes; li != NULL; li = li->next) {
3022 const char *name, *gtktype;
3028 if (n->type == ARGUMENT_NODE) {
3029 Argument *a = (Argument *)n;
3031 gtktype = a->gtktype;
3033 get = a->get != NULL;
3034 set = a->set != NULL;
3035 } else if (n->type == PROPERTY_NODE) {
3036 Property *p = (Property *)n;
3038 gtktype = p->gtktype;
3040 get = p->get != NULL;
3041 set = p->set != NULL;
3046 aname = g_strdup (name);
3050 cast = get_type (atype, TRUE);
3052 cast = g_strdup (get_cast (gtktype, TRUE));
3056 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3057 "\"%s\",(%s)(arg)\n",
3058 macrobase, aname, name, cast);
3060 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3061 "\"%s\",(%s*)(arg)\n",
3062 macrobase, aname, name, cast);
3065 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3067 macrobase, aname, name);
3069 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3071 macrobase, aname, name);
3079 put_argument_gnu_wrappers(Class *c)
3083 if(get_properties < 0 && set_properties < 0)
3086 for (li = c->nodes; li != NULL; li = li->next) {
3088 const char *name, *gtktype;
3094 if (n->type == ARGUMENT_NODE) {
3095 Argument *a = (Argument *)n;
3097 gtktype = a->gtktype;
3099 get = a->get != NULL;
3100 set = a->set != NULL;
3101 } else if (n->type == PROPERTY_NODE) {
3102 Property *p = (Property *)n;
3104 gtktype = p->gtktype;
3106 get = p->get != NULL;
3107 set = p->set != NULL;
3112 aname = g_strdup (name);
3116 cast = get_type (atype, TRUE);
3118 cast = g_strdup (get_cast (gtktype, TRUE));
3122 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3123 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3124 macrobase, aname, name, cast);
3126 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3127 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3128 macrobase, aname, name, cast);
3131 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3133 macrobase, aname, name);
3135 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3137 macrobase, aname, name);
3145 print_ccode_block(CCode *cc)
3148 switch(cc->cctype) {
3150 /* HT code is printed exactly like normal header
3151 code but is printed before */
3154 out_printf(fp, "\n");
3157 /* AT code is printed exactly like normal 'all'
3158 code but is printed before */
3161 out_printf(outph, "\n");
3162 out_printf(outph, "%s\n", cc->cbuf);
3163 out_addline_infile(outph, cc->line_no);
3164 out_addline_outfile(outph);
3166 out_printf(outh, "\n");
3167 out_printf(outh, "%s\n", cc->cbuf);
3169 out_printf(fp, "\n");
3170 out_addline_infile(fp, cc->line_no);
3175 out_printf(fp, "\n");
3176 out_addline_infile(fp, cc->line_no);
3183 out_printf(fp, "\n");
3184 out_addline_infile(fp, cc->line_no);
3187 out_printf(fp, "%s\n", cc->cbuf);
3188 if(cc->cctype == C_CCODE ||
3189 cc->cctype == A_CCODE ||
3190 cc->cctype == AT_CCODE ||
3191 cc->cctype == PH_CCODE)
3192 out_addline_outfile(fp);
3196 print_class_block(Class *c)
3200 gboolean printed_private = FALSE;
3203 out_printf(out, "/* utility types we may need */\n");
3204 if(special_array[SPECIAL_2POINTER])
3205 out_printf(out, "typedef struct { "
3206 "gpointer a; gpointer b; "
3207 "} ___twopointertype;\n");
3208 if(special_array[SPECIAL_3POINTER])
3209 out_printf(out, "typedef struct { "
3210 "gpointer a; gpointer b; "
3212 "} ___threepointertype;\n");
3213 if(special_array[SPECIAL_INT_POINTER])
3214 out_printf(out, "typedef struct { "
3215 "gint a; gpointer b; "
3216 "} ___intpointertype;\n");
3217 out_printf(out, "\n");
3220 out_printf(outh, "\n/*\n"
3221 " * Type checking and casting macros\n"
3223 out_printf(outh, "#define %s\t"
3224 "(%s_get_type())\n",
3225 macrotype, funcbase);
3226 out_printf(outh, "#define %s(obj)\t"
3227 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3228 macrobase, funcbase, typebase);
3229 out_printf(outh, "#define %s_CONST(obj)\t"
3230 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3231 macrobase, funcbase, typebase);
3232 out_printf(outh, "#define %s_CLASS(klass)\t"
3233 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3234 macrobase, funcbase, typebase);
3235 out_printf(outh, "#define %s(obj)\t"
3236 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3239 "#define %s_GET_CLASS(obj)\t"
3240 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3241 macrobase, funcbase, typebase);
3243 if ( ! no_self_alias) {
3244 out_printf(out, "/* self casting macros */\n");
3245 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3246 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3247 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3248 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3249 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3251 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3254 out_printf(out, "/* self typedefs */\n");
3255 out_printf(out, "typedef %s Self;\n", typebase);
3256 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3260 always_private_struct) {
3261 out_printf (outh, "\n/* Private structure type */\n");
3262 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3263 typebase, typebase);
3265 out_printf (outh, "/* There are no privates, this "
3266 "structure is thus never defined */\n");
3269 out_printf (outh, "\n/*\n"
3270 " * Main object structure\n"
3272 s = replace_sep (c->otype, '_');
3274 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3275 "#define __TYPEDEF_%s__\n", s, s);
3277 out_printf (outh, "typedef struct _%s %s;\n"
3278 "#endif\n", typebase, typebase);
3279 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3280 typebase, ptypebase);
3281 for (li = c->nodes; li; li=li->next) {
3282 static gboolean printed_public = FALSE;
3284 Variable *v = (Variable *)n;
3285 if(n->type == VARIABLE_NODE &&
3286 v->scope == PUBLIC_SCOPE) {
3287 if( ! printed_public) {
3288 out_printf(outh, "\t/*< public >*/\n");
3289 printed_public = TRUE;
3291 put_variable((Variable *)n, outh);
3294 /* put protecteds always AFTER publics */
3295 for (li = c->nodes; li != NULL; li = li->next) {
3297 Variable *v = (Variable *)n;
3298 if (n->type == VARIABLE_NODE &&
3299 v->scope == PROTECTED_SCOPE) {
3300 if ( ! printed_private) {
3301 out_printf (outh, "\t/*< private >*/\n");
3302 printed_private = TRUE;
3304 put_variable ((Variable *)n, outh);
3308 always_private_struct) {
3309 if ( ! printed_private)
3310 out_printf (outh, "\t/*< private >*/\n");
3311 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3313 out_printf (outh, "};\n");
3318 /* if we are to stick this into the private
3319 header, if not stick it directly into the
3326 out_printf (outfp, "struct _%sPrivate {\n",
3328 for(li=c->nodes; li; li=li->next) {
3330 Variable *v = (Variable *)n;
3331 if(n->type == VARIABLE_NODE &&
3332 v->scope == PRIVATE_SCOPE) {
3333 out_addline_infile(outfp, v->line_no);
3334 put_variable(v, outfp);
3337 out_addline_outfile(outfp);
3338 out_printf(outfp, "};\n");
3341 out_printf(outh, "\n/*\n"
3342 " * Class definition\n"
3344 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3345 typebase, typebase);
3347 "struct _%sClass {\n\t%sClass __parent__;\n",
3348 typebase, ptypebase);
3349 for(li = c->nodes; li != NULL; li = li->next) {
3351 if(n->type == METHOD_NODE)
3352 put_vs_method((Method *)n);
3354 /* If BonoboX type class put down the epv */
3355 if (c->bonobo_object_class != NULL) {
3357 "\t/* Bonobo object epv */\n"
3358 "\tPOA_%s__epv _epv;\n",
3359 c->bonobo_object_class);
3361 /* put class scope variables */
3362 for (li = c->nodes; li != NULL; li = li->next) {
3364 Variable *v = (Variable *)n;
3365 if (n->type == VARIABLE_NODE &&
3366 v->scope == CLASS_SCOPE)
3367 put_variable ((Variable *)n, outh);
3369 out_printf (outh, "};\n\n");
3371 out_printf (out, "/* here are local prototypes */\n");
3372 if (set_properties > 0) {
3373 out_printf (out, "static void ___object_set_property "
3374 "(GObject *object, guint property_id, "
3375 "const GValue *value, GParamSpec *pspec);\n");
3377 if (get_properties > 0) {
3378 out_printf (out, "static void ___object_get_property "
3379 "(GObject *object, guint property_id, "
3380 "GValue *value, GParamSpec *pspec);\n");
3383 out_printf (outh, "\n/*\n"
3384 " * Public methods\n"
3387 if ( ! overrode_get_type) {
3388 out_printf (outh, "GType\t%s_get_type\t(void);\n", funcbase);
3391 for(li = c->nodes; li != NULL; li = li->next) {
3393 if(n->type == METHOD_NODE) {
3394 put_pub_method((Method *)n);
3395 put_prot_method((Method *)n);
3396 put_priv_method_prot((Method *)n);
3400 /* this idea is less and less apealing to me */
3402 out_printf (outh, "\n/*\n"
3403 " * Signal connection wrapper macros\n"
3406 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3407 put_signal_macros (c, TRUE);
3408 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3409 put_signal_macros (c, FALSE);
3410 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3412 put_signal_macros (c, FALSE);
3413 out_printf(outh, "\n");
3416 out_printf (out, "\n/*\n"
3417 " * Signal connection wrapper macro shortcuts\n"
3419 put_local_signal_macros (c);
3420 out_printf(outh, "\n");
3423 /* argument wrapping macros */
3424 if(get_properties > 0 || set_properties > 0) {
3425 out_printf(outh, "\n/*\n"
3426 " * Argument wrapping macros\n"
3429 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3430 put_argument_gnu_wrappers(c);
3431 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3432 put_argument_nongnu_wrappers(c);
3433 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3435 put_argument_nongnu_wrappers(c);
3440 for(li = c->nodes; li != NULL; li = li->next) {
3442 if(n->type == METHOD_NODE)
3443 add_signal_prots((Method *)n);
3449 if(any_method_to_alias(c)) {
3450 out_printf (out, "/* Short form macros */\n");
3451 make_method_aliases (c);
3454 add_interface_inits (c);
3456 if ( ! overrode_get_type) {
3457 if (c->bonobo_object_class != NULL)
3458 add_bonobo_object_get_type ();
3463 out_printf (out, "/* a macro for creating a new object of our type */\n");
3465 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3466 typebase, funcbase);
3468 out_printf (out, "/* a function for creating a new object of our type */\n");
3469 out_printf (out, "#include <stdarg.h>\n");
3471 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3472 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3473 "{\n\t%s *ret;\n\tva_list ap;\n"
3474 "\tva_start (ap, first);\n"
3475 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3478 "\treturn ret;\n}\n\n",
3480 no_gnu ? "" : " G_GNUC_UNUSED",
3481 typebase, typebase, typebase, funcbase);
3491 if(set_properties > 0) {
3492 add_getset_arg(c, TRUE);
3495 if(get_properties > 0) {
3496 add_getset_arg(c, FALSE);
3499 for(li = c->nodes; li != NULL; li = li->next) {
3501 if(n->type == METHOD_NODE)
3502 put_method((Method *)n);
3505 add_bad_hack_to_avoid_unused_warnings(c);
3509 print_useful_macros(void)
3511 int major = 0, minor = 0, pl = 0;
3514 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3515 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3516 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3517 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3519 /* Useful priv macro thingie */
3520 /* FIXME: this should be done the same way that priv is, as a var,
3522 out_printf (out, "#define selfp (self->_priv)\n\n");
3526 print_more_useful_macros (void)
3529 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3530 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3532 out_printf (out, "#ifdef G_LIKELY\n");
3533 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3534 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3535 out_printf (out, "#else /* ! G_LIKELY */\n");
3536 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3537 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3538 out_printf (out, "#endif /* G_LIKELY */\n");
3543 print_file_comments(void)
3547 out_printf(outh, "/* Generated by GOB (v%s)"
3548 " (do not edit directly) */\n\n", VERSION);
3550 out_printf(outph, "/* Generated by GOB (v%s)"
3551 " (do not edit directly) */\n\n", VERSION);
3552 out_printf(out, "/* Generated by GOB (v%s) on %s"
3553 " (do not edit directly) */\n\n",
3554 VERSION, ctime(&curtime));
3556 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3560 print_includes(void)
3562 gboolean found_header;
3565 /* We may need string.h for memset */
3566 if(destructors > 0 &&
3567 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3568 out_printf(out, "#include <string.h> /* memset() */\n\n");
3571 p = g_strconcat(filebase, ".h", NULL);
3572 found_header = TRUE;
3573 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3574 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3575 found_header = FALSE;
3579 /* if we are creating a private header see if it was included */
3581 p = g_strconcat(filebase, "-private.h", NULL);
3582 if( ! g_list_find_custom(include_files, p,
3583 (GCompareFunc)strcmp)) {
3584 out_printf(out, "#include \"%s-private.h\"\n\n",
3587 error_printf(GOB_WARN, 0,
3588 "Implicit private header include "
3590 "\tsource file, while public "
3591 "header is at a custom location, "
3593 "\texplicitly include "
3594 "the private header below the "
3602 print_header_prefixes(void)
3606 p = replace_sep(((Class *)class)->otype, '_');
3608 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3610 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3611 "#define __%s_PRIVATE_H__\n\n"
3612 "#include \"%s.h\"\n\n", p, p, filebase);
3615 if( ! no_extern_c) {
3616 out_printf(outh, "#ifdef __cplusplus\n"
3618 "#endif /* __cplusplus */\n\n");
3620 out_printf(outph, "#ifdef __cplusplus\n"
3622 "#endif /* __cplusplus */\n\n");
3627 print_header_postfixes(void)
3630 out_printf(outh, "\n#ifdef __cplusplus\n"
3632 "#endif /* __cplusplus */\n");
3633 out_printf(outh, "\n#endif\n");
3636 out_printf(outph, "\n#ifdef __cplusplus\n"
3638 "#endif /* __cplusplus */\n");
3639 out_printf(outph, "\n#endif\n");
3648 /* print the AT_CCODE blocks */
3649 for(li = nodes; li != NULL; li = li->next) {
3650 Node *node = li->data;
3651 if(node->type == CCODE_NODE) {
3652 CCode *cc = (CCode *)node;
3653 if(cc->cctype == AT_CCODE)
3654 print_ccode_block((CCode *)node);
3660 print_header_top(void)
3664 /* mandatory includes */
3665 out_printf (outh, "#include <glib.h>\n");
3666 out_printf (outh, "#include <glib-object.h>\n");
3668 /* print the HT_CCODE blocks */
3669 for (li = nodes; li != NULL; li = li->next) {
3670 Node *node = li->data;
3671 if (node->type == CCODE_NODE) {
3672 CCode *cc = (CCode *)node;
3673 if (cc->cctype == HT_CCODE)
3674 print_ccode_block ((CCode *)node);
3680 print_enum (EnumDef *enode)
3687 funcprefix = replace_sep (enode->etype, '_');
3688 gob_strdown (funcprefix);
3689 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3691 type = remove_sep (enode->etype);
3693 out_printf (outh, "\ntypedef enum {\n");
3695 for (li = enode->values; li != NULL; li = li->next) {
3696 EnumValue *value = li->data;
3698 char *sname = gob_strdown (g_strdup (value->name));
3700 while ((p = strchr (sname, '_')) != NULL)
3703 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3704 if (value->value != NULL)
3705 out_printf (outh, " = %s", value->value);
3706 if (li->next != NULL)
3707 out_printf (outh, ",\n");
3709 out_printf (outh, "\n");
3711 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3712 enode->prefix, value->name,
3713 enode->prefix, value->name,
3719 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3721 out_printf (outh, "} %s;\n", type);
3723 str = make_pre_macro (enode->etype, "TYPE");
3724 out_printf (outh, "#define %s ", str);
3727 out_printf (outh, "%s_get_type()\n", funcprefix);
3728 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3731 "GType\n%s_get_type (void)\n"
3733 "\tstatic GType type = 0;\n"
3734 "\tif ___GOB_UNLIKELY(type == 0)\n"
3735 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3738 funcprefix, type, funcprefix);
3740 g_free (funcprefix);
3745 print_flags (Flags *fnode)
3753 funcprefix = replace_sep (fnode->ftype, '_');
3754 gob_strdown (funcprefix);
3755 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
3757 type = remove_sep (fnode->ftype);
3759 out_printf (outh, "\ntypedef enum {\n");
3761 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
3762 const char *name = li->data;
3764 char *sname = gob_strdown (g_strdup (name));
3766 while ((p = strchr (sname, '_')) != NULL)
3769 out_printf (outh, "\t%s_%s = 1<<%d",
3770 fnode->prefix, name, i);
3771 if (li->next != NULL)
3772 out_printf (outh, ",\n");
3774 out_printf (outh, "\n");
3776 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3777 fnode->prefix, name,
3778 fnode->prefix, name,
3784 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3786 out_printf (outh, "} %s;\n", type);
3788 str = make_pre_macro (fnode->ftype, "TYPE");
3789 out_printf (outh, "#define %s ", str);
3792 out_printf (outh, "%s_get_type()\n", funcprefix);
3793 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3796 "GType\n%s_get_type (void)\n"
3798 "\tstatic GType type = 0;\n"
3799 "\tif ___GOB_UNLIKELY(type == 0)\n"
3800 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
3803 funcprefix, type, funcprefix);
3805 g_free (funcprefix);
3810 print_error (Error *enode)
3817 funcprefix = replace_sep (enode->etype, '_');
3818 gob_strdown (funcprefix);
3819 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3821 type = remove_sep (enode->etype);
3823 out_printf (outh, "\ntypedef enum {\n");
3825 for (li = enode->values; li != NULL; li = li->next) {
3826 const char *name = li->data;
3828 char *sname = gob_strdown (g_strdup (name));
3830 while ((p = strchr (sname, '_')) != NULL)
3833 out_printf (outh, "\t%s_%s", enode->prefix, name);
3834 if (li->next != NULL)
3835 out_printf (outh, ",\n");
3837 out_printf (outh, "\n");
3839 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3840 enode->prefix, name,
3841 enode->prefix, name,
3847 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
3849 out_printf (outh, "} %s;\n", type);
3851 str = make_pre_macro (enode->etype, "TYPE");
3852 out_printf (outh, "#define %s ", str);
3855 out_printf (outh, "%s_get_type ()\n", funcprefix);
3856 out_printf (outh, "GType %s_get_type (void);\n\n", funcprefix);
3859 "GType\n%s_get_type (void)\n"
3861 "\tstatic GType type = 0;\n"
3862 "\tif ___GOB_UNLIKELY(type == 0)\n"
3863 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
3866 funcprefix, type, funcprefix);
3868 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
3869 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
3871 str = replace_sep (enode->etype, '-');
3875 "GQuark\n%s_quark (void)\n"
3877 "\tstatic GQuark q = 0;\n"
3879 "\t\tq = g_quark_from_static_string (\"%s\");\n"
3886 g_free (funcprefix);
3891 generate_outfiles(void)
3895 print_file_comments();
3901 print_header_prefixes();
3903 print_useful_macros();
3907 print_more_useful_macros ();
3909 for (li = nodes; li != NULL; li = li->next) {
3910 Node *node = li->data;
3911 if (node->type == CCODE_NODE) {
3912 CCode *cc = (CCode *)node;
3913 if (cc->cctype != HT_CCODE &&
3914 cc->cctype != AT_CCODE)
3915 print_ccode_block ((CCode *)node);
3916 } else if (node->type == CLASS_NODE) {
3917 print_class_block ((Class *)node);
3918 } else if (node->type == ENUMDEF_NODE) {
3919 print_enum ((EnumDef *)node);
3920 } else if (node->type == FLAGS_NODE) {
3921 print_flags ((Flags *)node);
3922 } else if (node->type == ERROR_NODE) {
3923 print_error ((Error *)node);
3925 g_assert_not_reached();
3929 print_header_postfixes();
3935 fprintf(stderr, "Gob version %s\n\n", VERSION);
3936 fprintf(stderr, "gob [options] file.gob\n\n");
3937 fprintf(stderr, "Options:\n"
3938 "\t--help,-h,-? Display this help\n"
3939 "\t--version Display version\n"
3940 "\t--exit-on-warn,-w Exit with an error on warnings\n"
3941 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
3942 "\t--for-cpp Create C++ files\n"
3943 "\t--no-extern-c Never print extern \"C\" into the "
3945 "\t--no-gnu Never use GNU extentions\n"
3946 "\t--no-touch-headers Don't touch headers unless they "
3948 "\t--always-private-header Always create a private header "
3950 "\t even if it would be empty\n"
3951 "\t--ondemand-private-header Create private header only when "
3954 "\t--no-private-header Don't create a private header, "
3956 "\t structure and protected "
3957 "prototypes inside c file\n"
3958 "\t--always-private-struct Always create a private pointer "
3960 "\t the object structure\n"
3961 "\t--m4 Preprocess source with m4. "
3962 "Following args will\n"
3963 "\t be passed to m4\n"
3964 "\t--m4-dir Print directory that will be "
3967 "\t--no-write,-n Don't write output files, just "
3969 "\t--no-lines Don't print '#line' to output\n"
3970 "\t--no-self-alias Don't create self type and macro "
3972 "\t--no-kill-underscores Ignored for compatibility\n"
3973 "\t-o,--output-dir The directory where output "
3974 "should be placed\n");
3978 parse_options(int argc, char *argv[])
3981 int got_file = FALSE;
3982 int no_opts = FALSE;
3983 int m4_opts = FALSE; /* if we are just passing on args to m4 */
3987 for(i = 1 ; i < argc; i++) {
3989 char *new_commandline;
3990 g_assert(m4_commandline!=NULL);
3992 /* check whether this one looks like the filename */
3993 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
3995 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
3999 /* insert flags before the filename */
4000 new_commandline=g_strconcat(m4_commandline,
4008 /* just an ordinary option */
4010 new_commandline=g_strconcat(m4_commandline,
4015 /* free old commandline */
4016 g_free(m4_commandline);
4017 m4_commandline=new_commandline;
4019 } else if(no_opts ||
4020 argv[i][0] != '-') {
4023 fprintf(stderr, "Specify only one file!\n");
4029 } else if(strcmp(argv[i], "--help")==0) {
4032 } else if(strcmp(argv[i], "--version")==0) {
4033 fprintf(stderr, "Gob version %s\n", VERSION);
4035 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4036 exit_on_warn = TRUE;
4037 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4038 exit_on_warn = FALSE;
4039 } else if(strcmp(argv[i], "--for-cpp")==0) {
4041 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4042 no_touch_headers = TRUE;
4043 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4044 private_header = PRIVATE_HEADER_ONDEMAND;
4045 } else if(strcmp(argv[i], "--always-private-header")==0) {
4046 private_header = PRIVATE_HEADER_ALWAYS;
4047 } else if(strcmp(argv[i], "--no-private-header")==0) {
4048 private_header = PRIVATE_HEADER_NEVER;
4049 } else if(strcmp(argv[i], "--no-gnu")==0) {
4051 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4053 } else if(strcmp(argv[i], "--no-write")==0) {
4055 } else if(strcmp(argv[i], "--no-lines")==0) {
4057 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4058 no_self_alias = TRUE;
4059 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4061 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4062 always_private_struct = TRUE;
4063 } else if(strcmp(argv[i], "--m4-dir")==0) {
4064 printf("%s\n",M4_INCLUDE_DIR);
4066 } else if(strcmp(argv[i], "--m4")==0) {
4070 m4_commandline=g_strdup(M4_COMMANDLINE);
4071 } else if(strcmp(argv[i], "--m4-clean")==0) {
4075 m4_commandline=g_strdup(M4_COMMANDLINE);
4076 } else if (strcmp (argv[i], "-o") == 0 ||
4077 strcmp (argv[i], "--output-dir") == 0) {
4079 output_dir = g_strdup (argv[i+1]);
4084 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4087 strlen ("--output-dir=")) == 0) {
4088 char *p = strchr (argv[i], '=');
4089 g_assert (p != NULL);
4090 output_dir = g_strdup (p+1);
4091 } else if(strcmp(argv[i], "--")==0) {
4092 /*further arguments are files*/
4094 } else if(strncmp(argv[i], "--", 2)==0) {
4095 /*unknown long option*/
4096 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4100 /*by now we know we have a string starting with
4101 - which is a short option string*/
4103 for(p = argv[i] + 1; *p; p++) {
4117 "Unknown option '%c'!\n", *p);
4126 /* if we are using m4, and got no filename, append m4 flags now */
4127 if(!got_file && use_m4 && !use_m4_clean) {
4128 char *new_commandline;
4129 new_commandline=g_strconcat(m4_commandline,
4133 g_free(m4_commandline);
4134 m4_commandline=new_commandline;
4139 /* this is a somewhat ugly hack, but it appears to work */
4141 compare_and_move_header(void)
4143 char *hfnew = g_strconcat(fullfilebase, ".h#gob#", NULL);
4144 char *hf = g_strconcat(fullfilebase, ".h", NULL);
4146 if(stat(hf, &s) == 0) {
4148 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
4149 if(system(s) == 0) {
4150 if(unlink(hfnew) != 0)
4151 error_printf(GOB_ERROR, 0,
4152 "Can't remove new header file");
4160 error_printf(GOB_ERROR, 0,
4161 "Can't remove old header file");
4163 if(rename(hfnew, hf) != 0)
4164 error_printf(GOB_ERROR, 0,
4165 "Can't rename new header file");
4171 main(int argc, char *argv[])
4173 parse_options(argc, argv);
4176 yyin = popen(m4_commandline, "r");
4178 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4182 } else if(filename) {
4183 yyin = fopen(filename, "r");
4185 fprintf(stderr, "Error: can't open file '%s'\n",
4194 /* This is where parsing is done */
4197 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4199 /* close input file */
4200 if(use_m4) pclose(yyin);
4205 error_print (GOB_ERROR, 0, "no class defined");
4208 exit_on_error = FALSE;
4210 signals = count_signals ((Class *)class);
4211 set_properties = count_set_properties ((Class *)class) +
4212 count_set_arguments ((Class *)class);
4213 get_properties = count_get_properties ((Class *)class) +
4214 count_get_arguments ((Class *)class);
4215 overrides = count_overrides ((Class *)class);
4216 privates = count_privates ((Class *)class);
4217 protecteds = count_protecteds ((Class *)class);
4218 unreftors = count_unreftors ((Class *)class);
4219 destructors = count_destructors ((Class *)class);
4220 initializers = count_initializers ((Class *)class);
4221 overrode_get_type = find_get_type ((Class *)class);
4224 make_inits ((Class *)class);
4226 need_dispose = TRUE;
4227 find_dispose ((Class *)class);
4229 if (destructors > 0 ||
4231 need_finalize = TRUE;
4232 find_finalize ((Class *)class);
4234 check_bad_symbols ((Class *)class);
4235 check_duplicate_symbols ((Class *)class);
4236 check_duplicate_overrides ((Class *)class);
4237 check_duplicate_signals_args ((Class *)class);
4238 check_public_new ((Class *)class);
4239 check_vararg ((Class *)class);
4240 check_firstarg ((Class *)class);
4241 check_nonvoidempty ((Class *)class);
4242 check_signal_args ((Class *)class);
4243 check_property_types ((Class *)class);
4244 check_argument_types ((Class *)class);
4245 check_func_arg_checks ((Class *)class);
4246 check_for_class_destructors ((Class *)class);
4248 exit_on_error = TRUE;
4253 any_special = setup_special_array ((Class *)class, special_array);
4257 generate_outfiles ();
4268 if (no_touch_headers &&
4270 compare_and_move_header ();