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;
125 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
126 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
127 char *m4_commandline = NULL;
128 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
129 #define M4_BASE_FILENAME "gobm4.m4"
130 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
131 #define M4_COMMANDLINE "m4"
133 int method_unique_id = 1;
138 filebase = replace_sep (((Class *)class)->otype, file_sep);
139 gob_strdown (filebase);
141 if (output_dir != NULL &&
142 output_dir[0] != '\0') {
143 fullfilebase = g_build_filename (output_dir, filebase, NULL);
145 fullfilebase = g_strdup (filebase);
148 funcbase = replace_sep (((Class *)class)->otype, '_');
149 gob_strdown (funcbase);
151 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
152 gob_strdown (pfuncbase);
154 macrobase = replace_sep (((Class *)class)->otype, '_');
155 gob_strup (macrobase);
157 macrois = make_pre_macro (((Class *)class)->otype, "IS");
158 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
160 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
161 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
163 typebase = remove_sep (((Class *)class)->otype);
165 ptypebase = remove_sep (((Class *)class)->ptype);
169 get_gtk_doc (const char *id)
176 val = g_hash_table_lookup(gtk_doc_hash, id);
178 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
180 val = g_hash_table_lookup(gtk_doc_hash, id);
182 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
188 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
192 s = get_type(t, postfix_to_stars);
193 out_printf(fp, "%s", s);
199 print_method (FILE *fp,
200 const char *typeprefix,
201 const char *nameprefix,
202 const char *subnameprefix,
203 const char *namepostfix,
204 const char *afterargs,
207 gboolean print_funcattrs,
208 gboolean one_arg_per_line,
209 gboolean no_funcbase,
210 gboolean kill_underscore,
211 gboolean first_unused,
217 out_printf(fp, "%s", typeprefix);
218 print_type(fp, m->mtype, TRUE);
223 out_printf(fp, "%s%s%s%s(",
224 nameprefix, subnameprefix, id, namepostfix);
226 out_printf(fp, "%s%s_%s%s%s(",
227 nameprefix, funcbase, subnameprefix, id,
231 for(li=m->args; li; li=g_list_next(li)) {
232 FuncArg *arg = li->data;
233 const char *unused = "";
236 ! for_cpp && /* g++ has a cow with this */
239 unused = " G_GNUC_UNUSED";
242 print_type(fp, arg->atype, FALSE);
244 out_printf (fp, "___fake___");
246 out_printf(fp, "%s%s%s,%s", arg->name,
247 arg->atype->postfix ?
248 arg->atype->postfix : "",
250 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
252 out_printf(fp, "%s%s%s", arg->name,
253 arg->atype->postfix ?
254 arg->atype->postfix : "",
258 out_printf(fp, ",%s...",
259 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
261 out_printf(fp, "void");
263 /* Slightly icky: sometimes we are called st m->funcattrs
264 hasn't been set, but if so it should be NULL since its been
266 if(print_funcattrs && m->funcattrs != NULL
267 && strlen(m->funcattrs) > 0) {
268 /* To keep the output neat, we trim off the trailing '\n'
269 from the end of funcattrs for a moment. */
270 size_t funcattrs_len = strlen(m->funcattrs);
271 gboolean funcattrs_chomped = FALSE;
272 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
273 m->funcattrs[funcattrs_len - 1] = '\0';
274 funcattrs_chomped = TRUE;
276 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
277 /* Put it back like it was (though it shouldn't matter). */
278 if (funcattrs_chomped) {
279 (m->funcattrs)[funcattrs_len - 1] = '\n';
283 out_printf(fp, "%s)%s", afterargs, postfix);
288 any_method_to_alias(Class *c)
292 for(li=c->nodes;li;li=g_list_next(li)) {
293 Node *node = li->data;
294 if(node->type == METHOD_NODE) {
295 Method *m = (Method *)node;
297 if(m->method == INIT_METHOD ||
298 m->method == CLASS_INIT_METHOD ||
299 m->method == CONSTRUCTOR_METHOD ||
300 m->method == DISPOSE_METHOD ||
301 m->method == FINALIZE_METHOD ||
302 m->method == OVERRIDE_METHOD)
313 make_method_aliases (Class *c)
317 for(li = c->nodes; li != NULL; li = li->next) {
318 Node *node = li->data;
319 if(node->type == METHOD_NODE) {
320 Method *m = (Method *)node;
322 if(m->method == INIT_METHOD ||
323 m->method == CLASS_INIT_METHOD ||
324 m->method == CONSTRUCTOR_METHOD ||
325 m->method == DISPOSE_METHOD ||
326 m->method == FINALIZE_METHOD ||
327 m->method == OVERRIDE_METHOD)
330 out_printf (out, "#define self_%s %s_%s\n",
339 add_bad_hack_to_avoid_unused_warnings(const Class *c)
343 /* if we haven't had any methods, just return */
348 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
350 "/*REALLY BAD HACK\n"
351 " This is to avoid unused warnings if you don't call\n"
352 " some method. I need to find a better way to do\n"
353 " this, not needed in GCC since we use some gcc\n"
354 " extentions to make saner, faster code */\n"
356 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
358 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
359 for(li=c->nodes;li;li=g_list_next(li)) {
360 Node *node = li->data;
361 if(node->type == METHOD_NODE) {
362 Method *m = (Method *)node;
364 if(m->method == INIT_METHOD ||
365 m->method == CLASS_INIT_METHOD ||
366 m->method == CONSTRUCTOR_METHOD ||
367 m->method == DISPOSE_METHOD ||
368 m->method == FINALIZE_METHOD ||
369 m->method == OVERRIDE_METHOD)
372 /* in C++ mode we don't alias new */
373 if(for_cpp && strcmp(m->id, "new")==0)
376 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
379 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
382 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
384 out_printf(out, "}\n\n");
388 put_variable(const Variable *v, FILE *fp)
390 out_printf(fp, "\t");
391 print_type(fp, v->vtype, FALSE);
392 out_printf(fp, "%s%s;", v->id,
394 v->vtype->postfix:"");
395 if(v->scope == PROTECTED_SCOPE)
396 out_printf(fp, " /* protected */");
397 out_printf(fp, "\n");
401 put_vs_method(const Method *m)
403 if(m->method != SIGNAL_LAST_METHOD &&
404 m->method != SIGNAL_FIRST_METHOD &&
405 m->method != VIRTUAL_METHOD)
408 /* if a signal mark it as such */
409 if(m->method != VIRTUAL_METHOD)
410 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
411 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
413 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
414 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
419 put_pub_method(const Method *m)
421 if(m->scope != PUBLIC_SCOPE)
424 out_addline_infile(outh, m->line_no);
425 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
426 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
427 out_addline_outfile(outh);
431 put_signal_macro (const Method *m, gboolean gnu)
433 if(m->method != SIGNAL_LAST_METHOD &&
434 m->method != SIGNAL_FIRST_METHOD)
439 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
440 "g_signal_connect(%s(object),\"%s\","
441 "(GCallback)(func),(data))\n",
442 funcbase, m->id, macrobase, m->id);
445 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
446 "g_signal_connect_after(%s(object),\"%s\","
447 "(GCallback)(func),(data))\n",
448 funcbase, m->id, macrobase, m->id);
451 out_printf (outh, "#define %s_connect_data__%s"
452 "(object,func,data,destroy_data,flags)\t"
453 "g_signal_connect_data(%s(object),\"%s\","
454 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
455 funcbase, m->id, macrobase, m->id);
458 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
460 "%s(__extension__ ({%s *___object = (object); ___object; })),"
462 "(GCallback) __extension__ ({",
463 funcbase, m->id, macrobase, typebase, m->id);
464 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
465 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
466 out_printf (outh, "___%s; }), (data))\n", m->id);
469 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
470 "g_signal_connect_after("
471 "%s(__extension__ ({%s *___object = (object); ___object; })),"
473 "(GCallback) __extension__ ({",
474 funcbase, m->id, macrobase, typebase, m->id);
475 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
476 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
477 out_printf (outh, "___%s; }), (data))\n", m->id);
480 out_printf (outh, "#define %s_connect_data__%s"
481 "(object,func,data,destroy_data,flags)\t"
482 "g_signal_connect_data("
483 "%s(__extension__ ({%s *___object = (object); ___object; })),"
485 "(GCallback) __extension__ ({",
486 funcbase, m->id, macrobase, typebase, m->id);
487 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
488 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
489 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
494 put_signal_macros (const Class *c, gboolean gnu)
501 for (li = c->nodes; li != NULL; li = li->next) {
502 const Node *n = li->data;
503 if (n->type == METHOD_NODE)
504 put_signal_macro ((Method *)n, gnu);
509 put_local_signal_macro (const Method *m)
511 if(m->method != SIGNAL_LAST_METHOD &&
512 m->method != SIGNAL_FIRST_METHOD)
516 out_printf (out, "#define self_connect__%s(object,func,data)\t"
517 "%s_connect__%s((object),(func),(data))\n",
518 m->id, funcbase, m->id);
521 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
522 "%s_connect_after__%s((object),(func),(data))\n",
523 m->id, funcbase, m->id);
526 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
527 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
528 m->id, funcbase, m->id);
532 put_local_signal_macros (const Class *c)
539 for (li = c->nodes; li != NULL; li = li->next) {
540 const Node *n = li->data;
541 if (n->type == METHOD_NODE)
542 put_local_signal_macro ((Method *)n);
548 put_prot_method(const Method *m)
552 if(m->scope != PROTECTED_SCOPE)
555 f = outph ? outph : out;
557 out_addline_infile(f, m->line_no);
558 print_method(f, "", "\t", "", "\t", "", ";\n",
559 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
560 out_addline_outfile(f);
564 put_priv_method_prot(const Method *m)
566 if(m->method == SIGNAL_LAST_METHOD ||
567 m->method == SIGNAL_FIRST_METHOD ||
568 m->method == VIRTUAL_METHOD) {
571 "static ", "___real_", "", " ", "", ";\n",
572 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
574 /* no else, here, it might still have a private prototype, it's not
577 if((m->method == OVERRIDE_METHOD &&
580 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
582 out_addline_infile(out, m->line_no);
583 print_method(out, "static ", s, "", " ", "",
584 no_gnu?";\n":" G_GNUC_UNUSED;\n",
585 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
587 out_addline_outfile(out);
589 } else if(m->scope == PRIVATE_SCOPE ||
590 m->method == INIT_METHOD ||
591 m->method == CLASS_INIT_METHOD ||
592 m->method == CONSTRUCTOR_METHOD ||
593 m->method == DISPOSE_METHOD ||
594 m->method == FINALIZE_METHOD) {
596 out_addline_infile(out, m->line_no);
597 print_method(out, "static ", "", "", " ", "",
598 no_gnu?";\n":" G_GNUC_UNUSED;\n",
599 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
601 out_addline_outfile(out);
606 make_func_arg (const char *typename, gboolean is_class, const char *name)
613 tn = g_strconcat (typename, ":Class", NULL);
615 tn = g_strdup (typename);
617 type = node_new (TYPE_NODE,
621 node = node_new (FUNCARG_NODE,
622 "atype:steal", (Type *)type,
625 return g_list_prepend (NULL, node);
629 make_inits(Class *cl)
631 int got_class_init = FALSE;
632 int got_init = FALSE;
635 for(li=cl->nodes;li;li=g_list_next(li)) {
637 if(n->type == METHOD_NODE) {
638 Method *m = (Method *)n;
639 if(m->method == INIT_METHOD) {
641 error_print(GOB_ERROR, m->line_no, "init defined more then once");
643 } else if(m->method == CLASS_INIT_METHOD) {
645 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
646 got_class_init = TRUE;
650 if(!got_class_init) {
651 Type *type = (Type *)node_new (TYPE_NODE,
654 node = node_new (METHOD_NODE,
656 "method", CLASS_INIT_METHOD,
659 "args:steal", make_func_arg (cl->otype,
662 "unique_id", method_unique_id++,
664 cl->nodes = g_list_prepend(cl->nodes, node);
667 Type *type = (Type *)node_new (TYPE_NODE,
670 node = node_new (METHOD_NODE,
672 "method", INIT_METHOD,
675 "args:steal", make_func_arg (cl->otype,
676 FALSE /* is_class */,
678 "unique_id", method_unique_id++,
680 cl->nodes = g_list_prepend(cl->nodes, node);
685 find_method(const Class *cl, int method, const char *id)
689 for(li=cl->nodes;li;li=g_list_next(li)) {
691 if(n->type == METHOD_NODE) {
692 Method *m = (Method *)n;
693 if (m->method == method
694 && (id == NULL || strcmp(m->id, id)==0))
703 find_constructor(const Class *cl)
705 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
709 find_dispose(const Class *cl)
711 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
712 if (dispose_handler != NULL) {
713 if(strcmp(dispose_handler->otype, "G:Object") != 0)
714 error_print(GOB_ERROR, dispose_handler->line_no,
715 "dispose method override "
716 "of class other then "
718 if(g_list_length(dispose_handler->args) != 1)
719 error_print(GOB_ERROR, dispose_handler->line_no,
720 "dispose method override "
721 "with more then one "
725 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
729 find_finalize(const Class *cl)
731 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
732 if (finalize_handler != NULL) {
733 if(strcmp(finalize_handler->otype, "G:Object") != 0)
734 error_print(GOB_ERROR, finalize_handler->line_no,
735 "finalize method override "
736 "of class other then "
738 if(g_list_length(finalize_handler->args) != 1)
739 error_print(GOB_ERROR, finalize_handler->line_no,
740 "finalize method override "
741 "with more then one "
745 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
749 /* hash of method -> name of signal prototype */
750 static GHashTable *marsh = NULL;
752 /* list of methods with different signal prototypes,
753 we check this list if we can use a signal prototype of a
754 previous signal method, there are only uniques here */
755 static GList *eq_signal_methods = NULL;
757 /* compare a list of strings */
759 is_list_equal(const GList *a, const GList *b)
761 for(;a && b; a=a->next, b=b->next) {
762 if(strcmp(a->data, b->data)!=0) {
766 /* the the lists were different length */
773 find_same_type_signal(const Method *m)
776 for(li=eq_signal_methods;li;li=li->next) {
777 Method *mm = li->data;
778 if(is_list_equal(mm->gtktypes, m->gtktypes))
785 print_signal_marsal_args (const Method *m)
787 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
790 for (i = 0, li = m->gtktypes->next;
792 i++, li = li->next) {
795 if (strcmp (li->data, "UNICHAR") == 0)
796 /* hack because glib is braindamaged */
797 get_func = g_strdup ("g_value_get_uint");
798 else if (strncmp(li->data, "BOXED_", 6) == 0)
799 get_func = g_strdup ("g_value_get_boxed");
801 get_func = g_strdup_printf
802 ("g_value_get_%s", (char *)li->data);
804 gob_strdown (get_func);
805 out_printf (out, ",\n\t\t(%s) "
806 "%s (param_values + %d)",
807 get_cast (li->data, FALSE),
812 out_printf (out, ",\n\t\tdata2);\n");
817 add_signal_prots(Method *m)
823 gboolean ret_none = FALSE;
824 gboolean arglist_none = FALSE;
826 const char *unused = "";
828 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
829 unused = " G_GNUC_UNUSED";
832 if (m->method != SIGNAL_LAST_METHOD &&
833 m->method != SIGNAL_FIRST_METHOD)
837 marsh = g_hash_table_new(NULL, NULL);
839 g_assert (m->gtktypes->next != NULL);
841 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
842 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
844 if (ret_none && arglist_none)
847 /* if we already did a signal prototype just use that */
848 mm = find_same_type_signal (m);
850 s = g_hash_table_lookup (marsh, mm);
851 g_hash_table_insert (marsh, m, s);
858 retcast = get_cast (m->gtktypes->data, FALSE);
860 s = g_strdup_printf("Sig%d", sig++);
862 g_hash_table_insert(marsh, m, s);
863 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
865 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
866 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
867 get_cast(m->gtktypes->data, FALSE), s, typebase);
869 if ( ! arglist_none) {
870 for (li = m->gtktypes->next; li != NULL; li = li->next)
871 out_printf (out, "%s, ", get_cast (li->data, FALSE));
873 out_printf (out, "gpointer);\n");
875 out_printf (out, "\nstatic void\n"
876 "___marshal_%s (GClosure *closure,\n"
877 "\tGValue *return_value%s,\n"
878 "\tguint n_param_values,\n"
879 "\tconst GValue *param_values,\n"
880 "\tgpointer invocation_hint%s,\n"
881 "\tgpointer marshal_data)\n"
888 out_printf (out, "\t%s v_return;\n", retcast);
890 out_printf (out, "\tregister ___%s callback;\n"
891 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
892 "\tregister gpointer data1, data2;\n\n",
895 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
896 arglist_none ? 1 : g_list_length (m->gtktypes));
899 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
900 "\t\tdata1 = closure->data;\n"
901 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
903 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
904 "\t\tdata2 = closure->data;\n"
907 out_printf (out, "\tcallback = (___%s) "
908 "(marshal_data != NULL ? marshal_data : cc->callback);"
912 out_printf (out, "\tcallback ((%s *)data1", typebase);
914 out_printf (out, "\tv_return = callback ((%s *)data1",
918 print_signal_marsal_args (m);
921 /* FIXME: This code is so fucking ugly it hurts */
922 gboolean take_ownership =
923 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
924 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
928 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
929 /* hack because glib is braindamaged */
930 set_func = g_strdup ("g_value_set_uint");
932 set_func = g_strdup_printf ("g_value_set_%s%s",
933 (char *)m->gtktypes->data,
935 "_take_ownership" : "");
936 gob_strdown (set_func);
938 out_printf (out, "\n\t%s (return_value, v_return);\n",
943 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
945 out_printf (out, "\n\treturn_value = NULL;\n");
946 out_printf (out, "\tinvocation_hint = NULL;\n");
949 out_printf (out, "}\n\n");
956 out_printf(out, "\n");
958 out_printf(out, "enum {\n");
959 for(li=c->nodes;li;li=g_list_next(li)) {
961 if(n->type == METHOD_NODE) {
962 Method *m = (Method *)n;
963 if(m->method == SIGNAL_LAST_METHOD ||
964 m->method == SIGNAL_FIRST_METHOD) {
965 char *s = g_strdup(m->id);
967 out_printf(out, "\t%s_SIGNAL,\n", s);
972 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
974 if (set_properties > 0 ||
975 get_properties > 0) {
976 out_printf(out, "enum {\n\tPROP_0");
977 for(li=c->nodes;li;li=g_list_next(li)) {
979 if (n->type == PROPERTY_NODE) {
980 Property *p = (Property *)n;
981 char *s = g_strdup (p->name);
983 out_printf (out, ",\n\tPROP_%s", s);
985 } else if (n->type == ARGUMENT_NODE) {
986 Argument *a = (Argument *)n;
987 char *s = g_strdup(a->name);
989 out_printf(out, ",\n\tPROP_%s", s);
993 out_printf(out, "\n};\n\n");
998 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1000 out_printf(out, "/* pointer to the class of our parent */\n");
1001 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
1005 add_interface_methods (Class *c, const char *interface)
1008 gboolean added_line = FALSE;
1010 for (li = c->nodes; li != NULL; li = li->next) {
1012 Method *m = (Method *)n;
1013 if (n->type != METHOD_NODE ||
1014 m->method == OVERRIDE_METHOD ||
1015 m->interface == NULL ||
1016 strcmp (m->interface, interface) != 0)
1019 if (m->line_no > 0) {
1020 out_addline_infile (out, m->line_no);
1022 } else if (m->line_no == 0 &&
1024 out_addline_outfile (out);
1027 out_printf (out, "\tiface->%s = self_%s;\n",
1031 out_addline_outfile (out);
1035 add_interface_inits (Class *c)
1039 if (c->interfaces == NULL)
1042 out_printf(out, "\n");
1044 for (li = c->interfaces; li != NULL; li = li->next) {
1045 const char *interface = li->data;
1047 char *name = replace_sep (interface, '_');
1048 char *type = remove_sep (interface);
1050 /* EEEK! evil, we should have some sort of option
1051 * to force this for arbitrary interfaces, since
1052 * some are Class and some are Iface. Glib is shite
1053 * in consistency. */
1054 if (strcmp (type, "GtkEditable") == 0 ||
1055 strcmp (type, "GTypePlugin") == 0)
1058 /* We'll assume Iface is the standard ending */
1061 out_printf (out, "\nstatic void\n"
1062 "___%s_init (%s%s *iface)\n"
1066 add_interface_methods (c, interface);
1068 out_printf (out, "}\n\n");
1076 add_interface_infos (void)
1079 for (li = ((Class *)class)->interfaces;
1082 char *name = replace_sep (li->data, '_');
1084 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1085 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1095 add_interfaces (void)
1098 for (li = ((Class *)class)->interfaces;
1101 char *name = replace_sep (li->data, '_');
1102 char *type = make_pre_macro (li->data, "TYPE");
1105 "\t\tg_type_add_interface_static (type,\n"
1107 "\t\t\t&%s_info);\n",
1119 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1123 "%s_get_type (void)\n"
1125 "\tstatic GType type = 0;\n\n"
1126 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1127 "\t\tstatic const GTypeInfo info = {\n"
1128 "\t\t\tsizeof (%sClass),\n"
1129 "\t\t\t(GBaseInitFunc) NULL,\n"
1130 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1131 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1132 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1133 "\t\t\tNULL /* class_data */,\n"
1134 "\t\t\tsizeof (%s),\n"
1135 "\t\t\t%d /* n_preallocs */,\n"
1136 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1139 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1141 add_interface_infos ();
1144 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
1145 pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1153 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1155 chunk_size, chunk_size);
1165 add_bonobo_object_get_type (void)
1167 /* char *chunk_size = ((Class*)class)->chunk_size; */
1168 /* _vicious_ spanks seth with a rusty nail
1170 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1171 "gob2 doesn't officially support it yet. It'd be safer "
1172 "and a lot more fun to blow goats.\"\n");
1177 "%s_get_type (void)\n" /* 1 */
1179 "\tstatic GType type = 0;\n\n"
1180 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1181 "\t\tstatic const GTypeInfo info = {\n"
1182 "\t\t\tsizeof (%sClass),\n" /* 2 */
1183 "\t\t\t(GBaseInitFunc) NULL,\n"
1184 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1185 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1186 "\t\t\tNULL, /* class_finalize */\n"
1187 "\t\t\tNULL, /* class_data */\n"
1188 "\t\t\tsizeof (%s),\n" /* 4 */
1189 "\t\t\t0, /* n_preallocs */\n"
1190 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1199 add_interface_infos ();
1202 "\t\ttype = bonobo_type_unique (\n"
1203 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1204 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1205 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1206 "\t\t\t&info, \"%s\");\n", /* 3 */
1207 ((Class*)class)->bonobo_object_class /* 1 */,
1216 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1218 chunk_size, chunk_size);
1227 add_overrides(Class *c, const char *oname,
1228 gboolean did_base_obj)
1234 done = g_hash_table_new (g_str_hash, g_str_equal);
1236 s = g_strdup ("GObject");
1237 g_hash_table_insert (done, s, s);
1239 for (li = c->nodes; li != NULL; li = li->next) {
1242 Method *m = (Method *)n;
1243 if(n->type != METHOD_NODE ||
1244 m->method != OVERRIDE_METHOD)
1247 s = remove_sep(m->otype);
1249 if(g_hash_table_lookup(done, s)) {
1253 g_hash_table_insert(done, s, s);
1255 f = replace_sep(m->otype, '_');
1258 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1263 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1264 g_hash_table_destroy (done);
1268 make_run_signal_flags(Method *m, gboolean last)
1283 gs = g_string_new(NULL);
1286 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1288 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1290 if(m->scope == PUBLIC_SCOPE)
1291 g_string_append(gs, " | G_SIGNAL_ACTION");
1293 for(li = m->flags; li; li = li->next) {
1294 char *flag = li->data;
1296 for(i=0;flags[i];i++) {
1297 if(strcmp(flags[i], flag)==0)
1300 /* if we haven't found it in our list */
1302 error_printf(GOB_WARN, m->line_no,
1303 "Unknown flag '%s' used, "
1304 "perhaps it was misspelled",
1307 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1311 char *ret = gs->str;
1312 g_string_free(gs, FALSE);
1319 add_signals(Class *c)
1323 out_printf(out, "\n");
1324 for(li=c->nodes;li;li=g_list_next(li)) {
1326 char *mar, *sig, *flags;
1327 gboolean is_none, last = FALSE;
1328 Method *m = (Method *)n;
1330 if(n->type != METHOD_NODE ||
1331 (m->method != SIGNAL_FIRST_METHOD &&
1332 m->method != SIGNAL_LAST_METHOD))
1335 if(m->method == SIGNAL_FIRST_METHOD)
1340 if(g_hash_table_lookup(marsh, m))
1341 mar = g_strconcat("___marshal_",
1342 (char *)g_hash_table_lookup(marsh, m),
1345 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1347 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1349 sig = g_strdup (m->id);
1351 flags = make_run_signal_flags (m, last);
1352 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1353 "\t\tg_signal_new (\"%s\",\n"
1354 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1355 "\t\t\t(GSignalFlags)(%s),\n"
1356 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1357 "\t\t\tNULL, NULL,\n"
1359 "\t\t\tG_TYPE_%s, %d",
1362 typebase, m->id, mar,
1363 (char *)m->gtktypes->data,
1364 is_none ? 0 : g_list_length(m->gtktypes->next));
1372 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1373 char *str = l->data;
1374 if (strncmp (str, "BOXED_", 6) == 0)
1375 t = g_strdup (&(str[6]));
1377 t = g_strconcat ("G_TYPE_", str, NULL);
1378 out_printf (out, ",\n\t\t\t%s", t);
1383 out_printf(out, ");\n");
1385 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1388 out_printf(out, "\tif ___GOB_UNLIKELY(");
1389 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1390 out_printf(out, "sizeof(");
1391 print_type(out, m->mtype, FALSE);
1392 out_printf(out, "%s",
1394 m->mtype->postfix : "");
1395 out_printf(out, ") != sizeof(%s) || ",
1396 get_cast(m->gtktypes->data, FALSE));
1399 for(al = m->args->next, gl = m->gtktypes->next;
1400 al != NULL && gl != NULL;
1401 al = al->next, gl = gl->next) {
1402 FuncArg *arg = al->data;
1403 char *gtkarg = gl->data;
1405 out_printf(out, "sizeof(");
1406 print_type(out, arg->atype, FALSE);
1407 out_printf(out, "%s",
1408 arg->atype->postfix ?
1409 arg->atype->postfix : "");
1410 out_printf(out, ") != sizeof(%s) || ",
1411 get_cast(gtkarg, FALSE));
1415 "parent_class == NULL /* avoid warning */");
1417 out_printf(out, ") {\n"
1418 "\t\tg_error(\"%s line %d: Type mismatch "
1419 "of \\\"%s\\\" signal signature\");\n"
1421 filename, m->line_no, m->id);
1428 set_def_handlers(Class *c, const char *oname)
1431 gboolean set_line = FALSE;
1433 out_printf(out, "\n");
1434 for(li = c->nodes; li; li = g_list_next(li)) {
1436 Method *m = (Method *)n;
1438 if(n->type != METHOD_NODE ||
1439 (m->method != SIGNAL_FIRST_METHOD &&
1440 m->method != SIGNAL_LAST_METHOD &&
1441 m->method != VIRTUAL_METHOD &&
1442 m->method != OVERRIDE_METHOD))
1445 if(m->line_no > 0 && m->cbuf) {
1446 out_addline_infile(out, m->line_no);
1448 } else if(set_line) {
1449 out_addline_outfile(out);
1454 if (m->method == OVERRIDE_METHOD) {
1456 s = replace_sep (m->otype, '_');
1460 dispose_handler != NULL &&
1461 strcmp (m->id, "dispose") == 0)
1462 out_printf (out, "\tg_object_class->dispose "
1464 else if (need_finalize &&
1466 strcmp(m->id, "finalize") == 0)
1468 "\tg_object_class->finalize = ___finalize;\n");
1469 else if (m->cbuf != NULL)
1471 "\t%s_class->%s = ___%x_%s_%s;\n",
1472 s, m->id, (guint)m->unique_id,
1475 out_printf(out, "\t%s_class->%s = NULL;\n",
1479 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1483 out_printf(out, "\t%s->%s = NULL;\n",
1488 out_addline_outfile(out);
1492 make_argument (Argument *a)
1497 char *argflags[] = {
1505 flags = g_string_new ("(GParamFlags)(");
1507 if(a->get && a->set)
1508 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1510 g_string_append (flags, "G_PARAM_READABLE");
1512 g_string_append (flags, "G_PARAM_WRITABLE");
1514 g_assert(a->get || a->set);
1516 for (l = a->flags; l != NULL; l = l->next) {
1517 char *flag = l->data;
1519 if(strcmp (flag, "READABLE") == 0 ||
1520 strcmp (flag, "WRITABLE") == 0) {
1521 error_print(GOB_WARN, a->line_no,
1523 "WRITABLE argument flags are "
1524 "set automatically");
1527 for(i = 0; argflags[i]; i++) {
1528 if(strcmp(argflags[i], flag)==0)
1531 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1534 g_string_append (flags, ")");
1536 s = g_strdup(a->name);
1538 if (!strcmp (a->gtktype, "ENUM"))
1539 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1540 "\t\tG_TYPE_ENUM, 0,\n"
1542 a->name, flags->str);
1543 if (!strcmp (a->gtktype, "FLAGS"))
1544 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1545 "\t\tG_TYPE_FLAGS, 0,\n"
1547 a->name, flags->str);
1548 else if (!strcmp (a->gtktype, "OBJECT"))
1549 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1550 "\t\tG_TYPE_OBJECT,\n"
1552 a->name, flags->str);
1553 else if (!strcmp (a->gtktype, "STRING"))
1554 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1557 a->name, flags->str);
1558 else if (!strcmp (a->gtktype, "INT"))
1559 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1560 "\t\tG_MININT, G_MAXINT,\n"
1563 a->name, flags->str);
1564 else if (!strcmp (a->gtktype, "UINT"))
1565 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1566 "\t\t0, G_MAXUINT,\n"
1569 a->name, flags->str);
1570 else if (!strcmp (a->gtktype, "INT"))
1571 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1572 "\t\tG_MININT, G_MAXINT,\n"
1575 a->name, flags->str);
1576 else if (!strcmp (a->gtktype, "CHAR"))
1577 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1581 a->name, flags->str);
1582 else if (!strcmp (a->gtktype, "UCHAR"))
1583 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1587 a->name, flags->str);
1588 else if (!strcmp (a->gtktype, "BOOL") ||
1589 !strcmp (a->gtktype, "BOOLEAN"))
1590 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1593 a->name, flags->str);
1594 else if (!strcmp (a->gtktype, "LONG"))
1595 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1596 "\t\tG_MINLONG, G_MAXLONG,\n"
1599 a->name, flags->str);
1600 else if (!strcmp (a->gtktype, "ULONG"))
1601 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1602 "\t\t0, G_MAXULONG,\n"
1605 a->name, flags->str);
1606 else if (!strcmp (a->gtktype, "INT64"))
1607 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1608 "\t\tG_MININT64, G_MAXINT64,\n"
1611 a->name, flags->str);
1612 else if (!strcmp (a->gtktype, "UINT64"))
1613 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1614 "\t\t0, G_MAXUINT64,\n"
1617 a->name, flags->str);
1618 else if (!strcmp (a->gtktype, "FLOAT"))
1619 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1620 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1623 a->name, flags->str);
1624 else if (!strcmp (a->gtktype, "DOUBLE"))
1625 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1626 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1629 a->name, flags->str);
1630 else if (!strcmp (a->gtktype, "POINTER"))
1631 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1633 a->name, flags->str);
1635 error_printf (GOB_ERROR, a->line_no,
1636 "%s type is not supported for arguments, try using properties",
1639 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1640 "\t\tPROP_%s, param_spec);\n", s);
1644 g_string_free(flags, TRUE);
1647 #define value_for_print(str, alt) (str != NULL ? str : alt)
1650 make_property (Property *p)
1654 if (p->get == NULL && p->set == NULL) {
1655 error_print (GOB_ERROR, p->line_no,
1656 "Property has no getter nor setter");
1660 if (p->flags != NULL)
1661 error_print (GOB_WARN, p->line_no,
1662 "Overridden property, flags ignored");
1663 if (p->nick != NULL)
1664 error_print (GOB_WARN, p->line_no,
1665 "Overridden property, nick ignored");
1666 if (p->blurb != NULL)
1667 error_print (GOB_WARN, p->line_no,
1668 "Overridden property, blurb ignored");
1669 if (p->minimum != NULL)
1670 error_print (GOB_WARN, p->line_no,
1671 "Overridden property, minimum ignored");
1672 if (p->maximum != NULL)
1673 error_print (GOB_WARN, p->line_no,
1674 "Overridden property, maximum ignored");
1675 if (p->default_value != NULL)
1676 error_print (GOB_WARN, p->line_no,
1677 "Overridden property, default_value ignored");
1679 s = g_strdup (p->name);
1681 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1683 "\t\t\"%s\");\n", s, p->name);
1688 char *argflags[] = {
1696 flags = g_string_new ("(GParamFlags)(");
1698 if (p->get != NULL && p->set != NULL)
1699 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1700 else if (p->get != NULL)
1701 g_string_append (flags, "G_PARAM_READABLE");
1703 g_string_append (flags, "G_PARAM_WRITABLE");
1706 for (l = p->flags; l != NULL; l = l->next) {
1707 char *flag = l->data;
1709 if(strcmp (flag, "READABLE") == 0 ||
1710 strcmp (flag, "WRITABLE") == 0) {
1711 error_print(GOB_WARN, p->line_no,
1713 "WRITABLE argument flags are "
1714 "set automatically");
1717 for(i = 0; argflags[i]; i++) {
1718 if(strcmp(argflags[i], flag)==0)
1721 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1724 g_string_append (flags, ")");
1726 if (strcmp (p->gtktype, "CHAR") == 0) {
1727 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1728 "\t\t(\"%s\" /* name */,\n"
1729 "\t\t %s /* nick */,\n"
1730 "\t\t %s /* blurb */,\n"
1731 "\t\t %s /* minimum */,\n"
1732 "\t\t %s /* maximum */,\n"
1733 "\t\t %s /* default_value */,\n"
1736 value_for_print (p->nick, "NULL"),
1737 value_for_print (p->blurb, "NULL"),
1738 value_for_print (p->minimum, "-128"),
1739 value_for_print (p->maximum, "127"),
1740 value_for_print (p->default_value, "0"),
1742 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1743 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1744 "\t\t(\"%s\" /* name */,\n"
1745 "\t\t %s /* nick */,\n"
1746 "\t\t %s /* blurb */,\n"
1747 "\t\t %s /* minimum */,\n"
1748 "\t\t %s /* maximum */,\n"
1749 "\t\t %s /* default_value */,\n"
1752 value_for_print (p->nick, "NULL"),
1753 value_for_print (p->blurb, "NULL"),
1754 value_for_print (p->minimum, "0"),
1755 value_for_print (p->maximum, "0xFF"),
1756 value_for_print (p->default_value, "0"),
1758 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1759 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1760 "\t\t(\"%s\" /* name */,\n"
1761 "\t\t %s /* nick */,\n"
1762 "\t\t %s /* blurb */,\n"
1763 "\t\t %s /* default_value */,\n"
1766 value_for_print (p->nick, "NULL"),
1767 value_for_print (p->blurb, "NULL"),
1768 value_for_print (p->default_value, "FALSE"),
1770 } else if (strcmp (p->gtktype, "INT") == 0) {
1771 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1772 "\t\t(\"%s\" /* name */,\n"
1773 "\t\t %s /* nick */,\n"
1774 "\t\t %s /* blurb */,\n"
1775 "\t\t %s /* minimum */,\n"
1776 "\t\t %s /* maximum */,\n"
1777 "\t\t %s /* default_value */,\n"
1780 value_for_print (p->nick, "NULL"),
1781 value_for_print (p->blurb, "NULL"),
1782 value_for_print (p->minimum, "G_MININT"),
1783 value_for_print (p->maximum, "G_MAXINT"),
1784 value_for_print (p->default_value, "0"),
1786 } else if (strcmp (p->gtktype, "UINT") == 0) {
1787 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1788 "\t\t(\"%s\" /* name */,\n"
1789 "\t\t %s /* nick */,\n"
1790 "\t\t %s /* blurb */,\n"
1791 "\t\t %s /* minimum */,\n"
1792 "\t\t %s /* maximum */,\n"
1793 "\t\t %s /* default_value */,\n"
1796 value_for_print (p->nick, "NULL"),
1797 value_for_print (p->blurb, "NULL"),
1798 value_for_print (p->minimum, "0"),
1799 value_for_print (p->maximum, "G_MAXUINT"),
1800 value_for_print (p->default_value, "0"),
1802 } else if (strcmp (p->gtktype, "LONG") == 0) {
1803 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1804 "\t\t(\"%s\" /* name */,\n"
1805 "\t\t %s /* nick */,\n"
1806 "\t\t %s /* blurb */,\n"
1807 "\t\t %s /* minimum */,\n"
1808 "\t\t %s /* maximum */,\n"
1809 "\t\t %s /* default_value */,\n"
1812 value_for_print (p->nick, "NULL"),
1813 value_for_print (p->blurb, "NULL"),
1814 value_for_print (p->minimum, "G_MINLONG"),
1815 value_for_print (p->maximum, "G_MAXLONG"),
1816 value_for_print (p->default_value, "0"),
1818 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1819 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1820 "\t\t(\"%s\" /* name */,\n"
1821 "\t\t %s /* nick */,\n"
1822 "\t\t %s /* blurb */,\n"
1823 "\t\t %s /* minimum */,\n"
1824 "\t\t %s /* maximum */,\n"
1825 "\t\t %s /* default_value */,\n"
1828 value_for_print (p->nick, "NULL"),
1829 value_for_print (p->blurb, "NULL"),
1830 value_for_print (p->minimum, "0"),
1831 value_for_print (p->maximum, "G_MAXULONG"),
1832 value_for_print (p->default_value, "0"),
1834 } else if (strcmp (p->gtktype, "INT64") == 0) {
1835 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1836 "\t\t(\"%s\" /* name */,\n"
1837 "\t\t %s /* nick */,\n"
1838 "\t\t %s /* blurb */,\n"
1839 "\t\t %s /* minimum */,\n"
1840 "\t\t %s /* maximum */,\n"
1841 "\t\t %s /* default_value */,\n"
1844 value_for_print (p->nick, "NULL"),
1845 value_for_print (p->blurb, "NULL"),
1846 value_for_print (p->minimum, "G_MININT64"),
1847 value_for_print (p->maximum, "G_MAXINT64"),
1848 value_for_print (p->default_value, "0"),
1850 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1851 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1852 "\t\t(\"%s\" /* name */,\n"
1853 "\t\t %s /* nick */,\n"
1854 "\t\t %s /* blurb */,\n"
1855 "\t\t %s /* minimum */,\n"
1856 "\t\t %s /* maximum */,\n"
1857 "\t\t %s /* default_value */,\n"
1860 value_for_print (p->nick, "NULL"),
1861 value_for_print (p->blurb, "NULL"),
1862 value_for_print (p->minimum, "0"),
1863 value_for_print (p->maximum, "G_MAXUINT64"),
1864 value_for_print (p->default_value, "0"),
1866 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1867 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1868 "\t\t(\"%s\" /* name */,\n"
1869 "\t\t %s /* nick */,\n"
1870 "\t\t %s /* blurb */,\n"
1871 "\t\t %s /* default_value */,\n"
1874 value_for_print (p->nick, "NULL"),
1875 value_for_print (p->blurb, "NULL"),
1876 value_for_print (p->default_value, "0"),
1878 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1879 char *type = make_me_type (p->extra_gtktype,
1881 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1882 "\t\t(\"%s\" /* name */,\n"
1883 "\t\t %s /* nick */,\n"
1884 "\t\t %s /* blurb */,\n"
1885 "\t\t %s /* enum_type */,\n"
1886 "\t\t %s /* default_value */,\n"
1889 value_for_print (p->nick, "NULL"),
1890 value_for_print (p->blurb, "NULL"),
1892 value_for_print (p->default_value, "0"),
1895 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1896 char *type = make_me_type (p->extra_gtktype,
1898 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1899 "\t\t(\"%s\" /* name */,\n"
1900 "\t\t %s /* nick */,\n"
1901 "\t\t %s /* blurb */,\n"
1902 "\t\t %s /* flags_type */,\n"
1903 "\t\t %s /* default_value */,\n"
1906 value_for_print (p->nick, "NULL"),
1907 value_for_print (p->blurb, "NULL"),
1909 value_for_print (p->default_value, "0"),
1912 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1913 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1914 "\t\t(\"%s\" /* name */,\n"
1915 "\t\t %s /* nick */,\n"
1916 "\t\t %s /* blurb */,\n"
1917 "\t\t %s /* minimum */,\n"
1918 "\t\t %s /* maximum */,\n"
1919 "\t\t %s /* default_value */,\n"
1922 value_for_print (p->nick, "NULL"),
1923 value_for_print (p->blurb, "NULL"),
1924 value_for_print (p->minimum, "-G_MAXFLOAT"),
1925 value_for_print (p->maximum, "G_MAXFLOAT"),
1926 value_for_print (p->default_value, "0.0"),
1928 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1929 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1930 "\t\t(\"%s\" /* name */,\n"
1931 "\t\t %s /* nick */,\n"
1932 "\t\t %s /* blurb */,\n"
1933 "\t\t %s /* minimum */,\n"
1934 "\t\t %s /* maximum */,\n"
1935 "\t\t %s /* default_value */,\n"
1938 value_for_print (p->nick, "NULL"),
1939 value_for_print (p->blurb, "NULL"),
1940 value_for_print (p->minimum, "-G_MAXDOUBLE"),
1941 value_for_print (p->maximum, "G_MAXDOUBLE"),
1942 value_for_print (p->default_value, "0.0"),
1944 } else if (strcmp (p->gtktype, "STRING") == 0) {
1945 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1946 "\t\t(\"%s\" /* name */,\n"
1947 "\t\t %s /* nick */,\n"
1948 "\t\t %s /* blurb */,\n"
1949 "\t\t %s /* default_value */,\n"
1952 value_for_print (p->nick, "NULL"),
1953 value_for_print (p->blurb, "NULL"),
1954 value_for_print (p->default_value, "NULL"),
1956 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1957 char *type = make_me_type (p->extra_gtktype,
1959 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1960 "\t\t(\"%s\" /* name */,\n"
1961 "\t\t %s /* nick */,\n"
1962 "\t\t %s /* blurb */,\n"
1963 "\t\t %s /* param_type */,\n"
1966 value_for_print (p->nick, "NULL"),
1967 value_for_print (p->blurb, "NULL"),
1971 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1972 char *type = make_me_type (p->extra_gtktype,
1974 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1975 "\t\t(\"%s\" /* name */,\n"
1976 "\t\t %s /* nick */,\n"
1977 "\t\t %s /* blurb */,\n"
1978 "\t\t %s /* boxed_type */,\n"
1981 value_for_print (p->nick, "NULL"),
1982 value_for_print (p->blurb, "NULL"),
1986 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1987 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1988 "\t\t(\"%s\" /* name */,\n"
1989 "\t\t %s /* nick */,\n"
1990 "\t\t %s /* blurb */,\n"
1993 value_for_print (p->nick, "NULL"),
1994 value_for_print (p->blurb, "NULL"),
1996 /* FIXME: VALUE_ARRAY */
1997 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1998 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1999 "\t\t(\"%s\" /* name */,\n"
2000 "\t\t %s /* nick */,\n"
2001 "\t\t %s /* blurb */,\n"
2004 value_for_print (p->nick, "NULL"),
2005 value_for_print (p->blurb, "NULL"),
2007 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2008 char *type = make_me_type (p->extra_gtktype,
2010 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2011 "\t\t(\"%s\" /* name */,\n"
2012 "\t\t %s /* nick */,\n"
2013 "\t\t %s /* blurb */,\n"
2014 "\t\t %s /* object_type */,\n"
2017 value_for_print (p->nick, "NULL"),
2018 value_for_print (p->blurb, "NULL"),
2023 error_printf (GOB_ERROR, p->line_no,
2024 "%s type is not supported by properties",
2028 s = g_strdup (p->name);
2030 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2032 "\t\tparam_spec);\n", s);
2035 g_string_free (flags, TRUE);
2040 make_arguments(Class *c)
2043 if (get_properties > 0)
2044 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2045 if (set_properties > 0)
2046 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2047 out_printf (out, " {\n");
2048 for (li = c->nodes; li != NULL; li = li->next) {
2050 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2051 || n->type == ARGUMENT_NODE) {
2052 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2057 for (li = c->nodes; li != NULL; li = li->next) {
2059 if (n->type == PROPERTY_NODE)
2060 make_property ((Property *)n);
2061 else if (n->type == ARGUMENT_NODE)
2062 make_argument ((Argument *)n);
2064 out_printf(out, " }\n");
2068 print_initializer(Method *m, Variable *v)
2075 if(v->initializer == NULL)
2078 if(v->scope == PRIVATE_SCOPE)
2079 root = g_strconcat(((FuncArg *)m->args->data)->name,
2082 root = g_strdup(((FuncArg *)m->args->data)->name);
2084 if(v->initializer_line > 0)
2085 out_addline_infile(out, v->initializer_line);
2087 if (v->initializer_simple)
2088 out_printf(out, "\t%s->%s = %s;\n",
2089 root, v->id, v->initializer);
2090 else if (strcmp(v->id, "_glade_xml") == 0)
2091 /* This is OK, this v->initializer string is set internally
2092 and it will eat exactly one string! */
2093 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2095 out_printf(out, "%s", v->initializer);
2097 if(v->initializer_line > 0)
2098 out_addline_outfile(out);
2104 print_glade_widget(Method *m, Variable *v)
2109 if(!v->glade_widget)
2112 if(v->scope == PRIVATE_SCOPE)
2113 root = g_strconcat(((FuncArg *)m->args->data)->name,
2116 root = g_strdup(((FuncArg *)m->args->data)->name);
2118 cast = get_type(v->vtype, FALSE);
2119 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2120 root, v->id, cast, root, v->id);
2126 print_destructor (Variable *v)
2130 if(v->destructor == NULL)
2133 if(v->scope == PRIVATE_SCOPE)
2134 root = "self->_priv";
2138 if(v->destructor_simple) {
2139 if(v->destructor_line > 0)
2140 out_addline_infile(out, v->destructor_line);
2143 out_printf(out, "\tif(%s->%s) { "
2144 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2145 "%s->%s = NULL; }\n",
2146 root, v->id, v->destructor, root, v->id,
2149 out_printf(out, "\tif(%s->%s) { "
2150 "%s ((gpointer) %s->%s); "
2151 "%s->%s = NULL; }\n",
2152 root, v->id, v->destructor, root, v->id,
2156 if(v->destructor_line > 0)
2157 out_addline_outfile(out);
2159 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2160 out_printf(out, "#define VAR %s\n", v->id);
2161 out_printf(out, "\t{\n");
2162 if(v->destructor_line > 0)
2163 out_addline_infile(out, v->destructor_line);
2165 out_printf(out, "\t%s}\n", v->destructor);
2167 if(v->destructor_line > 0)
2168 out_addline_outfile(out);
2169 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2171 out_printf(out, "#undef VAR\n");
2172 out_printf(out, "#undef %s\n", v->id);
2177 add_constructor (Class *c)
2179 out_printf(out, "\nstatic GObject *\n"
2180 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2183 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2186 out_printf(out, "\tGObject *obj_self;\n");
2187 out_printf(out, "\t%s *self;\n", typebase);
2189 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2190 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2192 if (user_constructor->line_no > 0)
2193 out_addline_infile (out, user_constructor->line_no);
2194 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2195 if (user_constructor->line_no > 0)
2196 out_addline_outfile (out);
2198 out_printf(out, "\treturn obj_self;\n");
2199 out_printf(out, "}\n"
2200 "#undef __GOB_FUNCTION__\n\n");
2204 print_unreftors (Class *c)
2207 for(li = ((Class *)class)->nodes;
2211 Variable *v = (Variable *)n;
2212 if (n->type == VARIABLE_NODE &&
2213 v->scope != CLASS_SCOPE &&
2214 v->destructor_unref)
2215 print_destructor (v);
2220 add_dispose (Class *c)
2222 out_printf(out, "\nstatic void\n"
2223 "___dispose (GObject *obj_self)\n"
2226 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2229 if (unreftors > 0 || user_dispose_method != NULL) {
2230 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2232 ! no_gnu ? " G_GNUC_UNUSED" : "",
2236 if (dispose_handler != NULL) {
2237 if (unreftors > 0) {
2238 print_unreftors (c);
2241 /* so we get possible bad argument warning */
2242 if (dispose_handler->line_no > 0)
2243 out_addline_infile (out, dispose_handler->line_no);
2244 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2245 (guint)dispose_handler->unique_id, funcbase);
2246 if (dispose_handler->line_no > 0)
2247 out_addline_outfile (out);
2249 if (user_dispose_method != NULL) {
2250 if (user_dispose_method->line_no > 0)
2251 out_addline_infile (out, user_dispose_method->line_no);
2252 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2253 if (user_dispose_method->line_no > 0)
2254 out_addline_outfile (out);
2257 if (unreftors > 0) {
2258 print_unreftors (c);
2262 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2263 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2266 out_printf(out, "}\n"
2267 "#undef __GOB_FUNCTION__\n\n");
2271 print_destructors (Class *c)
2274 for (li = ((Class *)class)->nodes;
2278 Variable *v = (Variable *)n;
2279 if (n->type == VARIABLE_NODE &&
2280 v->scope != CLASS_SCOPE &&
2281 ! v->destructor_unref)
2282 print_destructor (v);
2287 add_finalize (Class *c)
2291 "___finalize(GObject *obj_self)\n"
2294 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2299 user_finalize_method != NULL) {
2300 const char *unused = "";
2302 unused = " G_GNUC_UNUSED";
2303 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2304 typebase, unused, macrobase);
2307 const char *unused = "";
2309 unused = " G_GNUC_UNUSED";
2310 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2314 if(finalize_handler) {
2315 if (destructors > 0) {
2316 print_destructors (c);
2319 /* so we get possible bad argument warning */
2320 if(finalize_handler->line_no > 0)
2321 out_addline_infile(out, finalize_handler->line_no);
2322 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2323 (guint)finalize_handler->unique_id, funcbase);
2324 if(finalize_handler->line_no > 0)
2325 out_addline_outfile(out);
2327 if (user_finalize_method != NULL) {
2328 if (user_finalize_method->line_no > 0)
2329 out_addline_infile (out, user_finalize_method->line_no);
2330 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2331 if (user_finalize_method->line_no > 0)
2332 out_addline_outfile (out);
2335 if (destructors > 0) {
2336 print_destructors (c);
2340 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2341 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2344 out_printf(out, "}\n"
2345 "#undef __GOB_FUNCTION__\n\n");
2349 make_bonobo_object_epv (Class *c, const char *classname)
2352 gboolean added_line = FALSE;
2354 for (li = c->nodes; li != NULL; li = li->next) {
2356 Method *m = (Method *)n;
2357 if(n->type != METHOD_NODE ||
2358 m->method == OVERRIDE_METHOD)
2361 if (m->bonobo_object_func) {
2362 if(m->line_no > 0) {
2363 out_addline_infile(out, m->line_no);
2365 } else if (m->line_no == 0 &&
2367 out_addline_outfile(out);
2370 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2371 classname, m->id, m->id);
2375 out_addline_outfile(out);
2381 const char *unused = "";
2385 unused = " G_GNUC_UNUSED";
2387 for(li=c->nodes;li;li=g_list_next(li)) {
2391 if(n->type != METHOD_NODE)
2394 if(m->method == INIT_METHOD) {
2396 out_addline_infile(out, m->line_no);
2397 print_method(out, "static ", "\n", "", " ", "", "\n",
2398 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2400 out_printf(out, "{\n");
2402 out_addline_outfile(out);
2404 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2407 out_printf(out, "\t%s->_priv = "
2408 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2409 ((FuncArg *)m->args->data)->name,
2410 ((FuncArg *)m->args->data)->name,
2413 } else if(always_private_struct) {
2414 out_printf(out, "\t%s->_priv = NULL;\n",
2415 ((FuncArg *)m->args->data)->name);
2417 if(initializers > 0) {
2419 for(li = ((Class *)class)->nodes;
2423 Variable *v = (Variable *)n;
2424 if(n->type != VARIABLE_NODE ||
2425 v->scope == CLASS_SCOPE)
2427 print_initializer(m, v);
2430 if(glade_widgets > 0) {
2432 for(li = ((Class *)class)->nodes;
2436 Variable *v = (Variable *)n;
2437 if(n->type != VARIABLE_NODE ||
2438 v->scope == CLASS_SCOPE)
2440 print_glade_widget(m, v);
2443 } else if(m->method == CLASS_INIT_METHOD) {
2444 gboolean did_base_obj = FALSE;
2447 out_addline_infile(out, m->line_no);
2448 print_method(out, "static ", "\n", "", " ", "", "\n",
2449 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2451 out_printf(out, "{\n");
2453 out_addline_outfile(out);
2455 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2457 if (set_properties > 0 ||
2458 get_properties > 0 ||
2465 "g_object_class%s = "
2466 "(GObjectClass*) %s;\n",
2468 ((FuncArg *)m->args->data)->name);
2469 did_base_obj = TRUE;
2474 ((FuncArg *)m->args->data)->name,
2479 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2480 ((FuncArg *)m->args->data)->name,
2483 if (initializers > 0) {
2485 for(li = ((Class *)class)->nodes;
2489 Variable *v = (Variable *)n;
2490 if(n->type == VARIABLE_NODE &&
2491 v->scope == CLASS_SCOPE)
2492 print_initializer(m, v);
2496 out_printf(out, "\n\tparent_class = ");
2498 out_printf(out, "(%sClass *)", ptypebase);
2499 out_printf(out, "g_type_class_ref (%s);\n",
2505 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2507 /* if there are no handlers for these things, we
2508 * need to set them up here */
2509 if(need_constructor)
2510 out_printf(out, "\tg_object_class->constructor "
2511 "= ___constructor;\n");
2512 if(need_dispose && !dispose_handler)
2513 out_printf(out, "\tg_object_class->dispose "
2515 if(need_finalize && !finalize_handler)
2516 out_printf(out, "\tg_object_class->finalize = "
2519 if(get_properties > 0 || set_properties > 0)
2522 if (c->bonobo_object_class != NULL) {
2523 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2529 out_printf(out, " {\n");
2530 out_addline_infile(out, m->ccode_line);
2531 out_printf(out, "%s\n", m->cbuf);
2532 out_addline_outfile(out);
2533 out_printf(out, " }\n");
2535 out_printf(out, "}\n"
2536 "#undef __GOB_FUNCTION__\n");
2541 add_argument (Argument *a, gboolean is_set)
2545 char *the_type_lower;
2550 line_no = a->set_line;
2553 line_no = a->get_line;
2557 s = g_strdup(a->name);
2559 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2561 the_type_lower = g_strdup (a->gtktype);
2562 gob_strdown (the_type_lower);
2564 /* HACK because there is no g_value_set/get for unichar */
2565 if (strcmp (the_type_lower, "unichar") == 0) {
2566 g_free (the_type_lower);
2567 the_type_lower = g_strdup ("uint");
2572 const char *unused = "";
2574 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2575 unused = " G_GNUC_UNUSED";
2578 if (a->atype != NULL &&
2579 /* gcc -Wbad-function-cast is wanking stupid, moronic
2580 and otherwise evil so we should just use a (gint)
2581 or (guint) cast, not the specific type cast */
2583 (strcmp (a->gtktype, "ENUM") != 0 &&
2584 strcmp (a->gtktype, "FLAGS") != 0)))
2585 cast = get_type (a->atype, TRUE);
2587 cast = g_strdup (get_cast (a->gtktype, FALSE));
2589 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2590 cast, unused, cast, the_type_lower);
2593 } else if ( ! is_set) {
2596 if (a->atype != NULL)
2597 cast = get_type (a->atype, TRUE);
2599 cast = g_strdup (get_cast (a->gtktype, FALSE));
2600 out_printf (out, "\t%s ARG;\n"
2601 "\tmemset (&ARG, 0, sizeof (%s));\n",
2607 out_printf(out, "\t\t{\n");
2609 out_addline_infile (out, line_no);
2610 out_printf (out, "%s\n", cbuf);
2612 out_addline_outfile (out);
2613 out_printf (out, "\t\t}\n");
2615 if (strcmp (a->gtktype, "OBJECT") == 0)
2616 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2619 out_printf (out, "\t\t"
2620 "g_value_set_%s (VAL, ARG);\n",
2623 g_free (the_type_lower);
2626 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2627 out_printf (out, "\t\tif (&ARG) break;\n");
2630 out_printf (out, "\t\tbreak;\n");
2632 out_printf (out, "\t}\n");
2636 add_property (Property *p, gboolean is_set)
2639 char *the_type_lower;
2645 line_no = p->set_line;
2648 line_no = p->get_line;
2653 name_upper = g_strdup (p->name);
2654 gob_strup (name_upper);
2655 the_type_lower = g_strdup (p->gtktype);
2656 gob_strdown (the_type_lower);
2658 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2660 out_printf(out, "\t\t{\n");
2662 out_addline_infile (out, line_no);
2663 out_printf (out, "%s\n", cbuf);
2665 out_addline_outfile (out);
2666 out_printf (out, "\t\t}\n");
2668 g_free (name_upper);
2669 g_free (the_type_lower);
2671 out_printf (out, "\t\tbreak;\n");
2675 add_getset_arg(Class *c, gboolean is_set)
2678 const char *unused = "";
2679 const char *hack_unused = "";
2681 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2682 unused = " G_GNUC_UNUSED";
2684 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2687 out_printf(out, "\nstatic void\n"
2688 "___object_%s_property (GObject *object,\n"
2689 "\tguint property_id,\n"
2690 "\t%sGValue *VAL%s,\n"
2691 "\tGParamSpec *pspec%s)\n"
2692 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2695 "\tself = %s (object);\n\n"
2696 "\tswitch (property_id) {\n",
2697 is_set ? "set" : "get",
2698 is_set ? "const " : "",
2702 is_set ? "set" : "get",
2707 for (li = c->nodes; li != NULL; li = li->next) {
2709 if (n->type == PROPERTY_NODE)
2710 add_property ((Property *)n, is_set);
2711 else if (n->type == ARGUMENT_NODE)
2712 add_argument ((Argument *)n, is_set);
2714 out_printf (out, "\tdefault:\n"
2715 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2716 "#ifndef __PRETTY_FUNCTION__\n"
2717 "# undef G_STRLOC\n"
2718 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2720 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2721 "\t\t%sbreak;\n\t}\n"
2723 "#undef __GOB_FUNCTION__\n", hack_unused);
2727 print_checks (Method *m, FuncArg *fa)
2731 gboolean checked_null = FALSE;
2732 is_void = (strcmp(m->mtype->name, "void")==0 &&
2733 m->mtype->pointer == NULL);
2735 for(li = fa->checks; li != NULL; li = li->next) {
2736 Check *ch = li->data;
2738 /* point to the method prot in .gob for failed checks */
2740 out_addline_infile(out, m->line_no);
2742 out_printf(out, "\tg_return_if_fail (");
2744 out_printf(out, "\tg_return_val_if_fail (");
2745 switch(ch->chtype) {
2747 out_printf(out, "%s != NULL", fa->name);
2748 checked_null = TRUE;
2751 s = make_pre_macro(fa->atype->name, "IS");
2753 out_printf(out, "%s (%s)", s, fa->name);
2755 /* if not check null, null may be valid */
2756 out_printf(out, "!(%s) || %s (%s)", fa->name,
2761 out_printf(out, "%s < %s", fa->name, ch->number);
2764 out_printf(out, "%s > %s", fa->name, ch->number);
2767 out_printf(out, "%s <= %s", fa->name, ch->number);
2770 out_printf(out, "%s >= %s", fa->name, ch->number);
2773 out_printf(out, "%s == %s", fa->name, ch->number);
2776 out_printf(out, "%s != %s", fa->name, ch->number);
2780 out_printf(out, ");\n");
2782 out_printf(out, ", (");
2783 print_type(out, m->mtype, TRUE);
2784 out_printf(out, ")%s);\n",
2785 m->onerror?m->onerror:"0");
2791 print_preconditions(Method *m)
2795 for(li=m->args;li;li=g_list_next(li)) {
2796 FuncArg *fa = li->data;
2798 print_checks(m, fa);
2801 out_addline_outfile(out);
2805 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2807 out_printf(out, "{\n");
2809 out_addline_outfile(out);
2810 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2811 ((Class *)class)->otype,
2814 print_preconditions(m);
2818 (no_gnu || for_cpp) &&
2820 ((FuncArg *)(m->args->data))->name != NULL &&
2821 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2822 out_printf (out, "\tif (&self) { ; }\n");
2825 /* Note: the trailing }'s are on one line, this is so
2826 that we get the no return warning correctly and point to
2827 the correct line in the .gob file, yes this is slightly
2828 ugly in the .c file, but that is not supposed to be
2829 human readable anyway. */
2831 out_printf(out, "{\n");
2833 out_addline_infile(out, m->ccode_line);
2834 out_printf(out, "\t%s}", m->cbuf);
2837 /* Note, there is no \n between the last } and this } so that
2838 * errors/warnings reported on the end of the body get pointed to the
2839 * right line in the .gob source */
2840 out_printf(out, "}\n");
2843 out_addline_outfile(out);
2844 out_printf(out, "#undef __GOB_FUNCTION__\n");
2848 put_signal_args (Method *m)
2854 if (m->args->next == NULL)
2857 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2858 li != NULL && ali != NULL;
2859 li = li->next, ali = ali->next, i++) {
2860 FuncArg *fa = li->data;
2861 char *str = ali->data;
2862 char *cast = g_strdup (get_cast (str, FALSE));
2863 /* FIXME: This code is so fucking ugly it hurts */
2864 gboolean do_static =
2865 (strcmp (str, "STRING") == 0 ||
2866 strcmp (str, "BOXED") == 0 ||
2867 strncmp (str, "BOXED_", 6) == 0);
2872 cast = get_type (fa->atype, TRUE);
2874 /* we should have already proved before that
2875 the we know all the types */
2876 g_assert (cast != NULL);
2878 if (strncmp (str, "BOXED_", 6) == 0)
2879 t = g_strdup (&(str[6]));
2881 t = g_strconcat ("G_TYPE_", str, NULL);
2884 "\t___param_values[%d].g_type = 0;\n"
2885 "\tg_value_init (&___param_values[%d], %s);\n",
2889 if (strcmp (str, "UNICHAR") == 0)
2890 /* hack because glib is braindamaged */
2891 set_func = g_strdup ("g_value_set_uint");
2892 else if (strncmp (str, "BOXED_", 6) == 0)
2893 set_func = g_strdup ("g_value_set_static_boxed");
2895 set_func = g_strdup_printf ("g_value_set%s_%s",
2896 do_static ? "_static" : "",
2898 gob_strdown (set_func);
2900 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2901 set_func, i, cast, fa->name);
2909 clear_signal_args (Method *m)
2914 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2916 if (m->args->next == NULL)
2919 for (li = m->args->next, i = 1;
2921 li = li->next, i++) {
2923 "\tg_value_unset (&___param_values[%d]);\n", i);
2928 get_arg_names_for_macro (Method *m)
2932 GString *gs = g_string_new(NULL);
2934 for(li=m->args;li;li=g_list_next(li)) {
2935 FuncArg *arg = li->data;
2936 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2939 return g_string_free (gs, FALSE);
2943 put_method(Method *m)
2945 char *s, *args, *doc;
2947 is_void = (strcmp(m->mtype->name, "void")==0 &&
2948 m->mtype->pointer == NULL);
2949 out_printf(out, "\n");
2950 if(m->method != OVERRIDE_METHOD) {
2951 doc = get_gtk_doc(m->id);
2953 out_printf(out, "%s", doc);
2958 case REGULAR_METHOD:
2960 out_addline_infile(out, m->line_no);
2961 if(m->scope == PRIVATE_SCOPE)
2962 print_method(out, "static ", "\n", "", " ", "", "\n",
2963 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2964 else /* PUBLIC, PROTECTED */
2965 print_method(out, "", "\n", "", " ", "", "\n",
2966 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2967 print_method_body(m, TRUE, TRUE);
2968 /* the outfile line was added above */
2970 case SIGNAL_FIRST_METHOD:
2971 case SIGNAL_LAST_METHOD:
2973 out_addline_infile(out, m->line_no);
2974 if(m->scope == PRIVATE_SCOPE)
2975 print_method(out, "static ", "\n", "", " ", "", "\n",
2976 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2977 else /* PUBLIC, PROTECTED */
2978 print_method(out, "", "\n", "", " ", "", "\n",
2979 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2980 out_printf (out, "{\n");
2982 out_addline_outfile (out);
2985 "\tGValue ___param_values[%d];\n"
2986 "\tGValue ___return_val;\n\n"
2987 "memset (&___return_val, 0, "
2988 "sizeof (___return_val));\n"
2989 "memset (&___param_values, 0, "
2990 "sizeof (___param_values));\n\n",
2991 g_list_length (m->args));
2993 print_preconditions (m);
2996 "\n\t___param_values[0].g_type = 0;\n"
2997 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2998 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2999 ((FuncArg *)m->args->data)->name,
3000 ((FuncArg *)m->args->data)->name);
3002 put_signal_args (m);
3004 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3005 const char *defret = NULL;
3007 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3008 (char *)m->gtktypes->data);
3010 if (m->defreturn != NULL)
3011 defret = m->defreturn;
3012 else if (m->onerror != NULL)
3013 defret = m->onerror;
3015 if (defret != NULL) {
3017 /* FIXME: This code is so fucking ugly it hurts */
3018 gboolean do_static =
3019 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3020 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3021 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3023 cast = get_type (m->mtype, TRUE);
3025 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3026 /* hack because glib is braindamaged */
3027 set_func = g_strdup ("g_value_set_uint");
3029 set_func = g_strdup_printf ("g_value_set%s_%s",
3030 do_static ? "_static" : "",
3031 (char *)m->gtktypes->data);
3032 gob_strdown (set_func);
3034 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3035 set_func, cast, defret);
3040 out_printf (out, "\n");
3043 s = g_strdup (m->id);
3046 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3047 "\t\tobject_signals[%s_SIGNAL],\n"
3048 "\t\t0 /* detail */,\n"
3049 "\t\t&___return_val);\n", s);
3053 clear_signal_args (m);
3055 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3056 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3058 /* Hack because glib is very very braindead */
3060 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3061 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3062 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3063 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3065 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3066 /* hack because glib is braindamaged */
3067 getfunc = g_strdup ("g_value_get_uint");
3069 getfunc = g_strdup_printf ("g_value_%s_%s",
3070 do_dup ? "dup" : "get",
3071 (char *)m->gtktypes->data);
3072 gob_strdown (getfunc);
3075 cast = get_type (m->mtype, TRUE);
3080 print_type (out, m->mtype, TRUE);
3082 " ___ret = (%s) %s (&___return_val);\n"
3083 "\t\tg_value_unset (&___return_val);\n"
3084 "\t\treturn ___ret;\n"
3091 out_printf(out, "}\n");
3096 out_addline_infile(out, m->line_no);
3097 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3098 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3099 print_method_body(m, FALSE, TRUE);
3100 /* the outfile line was added above */
3102 case VIRTUAL_METHOD:
3104 out_addline_infile(out, m->line_no);
3105 if(m->scope==PRIVATE_SCOPE)
3106 print_method(out, "static ", "\n", "", " ", "", "\n",
3107 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3108 else /* PUBLIC, PROTECTED */
3109 print_method(out, "", "\n", "", " ", "", "\n",
3110 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3111 out_printf(out, "{\n");
3112 out_addline_outfile(out);
3113 out_printf(out, "\t%sClass *klass;\n", typebase);
3114 print_preconditions(m);
3115 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3116 "\tif(klass->%s)\n",
3117 macrobase, ((FuncArg *)m->args->data)->name,
3119 if(strcmp(m->mtype->name, "void") == 0 &&
3120 m->mtype->pointer == NULL) {
3122 out_printf(out, "\t\t(*klass->%s)(%s",
3124 ((FuncArg *)m->args->data)->name);
3125 for(li=m->args->next;li;li=g_list_next(li)) {
3126 FuncArg *fa = li->data;
3127 out_printf(out, ",%s", fa->name);
3129 out_printf(out, ");\n}\n");
3132 out_printf(out, "\t\treturn (*klass->%s)(%s",
3134 ((FuncArg *)m->args->data)->name);
3135 for(li=m->args->next;li;li=g_list_next(li)) {
3136 FuncArg *fa = li->data;
3137 out_printf(out, ",%s", fa->name);
3139 out_printf(out, ");\n"
3142 print_type(out, m->mtype, TRUE);
3144 out_printf(out, ")(%s);\n}\n", m->defreturn);
3146 out_printf(out, ")(%s);\n}\n", m->onerror);
3148 out_printf(out, ")(0);\n}\n");
3154 out_addline_infile(out, m->line_no);
3155 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3156 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3157 print_method_body(m, FALSE, TRUE);
3158 /* the outfile line was added above */
3160 case OVERRIDE_METHOD:
3164 out_addline_infile(out, m->line_no);
3165 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3166 print_method(out, "static ", s, "", " ", "", "\n",
3167 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3169 out_addline_outfile(out);
3170 s = replace_sep(m->otype, '_');
3172 args = get_arg_names_for_macro(m);
3174 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3175 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3176 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3177 args, s, m->id, s, m->id, args);
3179 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3180 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3181 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3183 args, s, m->id, s, m->id, args);
3184 out_printf(out, "(");
3185 print_type(out, m->mtype, TRUE);
3186 out_printf(out, ")%s))\n",
3187 m->onerror?m->onerror:"0");
3191 print_method_body(m, TRUE, TRUE);
3192 /* the outfile line was added above */
3193 out_printf(out, "#undef PARENT_HANDLER\n");
3195 case CONSTRUCTOR_METHOD:
3196 case DISPOSE_METHOD:
3197 case FINALIZE_METHOD:
3199 out_addline_infile(out, m->line_no);
3200 print_method(out, "static ", "\n", "", " ", "", "\n",
3201 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3202 print_method_body(m, TRUE, TRUE);
3203 /* the outfile line was added above */
3212 char *outfile, *outfileh, *outfileph;
3214 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3215 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3217 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3218 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3220 if ((privates > 0 || protecteds > 0 ||
3221 private_header == PRIVATE_HEADER_ALWAYS) &&
3222 private_header != PRIVATE_HEADER_NEVER) {
3223 char sep[2] = {0,0};
3226 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3227 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3229 outfilephbase = NULL;
3235 out = fopen (outfile, "w");
3237 error_printf (GOB_ERROR, 0,
3238 "Cannot open outfile: %s", outfile);
3240 outh = fopen (outfileh, "w");
3242 error_printf (GOB_ERROR, 0,
3243 "Cannot open outfile: %s", outfileh);
3245 if (outfileph != NULL) {
3246 outph = fopen (outfileph, "w");
3247 if (outph == NULL) {
3248 error_printf (GOB_ERROR, 0,
3249 "Cannot open outfile: %s",
3257 put_argument_nongnu_wrappers (Class *c)
3261 if (get_properties < 0 && set_properties < 0)
3264 for (li = c->nodes; li != NULL; li = li->next) {
3266 const char *name, *gtktype;
3272 if (n->type == ARGUMENT_NODE) {
3273 Argument *a = (Argument *)n;
3275 gtktype = a->gtktype;
3277 get = a->get != NULL;
3278 set = a->set != NULL;
3279 } else if (n->type == PROPERTY_NODE) {
3280 Property *p = (Property *)n;
3282 gtktype = p->gtktype;
3284 get = p->get != NULL;
3285 set = p->set != NULL;
3290 aname = g_strdup (name);
3294 cast = get_type (atype, TRUE);
3296 cast = g_strdup (get_cast (gtktype, TRUE));
3300 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3301 "\"%s\",(%s)(arg)\n",
3302 macrobase, aname, name, cast);
3304 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3305 "\"%s\",(%s*)(arg)\n",
3306 macrobase, aname, name, cast);
3309 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3311 macrobase, aname, name);
3313 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3315 macrobase, aname, name);
3323 put_argument_gnu_wrappers(Class *c)
3327 if(get_properties < 0 && set_properties < 0)
3330 for (li = c->nodes; li != NULL; li = li->next) {
3332 const char *name, *gtktype;
3338 if (n->type == ARGUMENT_NODE) {
3339 Argument *a = (Argument *)n;
3341 gtktype = a->gtktype;
3343 get = a->get != NULL;
3344 set = a->set != NULL;
3345 } else if (n->type == PROPERTY_NODE) {
3346 Property *p = (Property *)n;
3348 gtktype = p->gtktype;
3350 get = p->get != NULL;
3351 set = p->set != NULL;
3356 aname = g_strdup (name);
3360 cast = get_type (atype, TRUE);
3362 cast = g_strdup (get_cast (gtktype, TRUE));
3366 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3367 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3368 macrobase, aname, name, cast);
3370 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3371 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3372 macrobase, aname, name, cast);
3375 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3377 macrobase, aname, name);
3379 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3381 macrobase, aname, name);
3389 print_ccode_block(CCode *cc)
3392 switch(cc->cctype) {
3394 /* HT code is printed exactly like normal header
3395 code but is printed before */
3398 out_printf(fp, "\n");
3401 /* AT code is printed exactly like normal 'all'
3402 code but is printed before */
3405 out_printf(outph, "\n");
3406 out_printf(outph, "%s\n", cc->cbuf);
3407 out_addline_infile(outph, cc->line_no);
3408 out_addline_outfile(outph);
3410 out_printf(outh, "\n");
3411 out_printf(outh, "%s\n", cc->cbuf);
3413 out_printf(fp, "\n");
3414 out_addline_infile(fp, cc->line_no);
3420 out_printf(fp, "\n");
3421 out_addline_infile(fp, cc->line_no);
3428 out_printf(fp, "\n");
3429 out_addline_infile(fp, cc->line_no);
3432 out_printf(fp, "%s\n", cc->cbuf);
3433 if(cc->cctype == C_CCODE ||
3434 cc->cctype == AD_CCODE ||
3435 cc->cctype == A_CCODE ||
3436 cc->cctype == AT_CCODE ||
3437 cc->cctype == PH_CCODE)
3438 out_addline_outfile(fp);
3442 print_class_block(Class *c)
3446 gboolean printed_private = FALSE;
3450 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3451 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3455 out_printf(out, "/* utility types we may need */\n");
3456 if(special_array[SPECIAL_2POINTER])
3457 out_printf(out, "typedef struct { "
3458 "gpointer a; gpointer b; "
3459 "} ___twopointertype;\n");
3460 if(special_array[SPECIAL_3POINTER])
3461 out_printf(out, "typedef struct { "
3462 "gpointer a; gpointer b; "
3464 "} ___threepointertype;\n");
3465 if(special_array[SPECIAL_INT_POINTER])
3466 out_printf(out, "typedef struct { "
3467 "gint a; gpointer b; "
3468 "} ___intpointertype;\n");
3469 out_printf(out, "\n");
3472 out_printf(outh, "\n/*\n"
3473 " * Type checking and casting macros\n"
3475 out_printf(outh, "#define %s\t"
3476 "(%s_get_type())\n",
3477 macrotype, funcbase);
3478 out_printf(outh, "#define %s(obj)\t"
3479 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3480 macrobase, funcbase, typebase);
3481 out_printf(outh, "#define %s_CONST(obj)\t"
3482 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3483 macrobase, funcbase, typebase);
3484 out_printf(outh, "#define %s_CLASS(klass)\t"
3485 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3486 macrobase, funcbase, typebase);
3487 out_printf(outh, "#define %s(obj)\t"
3488 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3491 "#define %s_GET_CLASS(obj)\t"
3492 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3493 macrobase, funcbase, typebase);
3495 if ( ! no_self_alias) {
3496 out_printf(out, "/* self casting macros */\n");
3497 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3498 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3499 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3500 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3501 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3503 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3506 out_printf(out, "/* self typedefs */\n");
3507 out_printf(out, "typedef %s Self;\n", typebase);
3508 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3512 always_private_struct) {
3513 out_printf (outh, "\n/* Private structure type */\n");
3514 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3515 typebase, typebase);
3517 out_printf (outh, "/* There are no privates, this "
3518 "structure is thus never defined */\n");
3521 out_printf (outh, "\n/*\n"
3522 " * Main object structure\n"
3524 s = replace_sep (c->otype, '_');
3526 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3527 "#define __TYPEDEF_%s__\n", s, s);
3529 out_printf (outh, "typedef struct _%s %s;\n"
3530 "#endif\n", typebase, typebase);
3531 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3532 typebase, ptypebase);
3533 for (li = c->nodes; li; li=li->next) {
3534 static gboolean printed_public = FALSE;
3536 Variable *v = (Variable *)n;
3537 if(n->type == VARIABLE_NODE &&
3538 v->scope == PUBLIC_SCOPE) {
3539 if( ! printed_public) {
3540 out_printf(outh, "\t/*< public >*/\n");
3541 printed_public = TRUE;
3543 put_variable((Variable *)n, outh);
3546 /* put protecteds always AFTER publics */
3547 for (li = c->nodes; li != NULL; li = li->next) {
3549 Variable *v = (Variable *)n;
3550 if (n->type == VARIABLE_NODE &&
3551 v->scope == PROTECTED_SCOPE) {
3552 if ( ! printed_private) {
3553 out_printf (outh, "\t/*< private >*/\n");
3554 printed_private = TRUE;
3556 put_variable ((Variable *)n, outh);
3560 always_private_struct) {
3561 if ( ! printed_private)
3562 out_printf (outh, "\t/*< private >*/\n");
3563 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3565 out_printf (outh, "};\n");
3570 /* if we are to stick this into the private
3571 header, if not stick it directly into the
3578 out_printf (outfp, "struct _%sPrivate {\n",
3582 for(li=c->nodes; li; li=li->next) {
3584 Variable *v = (Variable *)n;
3585 if(n->type == VARIABLE_NODE &&
3586 v->scope == PRIVATE_SCOPE) {
3587 out_addline_infile(outfp, v->line_no);
3588 put_variable(v, outfp);
3591 out_addline_outfile(outfp);
3593 out_printf(outfp, "};\n");
3596 out_printf(outh, "\n/*\n"
3597 " * Class definition\n"
3599 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3600 typebase, typebase);
3602 "struct _%sClass {\n\t%sClass __parent__;\n",
3603 typebase, ptypebase);
3604 for(li = c->nodes; li != NULL; li = li->next) {
3606 if(n->type == METHOD_NODE)
3607 put_vs_method((Method *)n);
3609 /* If BonoboX type class put down the epv */
3610 if (c->bonobo_object_class != NULL) {
3612 "\t/* Bonobo object epv */\n"
3613 "\tPOA_%s__epv _epv;\n",
3614 c->bonobo_object_class);
3616 /* put class scope variables */
3617 for (li = c->nodes; li != NULL; li = li->next) {
3619 Variable *v = (Variable *)n;
3620 if (n->type == VARIABLE_NODE &&
3621 v->scope == CLASS_SCOPE)
3622 put_variable ((Variable *)n, outh);
3624 out_printf (outh, "};\n\n");
3626 out_printf (out, "/* here are local prototypes */\n");
3627 if (set_properties > 0) {
3628 out_printf (out, "static void ___object_set_property "
3629 "(GObject *object, guint property_id, "
3630 "const GValue *value, GParamSpec *pspec);\n");
3632 if (get_properties > 0) {
3633 out_printf (out, "static void ___object_get_property "
3634 "(GObject *object, guint property_id, "
3635 "GValue *value, GParamSpec *pspec);\n");
3638 out_printf (outh, "\n/*\n"
3639 " * Public methods\n"
3642 if ( ! overrode_get_type) {
3643 out_printf (outh, "GType\t%s_get_type\t(void) G_GNUC_CONST;\n", funcbase);
3646 for(li = c->nodes; li != NULL; li = li->next) {
3648 if(n->type == METHOD_NODE) {
3649 put_pub_method((Method *)n);
3650 put_prot_method((Method *)n);
3651 put_priv_method_prot((Method *)n);
3655 /* this idea is less and less apealing to me */
3657 out_printf (outh, "\n/*\n"
3658 " * Signal connection wrapper macros\n"
3661 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3662 put_signal_macros (c, TRUE);
3663 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3664 put_signal_macros (c, FALSE);
3665 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3667 put_signal_macros (c, FALSE);
3668 out_printf(outh, "\n");
3671 out_printf (out, "\n/*\n"
3672 " * Signal connection wrapper macro shortcuts\n"
3674 put_local_signal_macros (c);
3675 out_printf(outh, "\n");
3678 /* argument wrapping macros */
3679 if(get_properties > 0 || set_properties > 0) {
3680 out_printf(outh, "\n/*\n"
3681 " * Argument wrapping macros\n"
3684 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3685 put_argument_gnu_wrappers(c);
3686 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3687 put_argument_nongnu_wrappers(c);
3688 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3690 put_argument_nongnu_wrappers(c);
3695 for(li = c->nodes; li != NULL; li = li->next) {
3697 if(n->type == METHOD_NODE)
3698 add_signal_prots((Method *)n);
3704 if(any_method_to_alias(c)) {
3705 out_printf (out, "/* Short form macros */\n");
3706 make_method_aliases (c);
3709 add_interface_inits (c);
3711 if ( ! overrode_get_type) {
3712 if (c->bonobo_object_class != NULL)
3713 add_bonobo_object_get_type ();
3718 out_printf (out, "/* a macro for creating a new object of our type */\n");
3720 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3721 typebase, funcbase);
3723 out_printf (out, "/* a function for creating a new object of our type */\n");
3724 out_printf (out, "#include <stdarg.h>\n");
3726 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3727 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3728 "{\n\t%s *ret;\n\tva_list ap;\n"
3729 "\tva_start (ap, first);\n"
3730 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3733 "\treturn ret;\n}\n\n",
3735 no_gnu ? "" : " G_GNUC_UNUSED",
3736 typebase, typebase, typebase, funcbase);
3740 out_printf (out, "/* a function to connect glade callback */\n");
3741 out_printf (out,"static void\n"
3742 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3743 "GObject *object,\n"
3744 "const gchar *signal_name,\n"
3745 "const gchar *signal_data,\n"
3746 "GObject *connect_object,\n"
3748 "gpointer user_data)\n"
3750 "\tstatic GModule * allsymbols = NULL;\n"
3752 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3753 "\tif (allsymbols) {\n"
3754 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3755 "\t\tGCallback func;\n"
3757 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3758 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3759 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3760 "\t\t\t\tg_free(func_name);\n"
3765 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3767 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3768 "\t\tg_free(func_name);\n"
3775 for (li = nodes; li != NULL; li = li->next) {
3776 Node *node = li->data;
3777 if (node->type == CCODE_NODE) {
3778 CCode *cc = (CCode *)node;
3779 if (cc->cctype == AD_CCODE)
3780 print_ccode_block (cc);
3784 if (need_constructor)
3785 add_constructor (c);
3795 if(set_properties > 0) {
3796 add_getset_arg(c, TRUE);
3799 if(get_properties > 0) {
3800 add_getset_arg(c, FALSE);
3803 for(li = c->nodes; li != NULL; li = li->next) {
3805 if(n->type == METHOD_NODE)
3806 put_method((Method *)n);
3809 add_bad_hack_to_avoid_unused_warnings(c);
3813 print_useful_macros(void)
3815 int major = 0, minor = 0, pl = 0;
3818 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3819 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3820 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3821 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3823 /* Useful priv macro thingie */
3824 /* FIXME: this should be done the same way that priv is, as a var,
3826 out_printf (out, "#define selfp (self->_priv)\n\n");
3830 print_more_useful_macros (void)
3833 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3834 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3836 out_printf (out, "#ifdef G_LIKELY\n");
3837 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3838 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3839 out_printf (out, "#else /* ! G_LIKELY */\n");
3840 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3841 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3842 out_printf (out, "#endif /* G_LIKELY */\n");
3847 print_file_comments(void)
3849 out_printf(outh, "/* Generated by GOB (v%s)"
3850 " (do not edit directly) */\n\n", VERSION);
3852 out_printf(outph, "/* Generated by GOB (v%s)"
3853 " (do not edit directly) */\n\n", VERSION);
3854 out_printf(out, "/* Generated by GOB (v%s)"
3855 " (do not edit directly) */\n\n", VERSION);
3857 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3861 print_includes(void)
3863 gboolean found_header;
3866 /* We may need string.h for memset */
3867 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3868 out_printf(out, "#include <string.h> /* memset() */\n\n");
3871 p = g_strconcat(filebase, ".h", NULL);
3872 found_header = TRUE;
3873 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3874 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3875 found_header = FALSE;
3879 /* if we are creating a private header see if it was included */
3881 char sep[2] = {0,0};
3884 p = g_strconcat(filebase, sep, "private.h", NULL);
3885 if( ! g_list_find_custom(include_files, p,
3886 (GCompareFunc)strcmp)) {
3887 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
3891 error_printf(GOB_WARN, 0,
3892 "Implicit private header include "
3894 "\tsource file, while public "
3895 "header is at a custom location, "
3897 "\texplicitly include "
3898 "the private header below the "
3906 print_header_prefixes(void)
3910 p = replace_sep(((Class *)class)->otype, '_');
3912 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3914 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3915 "#define __%s_PRIVATE_H__\n\n"
3916 "#include \"%s.h\"\n\n", p, p, filebase);
3919 if( ! no_extern_c) {
3920 out_printf(outh, "#ifdef __cplusplus\n"
3922 "#endif /* __cplusplus */\n\n");
3924 out_printf(outph, "#ifdef __cplusplus\n"
3926 "#endif /* __cplusplus */\n\n");
3931 print_header_postfixes(void)
3934 out_printf(outh, "\n#ifdef __cplusplus\n"
3936 "#endif /* __cplusplus */\n");
3937 out_printf(outh, "\n#endif\n");
3940 out_printf(outph, "\n#ifdef __cplusplus\n"
3942 "#endif /* __cplusplus */\n");
3943 out_printf(outph, "\n#endif\n");
3952 /* print the AT_CCODE and CT_CCODE blocks */
3953 for(li = nodes; li != NULL; li = li->next) {
3954 Node *node = li->data;
3955 if(node->type == CCODE_NODE) {
3956 CCode *cc = (CCode *)node;
3957 if (cc->cctype == AT_CCODE ||
3958 cc->cctype == CT_CCODE)
3959 print_ccode_block((CCode *)node);
3965 print_header_top(void)
3969 /* mandatory includes */
3970 out_printf (outh, "#include <glib.h>\n");
3971 out_printf (outh, "#include <glib-object.h>\n");
3973 /* print the HT_CCODE blocks */
3974 for (li = nodes; li != NULL; li = li->next) {
3975 Node *node = li->data;
3976 if (node->type == CCODE_NODE) {
3977 CCode *cc = (CCode *)node;
3978 if (cc->cctype == HT_CCODE)
3979 print_ccode_block ((CCode *)node);
3985 print_enum (EnumDef *enode)
3992 funcprefix = replace_sep (enode->etype, '_');
3993 gob_strdown (funcprefix);
3994 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3996 type = remove_sep (enode->etype);
3998 out_printf (outh, "\ntypedef enum {\n");
4000 for (li = enode->values; li != NULL; li = li->next) {
4001 EnumValue *value = li->data;
4003 char *sname = gob_strdown (g_strdup (value->name));
4005 while ((p = strchr (sname, '_')) != NULL)
4008 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4009 if (value->value != NULL)
4010 out_printf (outh, " = %s", value->value);
4011 if (li->next != NULL)
4012 out_printf (outh, ",\n");
4014 out_printf (outh, "\n");
4016 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4017 enode->prefix, value->name,
4018 enode->prefix, value->name,
4024 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4026 out_printf (outh, "} %s;\n", type);
4028 str = make_pre_macro (enode->etype, "TYPE");
4029 out_printf (outh, "#define %s ", str);
4032 out_printf (outh, "%s_get_type()\n", funcprefix);
4033 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4036 "GType\n%s_get_type (void)\n"
4038 "\tstatic GType type = 0;\n"
4039 "\tif ___GOB_UNLIKELY(type == 0)\n"
4040 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4043 funcprefix, type, funcprefix);
4045 g_free (funcprefix);
4050 print_flags (Flags *fnode)
4058 funcprefix = replace_sep (fnode->ftype, '_');
4059 gob_strdown (funcprefix);
4060 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4062 type = remove_sep (fnode->ftype);
4064 out_printf (outh, "\ntypedef enum {\n");
4066 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4067 const char *name = li->data;
4069 char *sname = gob_strdown (g_strdup (name));
4071 while ((p = strchr (sname, '_')) != NULL)
4074 out_printf (outh, "\t%s_%s = 1<<%d",
4075 fnode->prefix, name, i);
4076 if (li->next != NULL)
4077 out_printf (outh, ",\n");
4079 out_printf (outh, "\n");
4081 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4082 fnode->prefix, name,
4083 fnode->prefix, name,
4089 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4091 out_printf (outh, "} %s;\n", type);
4093 str = make_pre_macro (fnode->ftype, "TYPE");
4094 out_printf (outh, "#define %s ", str);
4097 out_printf (outh, "%s_get_type()\n", funcprefix);
4098 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4101 "GType\n%s_get_type (void)\n"
4103 "\tstatic GType type = 0;\n"
4104 "\tif ___GOB_UNLIKELY(type == 0)\n"
4105 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4108 funcprefix, type, funcprefix);
4110 g_free (funcprefix);
4115 print_error (Error *enode)
4122 funcprefix = replace_sep (enode->etype, '_');
4123 gob_strdown (funcprefix);
4124 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4126 type = remove_sep (enode->etype);
4128 out_printf (outh, "\ntypedef enum {\n");
4130 for (li = enode->values; li != NULL; li = li->next) {
4131 const char *name = li->data;
4133 char *sname = gob_strdown (g_strdup (name));
4135 while ((p = strchr (sname, '_')) != NULL)
4138 out_printf (outh, "\t%s_%s", enode->prefix, name);
4139 if (li->next != NULL)
4140 out_printf (outh, ",\n");
4142 out_printf (outh, "\n");
4144 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4145 enode->prefix, name,
4146 enode->prefix, name,
4152 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4154 out_printf (outh, "} %s;\n", type);
4156 str = make_pre_macro (enode->etype, "TYPE");
4157 out_printf (outh, "#define %s ", str);
4160 out_printf (outh, "%s_get_type ()\n", funcprefix);
4161 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4164 "GType\n%s_get_type (void)\n"
4166 "\tstatic GType type = 0;\n"
4167 "\tif ___GOB_UNLIKELY(type == 0)\n"
4168 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4171 funcprefix, type, funcprefix);
4173 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4174 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4176 str = replace_sep (enode->etype, '-');
4180 "GQuark\n%s_quark (void)\n"
4182 "\tstatic GQuark q = 0;\n"
4184 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4191 g_free (funcprefix);
4196 generate_outfiles(void)
4200 print_file_comments();
4206 print_header_prefixes();
4208 print_useful_macros();
4212 print_more_useful_macros ();
4214 for (li = nodes; li != NULL; li = li->next) {
4215 Node *node = li->data;
4216 if (node->type == CCODE_NODE) {
4217 CCode *cc = (CCode *)node;
4218 if (cc->cctype != HT_CCODE &&
4219 cc->cctype != AT_CCODE &&
4220 cc->cctype != AD_CCODE)
4221 print_ccode_block ((CCode *)node);
4222 } else if (node->type == CLASS_NODE) {
4223 print_class_block ((Class *)node);
4224 } else if (node->type == ENUMDEF_NODE) {
4225 print_enum ((EnumDef *)node);
4226 } else if (node->type == FLAGS_NODE) {
4227 print_flags ((Flags *)node);
4228 } else if (node->type == ERROR_NODE) {
4229 print_error ((Error *)node);
4231 g_assert_not_reached();
4235 print_header_postfixes();
4241 fprintf(stderr, "Gob version %s\n\n", VERSION);
4242 fprintf(stderr, "gob [options] file.gob\n\n");
4243 fprintf(stderr, "Options:\n"
4244 "\t--help,-h,-? Display this help\n"
4245 "\t--version Display version\n"
4246 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4247 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4248 "\t--for-cpp Create C++ files\n"
4249 "\t--no-extern-c Never print extern \"C\" into the "
4251 "\t--no-gnu Never use GNU extentions\n"
4252 "\t--no-touch Don't touch output files unless they "
4254 "\t changed (implies --no-touch-headers)\n"
4255 "\t--no-touch-headers Don't touch headers unless they "
4257 "\t--always-private-header Always create a private header "
4259 "\t even if it would be empty\n"
4260 "\t--ondemand-private-header Create private header only when "
4263 "\t--no-private-header Don't create a private header, "
4265 "\t structure and protected "
4266 "prototypes inside c file\n"
4267 "\t--always-private-struct Always create a private pointer "
4269 "\t the object structure\n"
4270 "\t--m4 Preprocess source with m4. "
4271 "Following args will\n"
4272 "\t be passed to m4\n"
4273 "\t--m4-dir Print directory that will be "
4276 "\t--no-write,-n Don't write output files, just "
4278 "\t--no-lines Don't print '#line' to output\n"
4279 "\t--no-self-alias Don't create self type and macro "
4281 "\t--no-kill-underscores Ignored for compatibility\n"
4282 "\t-o,--output-dir The directory where output "
4283 "should be placed\n"
4284 "\t--file-sep[=c] replace default \'-\' file "
4285 "name separator\n\n");
4286 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4290 parse_options(int argc, char *argv[])
4293 int got_file = FALSE;
4294 int no_opts = FALSE;
4295 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4299 for(i = 1 ; i < argc; i++) {
4301 char *new_commandline;
4302 g_assert(m4_commandline!=NULL);
4304 /* check whether this one looks like the filename */
4305 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4307 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4311 /* insert flags before the filename */
4312 new_commandline=g_strconcat(m4_commandline,
4320 /* just an ordinary option */
4322 new_commandline=g_strconcat(m4_commandline,
4327 /* free old commandline */
4328 g_free(m4_commandline);
4329 m4_commandline=new_commandline;
4331 } else if(no_opts ||
4332 argv[i][0] != '-') {
4335 fprintf(stderr, "Specify only one file!\n");
4341 } else if(strcmp(argv[i], "--help")==0) {
4344 } else if(strcmp(argv[i], "--version")==0) {
4345 fprintf(stderr, "Gob version %s\n", VERSION);
4347 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4348 exit_on_warn = TRUE;
4349 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4350 exit_on_warn = FALSE;
4351 } else if(strcmp(argv[i], "--for-cpp")==0) {
4353 } else if(strcmp(argv[i], "--no-touch")==0) {
4355 no_touch_headers = TRUE;
4356 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4357 no_touch_headers = TRUE;
4358 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4359 private_header = PRIVATE_HEADER_ONDEMAND;
4360 } else if(strcmp(argv[i], "--always-private-header")==0) {
4361 private_header = PRIVATE_HEADER_ALWAYS;
4362 } else if(strcmp(argv[i], "--no-private-header")==0) {
4363 private_header = PRIVATE_HEADER_NEVER;
4364 } else if(strcmp(argv[i], "--no-gnu")==0) {
4366 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4368 } else if(strcmp(argv[i], "--no-write")==0) {
4370 } else if(strcmp(argv[i], "--no-lines")==0) {
4372 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4373 no_self_alias = TRUE;
4374 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4376 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4377 always_private_struct = TRUE;
4378 } else if(strcmp(argv[i], "--m4-dir")==0) {
4379 printf("%s\n",M4_INCLUDE_DIR);
4381 } else if(strcmp(argv[i], "--m4")==0) {
4385 m4_commandline=g_strdup(M4_COMMANDLINE);
4386 } else if(strcmp(argv[i], "--m4-clean")==0) {
4390 m4_commandline=g_strdup(M4_COMMANDLINE);
4391 } else if (strcmp (argv[i], "-o") == 0 ||
4392 strcmp (argv[i], "--output-dir") == 0) {
4394 output_dir = g_strdup (argv[i+1]);
4399 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4402 strlen ("--output-dir=")) == 0) {
4403 char *p = strchr (argv[i], '=');
4404 g_assert (p != NULL);
4405 output_dir = g_strdup (p+1);
4406 } else if (strncmp (argv[i], "--file-sep=",
4407 strlen ("--file-sep=")) == 0) {
4408 char *p = strchr (argv[i], '=');
4409 g_assert (p != NULL);
4411 } else if (strncmp (argv[i], "--file-sep",
4412 strlen ("--file-sep")) == 0) {
4414 file_sep = (argv[i+1])[0];
4419 } else if(strcmp(argv[i], "--")==0) {
4420 /*further arguments are files*/
4422 } else if(strncmp(argv[i], "--", 2)==0) {
4423 /*unknown long option*/
4424 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4428 /*by now we know we have a string starting with
4429 - which is a short option string*/
4431 for(p = argv[i] + 1; *p; p++) {
4445 "Unknown option '%c'!\n", *p);
4454 /* if we are using m4, and got no filename, append m4 flags now */
4455 if(!got_file && use_m4 && !use_m4_clean) {
4456 char *new_commandline;
4457 new_commandline=g_strconcat(m4_commandline,
4461 g_free(m4_commandline);
4462 m4_commandline=new_commandline;
4468 compare_and_move (const char *old_filename)
4470 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4472 gboolean equal = FALSE;
4474 old_f = fopen (old_filename, "r");
4477 gboolean error = FALSE;
4479 new_f = fopen (new_filename, "r");
4488 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4489 if (ferror (new_f)) {
4491 error_printf (GOB_ERROR, 0,
4492 "Can't read %s: %s",
4494 g_strerror (errno));
4498 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4500 || feof (new_f) != feof (old_f)
4502 || memcmp (new_buf, old_buf, new_n) != 0)
4511 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4512 new_filename, g_strerror (errno));
4520 if (! equal && unlink (old_filename) != 0) {
4521 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4522 old_filename, g_strerror (errno));
4528 if (unlink (new_filename) != 0)
4529 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4530 new_filename, g_strerror (errno));
4532 if (rename (new_filename, old_filename) != 0)
4533 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4534 new_filename, old_filename,
4535 g_strerror (errno));
4539 g_free (new_filename);
4543 main(int argc, char *argv[])
4545 parse_options(argc, argv);
4548 yyin = popen(m4_commandline, "r");
4550 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4554 } else if(filename) {
4555 yyin = fopen(filename, "r");
4557 fprintf(stderr, "Error: can't open file '%s'\n",
4566 /* This is where parsing is done */
4569 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4571 /* close input file */
4572 if(use_m4) pclose(yyin);
4577 error_print (GOB_ERROR, 0, "no class defined");
4580 exit_on_error = FALSE;
4582 signals = count_signals ((Class *)class);
4583 set_properties = count_set_properties ((Class *)class) +
4584 count_set_arguments ((Class *)class);
4585 get_properties = count_get_properties ((Class *)class) +
4586 count_get_arguments ((Class *)class);
4587 overrides = count_overrides ((Class *)class);
4588 privates = count_privates ((Class *)class);
4589 protecteds = count_protecteds ((Class *)class);
4590 unreftors = count_unreftors ((Class *)class);
4591 destructors = count_destructors ((Class *)class);
4592 initializers = count_initializers ((Class *)class);
4593 glade_widgets = count_glade_widgets ((Class *)class);
4594 overrode_get_type = find_get_type ((Class *)class);
4597 make_inits ((Class *)class);
4599 find_constructor ((Class *)class);
4600 if (user_constructor != NULL)
4601 need_constructor = TRUE;
4603 find_dispose ((Class *)class);
4604 if (unreftors > 0 ||
4605 dispose_handler != NULL ||
4606 user_dispose_method != NULL)
4607 need_dispose = TRUE;
4609 find_finalize ((Class *)class);
4610 if (destructors > 0 ||
4612 user_finalize_method != NULL) {
4613 need_finalize = TRUE;
4616 check_bad_symbols ((Class *)class);
4617 check_duplicate_symbols ((Class *)class);
4618 check_duplicate_overrides ((Class *)class);
4619 check_duplicate_signals_args ((Class *)class);
4620 check_public_new ((Class *)class);
4621 check_vararg ((Class *)class);
4622 check_firstarg ((Class *)class);
4623 check_nonvoidempty ((Class *)class);
4624 check_signal_args ((Class *)class);
4625 check_property_types ((Class *)class);
4626 check_argument_types ((Class *)class);
4627 check_func_arg_checks ((Class *)class);
4628 check_func_attrs ((Class *)class);
4629 check_for_class_destructors ((Class *)class);
4631 exit_on_error = TRUE;
4636 any_special = setup_special_array ((Class *)class, special_array);
4640 generate_outfiles ();
4651 compare_and_move (outfilebase);
4653 compare_and_move (outfilephbase);
4655 if (no_touch_headers)
4656 compare_and_move (outfilehbase);