2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2011 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,
34 #include "treefuncs.h"
42 char *filename = NULL;
52 extern GList *include_files;
54 extern GHashTable *gtk_doc_hash;
58 static char *outfilebase;
59 static char *outfilehbase;
60 static char *outfilephbase;
61 static char *funcbase;
62 static char *pfuncbase;
63 static char *macrobase;
65 static char *pmacrois;
66 static char *macrotype;
67 static char *pmacrotype;
68 static char *typebase;
69 static char *ptypebase;
71 char *output_dir = NULL;
75 static int signals = 0; /* number of signals */
76 static int set_properties = 0; /* number of named (set) properties */
77 static int get_properties = 0; /* number of named (get) properties */
78 static int overrides = 0; /* number of override methods */
79 static int privates = 0; /* number of private data members */
80 static int protecteds = 0; /* number of protected methods */
81 static int unreftors = 0; /* number of variable unreffing destructors */
82 static int destructors = 0; /* number of variable non-unreffing destructors */
83 static int initializers = 0; /* number of variable initializers */
84 static int glade_widgets = 0; /* number of glade widgets */
85 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
87 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
88 and need the REALLY UGLY HACK to
91 /* the special variable types we need to define */
92 static gboolean special_array[SPECIAL_LAST] = {0};
93 static gboolean any_special = FALSE;
95 static gboolean need_constructor = FALSE;
96 static Method * user_constructor = NULL;
98 static gboolean need_dispose = FALSE;
99 static Method * dispose_handler = NULL;
100 static Method * user_dispose_method = NULL;
102 static gboolean need_finalize = FALSE;
103 static Method * finalize_handler = NULL;
104 static Method * user_finalize_method = NULL;
110 gboolean no_touch = FALSE;
111 gboolean no_touch_headers = FALSE;
112 gboolean for_cpp = FALSE;
113 gboolean no_gnu = FALSE;
114 gboolean exit_on_warn = FALSE;
115 gboolean exit_on_error = TRUE;
116 gboolean got_error = FALSE;
117 gint private_header = PRIVATE_HEADER_ONDEMAND;
118 gboolean no_extern_c = FALSE;
119 gboolean no_write = FALSE;
120 gboolean no_lines = FALSE;
121 gboolean no_self_alias = FALSE;
122 gboolean always_private_struct = FALSE;
123 gboolean gtk3_ok = FALSE;
129 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
130 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
131 char *m4_commandline = NULL;
132 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
133 #define M4_BASE_FILENAME "gobm4.m4"
134 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
135 #define M4_COMMANDLINE "m4"
137 int method_unique_id = 1;
142 filebase = replace_sep (((Class *)class)->otype, file_sep);
143 gob_strdown (filebase);
145 if (output_dir != NULL &&
146 output_dir[0] != '\0') {
147 fullfilebase = g_build_filename (output_dir, filebase, NULL);
149 fullfilebase = g_strdup (filebase);
152 funcbase = replace_sep (((Class *)class)->otype, '_');
153 gob_strdown (funcbase);
155 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
156 gob_strdown (pfuncbase);
158 macrobase = replace_sep (((Class *)class)->otype, '_');
159 gob_strup (macrobase);
161 macrois = make_pre_macro (((Class *)class)->otype, "IS");
162 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
164 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
165 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
167 typebase = remove_sep (((Class *)class)->otype);
169 ptypebase = remove_sep (((Class *)class)->ptype);
173 get_gtk_doc (const char *id)
180 val = g_hash_table_lookup(gtk_doc_hash, id);
182 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
184 val = g_hash_table_lookup(gtk_doc_hash, id);
186 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
192 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
196 s = get_type(t, postfix_to_stars);
197 out_printf(fp, "%s", s);
203 print_method (FILE *fp,
204 const char *typeprefix,
205 const char *nameprefix,
206 const char *subnameprefix,
207 const char *namepostfix,
208 const char *afterargs,
211 gboolean print_funcattrs,
212 gboolean one_arg_per_line,
213 gboolean no_funcbase,
214 gboolean kill_underscore,
215 gboolean first_unused,
221 out_printf(fp, "%s", typeprefix);
222 print_type(fp, m->mtype, TRUE);
227 out_printf(fp, "%s%s%s%s(",
228 nameprefix, subnameprefix, id, namepostfix);
230 out_printf(fp, "%s%s_%s%s%s(",
231 nameprefix, funcbase, subnameprefix, id,
235 for(li=m->args; li; li=g_list_next(li)) {
236 FuncArg *arg = li->data;
237 const char *unused = "";
240 ! for_cpp && /* g++ has a cow with this */
243 unused = " G_GNUC_UNUSED";
246 print_type(fp, arg->atype, FALSE);
248 out_printf (fp, "___fake___");
250 out_printf(fp, "%s%s%s,%s", arg->name,
251 arg->atype->postfix ?
252 arg->atype->postfix : "",
254 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
256 out_printf(fp, "%s%s%s", arg->name,
257 arg->atype->postfix ?
258 arg->atype->postfix : "",
262 out_printf(fp, ",%s...",
263 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
265 out_printf(fp, "void");
267 /* Slightly icky: sometimes we are called st m->funcattrs
268 hasn't been set, but if so it should be NULL since its been
270 if(print_funcattrs && m->funcattrs != NULL
271 && strlen(m->funcattrs) > 0) {
272 /* To keep the output neat, we trim off the trailing '\n'
273 from the end of funcattrs for a moment. */
274 size_t funcattrs_len = strlen(m->funcattrs);
275 gboolean funcattrs_chomped = FALSE;
276 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
277 m->funcattrs[funcattrs_len - 1] = '\0';
278 funcattrs_chomped = TRUE;
280 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
281 /* Put it back like it was (though it shouldn't matter). */
282 if (funcattrs_chomped) {
283 (m->funcattrs)[funcattrs_len - 1] = '\n';
287 out_printf(fp, "%s)%s", afterargs, postfix);
292 any_method_to_alias(Class *c)
296 for(li=c->nodes;li;li=g_list_next(li)) {
297 Node *node = li->data;
298 if(node->type == METHOD_NODE) {
299 Method *m = (Method *)node;
301 if(m->method == INIT_METHOD ||
302 m->method == CLASS_INIT_METHOD ||
303 m->method == CONSTRUCTOR_METHOD ||
304 m->method == DISPOSE_METHOD ||
305 m->method == FINALIZE_METHOD ||
306 m->method == OVERRIDE_METHOD)
317 make_method_aliases (Class *c)
321 for(li = c->nodes; li != NULL; li = li->next) {
322 Node *node = li->data;
323 if(node->type == METHOD_NODE) {
324 Method *m = (Method *)node;
326 if(m->method == INIT_METHOD ||
327 m->method == CLASS_INIT_METHOD ||
328 m->method == CONSTRUCTOR_METHOD ||
329 m->method == DISPOSE_METHOD ||
330 m->method == FINALIZE_METHOD ||
331 m->method == OVERRIDE_METHOD)
334 out_printf (out, "#define self_%s %s_%s\n",
343 add_bad_hack_to_avoid_unused_warnings(const Class *c)
347 /* if we haven't had any methods, just return */
352 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
354 "/*REALLY BAD HACK\n"
355 " This is to avoid unused warnings if you don't call\n"
356 " some method. I need to find a better way to do\n"
357 " this, not needed in GCC since we use some gcc\n"
358 " extentions to make saner, faster code */\n"
360 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
362 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
363 for(li=c->nodes;li;li=g_list_next(li)) {
364 Node *node = li->data;
365 if(node->type == METHOD_NODE) {
366 Method *m = (Method *)node;
368 if(m->method == INIT_METHOD ||
369 m->method == CLASS_INIT_METHOD ||
370 m->method == CONSTRUCTOR_METHOD ||
371 m->method == DISPOSE_METHOD ||
372 m->method == FINALIZE_METHOD ||
373 m->method == OVERRIDE_METHOD)
376 /* in C++ mode we don't alias new */
377 if(for_cpp && strcmp(m->id, "new")==0)
380 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
383 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
386 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
388 out_printf(out, "}\n\n");
392 put_variable(const Variable *v, FILE *fp)
394 out_printf(fp, "\t");
395 print_type(fp, v->vtype, FALSE);
396 out_printf(fp, "%s%s;", v->id,
398 v->vtype->postfix:"");
399 if(v->scope == PROTECTED_SCOPE)
400 out_printf(fp, " /* protected */");
401 out_printf(fp, "\n");
405 put_vs_method(const Method *m)
407 if(m->method != SIGNAL_LAST_METHOD &&
408 m->method != SIGNAL_FIRST_METHOD &&
409 m->method != VIRTUAL_METHOD)
412 /* if a signal mark it as such */
413 if(m->method != VIRTUAL_METHOD)
414 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
415 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
417 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
418 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
423 put_pub_method(const Method *m)
425 if(m->scope != PUBLIC_SCOPE)
428 out_addline_infile(outh, m->line_no);
429 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
430 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
431 out_addline_outfile(outh);
435 put_signal_macro (const Method *m, gboolean gnu)
437 if(m->method != SIGNAL_LAST_METHOD &&
438 m->method != SIGNAL_FIRST_METHOD)
443 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
444 "g_signal_connect(%s(object),\"%s\","
445 "(GCallback)(func),(data))\n",
446 funcbase, m->id, macrobase, m->id);
449 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
450 "g_signal_connect_after(%s(object),\"%s\","
451 "(GCallback)(func),(data))\n",
452 funcbase, m->id, macrobase, m->id);
455 out_printf (outh, "#define %s_connect_data__%s"
456 "(object,func,data,destroy_data,flags)\t"
457 "g_signal_connect_data(%s(object),\"%s\","
458 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
459 funcbase, m->id, macrobase, m->id);
462 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
464 "%s(__extension__ ({%s *___object = (object); ___object; })),"
466 "(GCallback) __extension__ ({",
467 funcbase, m->id, macrobase, typebase, m->id);
468 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
469 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
470 out_printf (outh, "___%s; }), (data))\n", m->id);
473 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
474 "g_signal_connect_after("
475 "%s(__extension__ ({%s *___object = (object); ___object; })),"
477 "(GCallback) __extension__ ({",
478 funcbase, m->id, macrobase, typebase, m->id);
479 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
480 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
481 out_printf (outh, "___%s; }), (data))\n", m->id);
484 out_printf (outh, "#define %s_connect_data__%s"
485 "(object,func,data,destroy_data,flags)\t"
486 "g_signal_connect_data("
487 "%s(__extension__ ({%s *___object = (object); ___object; })),"
489 "(GCallback) __extension__ ({",
490 funcbase, m->id, macrobase, typebase, m->id);
491 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
492 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
493 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
498 put_signal_macros (const Class *c, gboolean gnu)
505 for (li = c->nodes; li != NULL; li = li->next) {
506 const Node *n = li->data;
507 if (n->type == METHOD_NODE)
508 put_signal_macro ((Method *)n, gnu);
513 put_local_signal_macro (const Method *m)
515 if(m->method != SIGNAL_LAST_METHOD &&
516 m->method != SIGNAL_FIRST_METHOD)
520 out_printf (out, "#define self_connect__%s(object,func,data)\t"
521 "%s_connect__%s((object),(func),(data))\n",
522 m->id, funcbase, m->id);
525 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
526 "%s_connect_after__%s((object),(func),(data))\n",
527 m->id, funcbase, m->id);
530 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
531 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
532 m->id, funcbase, m->id);
536 put_local_signal_macros (const Class *c)
543 for (li = c->nodes; li != NULL; li = li->next) {
544 const Node *n = li->data;
545 if (n->type == METHOD_NODE)
546 put_local_signal_macro ((Method *)n);
552 put_prot_method(const Method *m)
556 if(m->scope != PROTECTED_SCOPE)
559 f = outph ? outph : out;
561 out_addline_infile(f, m->line_no);
562 print_method(f, "", "\t", "", "\t", "", ";\n",
563 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
564 out_addline_outfile(f);
568 put_priv_method_prot(const Method *m)
570 if(m->method == SIGNAL_LAST_METHOD ||
571 m->method == SIGNAL_FIRST_METHOD ||
572 m->method == VIRTUAL_METHOD) {
575 "static ", "___real_", "", " ", "", ";\n",
576 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
578 /* no else, here, it might still have a private prototype, it's not
581 if((m->method == OVERRIDE_METHOD &&
584 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
586 out_addline_infile(out, m->line_no);
587 print_method(out, "static ", s, "", " ", "",
588 no_gnu?";\n":" G_GNUC_UNUSED;\n",
589 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
591 out_addline_outfile(out);
593 } else if(m->scope == PRIVATE_SCOPE ||
594 m->method == INIT_METHOD ||
595 m->method == CLASS_INIT_METHOD ||
596 m->method == CONSTRUCTOR_METHOD ||
597 m->method == DISPOSE_METHOD ||
598 m->method == FINALIZE_METHOD) {
600 out_addline_infile(out, m->line_no);
601 print_method(out, "static ", "", "", " ", "",
602 no_gnu?";\n":" G_GNUC_UNUSED;\n",
603 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
605 out_addline_outfile(out);
610 make_func_arg (const char *typename, gboolean is_class, const char *name)
617 tn = g_strconcat (typename, ":Class", NULL);
619 tn = g_strdup (typename);
621 type = node_new (TYPE_NODE,
625 node = node_new (FUNCARG_NODE,
626 "atype:steal", (Type *)type,
629 return g_list_prepend (NULL, node);
633 make_inits(Class *cl)
635 int got_class_init = FALSE;
636 int got_init = FALSE;
639 for(li=cl->nodes;li;li=g_list_next(li)) {
641 if(n->type == METHOD_NODE) {
642 Method *m = (Method *)n;
643 if(m->method == INIT_METHOD) {
645 error_print(GOB_ERROR, m->line_no, "init defined more then once");
647 } else if(m->method == CLASS_INIT_METHOD) {
649 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
650 got_class_init = TRUE;
654 if(!got_class_init) {
655 Type *type = (Type *)node_new (TYPE_NODE,
658 node = node_new (METHOD_NODE,
660 "method", CLASS_INIT_METHOD,
663 "args:steal", make_func_arg (cl->otype,
666 "unique_id", method_unique_id++,
668 cl->nodes = g_list_prepend(cl->nodes, node);
671 Type *type = (Type *)node_new (TYPE_NODE,
674 node = node_new (METHOD_NODE,
676 "method", INIT_METHOD,
679 "args:steal", make_func_arg (cl->otype,
680 FALSE /* is_class */,
682 "unique_id", method_unique_id++,
684 cl->nodes = g_list_prepend(cl->nodes, node);
689 find_method(const Class *cl, int method, const char *id)
693 for(li=cl->nodes;li;li=g_list_next(li)) {
695 if(n->type == METHOD_NODE) {
696 Method *m = (Method *)n;
697 if (m->method == method
698 && (id == NULL || strcmp(m->id, id)==0))
707 find_constructor(const Class *cl)
709 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
713 find_dispose(const Class *cl)
715 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
716 if (dispose_handler != NULL) {
717 if(strcmp(dispose_handler->otype, "G:Object") != 0)
718 error_print(GOB_ERROR, dispose_handler->line_no,
719 "dispose method override "
720 "of class other then "
722 if(g_list_length(dispose_handler->args) != 1)
723 error_print(GOB_ERROR, dispose_handler->line_no,
724 "dispose method override "
725 "with more then one "
729 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
733 find_finalize(const Class *cl)
735 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
736 if (finalize_handler != NULL) {
737 if(strcmp(finalize_handler->otype, "G:Object") != 0)
738 error_print(GOB_ERROR, finalize_handler->line_no,
739 "finalize method override "
740 "of class other then "
742 if(g_list_length(finalize_handler->args) != 1)
743 error_print(GOB_ERROR, finalize_handler->line_no,
744 "finalize method override "
745 "with more then one "
749 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
753 /* hash of method -> name of signal prototype */
754 static GHashTable *marsh = NULL;
756 /* list of methods with different signal prototypes,
757 we check this list if we can use a signal prototype of a
758 previous signal method, there are only uniques here */
759 static GList *eq_signal_methods = NULL;
761 /* compare a list of strings */
763 is_list_equal(const GList *a, const GList *b)
765 for(;a && b; a=a->next, b=b->next) {
766 if(strcmp(a->data, b->data)!=0) {
770 /* the the lists were different length */
777 find_same_type_signal(const Method *m)
780 for(li=eq_signal_methods;li;li=li->next) {
781 Method *mm = li->data;
782 if(is_list_equal(mm->gtktypes, m->gtktypes))
789 print_signal_marsal_args (const Method *m)
791 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
794 for (i = 0, li = m->gtktypes->next;
796 i++, li = li->next) {
799 if (strcmp (li->data, "UNICHAR") == 0)
800 /* hack because glib is braindamaged */
801 get_func = g_strdup ("g_value_get_uint");
802 else if (strncmp(li->data, "BOXED_", 6) == 0)
803 get_func = g_strdup ("g_value_get_boxed");
805 get_func = g_strdup_printf
806 ("g_value_get_%s", (char *)li->data);
808 gob_strdown (get_func);
809 out_printf (out, ",\n\t\t(%s) "
810 "%s (param_values + %d)",
811 get_cast (li->data, FALSE),
816 out_printf (out, ",\n\t\tdata2);\n");
821 add_signal_prots(Method *m)
827 gboolean ret_none = FALSE;
828 gboolean arglist_none = FALSE;
830 const char *unused = "";
832 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
833 unused = " G_GNUC_UNUSED";
836 if (m->method != SIGNAL_LAST_METHOD &&
837 m->method != SIGNAL_FIRST_METHOD)
841 marsh = g_hash_table_new(NULL, NULL);
843 g_assert (m->gtktypes->next != NULL);
845 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
846 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
848 if (ret_none && arglist_none)
851 /* if we already did a signal prototype just use that */
852 mm = find_same_type_signal (m);
854 s = g_hash_table_lookup (marsh, mm);
855 g_hash_table_insert (marsh, m, s);
862 retcast = get_cast (m->gtktypes->data, FALSE);
864 s = g_strdup_printf("Sig%d", sig++);
866 g_hash_table_insert(marsh, m, s);
867 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
869 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
870 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
871 get_cast(m->gtktypes->data, FALSE), s, typebase);
873 if ( ! arglist_none) {
874 for (li = m->gtktypes->next; li != NULL; li = li->next)
875 out_printf (out, "%s, ", get_cast (li->data, FALSE));
877 out_printf (out, "gpointer);\n");
879 out_printf (out, "\nstatic void\n"
880 "___marshal_%s (GClosure *closure,\n"
881 "\tGValue *return_value%s,\n"
882 "\tguint n_param_values,\n"
883 "\tconst GValue *param_values,\n"
884 "\tgpointer invocation_hint%s,\n"
885 "\tgpointer marshal_data)\n"
892 out_printf (out, "\t%s v_return;\n", retcast);
894 out_printf (out, "\tregister ___%s callback;\n"
895 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
896 "\tregister gpointer data1, data2;\n\n",
899 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
900 arglist_none ? 1 : g_list_length (m->gtktypes));
903 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
904 "\t\tdata1 = closure->data;\n"
905 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
907 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
908 "\t\tdata2 = closure->data;\n"
911 out_printf (out, "\tcallback = (___%s) "
912 "(marshal_data != NULL ? marshal_data : cc->callback);"
916 out_printf (out, "\tcallback ((%s *)data1", typebase);
918 out_printf (out, "\tv_return = callback ((%s *)data1",
922 print_signal_marsal_args (m);
925 /* FIXME: This code is so fucking ugly it hurts */
926 gboolean take_ownership =
927 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
928 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
932 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
933 /* hack because glib is braindamaged */
934 set_func = g_strdup ("g_value_set_uint");
936 set_func = g_strdup_printf ("g_value_%s_%s",
939 (char *)m->gtktypes->data);
940 gob_strdown (set_func);
942 out_printf (out, "\n\t%s (return_value, v_return);\n",
947 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
949 out_printf (out, "\n\treturn_value = NULL;\n");
950 out_printf (out, "\tinvocation_hint = NULL;\n");
953 out_printf (out, "}\n\n");
960 out_printf(out, "\n");
962 out_printf(out, "enum {\n");
963 for(li=c->nodes;li;li=g_list_next(li)) {
965 if(n->type == METHOD_NODE) {
966 Method *m = (Method *)n;
967 if(m->method == SIGNAL_LAST_METHOD ||
968 m->method == SIGNAL_FIRST_METHOD) {
969 char *s = g_strdup(m->id);
971 out_printf(out, "\t%s_SIGNAL,\n", s);
976 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
978 if (set_properties > 0 ||
979 get_properties > 0) {
980 out_printf(out, "enum {\n\tPROP_0");
981 for(li=c->nodes;li;li=g_list_next(li)) {
983 if (n->type == PROPERTY_NODE) {
984 Property *p = (Property *)n;
985 char *s = g_strdup (p->name);
987 out_printf (out, ",\n\tPROP_%s", s);
989 } else if (n->type == ARGUMENT_NODE) {
990 Argument *a = (Argument *)n;
991 char *s = g_strdup(a->name);
993 out_printf(out, ",\n\tPROP_%s", s);
997 out_printf(out, "\n};\n\n");
1002 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1004 out_printf(out, "/* pointer to the class of our parent */\n");
1005 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
1009 add_interface_methods (Class *c, const char *interface)
1012 gboolean added_line = FALSE;
1014 for (li = c->nodes; li != NULL; li = li->next) {
1016 Method *m = (Method *)n;
1017 if (n->type != METHOD_NODE ||
1018 m->method == OVERRIDE_METHOD ||
1019 m->interface == NULL ||
1020 strcmp (m->interface, interface) != 0)
1023 if (m->line_no > 0) {
1024 out_addline_infile (out, m->line_no);
1026 } else if (m->line_no == 0 &&
1028 out_addline_outfile (out);
1031 out_printf (out, "\tiface->%s = self_%s;\n",
1035 out_addline_outfile (out);
1039 add_interface_inits (Class *c)
1043 if (c->interfaces == NULL)
1046 out_printf(out, "\n");
1048 for (li = c->interfaces; li != NULL; li = li->next) {
1049 const char *interface = li->data;
1051 char *name = replace_sep (interface, '_');
1052 char *type = remove_sep (interface);
1056 /* EEEK! evil, we should have some sort of option
1057 * to force this for arbitrary interfaces, since
1058 * some are Class and some are Iface. Glib is shite
1059 * in consistency. */
1061 if (strcmp (type, "GtkEditable") == 0 ||
1062 strcmp (type, "GTypePlugin") == 0)
1065 // We'll assume Iface is the standard ending
1070 /*GTK3 doesn't need Iface end*/
1074 out_printf (out, "\nstatic void\n"
1075 "___%s_init (%s%s *iface)\n"
1079 add_interface_methods (c, interface);
1081 out_printf (out, "}\n\n");
1089 add_interface_infos (void)
1092 for (li = ((Class *)class)->interfaces;
1095 char *name = replace_sep (li->data, '_');
1097 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1098 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1108 add_interfaces (void)
1111 for (li = ((Class *)class)->interfaces;
1114 char *name = replace_sep (li->data, '_');
1115 char *type = make_pre_macro (li->data, "TYPE");
1118 "\t\tg_type_add_interface_static (type,\n"
1120 "\t\t\t&%s_info);\n",
1130 add_dynamic_interfaces(void)
1133 for (li = ((Class *)class)->interfaces;
1136 char *name = replace_sep (li->data, '_');
1137 char *type = make_pre_macro (li->data, "TYPE");
1140 "\t\tg_type_module_add_interface(\n"
1141 "\t\t\ttype_module,\n"
1142 "\t\t\t%s_type_id,\n"
1144 "\t\t\t&%s_info);\n",
1145 funcbase, type, name);
1155 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1159 "%s_get_type (void)\n"
1161 "\tstatic GType type = 0;\n\n"
1162 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1163 "\t\tstatic const GTypeInfo info = {\n"
1164 "\t\t\tsizeof (%sClass),\n"
1165 "\t\t\t(GBaseInitFunc) NULL,\n"
1166 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1167 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1168 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1169 "\t\t\tNULL /* class_data */,\n"
1170 "\t\t\tsizeof (%s),\n"
1171 "\t\t\t%d /* n_preallocs */,\n"
1172 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1175 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1177 add_interface_infos ();
1180 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
1181 pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1189 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1191 chunk_size, chunk_size);
1201 add_dynamic_get_type (void)
1204 "static GType %s_type_id;\n\n"
1206 "%s_get_type (void)\n"
1208 "\treturn %s_type_id;\n"
1210 funcbase, funcbase, funcbase);
1214 "%s_register_type (GTypeModule *type_module)\n"
1216 "\tstatic const GTypeInfo info = {\n"
1217 "\t\tsizeof (%sClass),\n"
1218 "\t\t(GBaseInitFunc) NULL,\n"
1219 "\t\t(GBaseFinalizeFunc) NULL,\n"
1220 "\t\t(GClassInitFunc) %s_class_init,\n"
1221 "\t\t(GClassFinalizeFunc) NULL,\n"
1222 "\t\tNULL /* class_data */,\n"
1223 "\t\tsizeof (%s),\n"
1224 "\t\t%d /* n_preallocs */,\n"
1225 "\t\t(GInstanceInitFunc) %s_init,\n"
1228 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1230 add_interface_infos();
1233 "\t%s_type_id = g_type_module_register_type(\n"
1234 "\t\ttype_module,\n"
1238 "\t\t(GTypeFlags)%s\n"
1241 funcbase, pmacrotype, typebase,
1242 ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1244 add_dynamic_interfaces();
1252 add_bonobo_object_get_type (void)
1254 /* char *chunk_size = ((Class*)class)->chunk_size; */
1255 /* _vicious_ spanks seth with a rusty nail
1257 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1258 "gob2 doesn't officially support it yet. It'd be safer "
1259 "and a lot more fun to blow goats.\"\n");
1264 "%s_get_type (void)\n" /* 1 */
1266 "\tstatic GType type = 0;\n\n"
1267 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1268 "\t\tstatic const GTypeInfo info = {\n"
1269 "\t\t\tsizeof (%sClass),\n" /* 2 */
1270 "\t\t\t(GBaseInitFunc) NULL,\n"
1271 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1272 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1273 "\t\t\tNULL, /* class_finalize */\n"
1274 "\t\t\tNULL, /* class_data */\n"
1275 "\t\t\tsizeof (%s),\n" /* 4 */
1276 "\t\t\t0, /* n_preallocs */\n"
1277 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1286 add_interface_infos ();
1289 "\t\ttype = bonobo_type_unique (\n"
1290 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1291 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1292 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1293 "\t\t\t&info, \"%s\");\n", /* 3 */
1294 ((Class*)class)->bonobo_object_class /* 1 */,
1303 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1305 chunk_size, chunk_size);
1314 add_overrides(Class *c, const char *oname,
1315 gboolean did_base_obj)
1321 done = g_hash_table_new (g_str_hash, g_str_equal);
1323 s = g_strdup ("GObject");
1324 g_hash_table_insert (done, s, s);
1326 for (li = c->nodes; li != NULL; li = li->next) {
1329 Method *m = (Method *)n;
1330 if(n->type != METHOD_NODE ||
1331 m->method != OVERRIDE_METHOD)
1334 s = remove_sep(m->otype);
1336 if(g_hash_table_lookup(done, s)) {
1340 g_hash_table_insert(done, s, s);
1342 f = replace_sep(m->otype, '_');
1345 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1350 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1351 g_hash_table_destroy (done);
1355 make_run_signal_flags(Method *m, gboolean last)
1370 gs = g_string_new(NULL);
1373 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1375 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1377 if(m->scope == PUBLIC_SCOPE)
1378 g_string_append(gs, " | G_SIGNAL_ACTION");
1380 for(li = m->flags; li; li = li->next) {
1381 char *flag = li->data;
1383 for(i=0;flags[i];i++) {
1384 if(strcmp(flags[i], flag)==0)
1387 /* if we haven't found it in our list */
1389 error_printf(GOB_WARN, m->line_no,
1390 "Unknown flag '%s' used, "
1391 "perhaps it was misspelled",
1394 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1398 char *ret = gs->str;
1399 g_string_free(gs, FALSE);
1406 add_signals(Class *c)
1410 out_printf(out, "\n");
1411 for(li=c->nodes;li;li=g_list_next(li)) {
1413 char *mar, *sig, *flags;
1414 gboolean is_none, last = FALSE;
1415 Method *m = (Method *)n;
1417 if(n->type != METHOD_NODE ||
1418 (m->method != SIGNAL_FIRST_METHOD &&
1419 m->method != SIGNAL_LAST_METHOD))
1422 if(m->method == SIGNAL_FIRST_METHOD)
1427 if(g_hash_table_lookup(marsh, m))
1428 mar = g_strconcat("___marshal_",
1429 (char *)g_hash_table_lookup(marsh, m),
1432 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1434 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1436 sig = g_strdup (m->id);
1438 flags = make_run_signal_flags (m, last);
1439 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1440 "\t\tg_signal_new (%s,\n"
1441 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1442 "\t\t\t(GSignalFlags)(%s),\n"
1443 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1444 "\t\t\tNULL, NULL,\n"
1446 "\t\t\tG_TYPE_%s, %d",
1447 sig, m->signal_name /*m->id* if not given signal_name*/,
1449 typebase, m->id, mar,
1450 (char *)m->gtktypes->data,
1451 is_none ? 0 : g_list_length(m->gtktypes->next));
1459 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1460 char *str = l->data;
1461 if (strncmp (str, "BOXED_", 6) == 0)
1462 t = g_strdup (&(str[6]));
1464 t = g_strconcat ("G_TYPE_", str, NULL);
1465 out_printf (out, ",\n\t\t\t%s", t);
1470 out_printf(out, ");\n");
1472 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1475 out_printf(out, "\tif ___GOB_UNLIKELY(");
1476 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1477 out_printf(out, "sizeof(");
1478 print_type(out, m->mtype, FALSE);
1479 out_printf(out, "%s",
1481 m->mtype->postfix : "");
1482 out_printf(out, ") != sizeof(%s) || ",
1483 get_cast(m->gtktypes->data, FALSE));
1486 for(al = m->args->next, gl = m->gtktypes->next;
1487 al != NULL && gl != NULL;
1488 al = al->next, gl = gl->next) {
1489 FuncArg *arg = al->data;
1490 char *gtkarg = gl->data;
1492 out_printf(out, "sizeof(");
1493 print_type(out, arg->atype, FALSE);
1494 out_printf(out, "%s",
1495 arg->atype->postfix ?
1496 arg->atype->postfix : "");
1497 out_printf(out, ") != sizeof(%s) || ",
1498 get_cast(gtkarg, FALSE));
1502 "parent_class == NULL /* avoid warning */");
1504 out_printf(out, ") {\n"
1505 "\t\tg_error(\"%s line %d: Type mismatch "
1506 "of \\\"%s\\\" signal signature\");\n"
1508 filename, m->line_no, m->id);
1515 set_def_handlers(Class *c, const char *oname)
1518 gboolean set_line = FALSE;
1520 out_printf(out, "\n");
1521 for(li = c->nodes; li; li = g_list_next(li)) {
1523 Method *m = (Method *)n;
1525 if(n->type != METHOD_NODE ||
1526 (m->method != SIGNAL_FIRST_METHOD &&
1527 m->method != SIGNAL_LAST_METHOD &&
1528 m->method != VIRTUAL_METHOD &&
1529 m->method != OVERRIDE_METHOD))
1532 if(m->line_no > 0 && m->cbuf) {
1533 out_addline_infile(out, m->line_no);
1535 } else if(set_line) {
1536 out_addline_outfile(out);
1541 if (m->method == OVERRIDE_METHOD) {
1543 s = replace_sep (m->otype, '_');
1547 dispose_handler != NULL &&
1548 strcmp (m->id, "dispose") == 0)
1549 out_printf (out, "\tg_object_class->dispose "
1551 else if (need_finalize &&
1553 strcmp(m->id, "finalize") == 0)
1555 "\tg_object_class->finalize = ___finalize;\n");
1556 else if (m->cbuf != NULL)
1558 "\t%s_class->%s = ___%x_%s_%s;\n",
1559 s, m->id, (guint)m->unique_id,
1562 out_printf(out, "\t%s_class->%s = NULL;\n",
1566 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1570 out_printf(out, "\t%s->%s = NULL;\n",
1575 out_addline_outfile(out);
1579 make_argument (Argument *a)
1584 char *argflags[] = {
1592 flags = g_string_new ("(GParamFlags)(");
1594 if(a->get && a->set)
1595 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1597 g_string_append (flags, "G_PARAM_READABLE");
1599 g_string_append (flags, "G_PARAM_WRITABLE");
1601 g_assert(a->get || a->set);
1603 for (l = a->flags; l != NULL; l = l->next) {
1604 char *flag = l->data;
1606 if(strcmp (flag, "READABLE") == 0 ||
1607 strcmp (flag, "WRITABLE") == 0) {
1608 error_print(GOB_WARN, a->line_no,
1610 "WRITABLE argument flags are "
1611 "set automatically");
1614 for(i = 0; argflags[i]; i++) {
1615 if(strcmp(argflags[i], flag)==0)
1618 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1621 g_string_append (flags, ")");
1623 s = g_strdup(a->name);
1625 if (!strcmp (a->gtktype, "ENUM"))
1626 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1627 "\t\tG_TYPE_ENUM, 0,\n"
1629 a->name, flags->str);
1630 if (!strcmp (a->gtktype, "FLAGS"))
1631 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1632 "\t\tG_TYPE_FLAGS, 0,\n"
1634 a->name, flags->str);
1635 else if (!strcmp (a->gtktype, "OBJECT"))
1636 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1637 "\t\tG_TYPE_OBJECT,\n"
1639 a->name, flags->str);
1640 else if (!strcmp (a->gtktype, "STRING"))
1641 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1644 a->name, flags->str);
1645 else if (!strcmp (a->gtktype, "INT"))
1646 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1647 "\t\tG_MININT, G_MAXINT,\n"
1650 a->name, flags->str);
1651 else if (!strcmp (a->gtktype, "UINT"))
1652 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1653 "\t\t0, G_MAXUINT,\n"
1656 a->name, flags->str);
1657 else if (!strcmp (a->gtktype, "INT"))
1658 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1659 "\t\tG_MININT, G_MAXINT,\n"
1662 a->name, flags->str);
1663 else if (!strcmp (a->gtktype, "CHAR"))
1664 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1668 a->name, flags->str);
1669 else if (!strcmp (a->gtktype, "UCHAR"))
1670 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1674 a->name, flags->str);
1675 else if (!strcmp (a->gtktype, "BOOL") ||
1676 !strcmp (a->gtktype, "BOOLEAN"))
1677 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1680 a->name, flags->str);
1681 else if (!strcmp (a->gtktype, "LONG"))
1682 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1683 "\t\tG_MINLONG, G_MAXLONG,\n"
1686 a->name, flags->str);
1687 else if (!strcmp (a->gtktype, "ULONG"))
1688 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1689 "\t\t0, G_MAXULONG,\n"
1692 a->name, flags->str);
1693 else if (!strcmp (a->gtktype, "INT64"))
1694 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1695 "\t\tG_MININT64, G_MAXINT64,\n"
1698 a->name, flags->str);
1699 else if (!strcmp (a->gtktype, "UINT64"))
1700 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1701 "\t\t0, G_MAXUINT64,\n"
1704 a->name, flags->str);
1705 else if (!strcmp (a->gtktype, "FLOAT"))
1706 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1707 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1710 a->name, flags->str);
1711 else if (!strcmp (a->gtktype, "DOUBLE"))
1712 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1713 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1716 a->name, flags->str);
1717 else if (!strcmp (a->gtktype, "POINTER"))
1718 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1720 a->name, flags->str);
1722 error_printf (GOB_ERROR, a->line_no,
1723 "%s type is not supported for arguments, try using properties",
1726 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1727 "\t\tPROP_%s, param_spec);\n", s);
1731 g_string_free(flags, TRUE);
1734 #define value_for_print(str, alt) (str != NULL ? str : alt)
1737 make_property (Property *p)
1741 if (p->get == NULL && p->set == NULL) {
1742 error_print (GOB_ERROR, p->line_no,
1743 "Property has no getter nor setter");
1747 if (p->flags != NULL)
1748 error_print (GOB_WARN, p->line_no,
1749 "Overridden property, flags ignored");
1750 if (p->nick != NULL)
1751 error_print (GOB_WARN, p->line_no,
1752 "Overridden property, nick ignored");
1753 if (p->blurb != NULL)
1754 error_print (GOB_WARN, p->line_no,
1755 "Overridden property, blurb ignored");
1756 if (p->minimum != NULL)
1757 error_print (GOB_WARN, p->line_no,
1758 "Overridden property, minimum ignored");
1759 if (p->maximum != NULL)
1760 error_print (GOB_WARN, p->line_no,
1761 "Overridden property, maximum ignored");
1762 if (p->default_value != NULL)
1763 error_print (GOB_WARN, p->line_no,
1764 "Overridden property, default_value ignored");
1766 s = g_strdup (p->name);
1768 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1770 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1775 char *argflags[] = {
1783 flags = g_string_new ("(GParamFlags)(");
1785 if (p->get != NULL && p->set != NULL)
1786 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1787 else if (p->get != NULL)
1788 g_string_append (flags, "G_PARAM_READABLE");
1790 g_string_append (flags, "G_PARAM_WRITABLE");
1793 for (l = p->flags; l != NULL; l = l->next) {
1794 char *flag = l->data;
1796 if(strcmp (flag, "READABLE") == 0 ||
1797 strcmp (flag, "WRITABLE") == 0) {
1798 error_print(GOB_WARN, p->line_no,
1800 "WRITABLE argument flags are "
1801 "set automatically");
1804 for(i = 0; argflags[i]; i++) {
1805 if(strcmp(argflags[i], flag)==0)
1808 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1811 g_string_append (flags, ")");
1813 if (strcmp (p->gtktype, "CHAR") == 0) {
1814 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1815 "\t\t(\"%s\" /* name */,\n"
1816 "\t\t %s /* nick */,\n"
1817 "\t\t %s /* blurb */,\n"
1818 "\t\t %s /* minimum */,\n"
1819 "\t\t %s /* maximum */,\n"
1820 "\t\t %s /* default_value */,\n"
1822 value_for_print (p->canonical_name, p->name),
1823 value_for_print (p->nick, "NULL"),
1824 value_for_print (p->blurb, "NULL"),
1825 value_for_print (p->minimum, "-128"),
1826 value_for_print (p->maximum, "127"),
1827 value_for_print (p->default_value, "0"),
1829 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1830 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1831 "\t\t(\"%s\" /* name */,\n"
1832 "\t\t %s /* nick */,\n"
1833 "\t\t %s /* blurb */,\n"
1834 "\t\t %s /* minimum */,\n"
1835 "\t\t %s /* maximum */,\n"
1836 "\t\t %s /* default_value */,\n"
1838 value_for_print (p->canonical_name, p->name),
1839 value_for_print (p->nick, "NULL"),
1840 value_for_print (p->blurb, "NULL"),
1841 value_for_print (p->minimum, "0"),
1842 value_for_print (p->maximum, "0xFF"),
1843 value_for_print (p->default_value, "0"),
1845 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1846 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1847 "\t\t(\"%s\" /* name */,\n"
1848 "\t\t %s /* nick */,\n"
1849 "\t\t %s /* blurb */,\n"
1850 "\t\t %s /* default_value */,\n"
1852 value_for_print (p->canonical_name, p->name),
1853 value_for_print (p->nick, "NULL"),
1854 value_for_print (p->blurb, "NULL"),
1855 value_for_print (p->default_value, "FALSE"),
1857 } else if (strcmp (p->gtktype, "INT") == 0) {
1858 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1859 "\t\t(\"%s\" /* name */,\n"
1860 "\t\t %s /* nick */,\n"
1861 "\t\t %s /* blurb */,\n"
1862 "\t\t %s /* minimum */,\n"
1863 "\t\t %s /* maximum */,\n"
1864 "\t\t %s /* default_value */,\n"
1866 value_for_print (p->canonical_name, p->name),
1867 value_for_print (p->nick, "NULL"),
1868 value_for_print (p->blurb, "NULL"),
1869 value_for_print (p->minimum, "G_MININT"),
1870 value_for_print (p->maximum, "G_MAXINT"),
1871 value_for_print (p->default_value, "0"),
1873 } else if (strcmp (p->gtktype, "UINT") == 0) {
1874 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1875 "\t\t(\"%s\" /* name */,\n"
1876 "\t\t %s /* nick */,\n"
1877 "\t\t %s /* blurb */,\n"
1878 "\t\t %s /* minimum */,\n"
1879 "\t\t %s /* maximum */,\n"
1880 "\t\t %s /* default_value */,\n"
1882 value_for_print (p->canonical_name, p->name),
1883 value_for_print (p->nick, "NULL"),
1884 value_for_print (p->blurb, "NULL"),
1885 value_for_print (p->minimum, "0"),
1886 value_for_print (p->maximum, "G_MAXUINT"),
1887 value_for_print (p->default_value, "0"),
1889 } else if (strcmp (p->gtktype, "LONG") == 0) {
1890 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1891 "\t\t(\"%s\" /* name */,\n"
1892 "\t\t %s /* nick */,\n"
1893 "\t\t %s /* blurb */,\n"
1894 "\t\t %s /* minimum */,\n"
1895 "\t\t %s /* maximum */,\n"
1896 "\t\t %s /* default_value */,\n"
1898 value_for_print (p->canonical_name, p->name),
1899 value_for_print (p->nick, "NULL"),
1900 value_for_print (p->blurb, "NULL"),
1901 value_for_print (p->minimum, "G_MINLONG"),
1902 value_for_print (p->maximum, "G_MAXLONG"),
1903 value_for_print (p->default_value, "0"),
1905 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1906 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1907 "\t\t(\"%s\" /* name */,\n"
1908 "\t\t %s /* nick */,\n"
1909 "\t\t %s /* blurb */,\n"
1910 "\t\t %s /* minimum */,\n"
1911 "\t\t %s /* maximum */,\n"
1912 "\t\t %s /* default_value */,\n"
1914 value_for_print (p->canonical_name, p->name),
1915 value_for_print (p->nick, "NULL"),
1916 value_for_print (p->blurb, "NULL"),
1917 value_for_print (p->minimum, "0"),
1918 value_for_print (p->maximum, "G_MAXULONG"),
1919 value_for_print (p->default_value, "0"),
1921 } else if (strcmp (p->gtktype, "INT64") == 0) {
1922 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1923 "\t\t(\"%s\" /* name */,\n"
1924 "\t\t %s /* nick */,\n"
1925 "\t\t %s /* blurb */,\n"
1926 "\t\t %s /* minimum */,\n"
1927 "\t\t %s /* maximum */,\n"
1928 "\t\t %s /* default_value */,\n"
1930 value_for_print (p->canonical_name, p->name),
1931 value_for_print (p->nick, "NULL"),
1932 value_for_print (p->blurb, "NULL"),
1933 value_for_print (p->minimum, "G_MININT64"),
1934 value_for_print (p->maximum, "G_MAXINT64"),
1935 value_for_print (p->default_value, "0"),
1937 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1938 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1939 "\t\t(\"%s\" /* name */,\n"
1940 "\t\t %s /* nick */,\n"
1941 "\t\t %s /* blurb */,\n"
1942 "\t\t %s /* minimum */,\n"
1943 "\t\t %s /* maximum */,\n"
1944 "\t\t %s /* default_value */,\n"
1946 value_for_print (p->canonical_name, p->name),
1947 value_for_print (p->nick, "NULL"),
1948 value_for_print (p->blurb, "NULL"),
1949 value_for_print (p->minimum, "0"),
1950 value_for_print (p->maximum, "G_MAXUINT64"),
1951 value_for_print (p->default_value, "0"),
1953 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1954 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1955 "\t\t(\"%s\" /* name */,\n"
1956 "\t\t %s /* nick */,\n"
1957 "\t\t %s /* blurb */,\n"
1958 "\t\t %s /* default_value */,\n"
1960 value_for_print (p->canonical_name, p->name),
1961 value_for_print (p->nick, "NULL"),
1962 value_for_print (p->blurb, "NULL"),
1963 value_for_print (p->default_value, "0"),
1965 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1966 char *type = make_me_type (p->extra_gtktype,
1968 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1969 "\t\t(\"%s\" /* name */,\n"
1970 "\t\t %s /* nick */,\n"
1971 "\t\t %s /* blurb */,\n"
1972 "\t\t %s /* enum_type */,\n"
1973 "\t\t %s /* default_value */,\n"
1975 value_for_print (p->canonical_name, p->name),
1976 value_for_print (p->nick, "NULL"),
1977 value_for_print (p->blurb, "NULL"),
1979 value_for_print (p->default_value, "0"),
1982 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1983 char *type = make_me_type (p->extra_gtktype,
1985 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1986 "\t\t(\"%s\" /* name */,\n"
1987 "\t\t %s /* nick */,\n"
1988 "\t\t %s /* blurb */,\n"
1989 "\t\t %s /* flags_type */,\n"
1990 "\t\t %s /* default_value */,\n"
1992 value_for_print (p->canonical_name, p->name),
1993 value_for_print (p->nick, "NULL"),
1994 value_for_print (p->blurb, "NULL"),
1996 value_for_print (p->default_value, "0"),
1999 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2000 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2001 "\t\t(\"%s\" /* name */,\n"
2002 "\t\t %s /* nick */,\n"
2003 "\t\t %s /* blurb */,\n"
2004 "\t\t %s /* minimum */,\n"
2005 "\t\t %s /* maximum */,\n"
2006 "\t\t %s /* default_value */,\n"
2008 value_for_print (p->canonical_name, p->name),
2009 value_for_print (p->nick, "NULL"),
2010 value_for_print (p->blurb, "NULL"),
2011 value_for_print (p->minimum, "-G_MAXFLOAT"),
2012 value_for_print (p->maximum, "G_MAXFLOAT"),
2013 value_for_print (p->default_value, "0.0"),
2015 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2016 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2017 "\t\t(\"%s\" /* name */,\n"
2018 "\t\t %s /* nick */,\n"
2019 "\t\t %s /* blurb */,\n"
2020 "\t\t %s /* minimum */,\n"
2021 "\t\t %s /* maximum */,\n"
2022 "\t\t %s /* default_value */,\n"
2024 value_for_print (p->canonical_name, p->name),
2025 value_for_print (p->nick, "NULL"),
2026 value_for_print (p->blurb, "NULL"),
2027 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2028 value_for_print (p->maximum, "G_MAXDOUBLE"),
2029 value_for_print (p->default_value, "0.0"),
2031 } else if (strcmp (p->gtktype, "STRING") == 0) {
2032 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2033 "\t\t(\"%s\" /* name */,\n"
2034 "\t\t %s /* nick */,\n"
2035 "\t\t %s /* blurb */,\n"
2036 "\t\t %s /* default_value */,\n"
2038 value_for_print (p->canonical_name, p->name),
2039 value_for_print (p->nick, "NULL"),
2040 value_for_print (p->blurb, "NULL"),
2041 value_for_print (p->default_value, "NULL"),
2043 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2044 char *type = make_me_type (p->extra_gtktype,
2046 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2047 "\t\t(\"%s\" /* name */,\n"
2048 "\t\t %s /* nick */,\n"
2049 "\t\t %s /* blurb */,\n"
2050 "\t\t %s /* param_type */,\n"
2052 value_for_print (p->canonical_name, p->name),
2053 value_for_print (p->nick, "NULL"),
2054 value_for_print (p->blurb, "NULL"),
2058 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2059 char *type = make_me_type (p->extra_gtktype,
2061 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2062 "\t\t(\"%s\" /* name */,\n"
2063 "\t\t %s /* nick */,\n"
2064 "\t\t %s /* blurb */,\n"
2065 "\t\t %s /* boxed_type */,\n"
2067 value_for_print (p->canonical_name, p->name),
2068 value_for_print (p->nick, "NULL"),
2069 value_for_print (p->blurb, "NULL"),
2073 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2074 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2075 "\t\t(\"%s\" /* name */,\n"
2076 "\t\t %s /* nick */,\n"
2077 "\t\t %s /* blurb */,\n"
2079 value_for_print (p->canonical_name, p->name),
2080 value_for_print (p->nick, "NULL"),
2081 value_for_print (p->blurb, "NULL"),
2083 /* FIXME: VALUE_ARRAY */
2084 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2085 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2086 "\t\t(\"%s\" /* name */,\n"
2087 "\t\t %s /* nick */,\n"
2088 "\t\t %s /* blurb */,\n"
2090 value_for_print (p->canonical_name, p->name),
2091 value_for_print (p->nick, "NULL"),
2092 value_for_print (p->blurb, "NULL"),
2094 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2095 char *type = make_me_type (p->extra_gtktype,
2097 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2098 "\t\t(\"%s\" /* name */,\n"
2099 "\t\t %s /* nick */,\n"
2100 "\t\t %s /* blurb */,\n"
2101 "\t\t %s /* object_type */,\n"
2103 value_for_print (p->canonical_name, p->name),
2104 value_for_print (p->nick, "NULL"),
2105 value_for_print (p->blurb, "NULL"),
2110 error_printf (GOB_ERROR, p->line_no,
2111 "%s type is not supported by properties",
2115 s = g_strdup (p->name);
2117 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2119 "\t\tparam_spec);\n", s);
2122 g_string_free (flags, TRUE);
2127 make_arguments(Class *c)
2130 if (get_properties > 0)
2131 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2132 if (set_properties > 0)
2133 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2134 out_printf (out, " {\n");
2135 for (li = c->nodes; li != NULL; li = li->next) {
2137 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2138 || n->type == ARGUMENT_NODE) {
2139 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2144 for (li = c->nodes; li != NULL; li = li->next) {
2146 if (n->type == PROPERTY_NODE)
2147 make_property ((Property *)n);
2148 else if (n->type == ARGUMENT_NODE)
2149 make_argument ((Argument *)n);
2151 out_printf(out, " }\n");
2155 print_initializer(Method *m, Variable *v)
2162 if(v->initializer == NULL)
2165 if(v->scope == PRIVATE_SCOPE)
2166 root = g_strconcat(((FuncArg *)m->args->data)->name,
2169 root = g_strdup(((FuncArg *)m->args->data)->name);
2171 if(v->initializer_line > 0)
2172 out_addline_infile(out, v->initializer_line);
2174 if (v->initializer_simple)
2175 out_printf(out, "\t%s->%s = %s;\n",
2176 root, v->id, v->initializer);
2177 else if (strcmp(v->id, "_glade_xml") == 0)
2178 /* This is OK, this v->initializer string is set internally
2179 and it will eat exactly one string! */
2180 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2182 out_printf(out, "%s", v->initializer);
2184 if(v->initializer_line > 0)
2185 out_addline_outfile(out);
2191 print_glade_widget(Method *m, Variable *v)
2196 if(!v->glade_widget)
2199 if(v->scope == PRIVATE_SCOPE)
2200 root = g_strconcat(((FuncArg *)m->args->data)->name,
2203 root = g_strdup(((FuncArg *)m->args->data)->name);
2205 cast = get_type(v->vtype, FALSE);
2206 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2207 root, v->id, cast, root, v->id);
2213 print_destructor (Variable *v)
2217 if(v->destructor == NULL)
2220 if(v->scope == PRIVATE_SCOPE)
2221 root = "self->_priv";
2225 if(v->destructor_simple) {
2226 if(v->destructor_line > 0)
2227 out_addline_infile(out, v->destructor_line);
2230 out_printf(out, "\tif(%s->%s) { "
2231 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2232 "%s->%s = NULL; }\n",
2233 root, v->id, v->destructor, root, v->id,
2236 out_printf(out, "\tif(%s->%s) { "
2237 "%s ((gpointer) %s->%s); "
2238 "%s->%s = NULL; }\n",
2239 root, v->id, v->destructor, root, v->id,
2243 if(v->destructor_line > 0)
2244 out_addline_outfile(out);
2246 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2247 out_printf(out, "#define VAR %s\n", v->id);
2248 out_printf(out, "\t{\n");
2249 if(v->destructor_line > 0)
2250 out_addline_infile(out, v->destructor_line);
2252 out_printf(out, "\t%s}\n", v->destructor);
2254 if(v->destructor_line > 0)
2255 out_addline_outfile(out);
2256 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2258 out_printf(out, "#undef VAR\n");
2259 out_printf(out, "#undef %s\n", v->id);
2264 add_constructor (Class *c)
2266 out_printf(out, "\nstatic GObject *\n"
2267 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2270 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2273 out_printf(out, "\tGObject *obj_self;\n");
2274 out_printf(out, "\t%s *self;\n", typebase);
2276 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2277 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2279 if (user_constructor->line_no > 0)
2280 out_addline_infile (out, user_constructor->line_no);
2281 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2282 if (user_constructor->line_no > 0)
2283 out_addline_outfile (out);
2285 out_printf(out, "\treturn obj_self;\n");
2286 out_printf(out, "}\n"
2287 "#undef __GOB_FUNCTION__\n\n");
2291 print_unreftors (Class *c)
2294 for(li = ((Class *)class)->nodes;
2298 Variable *v = (Variable *)n;
2299 if (n->type == VARIABLE_NODE &&
2300 v->scope != CLASS_SCOPE &&
2301 v->destructor_unref)
2302 print_destructor (v);
2307 add_dispose (Class *c)
2309 out_printf(out, "\nstatic void\n"
2310 "___dispose (GObject *obj_self)\n"
2313 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2316 if (unreftors > 0 || user_dispose_method != NULL) {
2317 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2319 ! no_gnu ? " G_GNUC_UNUSED" : "",
2323 if (dispose_handler != NULL) {
2324 if (unreftors > 0) {
2325 print_unreftors (c);
2328 /* so we get possible bad argument warning */
2329 if (dispose_handler->line_no > 0)
2330 out_addline_infile (out, dispose_handler->line_no);
2331 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2332 (guint)dispose_handler->unique_id, funcbase);
2333 if (dispose_handler->line_no > 0)
2334 out_addline_outfile (out);
2336 if (user_dispose_method != NULL) {
2337 if (user_dispose_method->line_no > 0)
2338 out_addline_infile (out, user_dispose_method->line_no);
2339 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2340 if (user_dispose_method->line_no > 0)
2341 out_addline_outfile (out);
2344 if (unreftors > 0) {
2345 print_unreftors (c);
2349 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2350 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2353 out_printf(out, "}\n"
2354 "#undef __GOB_FUNCTION__\n\n");
2358 print_destructors (Class *c)
2361 for (li = ((Class *)class)->nodes;
2365 Variable *v = (Variable *)n;
2366 if (n->type == VARIABLE_NODE &&
2367 v->scope != CLASS_SCOPE &&
2368 ! v->destructor_unref)
2369 print_destructor (v);
2374 add_finalize (Class *c)
2378 "___finalize(GObject *obj_self)\n"
2381 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2386 user_finalize_method != NULL) {
2387 const char *unused = "";
2389 unused = " G_GNUC_UNUSED";
2390 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2391 typebase, unused, macrobase);
2394 const char *unused = "";
2396 unused = " G_GNUC_UNUSED";
2397 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2401 if(finalize_handler) {
2402 if (destructors > 0) {
2403 print_destructors (c);
2406 /* so we get possible bad argument warning */
2407 if(finalize_handler->line_no > 0)
2408 out_addline_infile(out, finalize_handler->line_no);
2409 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2410 (guint)finalize_handler->unique_id, funcbase);
2411 if(finalize_handler->line_no > 0)
2412 out_addline_outfile(out);
2414 if (user_finalize_method != NULL) {
2415 if (user_finalize_method->line_no > 0)
2416 out_addline_infile (out, user_finalize_method->line_no);
2417 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2418 if (user_finalize_method->line_no > 0)
2419 out_addline_outfile (out);
2422 if (destructors > 0) {
2423 print_destructors (c);
2427 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2428 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2431 out_printf(out, "}\n"
2432 "#undef __GOB_FUNCTION__\n\n");
2436 make_bonobo_object_epv (Class *c, const char *classname)
2439 gboolean added_line = FALSE;
2441 for (li = c->nodes; li != NULL; li = li->next) {
2443 Method *m = (Method *)n;
2444 if(n->type != METHOD_NODE ||
2445 m->method == OVERRIDE_METHOD)
2448 if (m->bonobo_object_func) {
2449 if(m->line_no > 0) {
2450 out_addline_infile(out, m->line_no);
2452 } else if (m->line_no == 0 &&
2454 out_addline_outfile(out);
2457 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2458 classname, m->id, m->id);
2462 out_addline_outfile(out);
2468 const char *unused = "";
2472 unused = " G_GNUC_UNUSED";
2474 for(li=c->nodes;li;li=g_list_next(li)) {
2478 if(n->type != METHOD_NODE)
2481 if(m->method == INIT_METHOD) {
2483 out_addline_infile(out, m->line_no);
2484 print_method(out, "static ", "\n", "", " ", "", "\n",
2485 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2487 out_printf(out, "{\n");
2489 out_addline_outfile(out);
2491 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2494 out_printf(out, "\t%s->_priv = "
2495 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2496 ((FuncArg *)m->args->data)->name,
2497 ((FuncArg *)m->args->data)->name,
2500 } else if(always_private_struct) {
2501 out_printf(out, "\t%s->_priv = NULL;\n",
2502 ((FuncArg *)m->args->data)->name);
2504 if(initializers > 0) {
2506 for(li = ((Class *)class)->nodes;
2510 Variable *v = (Variable *)n;
2511 if(n->type != VARIABLE_NODE ||
2512 v->scope == CLASS_SCOPE)
2514 print_initializer(m, v);
2517 if(glade_widgets > 0) {
2519 for(li = ((Class *)class)->nodes;
2523 Variable *v = (Variable *)n;
2524 if(n->type != VARIABLE_NODE ||
2525 v->scope == CLASS_SCOPE)
2527 print_glade_widget(m, v);
2530 } else if(m->method == CLASS_INIT_METHOD) {
2531 gboolean did_base_obj = FALSE;
2534 out_addline_infile(out, m->line_no);
2535 print_method(out, "static ", "\n", "", " ", "", "\n",
2536 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2538 out_printf(out, "{\n");
2540 out_addline_outfile(out);
2542 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2544 if (set_properties > 0 ||
2545 get_properties > 0 ||
2552 "g_object_class%s = "
2553 "(GObjectClass*) %s;\n",
2555 ((FuncArg *)m->args->data)->name);
2556 did_base_obj = TRUE;
2561 ((FuncArg *)m->args->data)->name,
2566 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2567 ((FuncArg *)m->args->data)->name,
2570 if (initializers > 0) {
2572 for(li = ((Class *)class)->nodes;
2576 Variable *v = (Variable *)n;
2577 if(n->type == VARIABLE_NODE &&
2578 v->scope == CLASS_SCOPE)
2579 print_initializer(m, v);
2583 out_printf(out, "\n\tparent_class = ");
2585 out_printf(out, "(%sClass *)", ptypebase);
2586 out_printf(out, "g_type_class_ref (%s);\n",
2592 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2594 /* if there are no handlers for these things, we
2595 * need to set them up here */
2596 if(need_constructor)
2597 out_printf(out, "\tg_object_class->constructor "
2598 "= ___constructor;\n");
2599 if(need_dispose && !dispose_handler)
2600 out_printf(out, "\tg_object_class->dispose "
2602 if(need_finalize && !finalize_handler)
2603 out_printf(out, "\tg_object_class->finalize = "
2606 if(get_properties > 0 || set_properties > 0)
2609 if (c->bonobo_object_class != NULL) {
2610 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2616 out_printf(out, " {\n");
2617 out_addline_infile(out, m->ccode_line);
2618 out_printf(out, "%s\n", m->cbuf);
2619 out_addline_outfile(out);
2620 out_printf(out, " }\n");
2622 out_printf(out, "}\n"
2623 "#undef __GOB_FUNCTION__\n");
2628 add_argument (Argument *a, gboolean is_set)
2632 char *the_type_lower;
2637 line_no = a->set_line;
2640 line_no = a->get_line;
2644 s = g_strdup(a->name);
2646 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2648 the_type_lower = g_strdup (a->gtktype);
2649 gob_strdown (the_type_lower);
2651 /* HACK because there is no g_value_set/get for unichar */
2652 if (strcmp (the_type_lower, "unichar") == 0) {
2653 g_free (the_type_lower);
2654 the_type_lower = g_strdup ("uint");
2659 const char *unused = "";
2661 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2662 unused = " G_GNUC_UNUSED";
2665 if (a->atype != NULL &&
2666 /* gcc -Wbad-function-cast is wanking stupid, moronic
2667 and otherwise evil so we should just use a (gint)
2668 or (guint) cast, not the specific type cast */
2670 (strcmp (a->gtktype, "ENUM") != 0 &&
2671 strcmp (a->gtktype, "FLAGS") != 0)))
2672 cast = get_type (a->atype, TRUE);
2674 cast = g_strdup (get_cast (a->gtktype, FALSE));
2676 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2677 cast, unused, cast, the_type_lower);
2680 } else if ( ! is_set) {
2683 if (a->atype != NULL)
2684 cast = get_type (a->atype, TRUE);
2686 cast = g_strdup (get_cast (a->gtktype, FALSE));
2687 out_printf (out, "\t%s ARG;\n"
2688 "\tmemset (&ARG, 0, sizeof (%s));\n",
2694 out_printf(out, "\t\t{\n");
2696 out_addline_infile (out, line_no);
2697 out_printf (out, "%s\n", cbuf);
2699 out_addline_outfile (out);
2700 out_printf (out, "\t\t}\n");
2702 if (strcmp (a->gtktype, "OBJECT") == 0)
2703 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2706 out_printf (out, "\t\t"
2707 "g_value_set_%s (VAL, ARG);\n",
2710 g_free (the_type_lower);
2713 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2714 out_printf (out, "\t\tif (&ARG) break;\n");
2717 out_printf (out, "\t\tbreak;\n");
2719 out_printf (out, "\t}\n");
2723 add_property (Property *p, gboolean is_set)
2726 char *the_type_lower;
2732 line_no = p->set_line;
2735 line_no = p->get_line;
2740 name_upper = g_strdup (p->name);
2741 gob_strup (name_upper);
2742 the_type_lower = g_strdup (p->gtktype);
2743 gob_strdown (the_type_lower);
2745 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2747 out_printf(out, "\t\t{\n");
2749 out_addline_infile (out, line_no);
2750 out_printf (out, "%s\n", cbuf);
2752 out_addline_outfile (out);
2753 out_printf (out, "\t\t}\n");
2755 g_free (name_upper);
2756 g_free (the_type_lower);
2758 out_printf (out, "\t\tbreak;\n");
2762 add_getset_arg(Class *c, gboolean is_set)
2765 const char *unused = "";
2766 const char *hack_unused = "";
2768 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2769 unused = " G_GNUC_UNUSED";
2771 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2774 out_printf(out, "\nstatic void\n"
2775 "___object_%s_property (GObject *object,\n"
2776 "\tguint property_id,\n"
2777 "\t%sGValue *VAL%s,\n"
2778 "\tGParamSpec *pspec%s)\n"
2779 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2782 "\tself = %s (object);\n\n"
2783 "\tswitch (property_id) {\n",
2784 is_set ? "set" : "get",
2785 is_set ? "const " : "",
2789 is_set ? "set" : "get",
2794 for (li = c->nodes; li != NULL; li = li->next) {
2796 if (n->type == PROPERTY_NODE)
2797 add_property ((Property *)n, is_set);
2798 else if (n->type == ARGUMENT_NODE)
2799 add_argument ((Argument *)n, is_set);
2801 out_printf (out, "\tdefault:\n"
2802 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2803 "#ifndef __PRETTY_FUNCTION__\n"
2804 "# undef G_STRLOC\n"
2805 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2807 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2808 "\t\t%sbreak;\n\t}\n"
2810 "#undef __GOB_FUNCTION__\n", hack_unused);
2814 print_checks (Method *m, FuncArg *fa)
2818 gboolean checked_null = FALSE;
2819 is_void = (strcmp(m->mtype->name, "void")==0 &&
2820 m->mtype->pointer == NULL);
2822 for(li = fa->checks; li != NULL; li = li->next) {
2823 Check *ch = li->data;
2825 /* point to the method prot in .gob for failed checks */
2827 out_addline_infile(out, m->line_no);
2829 out_printf(out, "\tg_return_if_fail (");
2831 out_printf(out, "\tg_return_val_if_fail (");
2832 switch(ch->chtype) {
2834 out_printf(out, "%s != NULL", fa->name);
2835 checked_null = TRUE;
2838 s = make_pre_macro(fa->atype->name, "IS");
2840 out_printf(out, "%s (%s)", s, fa->name);
2842 /* if not check null, null may be valid */
2843 out_printf(out, "!(%s) || %s (%s)", fa->name,
2848 out_printf(out, "%s < %s", fa->name, ch->number);
2851 out_printf(out, "%s > %s", fa->name, ch->number);
2854 out_printf(out, "%s <= %s", fa->name, ch->number);
2857 out_printf(out, "%s >= %s", fa->name, ch->number);
2860 out_printf(out, "%s == %s", fa->name, ch->number);
2863 out_printf(out, "%s != %s", fa->name, ch->number);
2867 out_printf(out, ");\n");
2869 out_printf(out, ", (");
2870 print_type(out, m->mtype, TRUE);
2871 out_printf(out, ")%s);\n",
2872 m->onerror?m->onerror:"0");
2878 print_preconditions(Method *m)
2882 for(li=m->args;li;li=g_list_next(li)) {
2883 FuncArg *fa = li->data;
2885 print_checks(m, fa);
2888 out_addline_outfile(out);
2892 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2894 out_printf(out, "{\n");
2896 out_addline_outfile(out);
2897 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2898 ((Class *)class)->otype,
2901 print_preconditions(m);
2905 (no_gnu || for_cpp) &&
2907 ((FuncArg *)(m->args->data))->name != NULL &&
2908 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2909 out_printf (out, "\tif (&self) { ; }\n");
2912 /* Note: the trailing }'s are on one line, this is so
2913 that we get the no return warning correctly and point to
2914 the correct line in the .gob file, yes this is slightly
2915 ugly in the .c file, but that is not supposed to be
2916 human readable anyway. */
2918 out_printf(out, "{\n");
2920 out_addline_infile(out, m->ccode_line);
2921 out_printf(out, "\t%s}", m->cbuf);
2924 /* Note, there is no \n between the last } and this } so that
2925 * errors/warnings reported on the end of the body get pointed to the
2926 * right line in the .gob source */
2927 out_printf(out, "}\n");
2930 out_addline_outfile(out);
2931 out_printf(out, "#undef __GOB_FUNCTION__\n");
2935 put_signal_args (Method *m)
2941 if (m->args->next == NULL)
2944 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2945 li != NULL && ali != NULL;
2946 li = li->next, ali = ali->next, i++) {
2947 FuncArg *fa = li->data;
2948 char *str = ali->data;
2949 char *cast = g_strdup (get_cast (str, FALSE));
2950 /* FIXME: This code is so fucking ugly it hurts */
2951 gboolean do_static =
2952 (strcmp (str, "STRING") == 0 ||
2953 strcmp (str, "BOXED") == 0 ||
2954 strncmp (str, "BOXED_", 6) == 0);
2959 cast = get_type (fa->atype, TRUE);
2961 /* we should have already proved before that
2962 the we know all the types */
2963 g_assert (cast != NULL);
2965 if (strncmp (str, "BOXED_", 6) == 0)
2966 t = g_strdup (&(str[6]));
2968 t = g_strconcat ("G_TYPE_", str, NULL);
2971 "\t___param_values[%d].g_type = 0;\n"
2972 "\tg_value_init (&___param_values[%d], %s);\n",
2976 if (strcmp (str, "UNICHAR") == 0)
2977 /* hack because glib is braindamaged */
2978 set_func = g_strdup ("g_value_set_uint");
2979 else if (strncmp (str, "BOXED_", 6) == 0)
2980 set_func = g_strdup ("g_value_set_static_boxed");
2982 set_func = g_strdup_printf ("g_value_set%s_%s",
2983 do_static ? "_static" : "",
2985 gob_strdown (set_func);
2987 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2988 set_func, i, cast, fa->name);
2996 clear_signal_args (Method *m)
3001 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3003 if (m->args->next == NULL)
3006 for (li = m->args->next, i = 1;
3008 li = li->next, i++) {
3010 "\tg_value_unset (&___param_values[%d]);\n", i);
3015 get_arg_names_for_macro (Method *m)
3019 GString *gs = g_string_new(NULL);
3021 for(li=m->args;li;li=g_list_next(li)) {
3022 FuncArg *arg = li->data;
3023 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
3026 return g_string_free (gs, FALSE);
3030 put_method(Method *m)
3032 char *s, *args, *doc;
3034 is_void = (strcmp(m->mtype->name, "void")==0 &&
3035 m->mtype->pointer == NULL);
3036 out_printf(out, "\n");
3037 if(m->method != OVERRIDE_METHOD) {
3038 doc = get_gtk_doc(m->id);
3040 out_printf(out, "%s", doc);
3045 case REGULAR_METHOD:
3047 out_addline_infile(out, m->line_no);
3048 if(m->scope == PRIVATE_SCOPE)
3049 print_method(out, "static ", "\n", "", " ", "", "\n",
3050 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3051 else /* PUBLIC, PROTECTED */
3052 print_method(out, "", "\n", "", " ", "", "\n",
3053 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3054 print_method_body(m, TRUE, TRUE);
3055 /* the outfile line was added above */
3057 case SIGNAL_FIRST_METHOD:
3058 case SIGNAL_LAST_METHOD:
3060 out_addline_infile(out, m->line_no);
3061 if(m->scope == PRIVATE_SCOPE)
3062 print_method(out, "static ", "\n", "", " ", "", "\n",
3063 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3064 else /* PUBLIC, PROTECTED */
3065 print_method(out, "", "\n", "", " ", "", "\n",
3066 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3067 out_printf (out, "{\n");
3069 out_addline_outfile (out);
3072 "\tGValue ___param_values[%d];\n"
3073 "\tGValue ___return_val;\n\n"
3074 "memset (&___return_val, 0, "
3075 "sizeof (___return_val));\n"
3076 "memset (&___param_values, 0, "
3077 "sizeof (___param_values));\n\n",
3078 g_list_length (m->args));
3080 print_preconditions (m);
3083 "\n\t___param_values[0].g_type = 0;\n"
3084 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3085 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3086 ((FuncArg *)m->args->data)->name,
3087 ((FuncArg *)m->args->data)->name);
3089 put_signal_args (m);
3091 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3092 const char *defret = NULL;
3094 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3095 (char *)m->gtktypes->data);
3097 if (m->defreturn != NULL)
3098 defret = m->defreturn;
3099 else if (m->onerror != NULL)
3100 defret = m->onerror;
3102 if (defret != NULL) {
3104 /* FIXME: This code is so fucking ugly it hurts */
3105 gboolean do_static =
3106 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3107 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3108 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3110 cast = get_type (m->mtype, TRUE);
3112 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3113 /* hack because glib is braindamaged */
3114 set_func = g_strdup ("g_value_set_uint");
3116 set_func = g_strdup_printf ("g_value_set%s_%s",
3117 do_static ? "_static" : "",
3118 (char *)m->gtktypes->data);
3119 gob_strdown (set_func);
3121 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3122 set_func, cast, defret);
3127 out_printf (out, "\n");
3130 s = g_strdup (m->id);
3133 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3134 "\t\tobject_signals[%s_SIGNAL],\n"
3135 "\t\t0 /* detail */,\n"
3136 "\t\t&___return_val);\n", s);
3140 clear_signal_args (m);
3142 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3143 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3145 /* Hack because glib is very very braindead */
3147 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3148 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3149 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3150 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3152 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3153 /* hack because glib is braindamaged */
3154 getfunc = g_strdup ("g_value_get_uint");
3156 getfunc = g_strdup_printf ("g_value_%s_%s",
3157 do_dup ? "dup" : "get",
3158 (char *)m->gtktypes->data);
3159 gob_strdown (getfunc);
3162 cast = get_type (m->mtype, TRUE);
3167 print_type (out, m->mtype, TRUE);
3169 " ___ret = (%s) %s (&___return_val);\n"
3170 "\t\tg_value_unset (&___return_val);\n"
3171 "\t\treturn ___ret;\n"
3178 out_printf(out, "}\n");
3183 out_addline_infile(out, m->line_no);
3184 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3185 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3186 print_method_body(m, FALSE, TRUE);
3187 /* the outfile line was added above */
3189 case VIRTUAL_METHOD:
3191 out_addline_infile(out, m->line_no);
3192 if(m->scope==PRIVATE_SCOPE)
3193 print_method(out, "static ", "\n", "", " ", "", "\n",
3194 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3195 else /* PUBLIC, PROTECTED */
3196 print_method(out, "", "\n", "", " ", "", "\n",
3197 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3198 out_printf(out, "{\n");
3199 out_addline_outfile(out);
3200 out_printf(out, "\t%sClass *klass;\n", typebase);
3201 print_preconditions(m);
3202 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3203 "\tif(klass->%s)\n",
3204 macrobase, ((FuncArg *)m->args->data)->name,
3206 if(strcmp(m->mtype->name, "void") == 0 &&
3207 m->mtype->pointer == NULL) {
3209 out_printf(out, "\t\t(*klass->%s)(%s",
3211 ((FuncArg *)m->args->data)->name);
3212 for(li=m->args->next;li;li=g_list_next(li)) {
3213 FuncArg *fa = li->data;
3214 out_printf(out, ",%s", fa->name);
3216 out_printf(out, ");\n}\n");
3219 out_printf(out, "\t\treturn (*klass->%s)(%s",
3221 ((FuncArg *)m->args->data)->name);
3222 for(li=m->args->next;li;li=g_list_next(li)) {
3223 FuncArg *fa = li->data;
3224 out_printf(out, ",%s", fa->name);
3226 out_printf(out, ");\n"
3229 print_type(out, m->mtype, TRUE);
3231 out_printf(out, ")(%s);\n}\n", m->defreturn);
3233 out_printf(out, ")(%s);\n}\n", m->onerror);
3235 out_printf(out, ")(0);\n}\n");
3241 out_addline_infile(out, m->line_no);
3242 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3243 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3244 print_method_body(m, FALSE, TRUE);
3245 /* the outfile line was added above */
3247 case OVERRIDE_METHOD:
3251 out_addline_infile(out, m->line_no);
3252 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3253 print_method(out, "static ", s, "", " ", "", "\n",
3254 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3256 out_addline_outfile(out);
3257 s = replace_sep(m->otype, '_');
3259 args = get_arg_names_for_macro(m);
3261 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3262 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3263 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3264 args, s, m->id, s, m->id, args);
3266 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3267 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3268 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3270 args, s, m->id, s, m->id, args);
3271 out_printf(out, "(");
3272 print_type(out, m->mtype, TRUE);
3273 out_printf(out, ")%s))\n",
3274 m->onerror?m->onerror:"0");
3278 print_method_body(m, TRUE, TRUE);
3279 /* the outfile line was added above */
3280 out_printf(out, "#undef PARENT_HANDLER\n");
3282 case CONSTRUCTOR_METHOD:
3283 case DISPOSE_METHOD:
3284 case FINALIZE_METHOD:
3286 out_addline_infile(out, m->line_no);
3287 print_method(out, "static ", "\n", "", " ", "", "\n",
3288 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3289 print_method_body(m, TRUE, TRUE);
3290 /* the outfile line was added above */
3299 char *outfile, *outfileh, *outfileph;
3301 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3302 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3304 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3305 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3307 if ((privates > 0 || protecteds > 0 ||
3308 private_header == PRIVATE_HEADER_ALWAYS) &&
3309 private_header != PRIVATE_HEADER_NEVER) {
3310 char sep[2] = {0,0};
3313 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3314 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3316 outfilephbase = NULL;
3322 out = fopen (outfile, "w");
3324 error_printf (GOB_ERROR, 0,
3325 "Cannot open outfile: %s", outfile);
3327 outh = fopen (outfileh, "w");
3329 error_printf (GOB_ERROR, 0,
3330 "Cannot open outfile: %s", outfileh);
3332 if (outfileph != NULL) {
3333 outph = fopen (outfileph, "w");
3334 if (outph == NULL) {
3335 error_printf (GOB_ERROR, 0,
3336 "Cannot open outfile: %s",
3344 put_argument_nongnu_wrappers (Class *c)
3348 if (get_properties < 0 && set_properties < 0)
3351 for (li = c->nodes; li != NULL; li = li->next) {
3353 const char *name, *gtktype;
3359 if (n->type == ARGUMENT_NODE) {
3360 Argument *a = (Argument *)n;
3362 gtktype = a->gtktype;
3364 get = a->get != NULL;
3365 set = a->set != NULL;
3366 } else if (n->type == PROPERTY_NODE) {
3367 Property *p = (Property *)n;
3369 gtktype = p->gtktype;
3371 get = p->get != NULL;
3372 set = p->set != NULL;
3377 aname = g_strdup (name);
3381 cast = get_type (atype, TRUE);
3383 cast = g_strdup (get_cast (gtktype, TRUE));
3387 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3388 "\"%s\",(%s)(arg)\n",
3389 macrobase, aname, name, cast);
3391 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3392 "\"%s\",(%s*)(arg)\n",
3393 macrobase, aname, name, cast);
3396 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3398 macrobase, aname, name);
3400 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3402 macrobase, aname, name);
3410 put_argument_gnu_wrappers(Class *c)
3414 if(get_properties < 0 && set_properties < 0)
3417 for (li = c->nodes; li != NULL; li = li->next) {
3419 const char *name, *gtktype;
3425 if (n->type == ARGUMENT_NODE) {
3426 Argument *a = (Argument *)n;
3428 gtktype = a->gtktype;
3430 get = a->get != NULL;
3431 set = a->set != NULL;
3432 } else if (n->type == PROPERTY_NODE) {
3433 Property *p = (Property *)n;
3435 gtktype = p->gtktype;
3437 get = p->get != NULL;
3438 set = p->set != NULL;
3443 aname = g_strdup (name);
3447 cast = get_type (atype, TRUE);
3449 cast = g_strdup (get_cast (gtktype, TRUE));
3453 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3454 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3455 macrobase, aname, name, cast);
3457 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3458 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3459 macrobase, aname, name, cast);
3462 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3464 macrobase, aname, name);
3466 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3468 macrobase, aname, name);
3476 print_ccode_block(CCode *cc)
3479 switch(cc->cctype) {
3481 /* HT code is printed exactly like normal header
3482 code but is printed before */
3485 out_printf(fp, "\n");
3488 /* AT code is printed exactly like normal 'all'
3489 code but is printed before */
3492 out_printf(outph, "\n");
3493 out_printf(outph, "%s\n", cc->cbuf);
3494 out_addline_infile(outph, cc->line_no);
3495 out_addline_outfile(outph);
3497 out_printf(outh, "\n");
3498 out_printf(outh, "%s\n", cc->cbuf);
3500 out_printf(fp, "\n");
3501 out_addline_infile(fp, cc->line_no);
3507 out_printf(fp, "\n");
3508 out_addline_infile(fp, cc->line_no);
3515 out_printf(fp, "\n");
3516 out_addline_infile(fp, cc->line_no);
3519 out_printf(fp, "%s\n", cc->cbuf);
3520 if(cc->cctype == C_CCODE ||
3521 cc->cctype == AD_CCODE ||
3522 cc->cctype == A_CCODE ||
3523 cc->cctype == AT_CCODE ||
3524 cc->cctype == PH_CCODE)
3525 out_addline_outfile(fp);
3529 print_class_block(Class *c)
3533 gboolean printed_private = FALSE;
3537 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3538 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3542 out_printf(out, "/* utility types we may need */\n");
3543 if(special_array[SPECIAL_2POINTER])
3544 out_printf(out, "typedef struct { "
3545 "gpointer a; gpointer b; "
3546 "} ___twopointertype;\n");
3547 if(special_array[SPECIAL_3POINTER])
3548 out_printf(out, "typedef struct { "
3549 "gpointer a; gpointer b; "
3551 "} ___threepointertype;\n");
3552 if(special_array[SPECIAL_INT_POINTER])
3553 out_printf(out, "typedef struct { "
3554 "gint a; gpointer b; "
3555 "} ___intpointertype;\n");
3556 out_printf(out, "\n");
3559 out_printf(outh, "\n/*\n"
3560 " * Type checking and casting macros\n"
3562 out_printf(outh, "#define %s\t"
3563 "(%s_get_type())\n",
3564 macrotype, funcbase);
3565 out_printf(outh, "#define %s(obj)\t"
3566 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3567 macrobase, funcbase, typebase);
3568 out_printf(outh, "#define %s_CONST(obj)\t"
3569 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3570 macrobase, funcbase, typebase);
3571 out_printf(outh, "#define %s_CLASS(klass)\t"
3572 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3573 macrobase, funcbase, typebase);
3574 out_printf(outh, "#define %s(obj)\t"
3575 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3578 "#define %s_GET_CLASS(obj)\t"
3579 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3580 macrobase, funcbase, typebase);
3582 if ( ! no_self_alias) {
3583 out_printf(out, "/* self casting macros */\n");
3584 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3585 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3586 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3587 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3588 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3590 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3593 out_printf(out, "/* self typedefs */\n");
3594 out_printf(out, "typedef %s Self;\n", typebase);
3595 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3599 always_private_struct) {
3600 out_printf (outh, "\n/* Private structure type */\n");
3601 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3602 typebase, typebase);
3604 out_printf (outh, "/* There are no privates, this "
3605 "structure is thus never defined */\n");
3608 out_printf (outh, "\n/*\n"
3609 " * Main object structure\n"
3611 s = replace_sep (c->otype, '_');
3613 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3614 "#define __TYPEDEF_%s__\n", s, s);
3616 out_printf (outh, "typedef struct _%s %s;\n"
3617 "#endif\n", typebase, typebase);
3618 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3619 typebase, ptypebase);
3620 for (li = c->nodes; li; li=li->next) {
3621 static gboolean printed_public = FALSE;
3623 Variable *v = (Variable *)n;
3624 if(n->type == VARIABLE_NODE &&
3625 v->scope == PUBLIC_SCOPE) {
3626 if( ! printed_public) {
3627 out_printf(outh, "\t/*< public >*/\n");
3628 printed_public = TRUE;
3630 put_variable((Variable *)n, outh);
3633 /* put protecteds always AFTER publics */
3634 for (li = c->nodes; li != NULL; li = li->next) {
3636 Variable *v = (Variable *)n;
3637 if (n->type == VARIABLE_NODE &&
3638 v->scope == PROTECTED_SCOPE) {
3639 if ( ! printed_private) {
3640 out_printf (outh, "\t/*< private >*/\n");
3641 printed_private = TRUE;
3643 put_variable ((Variable *)n, outh);
3647 always_private_struct) {
3648 if ( ! printed_private)
3649 out_printf (outh, "\t/*< private >*/\n");
3650 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3652 out_printf (outh, "};\n");
3657 /* if we are to stick this into the private
3658 header, if not stick it directly into the
3665 out_printf (outfp, "struct _%sPrivate {\n",
3669 for(li=c->nodes; li; li=li->next) {
3671 Variable *v = (Variable *)n;
3672 if(n->type == VARIABLE_NODE &&
3673 v->scope == PRIVATE_SCOPE) {
3674 out_addline_infile(outfp, v->line_no);
3675 put_variable(v, outfp);
3678 out_addline_outfile(outfp);
3680 out_printf(outfp, "};\n");
3683 out_printf(outh, "\n/*\n"
3684 " * Class definition\n"
3686 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3687 typebase, typebase);
3689 "struct _%sClass {\n\t%sClass __parent__;\n",
3690 typebase, ptypebase);
3691 for(li = c->nodes; li != NULL; li = li->next) {
3693 if(n->type == METHOD_NODE)
3694 put_vs_method((Method *)n);
3696 /* If BonoboX type class put down the epv */
3697 if (c->bonobo_object_class != NULL) {
3699 "\t/* Bonobo object epv */\n"
3700 "\tPOA_%s__epv _epv;\n",
3701 c->bonobo_object_class);
3703 /* put class scope variables */
3704 for (li = c->nodes; li != NULL; li = li->next) {
3706 Variable *v = (Variable *)n;
3707 if (n->type == VARIABLE_NODE &&
3708 v->scope == CLASS_SCOPE)
3709 put_variable ((Variable *)n, outh);
3711 out_printf (outh, "};\n\n");
3713 out_printf (out, "/* here are local prototypes */\n");
3714 if (set_properties > 0) {
3715 out_printf (out, "static void ___object_set_property "
3716 "(GObject *object, guint property_id, "
3717 "const GValue *value, GParamSpec *pspec);\n");
3719 if (get_properties > 0) {
3720 out_printf (out, "static void ___object_get_property "
3721 "(GObject *object, guint property_id, "
3722 "GValue *value, GParamSpec *pspec);\n");
3725 out_printf (outh, "\n/*\n"
3726 " * Public methods\n"
3729 if (!overrode_get_type) {
3731 * For ordinary "static" types it should be safe to mark the
3732 * get_type implementation as const, since the get_type
3733 * function return really is constant at the call boundary
3734 * (even though there is an initial setup on the first call).
3735 * But for dynamic types, since the registration is explicitly
3736 * separated, we need to settle for "pure" as the results of
3737 * get_type differ before and after type registration.
3739 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3740 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3744 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3748 for(li = c->nodes; li != NULL; li = li->next) {
3750 if(n->type == METHOD_NODE) {
3751 put_pub_method((Method *)n);
3752 put_prot_method((Method *)n);
3753 put_priv_method_prot((Method *)n);
3757 /* this idea is less and less apealing to me */
3759 out_printf (outh, "\n/*\n"
3760 " * Signal connection wrapper macros\n"
3763 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3764 put_signal_macros (c, TRUE);
3765 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3766 put_signal_macros (c, FALSE);
3767 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3769 put_signal_macros (c, FALSE);
3770 out_printf(outh, "\n");
3773 out_printf (out, "\n/*\n"
3774 " * Signal connection wrapper macro shortcuts\n"
3776 put_local_signal_macros (c);
3777 out_printf(outh, "\n");
3780 /* argument wrapping macros */
3781 if(get_properties > 0 || set_properties > 0) {
3782 out_printf(outh, "\n/*\n"
3783 " * Argument wrapping macros\n"
3786 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3787 put_argument_gnu_wrappers(c);
3788 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3789 put_argument_nongnu_wrappers(c);
3790 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3792 put_argument_nongnu_wrappers(c);
3797 for(li = c->nodes; li != NULL; li = li->next) {
3799 if(n->type == METHOD_NODE)
3800 add_signal_prots((Method *)n);
3806 if(any_method_to_alias(c)) {
3807 out_printf (out, "/* Short form macros */\n");
3808 make_method_aliases (c);
3811 add_interface_inits (c);
3813 if (!overrode_get_type) {
3814 if (c->bonobo_object_class != NULL)
3815 add_bonobo_object_get_type();
3816 else if (c->dynamic)
3817 add_dynamic_get_type();
3822 out_printf (out, "/* a macro for creating a new object of our type */\n");
3824 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3825 typebase, funcbase);
3827 out_printf (out, "/* a function for creating a new object of our type */\n");
3828 out_printf (out, "#include <stdarg.h>\n");
3830 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3831 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3832 "{\n\t%s *ret;\n\tva_list ap;\n"
3833 "\tva_start (ap, first);\n"
3834 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3837 "\treturn ret;\n}\n\n",
3839 no_gnu ? "" : " G_GNUC_UNUSED",
3840 typebase, typebase, typebase, funcbase);
3844 out_printf (out, "/* a function to connect glade callback */\n");
3845 out_printf (out,"static void\n"
3846 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3847 "GObject *object,\n"
3848 "const gchar *signal_name,\n"
3849 "const gchar *signal_data,\n"
3850 "GObject *connect_object,\n"
3852 "gpointer user_data)\n"
3854 "\tstatic GModule * allsymbols = NULL;\n"
3856 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3857 "\tif (allsymbols) {\n"
3858 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3859 "\t\tGCallback func;\n"
3861 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3862 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3863 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3864 "\t\t\t\tg_free(func_name);\n"
3869 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3871 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3872 "\t\tg_free(func_name);\n"
3879 for (li = nodes; li != NULL; li = li->next) {
3880 Node *node = li->data;
3881 if (node->type == CCODE_NODE) {
3882 CCode *cc = (CCode *)node;
3883 if (cc->cctype == AD_CCODE)
3884 print_ccode_block (cc);
3888 if (need_constructor)
3889 add_constructor (c);
3899 if(set_properties > 0) {
3900 add_getset_arg(c, TRUE);
3903 if(get_properties > 0) {
3904 add_getset_arg(c, FALSE);
3907 for(li = c->nodes; li != NULL; li = li->next) {
3909 if(n->type == METHOD_NODE)
3910 put_method((Method *)n);
3913 add_bad_hack_to_avoid_unused_warnings(c);
3917 print_useful_macros(void)
3919 int major = 0, minor = 0, pl = 0;
3922 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3923 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3924 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3925 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3927 /* Useful priv macro thingie */
3928 /* FIXME: this should be done the same way that priv is, as a var,
3930 out_printf (out, "#define selfp (self->_priv)\n\n");
3934 print_more_useful_macros (void)
3937 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3938 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3940 out_printf (out, "#ifdef G_LIKELY\n");
3941 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3942 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3943 out_printf (out, "#else /* ! G_LIKELY */\n");
3944 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3945 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3946 out_printf (out, "#endif /* G_LIKELY */\n");
3951 print_file_comments(void)
3953 out_printf(outh, "/* Generated by GOB (v%s)"
3954 " (do not edit directly) */\n\n", VERSION);
3956 out_printf(outph, "/* Generated by GOB (v%s)"
3957 " (do not edit directly) */\n\n", VERSION);
3958 out_printf(out, "/* Generated by GOB (v%s)"
3959 " (do not edit directly) */\n\n", VERSION);
3961 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3965 print_includes(void)
3967 gboolean found_header;
3970 /* We may need string.h for memset */
3971 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3972 out_printf(out, "#include <string.h> /* memset() */\n\n");
3975 p = g_strconcat(filebase, ".h", NULL);
3976 found_header = TRUE;
3977 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3978 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3979 found_header = FALSE;
3983 /* if we are creating a private header see if it was included */
3985 char sep[2] = {0,0};
3988 p = g_strconcat(filebase, sep, "private.h", NULL);
3989 if( ! g_list_find_custom(include_files, p,
3990 (GCompareFunc)strcmp)) {
3991 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
3995 error_printf(GOB_WARN, 0,
3996 "Implicit private header include "
3998 "\tsource file, while public "
3999 "header is at a custom location, "
4001 "\texplicitly include "
4002 "the private header below the "
4010 print_header_prefixes(void)
4014 p = replace_sep(((Class *)class)->otype, '_');
4016 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4018 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4019 "#define __%s_PRIVATE_H__\n\n"
4020 "#include \"%s.h\"\n\n", p, p, filebase);
4023 if( ! no_extern_c) {
4024 out_printf(outh, "#ifdef __cplusplus\n"
4026 "#endif /* __cplusplus */\n\n");
4028 out_printf(outph, "#ifdef __cplusplus\n"
4030 "#endif /* __cplusplus */\n\n");
4035 print_header_postfixes(void)
4038 out_printf(outh, "\n#ifdef __cplusplus\n"
4040 "#endif /* __cplusplus */\n");
4041 out_printf(outh, "\n#endif\n");
4044 out_printf(outph, "\n#ifdef __cplusplus\n"
4046 "#endif /* __cplusplus */\n");
4047 out_printf(outph, "\n#endif\n");
4056 /* print the AT_CCODE and CT_CCODE blocks */
4057 for(li = nodes; li != NULL; li = li->next) {
4058 Node *node = li->data;
4059 if(node->type == CCODE_NODE) {
4060 CCode *cc = (CCode *)node;
4061 if (cc->cctype == AT_CCODE ||
4062 cc->cctype == CT_CCODE)
4063 print_ccode_block((CCode *)node);
4069 print_header_top(void)
4073 /* mandatory includes */
4074 out_printf (outh, "#include <glib.h>\n");
4075 out_printf (outh, "#include <glib-object.h>\n");
4077 /* print the HT_CCODE blocks */
4078 for (li = nodes; li != NULL; li = li->next) {
4079 Node *node = li->data;
4080 if (node->type == CCODE_NODE) {
4081 CCode *cc = (CCode *)node;
4082 if (cc->cctype == HT_CCODE)
4083 print_ccode_block ((CCode *)node);
4089 print_enum (EnumDef *enode)
4096 funcprefix = replace_sep (enode->etype, '_');
4097 gob_strdown (funcprefix);
4098 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4100 type = remove_sep (enode->etype);
4102 out_printf (outh, "\ntypedef enum {\n");
4104 for (li = enode->values; li != NULL; li = li->next) {
4105 EnumValue *value = li->data;
4107 char *sname = gob_strdown (g_strdup (value->name));
4109 while ((p = strchr (sname, '_')) != NULL)
4112 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4113 if (value->value != NULL)
4114 out_printf (outh, " = %s", value->value);
4115 if (li->next != NULL)
4116 out_printf (outh, ",\n");
4118 out_printf (outh, "\n");
4120 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4121 enode->prefix, value->name,
4122 enode->prefix, value->name,
4128 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4130 out_printf (outh, "} %s;\n", type);
4132 str = make_pre_macro (enode->etype, "TYPE");
4133 out_printf (outh, "#define %s ", str);
4136 out_printf (outh, "%s_get_type()\n", funcprefix);
4137 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4140 "GType\n%s_get_type (void)\n"
4142 "\tstatic GType type = 0;\n"
4143 "\tif ___GOB_UNLIKELY(type == 0)\n"
4144 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4147 funcprefix, type, funcprefix);
4149 g_free (funcprefix);
4154 print_flags (Flags *fnode)
4162 funcprefix = replace_sep (fnode->ftype, '_');
4163 gob_strdown (funcprefix);
4164 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4166 type = remove_sep (fnode->ftype);
4168 out_printf (outh, "\ntypedef enum {\n");
4170 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4171 const char *name = li->data;
4173 char *sname = gob_strdown (g_strdup (name));
4175 while ((p = strchr (sname, '_')) != NULL)
4178 out_printf (outh, "\t%s_%s = 1<<%d",
4179 fnode->prefix, name, i);
4180 if (li->next != NULL)
4181 out_printf (outh, ",\n");
4183 out_printf (outh, "\n");
4185 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4186 fnode->prefix, name,
4187 fnode->prefix, name,
4193 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4195 out_printf (outh, "} %s;\n", type);
4197 str = make_pre_macro (fnode->ftype, "TYPE");
4198 out_printf (outh, "#define %s ", str);
4201 out_printf (outh, "%s_get_type()\n", funcprefix);
4202 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4205 "GType\n%s_get_type (void)\n"
4207 "\tstatic GType type = 0;\n"
4208 "\tif ___GOB_UNLIKELY(type == 0)\n"
4209 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4212 funcprefix, type, funcprefix);
4214 g_free (funcprefix);
4219 print_error (Error *enode)
4226 funcprefix = replace_sep (enode->etype, '_');
4227 gob_strdown (funcprefix);
4228 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4230 type = remove_sep (enode->etype);
4232 out_printf (outh, "\ntypedef enum {\n");
4234 for (li = enode->values; li != NULL; li = li->next) {
4235 const char *name = li->data;
4237 char *sname = gob_strdown (g_strdup (name));
4239 while ((p = strchr (sname, '_')) != NULL)
4242 out_printf (outh, "\t%s_%s", enode->prefix, name);
4243 if (li->next != NULL)
4244 out_printf (outh, ",\n");
4246 out_printf (outh, "\n");
4248 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4249 enode->prefix, name,
4250 enode->prefix, name,
4256 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4258 out_printf (outh, "} %s;\n", type);
4260 str = make_pre_macro (enode->etype, "TYPE");
4261 out_printf (outh, "#define %s ", str);
4264 out_printf (outh, "%s_get_type ()\n", funcprefix);
4265 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4268 "GType\n%s_get_type (void)\n"
4270 "\tstatic GType type = 0;\n"
4271 "\tif ___GOB_UNLIKELY(type == 0)\n"
4272 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4275 funcprefix, type, funcprefix);
4277 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4278 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4280 str = replace_sep (enode->etype, '-');
4284 "GQuark\n%s_quark (void)\n"
4286 "\tstatic GQuark q = 0;\n"
4288 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4295 g_free (funcprefix);
4300 generate_outfiles(void)
4304 print_file_comments();
4310 print_header_prefixes();
4312 print_useful_macros();
4316 print_more_useful_macros ();
4318 for (li = nodes; li != NULL; li = li->next) {
4319 Node *node = li->data;
4320 if (node->type == CCODE_NODE) {
4321 CCode *cc = (CCode *)node;
4322 if (cc->cctype != HT_CCODE &&
4323 cc->cctype != AT_CCODE &&
4324 cc->cctype != AD_CCODE)
4325 print_ccode_block ((CCode *)node);
4326 } else if (node->type == CLASS_NODE) {
4327 print_class_block ((Class *)node);
4328 } else if (node->type == ENUMDEF_NODE) {
4329 print_enum ((EnumDef *)node);
4330 } else if (node->type == FLAGS_NODE) {
4331 print_flags ((Flags *)node);
4332 } else if (node->type == ERROR_NODE) {
4333 print_error ((Error *)node);
4335 g_assert_not_reached();
4339 print_header_postfixes();
4345 fprintf(stderr, "Gob version %s\n\n", VERSION);
4346 fprintf(stderr, "gob [options] file.gob\n\n");
4347 fprintf(stderr, "Options:\n"
4348 "\t--help,-h,-? Display this help\n"
4349 "\t--version Display version\n"
4350 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4351 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4352 "\t--for-cpp Create C++ files\n"
4353 "\t--no-extern-c Never print extern \"C\" into the "
4355 "\t--no-gnu Never use GNU extentions\n"
4356 "\t--no-touch Don't touch output files unless they "
4358 "\t changed (implies --no-touch-headers)\n"
4359 "\t--no-touch-headers Don't touch headers unless they "
4361 "\t--always-private-header Always create a private header "
4363 "\t even if it would be empty\n"
4364 "\t--ondemand-private-header Create private header only when "
4367 "\t--no-private-header Don't create a private header, "
4369 "\t structure and protected "
4370 "prototypes inside c file\n"
4371 "\t--always-private-struct Always create a private pointer "
4373 "\t the object structure\n"
4374 "\t--m4 Preprocess source with m4. "
4375 "Following args will\n"
4376 "\t be passed to m4\n"
4377 "\t--m4-dir Print directory that will be "
4380 "\t--no-write,-n Don't write output files, just "
4382 "\t--no-lines Don't print '#line' to output\n"
4383 "\t--no-self-alias Don't create self type and macro "
4385 "\t--no-kill-underscores Ignored for compatibility\n"
4386 "\t-o,--output-dir The directory where output "
4387 "should be placed\n"
4388 "\t--file-sep[=c] replace default \'-\' file "
4389 "name separator\n\n"
4390 "\t--gtk3 Use gtk+3\n"
4392 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4396 parse_options(int argc, char *argv[])
4399 int got_file = FALSE;
4400 int no_opts = FALSE;
4401 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4405 for(i = 1 ; i < argc; i++) {
4407 char *new_commandline;
4408 g_assert(m4_commandline!=NULL);
4410 /* check whether this one looks like the filename */
4411 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4413 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4417 /* insert flags before the filename */
4418 new_commandline=g_strconcat(m4_commandline,
4426 /* just an ordinary option */
4428 new_commandline=g_strconcat(m4_commandline,
4433 /* free old commandline */
4434 g_free(m4_commandline);
4435 m4_commandline=new_commandline;
4437 } else if(no_opts ||
4438 argv[i][0] != '-') {
4441 fprintf(stderr, "Specify only one file!\n");
4447 } else if(strcmp(argv[i], "--help")==0) {
4450 } else if(strcmp(argv[i], "--version")==0) {
4451 fprintf(stderr, "Gob version %s\n", VERSION);
4453 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4454 exit_on_warn = TRUE;
4455 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4456 exit_on_warn = FALSE;
4457 } else if(strcmp(argv[i], "--for-cpp")==0) {
4459 } else if(strcmp(argv[i], "--no-touch")==0) {
4461 no_touch_headers = TRUE;
4462 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4463 no_touch_headers = TRUE;
4464 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4465 private_header = PRIVATE_HEADER_ONDEMAND;
4466 } else if(strcmp(argv[i], "--always-private-header")==0) {
4467 private_header = PRIVATE_HEADER_ALWAYS;
4468 } else if(strcmp(argv[i], "--no-private-header")==0) {
4469 private_header = PRIVATE_HEADER_NEVER;
4470 } else if(strcmp(argv[i], "--no-gnu")==0) {
4472 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4474 } else if(strcmp(argv[i], "--no-write")==0) {
4476 } else if(strcmp(argv[i], "--no-lines")==0) {
4478 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4479 no_self_alias = TRUE;
4480 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4482 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4483 always_private_struct = TRUE;
4484 } else if(strcmp(argv[i], "--m4-dir")==0) {
4485 printf("%s\n",M4_INCLUDE_DIR);
4487 } else if(strcmp(argv[i], "--m4")==0) {
4491 m4_commandline=g_strdup(M4_COMMANDLINE);
4492 } else if(strcmp(argv[i], "--m4-clean")==0) {
4496 m4_commandline=g_strdup(M4_COMMANDLINE);
4497 } else if (strcmp (argv[i], "-o") == 0 ||
4498 strcmp (argv[i], "--output-dir") == 0) {
4500 output_dir = g_strdup (argv[i+1]);
4505 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4508 strlen ("--output-dir=")) == 0) {
4509 char *p = strchr (argv[i], '=');
4510 g_assert (p != NULL);
4511 output_dir = g_strdup (p+1);
4512 } else if (strncmp (argv[i], "--file-sep=",
4513 strlen ("--file-sep=")) == 0) {
4514 char *p = strchr (argv[i], '=');
4515 g_assert (p != NULL);
4517 } else if (strncmp (argv[i], "--file-sep",
4518 strlen ("--file-sep")) == 0) {
4520 file_sep = (argv[i+1])[0];
4525 } else if(strcmp(argv[i], "--gtk3")==0) {
4527 } else if(strcmp(argv[i], "--")==0) {
4528 /*further arguments are files*/
4530 } else if(strncmp(argv[i], "--", 2)==0) {
4531 /*unknown long option*/
4532 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4536 /*by now we know we have a string starting with
4537 - which is a short option string*/
4539 for(p = argv[i] + 1; *p; p++) {
4553 "Unknown option '%c'!\n", *p);
4562 /* if we are using m4, and got no filename, append m4 flags now */
4563 if(!got_file && use_m4 && !use_m4_clean) {
4564 char *new_commandline;
4565 new_commandline=g_strconcat(m4_commandline,
4569 g_free(m4_commandline);
4570 m4_commandline=new_commandline;
4576 compare_and_move (const char *old_filename)
4578 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4580 gboolean equal = FALSE;
4582 old_f = fopen (old_filename, "r");
4585 gboolean error = FALSE;
4587 new_f = fopen (new_filename, "r");
4596 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4597 if (ferror (new_f)) {
4599 error_printf (GOB_ERROR, 0,
4600 "Can't read %s: %s",
4602 g_strerror (errno));
4606 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4608 || feof (new_f) != feof (old_f)
4610 || memcmp (new_buf, old_buf, new_n) != 0)
4619 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4620 new_filename, g_strerror (errno));
4628 if (! equal && unlink (old_filename) != 0) {
4629 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4630 old_filename, g_strerror (errno));
4636 if (unlink (new_filename) != 0)
4637 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4638 new_filename, g_strerror (errno));
4640 if (rename (new_filename, old_filename) != 0)
4641 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4642 new_filename, old_filename,
4643 g_strerror (errno));
4647 g_free (new_filename);
4651 main(int argc, char *argv[])
4653 parse_options(argc, argv);
4656 yyin = popen(m4_commandline, "r");
4658 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4662 } else if(filename) {
4663 yyin = fopen(filename, "r");
4665 fprintf(stderr, "Error: can't open file '%s'\n",
4674 /* This is where parsing is done */
4677 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4679 /* close input file */
4680 if(use_m4) pclose(yyin);
4685 error_print (GOB_ERROR, 0, "no class defined");
4688 exit_on_error = FALSE;
4690 signals = count_signals ((Class *)class);
4691 set_properties = count_set_properties ((Class *)class) +
4692 count_set_arguments ((Class *)class);
4693 get_properties = count_get_properties ((Class *)class) +
4694 count_get_arguments ((Class *)class);
4695 overrides = count_overrides ((Class *)class);
4696 privates = count_privates ((Class *)class);
4697 protecteds = count_protecteds ((Class *)class);
4698 unreftors = count_unreftors ((Class *)class);
4699 destructors = count_destructors ((Class *)class);
4700 initializers = count_initializers ((Class *)class);
4701 glade_widgets = count_glade_widgets ((Class *)class);
4702 overrode_get_type = find_get_type ((Class *)class);
4705 make_inits ((Class *)class);
4707 find_constructor ((Class *)class);
4708 if (user_constructor != NULL)
4709 need_constructor = TRUE;
4711 find_dispose ((Class *)class);
4712 if (unreftors > 0 ||
4713 dispose_handler != NULL ||
4714 user_dispose_method != NULL)
4715 need_dispose = TRUE;
4717 find_finalize ((Class *)class);
4718 if (destructors > 0 ||
4720 user_finalize_method != NULL) {
4721 need_finalize = TRUE;
4724 check_bad_symbols ((Class *)class);
4725 check_duplicate_symbols ((Class *)class);
4726 check_duplicate_overrides ((Class *)class);
4727 check_duplicate_signals_args ((Class *)class);
4728 check_public_new ((Class *)class);
4729 check_vararg ((Class *)class);
4730 check_firstarg ((Class *)class);
4731 check_nonvoidempty ((Class *)class);
4732 check_signal_args ((Class *)class);
4733 check_property_types ((Class *)class);
4734 check_argument_types ((Class *)class);
4735 check_func_arg_checks ((Class *)class);
4736 check_func_attrs ((Class *)class);
4737 check_for_class_destructors ((Class *)class);
4739 exit_on_error = TRUE;
4744 any_special = setup_special_array ((Class *)class, special_array);
4748 generate_outfiles ();
4759 compare_and_move (outfilebase);
4761 compare_and_move (outfilephbase);
4763 if (no_touch_headers)
4764 compare_and_move (outfilehbase);