2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2011 George (Jiri) Lebl
5 * Copyright © 2019-2021 Nick Bowler
7 * Author: George (Jiri) Lebl
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
37 #include "treefuncs.h"
55 static const char sopts[] = "wnho:";
56 static const struct option lopts[] = {
57 { "help", 0, NULL, 'h' },
58 { "version", 0, NULL, LOPT_VERSION },
59 { "exit-on-warn", 0, NULL, 'w' },
60 { "no-exit-on-warn", 0, &exit_on_warn, FALSE },
61 { "for-cpp", 0, &for_cpp, TRUE },
62 { "no-extern-c", 0, &no_extern_c, TRUE },
63 { "no-gnu", 0, &no_gnu, TRUE },
64 { "no-touch", 0, NULL, LOPT_NO_TOUCH },
65 { "no-touch-headers", 0, &no_touch_headers, TRUE },
66 { "always-private-header", 0, &private_header, PRIVATE_HEADER_ALWAYS },
67 { "ondemand-private-header", 0, &private_header, PRIVATE_HEADER_ONDEMAND },
68 { "no-private-header", 0, &private_header, PRIVATE_HEADER_NEVER },
69 { "always-private-struct", 0, &always_private_struct, TRUE },
70 { "m4", 0, NULL, LOPT_M4 },
71 { "m4-clean", 0, NULL, LOPT_M4_CLEAN },
72 { "m4-dir", 0, NULL, LOPT_M4_DIR },
73 { "no-write", 0, NULL, 'n' },
74 { "no-lines", 0, &no_lines, TRUE },
75 { "no-self-alias", 0, &no_self_alias, TRUE },
76 { "no-kill-underscores", 0, NULL, 0 /* no-op */ },
77 { "output-dir", 1, NULL, 'o' },
78 { "file-sep", 2, NULL, LOPT_FILE_SEP },
79 { "gtk3", 0, >k3_ok, TRUE },
83 char *filename = NULL;
93 extern GList *include_files;
95 extern GHashTable *gtk_doc_hash;
99 static char *outfilebase;
100 static char *outfilehbase;
101 static char *outfilephbase;
102 static char *funcbase;
103 static char *pfuncbase;
104 static char *macrobase;
105 static char *macrois;
106 static char *pmacrois;
107 static char *macrotype;
108 static char *pmacrotype;
109 static char *typebase;
110 static char *ptypebase;
112 char *output_dir = NULL;
116 static int signals = 0; /* number of signals */
117 static int set_properties = 0; /* number of named (set) properties */
118 static int get_properties = 0; /* number of named (get) properties */
119 static int overrides = 0; /* number of override methods */
120 static int privates = 0; /* number of private data members */
121 static int protecteds = 0; /* number of protected methods */
122 static int unreftors = 0; /* number of variable unreffing destructors */
123 static int destructors = 0; /* number of variable non-unreffing destructors */
124 static int initializers = 0; /* number of variable initializers */
125 static int glade_widgets = 0; /* number of glade widgets */
126 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
128 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
129 and need the REALLY UGLY HACK to
132 /* the special variable types we need to define */
133 static gboolean special_array[SPECIAL_LAST] = {0};
134 static gboolean any_special = FALSE;
136 static gboolean need_constructor = FALSE;
137 static Method * user_constructor = NULL;
139 static gboolean need_dispose = FALSE;
140 static Method * dispose_handler = NULL;
141 static Method * user_dispose_method = NULL;
143 static gboolean need_finalize = FALSE;
144 static Method * finalize_handler = NULL;
145 static Method * user_finalize_method = NULL;
151 gboolean no_touch = FALSE;
152 gboolean no_touch_headers = FALSE;
153 gboolean for_cpp = FALSE;
154 gboolean no_gnu = FALSE;
155 gboolean exit_on_warn = FALSE;
156 gboolean exit_on_error = TRUE;
157 gboolean got_error = FALSE;
158 gint private_header = PRIVATE_HEADER_ONDEMAND;
159 gboolean no_extern_c = FALSE;
160 gboolean no_write = FALSE;
161 gboolean no_lines = FALSE;
162 gboolean no_self_alias = FALSE;
163 gboolean always_private_struct = FALSE;
164 gboolean gtk3_ok = FALSE;
170 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
171 char *m4_commandline = NULL;
172 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
173 #define M4_BASE_FILENAME "gobm4.m4"
174 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
175 #define M4_COMMANDLINE "m4"
177 int method_unique_id = 1;
182 filebase = replace_sep (((Class *)class)->otype, file_sep);
183 gob_strdown (filebase);
185 if (output_dir != NULL &&
186 output_dir[0] != '\0') {
187 fullfilebase = g_build_filename (output_dir, filebase, NULL);
189 fullfilebase = g_strdup (filebase);
192 funcbase = replace_sep (((Class *)class)->otype, '_');
193 gob_strdown (funcbase);
195 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
196 gob_strdown (pfuncbase);
198 macrobase = replace_sep (((Class *)class)->otype, '_');
199 gob_strup (macrobase);
201 macrois = make_pre_macro (((Class *)class)->otype, "IS");
202 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
204 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
205 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
207 typebase = remove_sep (((Class *)class)->otype);
209 ptypebase = remove_sep (((Class *)class)->ptype);
213 get_gtk_doc (const char *id)
220 val = g_hash_table_lookup(gtk_doc_hash, id);
222 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
224 val = g_hash_table_lookup(gtk_doc_hash, id);
226 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
232 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
236 s = get_type(t, postfix_to_stars);
237 out_printf(fp, "%s", s);
243 print_method (FILE *fp,
244 const char *typeprefix,
245 const char *nameprefix,
246 const char *subnameprefix,
247 const char *namepostfix,
248 const char *afterargs,
251 gboolean print_funcattrs,
252 gboolean one_arg_per_line,
253 gboolean no_funcbase,
254 gboolean kill_underscore,
255 gboolean first_unused,
261 out_printf(fp, "%s", typeprefix);
262 print_type(fp, m->mtype, TRUE);
267 out_printf(fp, "%s%s%s%s(",
268 nameprefix, subnameprefix, id, namepostfix);
270 out_printf(fp, "%s%s_%s%s%s(",
271 nameprefix, funcbase, subnameprefix, id,
275 for(li=m->args; li; li=g_list_next(li)) {
276 FuncArg *arg = li->data;
277 const char *unused = "";
280 ! for_cpp && /* g++ has a cow with this */
283 unused = " G_GNUC_UNUSED";
286 print_type(fp, arg->atype, FALSE);
288 out_printf (fp, "___fake___");
290 out_printf(fp, "%s%s%s,%s", arg->name,
291 arg->atype->postfix ?
292 arg->atype->postfix : "",
294 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
296 out_printf(fp, "%s%s%s", arg->name,
297 arg->atype->postfix ?
298 arg->atype->postfix : "",
302 out_printf(fp, ",%s...",
303 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
305 out_printf(fp, "void");
307 /* Slightly icky: sometimes we are called st m->funcattrs
308 hasn't been set, but if so it should be NULL since its been
310 if(print_funcattrs && m->funcattrs != NULL
311 && strlen(m->funcattrs) > 0) {
312 /* To keep the output neat, we trim off the trailing '\n'
313 from the end of funcattrs for a moment. */
314 size_t funcattrs_len = strlen(m->funcattrs);
315 gboolean funcattrs_chomped = FALSE;
316 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
317 m->funcattrs[funcattrs_len - 1] = '\0';
318 funcattrs_chomped = TRUE;
320 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
321 /* Put it back like it was (though it shouldn't matter). */
322 if (funcattrs_chomped) {
323 (m->funcattrs)[funcattrs_len - 1] = '\n';
327 out_printf(fp, "%s)%s", afterargs, postfix);
332 any_method_to_alias(Class *c)
336 for(li=c->nodes;li;li=g_list_next(li)) {
337 Node *node = li->data;
338 if(node->type == METHOD_NODE) {
339 Method *m = (Method *)node;
341 if(m->method == INIT_METHOD ||
342 m->method == CLASS_INIT_METHOD ||
343 m->method == CONSTRUCTOR_METHOD ||
344 m->method == DISPOSE_METHOD ||
345 m->method == FINALIZE_METHOD ||
346 m->method == OVERRIDE_METHOD)
357 make_method_aliases (Class *c)
361 for(li = c->nodes; li != NULL; li = li->next) {
362 Node *node = li->data;
363 if(node->type == METHOD_NODE) {
364 Method *m = (Method *)node;
366 if(m->method == INIT_METHOD ||
367 m->method == CLASS_INIT_METHOD ||
368 m->method == CONSTRUCTOR_METHOD ||
369 m->method == DISPOSE_METHOD ||
370 m->method == FINALIZE_METHOD ||
371 m->method == OVERRIDE_METHOD)
374 out_printf (out, "#define self_%s %s_%s\n",
383 add_bad_hack_to_avoid_unused_warnings(const Class *c)
387 /* if we haven't had any methods, just return */
392 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
394 "/*REALLY BAD HACK\n"
395 " This is to avoid unused warnings if you don't call\n"
396 " some method. I need to find a better way to do\n"
397 " this, not needed in GCC since we use some gcc\n"
398 " extentions to make saner, faster code */\n"
400 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
402 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
403 for(li=c->nodes;li;li=g_list_next(li)) {
404 Node *node = li->data;
405 if(node->type == METHOD_NODE) {
406 Method *m = (Method *)node;
408 if(m->method == INIT_METHOD ||
409 m->method == CLASS_INIT_METHOD ||
410 m->method == CONSTRUCTOR_METHOD ||
411 m->method == DISPOSE_METHOD ||
412 m->method == FINALIZE_METHOD ||
413 m->method == OVERRIDE_METHOD)
416 /* in C++ mode we don't alias new */
417 if(for_cpp && strcmp(m->id, "new")==0)
420 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
423 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
426 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
428 out_printf(out, "}\n\n");
432 put_variable(const Variable *v, FILE *fp)
434 out_printf(fp, "\t");
435 print_type(fp, v->vtype, FALSE);
436 out_printf(fp, "%s%s;", v->id,
438 v->vtype->postfix:"");
439 if(v->scope == PROTECTED_SCOPE)
440 out_printf(fp, " /* protected */");
441 out_printf(fp, "\n");
445 put_vs_method(const Method *m)
447 if(m->method != SIGNAL_LAST_METHOD &&
448 m->method != SIGNAL_FIRST_METHOD &&
449 m->method != VIRTUAL_METHOD)
452 /* if a signal mark it as such */
453 if(m->method != VIRTUAL_METHOD)
454 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
455 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
457 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
458 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
463 put_pub_method(const Method *m)
465 if(m->scope != PUBLIC_SCOPE)
468 out_addline_infile(outh, m->line_no);
469 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
470 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
471 out_addline_outfile(outh);
475 put_signal_macro (const Method *m, gboolean gnu)
477 if(m->method != SIGNAL_LAST_METHOD &&
478 m->method != SIGNAL_FIRST_METHOD)
483 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
484 "g_signal_connect(%s(object),\"%s\","
485 "(GCallback)(func),(data))\n",
486 funcbase, m->id, macrobase, m->id);
489 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
490 "g_signal_connect_after(%s(object),\"%s\","
491 "(GCallback)(func),(data))\n",
492 funcbase, m->id, macrobase, m->id);
495 out_printf (outh, "#define %s_connect_data__%s"
496 "(object,func,data,destroy_data,flags)\t"
497 "g_signal_connect_data(%s(object),\"%s\","
498 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
499 funcbase, m->id, macrobase, m->id);
502 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
504 "%s(__extension__ ({%s *___object = (object); ___object; })),"
506 "(GCallback) __extension__ ({",
507 funcbase, m->id, macrobase, typebase, m->id);
508 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
509 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
510 out_printf (outh, "___%s; }), (data))\n", m->id);
513 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
514 "g_signal_connect_after("
515 "%s(__extension__ ({%s *___object = (object); ___object; })),"
517 "(GCallback) __extension__ ({",
518 funcbase, m->id, macrobase, typebase, m->id);
519 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
520 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
521 out_printf (outh, "___%s; }), (data))\n", m->id);
524 out_printf (outh, "#define %s_connect_data__%s"
525 "(object,func,data,destroy_data,flags)\t"
526 "g_signal_connect_data("
527 "%s(__extension__ ({%s *___object = (object); ___object; })),"
529 "(GCallback) __extension__ ({",
530 funcbase, m->id, macrobase, typebase, m->id);
531 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
532 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
533 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
538 put_signal_macros (const Class *c, gboolean gnu)
545 for (li = c->nodes; li != NULL; li = li->next) {
546 const Node *n = li->data;
547 if (n->type == METHOD_NODE)
548 put_signal_macro ((Method *)n, gnu);
553 put_local_signal_macro (const Method *m)
555 if(m->method != SIGNAL_LAST_METHOD &&
556 m->method != SIGNAL_FIRST_METHOD)
560 out_printf (out, "#define self_connect__%s(object,func,data)\t"
561 "%s_connect__%s((object),(func),(data))\n",
562 m->id, funcbase, m->id);
565 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
566 "%s_connect_after__%s((object),(func),(data))\n",
567 m->id, funcbase, m->id);
570 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
571 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
572 m->id, funcbase, m->id);
576 put_local_signal_macros (const Class *c)
583 for (li = c->nodes; li != NULL; li = li->next) {
584 const Node *n = li->data;
585 if (n->type == METHOD_NODE)
586 put_local_signal_macro ((Method *)n);
592 put_prot_method(const Method *m)
596 if(m->scope != PROTECTED_SCOPE)
599 f = outph ? outph : out;
601 out_addline_infile(f, m->line_no);
602 print_method(f, "", "\t", "", "\t", "", ";\n",
603 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
604 out_addline_outfile(f);
608 put_priv_method_prot(const Method *m)
610 if(m->method == SIGNAL_LAST_METHOD ||
611 m->method == SIGNAL_FIRST_METHOD ||
612 m->method == VIRTUAL_METHOD) {
615 "static ", "___real_", "", " ", "", ";\n",
616 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
618 /* no else, here, it might still have a private prototype, it's not
621 if((m->method == OVERRIDE_METHOD &&
624 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
626 out_addline_infile(out, m->line_no);
627 print_method(out, "static ", s, "", " ", "",
628 no_gnu?";\n":" G_GNUC_UNUSED;\n",
629 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
631 out_addline_outfile(out);
633 } else if(m->scope == PRIVATE_SCOPE ||
634 m->method == INIT_METHOD ||
635 m->method == CLASS_INIT_METHOD ||
636 m->method == CONSTRUCTOR_METHOD ||
637 m->method == DISPOSE_METHOD ||
638 m->method == FINALIZE_METHOD) {
640 out_addline_infile(out, m->line_no);
641 print_method(out, "static ", "", "", " ", "",
642 no_gnu?";\n":" G_GNUC_UNUSED;\n",
643 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
645 out_addline_outfile(out);
650 make_func_arg (const char *typename, gboolean is_class, const char *name)
657 tn = g_strconcat (typename, ":Class", NULL);
659 tn = g_strdup (typename);
661 type = node_new (TYPE_NODE,
665 node = node_new (FUNCARG_NODE,
666 "atype:steal", (Type *)type,
669 return g_list_prepend (NULL, node);
673 make_inits(Class *cl)
675 int got_class_init = FALSE;
676 int got_init = FALSE;
679 for(li=cl->nodes;li;li=g_list_next(li)) {
681 if(n->type == METHOD_NODE) {
682 Method *m = (Method *)n;
683 if(m->method == INIT_METHOD) {
685 error_print(GOB_ERROR, m->line_no, "init defined more then once");
687 } else if(m->method == CLASS_INIT_METHOD) {
689 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
690 got_class_init = TRUE;
694 if(!got_class_init) {
695 Type *type = (Type *)node_new (TYPE_NODE,
698 node = node_new (METHOD_NODE,
700 "method", CLASS_INIT_METHOD,
703 "args:steal", make_func_arg (cl->otype,
706 "unique_id", method_unique_id++,
708 cl->nodes = g_list_prepend(cl->nodes, node);
711 Type *type = (Type *)node_new (TYPE_NODE,
714 node = node_new (METHOD_NODE,
716 "method", INIT_METHOD,
719 "args:steal", make_func_arg (cl->otype,
720 FALSE /* is_class */,
722 "unique_id", method_unique_id++,
724 cl->nodes = g_list_prepend(cl->nodes, node);
729 find_method(const Class *cl, int method, const char *id)
733 for(li=cl->nodes;li;li=g_list_next(li)) {
735 if(n->type == METHOD_NODE) {
736 Method *m = (Method *)n;
737 if (m->method == method
738 && (id == NULL || strcmp(m->id, id)==0))
747 find_constructor(const Class *cl)
749 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
753 find_dispose(const Class *cl)
755 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
756 if (dispose_handler != NULL) {
757 if(strcmp(dispose_handler->otype, "G:Object") != 0)
758 error_print(GOB_ERROR, dispose_handler->line_no,
759 "dispose method override "
760 "of class other then "
762 if(g_list_length(dispose_handler->args) != 1)
763 error_print(GOB_ERROR, dispose_handler->line_no,
764 "dispose method override "
765 "with more then one "
769 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
773 find_finalize(const Class *cl)
775 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
776 if (finalize_handler != NULL) {
777 if(strcmp(finalize_handler->otype, "G:Object") != 0)
778 error_print(GOB_ERROR, finalize_handler->line_no,
779 "finalize method override "
780 "of class other then "
782 if(g_list_length(finalize_handler->args) != 1)
783 error_print(GOB_ERROR, finalize_handler->line_no,
784 "finalize method override "
785 "with more then one "
789 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
793 /* hash of method -> name of signal prototype */
794 static GHashTable *marsh = NULL;
796 /* list of methods with different signal prototypes,
797 we check this list if we can use a signal prototype of a
798 previous signal method, there are only uniques here */
799 static GList *eq_signal_methods = NULL;
801 /* compare a list of strings */
803 is_list_equal(const GList *a, const GList *b)
805 for(;a && b; a=a->next, b=b->next) {
806 if(strcmp(a->data, b->data)!=0) {
810 /* the the lists were different length */
817 find_same_type_signal(const Method *m)
820 for(li=eq_signal_methods;li;li=li->next) {
821 Method *mm = li->data;
822 if(is_list_equal(mm->gtktypes, m->gtktypes))
829 print_signal_marsal_args (const Method *m)
831 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
834 for (i = 0, li = m->gtktypes->next;
836 i++, li = li->next) {
839 if (strcmp (li->data, "UNICHAR") == 0)
840 /* hack because glib is braindamaged */
841 get_func = g_strdup ("g_value_get_uint");
842 else if (strncmp(li->data, "BOXED_", 6) == 0)
843 get_func = g_strdup ("g_value_get_boxed");
845 get_func = g_strdup_printf
846 ("g_value_get_%s", (char *)li->data);
848 gob_strdown (get_func);
849 out_printf (out, ",\n\t\t(%s) "
850 "%s (param_values + %d)",
851 get_cast (li->data, FALSE),
856 out_printf (out, ",\n\t\tdata2);\n");
861 add_signal_prots(Method *m)
867 gboolean ret_none = FALSE;
868 gboolean arglist_none = FALSE;
870 const char *unused = "";
872 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
873 unused = " G_GNUC_UNUSED";
876 if (m->method != SIGNAL_LAST_METHOD &&
877 m->method != SIGNAL_FIRST_METHOD)
881 marsh = g_hash_table_new(NULL, NULL);
883 g_assert (m->gtktypes->next != NULL);
885 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
886 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
888 if (ret_none && arglist_none)
891 /* if we already did a signal prototype just use that */
892 mm = find_same_type_signal (m);
894 s = g_hash_table_lookup (marsh, mm);
895 g_hash_table_insert (marsh, m, s);
902 retcast = get_cast (m->gtktypes->data, FALSE);
904 s = g_strdup_printf("Sig%d", sig++);
906 g_hash_table_insert(marsh, m, s);
907 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
909 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
910 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
911 get_cast(m->gtktypes->data, FALSE), s, typebase);
913 if ( ! arglist_none) {
914 for (li = m->gtktypes->next; li != NULL; li = li->next)
915 out_printf (out, "%s, ", get_cast (li->data, FALSE));
917 out_printf (out, "gpointer);\n");
919 out_printf (out, "\nstatic void\n"
920 "___marshal_%s (GClosure *closure,\n"
921 "\tGValue *return_value%s,\n"
922 "\tguint n_param_values,\n"
923 "\tconst GValue *param_values,\n"
924 "\tgpointer invocation_hint%s,\n"
925 "\tgpointer marshal_data)\n"
932 out_printf (out, "\t%s v_return;\n", retcast);
934 out_printf (out, "\tregister ___%s callback;\n"
935 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
936 "\tregister gpointer data1, data2;\n\n",
939 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
940 arglist_none ? 1 : g_list_length (m->gtktypes));
943 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
944 "\t\tdata1 = closure->data;\n"
945 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
947 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
948 "\t\tdata2 = closure->data;\n"
951 out_printf (out, "\tcallback = (___%s) "
952 "(marshal_data != NULL ? marshal_data : cc->callback);"
956 out_printf (out, "\tcallback ((%s *)data1", typebase);
958 out_printf (out, "\tv_return = callback ((%s *)data1",
962 print_signal_marsal_args (m);
965 /* FIXME: This code is so fucking ugly it hurts */
966 gboolean take_ownership =
967 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
968 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
972 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
973 /* hack because glib is braindamaged */
974 set_func = g_strdup ("g_value_set_uint");
976 set_func = g_strdup_printf ("g_value_%s_%s",
979 (char *)m->gtktypes->data);
980 gob_strdown (set_func);
982 out_printf (out, "\n\t%s (return_value, v_return);\n",
987 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
989 out_printf (out, "\n\treturn_value = NULL;\n");
990 out_printf (out, "\tinvocation_hint = NULL;\n");
993 out_printf (out, "}\n\n");
997 interface_type(const char *if_name)
999 char *rawtype = remove_sep(if_name);
1000 char *end = "", *typename;
1004 * EEEK! evil, we should have some sort of option
1005 * to force this for arbitrary interfaces, since
1006 * some are Class and some are Iface. Glib is shite
1010 if (strcmp (rawtype, "GtkEditable") == 0
1011 || strcmp (rawtype, "GTypePlugin") == 0)
1015 /* We'll assume Iface is the standard ending */
1019 /* GTK3 doesn't need Iface end */
1023 typename = g_strconcat(rawtype, end, (char *)NULL);
1030 define_parent_interface_refs(Class *c)
1037 out_printf(out, "\n/* parent class interface implementations */\n");
1038 for (li = c->interfaces; li != NULL; li = li->next) {
1039 char *name = replace_sep(li->data, '_');
1040 char *type = interface_type(li->data);
1042 out_printf (out, "static %s *%s_parent_iface;\n", type, name);
1053 out_printf(out, "\n");
1055 out_printf(out, "enum {\n");
1056 for(li=c->nodes;li;li=g_list_next(li)) {
1058 if(n->type == METHOD_NODE) {
1059 Method *m = (Method *)n;
1060 if(m->method == SIGNAL_LAST_METHOD ||
1061 m->method == SIGNAL_FIRST_METHOD) {
1062 char *s = g_strdup(m->id);
1064 out_printf(out, "\t%s_SIGNAL,\n", s);
1069 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
1071 if (set_properties > 0 ||
1072 get_properties > 0) {
1073 out_printf(out, "enum {\n\tPROP_0");
1074 for(li=c->nodes;li;li=g_list_next(li)) {
1076 if (n->type == PROPERTY_NODE) {
1077 Property *p = (Property *)n;
1078 char *s = g_strdup (p->name);
1080 out_printf (out, ",\n\tPROP_%s", s);
1082 } else if (n->type == ARGUMENT_NODE) {
1083 Argument *a = (Argument *)n;
1084 char *s = g_strdup(a->name);
1086 out_printf(out, ",\n\tPROP_%s", s);
1090 out_printf(out, "\n};\n\n");
1095 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1097 out_printf(out, "/* pointer to the class of our parent */\n");
1098 out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase);
1099 define_parent_interface_refs(c);
1100 out_printf(out, "\n");
1104 add_interface_methods (Class *c, const char *interface)
1107 gboolean added_line = FALSE;
1109 for (li = c->nodes; li != NULL; li = li->next) {
1111 Method *m = (Method *)n;
1112 if (n->type != METHOD_NODE ||
1113 m->method == OVERRIDE_METHOD ||
1114 m->interface == NULL ||
1115 strcmp (m->interface, interface) != 0)
1118 if (m->line_no > 0) {
1119 out_addline_infile (out, m->line_no);
1121 } else if (m->line_no == 0 &&
1123 out_addline_outfile (out);
1126 out_printf (out, "\tiface->%s = self_%s;\n",
1130 out_addline_outfile (out);
1134 add_interface_inits(Class *c)
1138 if (c->interfaces == NULL)
1141 out_printf(out, "\n");
1143 for (li = c->interfaces; li != NULL; li = li->next) {
1144 char *name = replace_sep(li->data, '_');
1145 char *type = interface_type(li->data);
1147 out_printf(out, "static void\n"
1148 "___%s_init (%s *iface)\n"
1151 add_interface_methods(c, li->data);
1153 out_printf(out, "\t%s_parent_iface\n", name);
1154 out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type);
1155 out_printf(out, "g_type_interface_peek_parent(iface);\n"
1164 add_interface_infos(Class *c, gboolean static_storage)
1168 for (li = c->interfaces; li; li = li->next) {
1169 char *name = replace_sep(li->data, '_');
1170 out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n"
1171 "\t\t(GInterfaceInitFunc) ___%s_init,\n"
1175 static_storage ? "static " : "",
1180 out_printf(out, "\n");
1184 define_add_interfaces(Class *c)
1191 out_printf(out, "static void ___add_interfaces(GType type)\n{\n");
1192 add_interface_infos(c, TRUE);
1194 for (li = c->interfaces; li; li = li->next) {
1195 char *type = make_pre_macro(li->data, "TYPE");
1196 char *name = replace_sep(li->data, '_');
1198 out_printf(out, "\tg_type_add_interface_static\n"
1209 out_printf(out, "}\n\n");
1213 define_dynamic_add_interfaces(Class *c)
1220 out_printf(out, "static void ___add_interfaces"
1221 "(GTypeModule *type_module, GType type)\n"
1223 add_interface_infos(c, FALSE);
1226 * Hack to work around bug in g_type_module_add_interface,
1227 * which will fail to add an interface to types that derive
1228 * from something that also implements the same interface.
1230 * The actual GType system does not have any such problem,
1231 * and the GTypeModule implementation details relied upon
1232 * here have not changed once since the feature was first
1233 * implemented almost 20 years ago.
1235 out_printf(out, "\tstruct _ModuleInterfaceInfo {\n"
1236 "\t\tgboolean loaded;\n"
1237 "\t\tGType instance_type;\n"
1238 "\t\tGType interface_type;\n"
1239 "\t\tGInterfaceInfo info;\n"
1242 for (li = c->interfaces; li; li = li->next) {
1243 char *type = make_pre_macro(li->data, "TYPE");
1244 char *name = replace_sep(li->data, '_');
1246 out_printf(out, "\n"
1247 "\tmodinfo = g_malloc(sizeof *modinfo);\n"
1248 "\tmodinfo->loaded = TRUE;\n"
1249 "\tmodinfo->instance_type = type;\n"
1250 "\tmodinfo->interface_type = %s;\n"
1251 "\tmodinfo->info = %s_info;\n"
1252 "\tg_type_add_interface_dynamic\n"
1253 "\t\t( modinfo->instance_type\n"
1254 "\t\t, modinfo->interface_type\n"
1255 "\t\t, G_TYPE_PLUGIN(type_module)\n"
1257 "\ttype_module->interface_infos = g_slist_prepend\n"
1258 "\t\t( type_module->interface_infos\n"
1267 out_printf(out, "}\n\n");
1270 static void define_add_privates(Class *c)
1272 const char *addprivate = c->dynamic
1273 ? "G_ADD_PRIVATE_DYNAMIC"
1279 out_printf(out, "#ifdef %s\n"
1280 "#define ___add_privates() %s(%s)\n"
1282 "#define ___add_privates()\n"
1284 addprivate, addprivate, typebase);
1287 static void add_type_info(void)
1289 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1290 "\t\tsizeof (%sClass),\n"
1291 "\t\t(GBaseInitFunc) NULL,\n"
1292 "\t\t(GBaseFinalizeFunc) NULL,\n"
1293 "\t\t(GClassInitFunc) %s_class_init,\n"
1294 "\t\t(GClassFinalizeFunc) NULL,\n"
1295 "\t\tNULL /* class_data */,\n"
1296 "\t\tsizeof (%s),\n"
1297 "\t\t%d /* n_preallocs */,\n"
1298 "\t\t(GInstanceInitFunc) %s_init,\n"
1301 typebase, funcbase, typebase, prealloc, funcbase);
1307 Class *c = (Class *)class;
1309 define_add_interfaces(c);
1310 define_add_privates(c);
1312 out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
1313 "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
1314 "\t(GTypeFlags)%s,\n",
1315 typebase, funcbase, pmacrotype,
1316 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1319 out_printf(out, "\t___add_privates();\n");
1322 out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
1324 /* Fallback for GLib < 2.4 */
1325 out_printf(out, ");\n\n"
1327 "GType %s_get_type(void)\n"
1329 "\tstatic GType type = 0;\n",
1334 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1335 "\t\ttype = g_type_register_static\n"
1339 "\t\t\t, (GTypeFlags)%s\n"
1341 pmacrotype, typebase,
1342 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1345 out_printf(out, "\t\t___add_interfaces(type);\n");
1347 out_printf(out, "\t}\n\n"
1354 add_dynamic_get_type(void)
1356 Class *c = (Class *)class;
1358 define_dynamic_add_interfaces(c);
1359 define_add_privates(c);
1362 * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
1363 * some reason it defines an xxx_register_type function with internal
1364 * linkage. This is kind of weird so we have to work around that.
1366 out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
1367 "static void %s_class_finalize(%sClass *c) { }\n\n"
1368 "#define %s_register_type ___register_type\n",
1369 funcbase, typebase, funcbase);
1371 out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
1372 "\t(GTypeFlags)%s,\n",
1373 typebase, funcbase, pmacrotype,
1374 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1377 out_printf(out, "\t___add_privates();\n");
1379 if (c->interfaces) {
1380 out_printf(out, "\t___add_interfaces"
1381 "(type_module, %s_type_id);\n", funcbase);
1384 out_printf(out, ");\n"
1385 "#undef %s_register_type\n\n"
1386 "void %s_register_type(GTypeModule *type_module)\n"
1388 "\t___register_type(type_module);\n"
1390 funcbase, funcbase);
1392 /* Fallback for GLib < 2.14 */
1393 out_printf(out, "#else\n\n"
1394 "static GType %s_type_id;\n\n"
1395 "GType %s_get_type(void)\n"
1397 "\treturn %s_type_id;\n"
1399 funcbase, funcbase, funcbase);
1401 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1407 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1408 "\t\t( type_module\n"
1412 "\t\t, (GTypeFlags)%s\n"
1414 funcbase, pmacrotype, typebase,
1415 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1417 if (c->interfaces) {
1418 out_printf(out, "\t___add_interfaces"
1419 "(type_module, %s_type_id);\n",
1423 out_printf(out, "}\n\n"
1428 add_bonobo_object_get_type(void)
1430 Class *c = (Class *)class;
1432 define_add_interfaces(c);
1434 out_printf (out, "GType %s_get_type(void)\n"
1436 "\tstatic GType type = 0;\n",
1441 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1442 "\t\ttype = bonobo_type_unique\n"
1443 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1444 "\t\t\t, POA_%s__init, NULL\n"
1445 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1449 c->bonobo_object_class, typebase, typebase);
1451 if (((Class *)class)->interfaces)
1452 out_printf(out, "\t\t___add_interfaces(type);\n");
1454 out_printf(out, "\t}\n\n"
1460 add_overrides(Class *c, const char *oname,
1461 gboolean did_base_obj)
1467 done = g_hash_table_new (g_str_hash, g_str_equal);
1469 s = g_strdup ("GObject");
1470 g_hash_table_insert (done, s, s);
1472 for (li = c->nodes; li != NULL; li = li->next) {
1475 Method *m = (Method *)n;
1476 if(n->type != METHOD_NODE ||
1477 m->method != OVERRIDE_METHOD)
1480 s = remove_sep(m->otype);
1482 if(g_hash_table_lookup(done, s)) {
1486 g_hash_table_insert(done, s, s);
1488 f = replace_sep(m->otype, '_');
1491 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1496 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1497 g_hash_table_destroy (done);
1501 make_run_signal_flags(Method *m, gboolean last)
1516 gs = g_string_new(NULL);
1519 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1521 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1523 if(m->scope == PUBLIC_SCOPE)
1524 g_string_append(gs, " | G_SIGNAL_ACTION");
1526 for(li = m->flags; li; li = li->next) {
1527 char *flag = li->data;
1529 for(i=0;flags[i];i++) {
1530 if(strcmp(flags[i], flag)==0)
1533 /* if we haven't found it in our list */
1535 error_printf(GOB_WARN, m->line_no,
1536 "Unknown flag '%s' used, "
1537 "perhaps it was misspelled",
1540 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1544 char *ret = gs->str;
1545 g_string_free(gs, FALSE);
1552 add_signals(Class *c)
1556 out_printf(out, "\n");
1557 for(li=c->nodes;li;li=g_list_next(li)) {
1559 char *mar, *sig, *flags;
1560 gboolean is_none, last = FALSE;
1561 Method *m = (Method *)n;
1563 if(n->type != METHOD_NODE ||
1564 (m->method != SIGNAL_FIRST_METHOD &&
1565 m->method != SIGNAL_LAST_METHOD))
1568 if(m->method == SIGNAL_FIRST_METHOD)
1573 if(g_hash_table_lookup(marsh, m))
1574 mar = g_strconcat("___marshal_",
1575 (char *)g_hash_table_lookup(marsh, m),
1578 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1580 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1582 sig = g_strdup (m->id);
1584 flags = make_run_signal_flags (m, last);
1585 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1586 "\t\tg_signal_new (%s,\n"
1587 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1588 "\t\t\t(GSignalFlags)(%s),\n"
1589 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1590 "\t\t\tNULL, NULL,\n"
1592 "\t\t\tG_TYPE_%s, %d",
1593 sig, m->signal_name /*m->id* if not given signal_name*/,
1595 typebase, m->id, mar,
1596 (char *)m->gtktypes->data,
1597 is_none ? 0 : g_list_length(m->gtktypes->next));
1605 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1606 char *str = l->data;
1607 if (strncmp (str, "BOXED_", 6) == 0)
1608 t = g_strdup (&(str[6]));
1610 t = g_strconcat ("G_TYPE_", str, NULL);
1611 out_printf (out, ",\n\t\t\t%s", t);
1616 out_printf(out, ");\n");
1618 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1621 out_printf(out, "\tif ___GOB_UNLIKELY(");
1622 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1623 out_printf(out, "sizeof(");
1624 print_type(out, m->mtype, FALSE);
1625 out_printf(out, "%s",
1627 m->mtype->postfix : "");
1628 out_printf(out, ") != sizeof(%s) || ",
1629 get_cast(m->gtktypes->data, FALSE));
1632 for(al = m->args->next, gl = m->gtktypes->next;
1633 al != NULL && gl != NULL;
1634 al = al->next, gl = gl->next) {
1635 FuncArg *arg = al->data;
1636 char *gtkarg = gl->data;
1638 out_printf(out, "sizeof(");
1639 print_type(out, arg->atype, FALSE);
1640 out_printf(out, "%s",
1641 arg->atype->postfix ?
1642 arg->atype->postfix : "");
1643 out_printf(out, ") != sizeof(%s) || ",
1644 get_cast(gtkarg, FALSE));
1648 "parent_class == NULL /* avoid warning */");
1650 out_printf(out, ") {\n"
1651 "\t\tg_error(\"%s line %d: Type mismatch "
1652 "of \\\"%s\\\" signal signature\");\n"
1654 filename, m->line_no, m->id);
1661 set_def_handlers(Class *c, const char *oname)
1664 gboolean set_line = FALSE;
1666 out_printf(out, "\n");
1667 for(li = c->nodes; li; li = g_list_next(li)) {
1669 Method *m = (Method *)n;
1671 if(n->type != METHOD_NODE ||
1672 (m->method != SIGNAL_FIRST_METHOD &&
1673 m->method != SIGNAL_LAST_METHOD &&
1674 m->method != VIRTUAL_METHOD &&
1675 m->method != OVERRIDE_METHOD))
1678 if(m->line_no > 0 && m->cbuf) {
1679 out_addline_infile(out, m->line_no);
1681 } else if(set_line) {
1682 out_addline_outfile(out);
1687 if (m->method == OVERRIDE_METHOD) {
1689 s = replace_sep (m->otype, '_');
1693 dispose_handler != NULL &&
1694 strcmp (m->id, "dispose") == 0)
1695 out_printf (out, "\tg_object_class->dispose "
1697 else if (need_finalize &&
1699 strcmp(m->id, "finalize") == 0)
1701 "\tg_object_class->finalize = ___finalize;\n");
1702 else if (m->cbuf != NULL)
1704 "\t%s_class->%s = ___%x_%s_%s;\n",
1705 s, m->id, (guint)m->unique_id,
1708 out_printf(out, "\t%s_class->%s = NULL;\n",
1712 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1716 out_printf(out, "\t%s->%s = NULL;\n",
1721 out_addline_outfile(out);
1725 make_argument (Argument *a)
1730 char *argflags[] = {
1738 flags = g_string_new ("(GParamFlags)(");
1740 if(a->get && a->set)
1741 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1743 g_string_append (flags, "G_PARAM_READABLE");
1745 g_string_append (flags, "G_PARAM_WRITABLE");
1747 g_assert(a->get || a->set);
1749 for (l = a->flags; l != NULL; l = l->next) {
1750 char *flag = l->data;
1752 if(strcmp (flag, "READABLE") == 0 ||
1753 strcmp (flag, "WRITABLE") == 0) {
1754 error_print(GOB_WARN, a->line_no,
1756 "WRITABLE argument flags are "
1757 "set automatically");
1760 for(i = 0; argflags[i]; i++) {
1761 if(strcmp(argflags[i], flag)==0)
1764 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1767 g_string_append (flags, ")");
1769 s = g_strdup(a->name);
1771 if (!strcmp (a->gtktype, "ENUM"))
1772 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1773 "\t\tG_TYPE_ENUM, 0,\n"
1775 a->name, flags->str);
1776 if (!strcmp (a->gtktype, "FLAGS"))
1777 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1778 "\t\tG_TYPE_FLAGS, 0,\n"
1780 a->name, flags->str);
1781 else if (!strcmp (a->gtktype, "OBJECT"))
1782 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1783 "\t\tG_TYPE_OBJECT,\n"
1785 a->name, flags->str);
1786 else if (!strcmp (a->gtktype, "STRING"))
1787 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1790 a->name, flags->str);
1791 else if (!strcmp (a->gtktype, "INT"))
1792 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1793 "\t\tG_MININT, G_MAXINT,\n"
1796 a->name, flags->str);
1797 else if (!strcmp (a->gtktype, "UINT"))
1798 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1799 "\t\t0, G_MAXUINT,\n"
1802 a->name, flags->str);
1803 else if (!strcmp (a->gtktype, "INT"))
1804 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1805 "\t\tG_MININT, G_MAXINT,\n"
1808 a->name, flags->str);
1809 else if (!strcmp (a->gtktype, "CHAR"))
1810 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1814 a->name, flags->str);
1815 else if (!strcmp (a->gtktype, "UCHAR"))
1816 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1820 a->name, flags->str);
1821 else if (!strcmp (a->gtktype, "BOOL") ||
1822 !strcmp (a->gtktype, "BOOLEAN"))
1823 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1826 a->name, flags->str);
1827 else if (!strcmp (a->gtktype, "LONG"))
1828 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1829 "\t\tG_MINLONG, G_MAXLONG,\n"
1832 a->name, flags->str);
1833 else if (!strcmp (a->gtktype, "ULONG"))
1834 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1835 "\t\t0, G_MAXULONG,\n"
1838 a->name, flags->str);
1839 else if (!strcmp (a->gtktype, "INT64"))
1840 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1841 "\t\tG_MININT64, G_MAXINT64,\n"
1844 a->name, flags->str);
1845 else if (!strcmp (a->gtktype, "UINT64"))
1846 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1847 "\t\t0, G_MAXUINT64,\n"
1850 a->name, flags->str);
1851 else if (!strcmp (a->gtktype, "FLOAT"))
1852 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1853 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1856 a->name, flags->str);
1857 else if (!strcmp (a->gtktype, "DOUBLE"))
1858 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1859 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1862 a->name, flags->str);
1863 else if (!strcmp (a->gtktype, "POINTER"))
1864 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1866 a->name, flags->str);
1868 error_printf (GOB_ERROR, a->line_no,
1869 "%s type is not supported for arguments, try using properties",
1872 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1873 "\t\tPROP_%s, param_spec);\n", s);
1877 g_string_free(flags, TRUE);
1880 #define value_for_print(str, alt) (str != NULL ? str : alt)
1883 make_property (Property *p)
1887 if (p->get == NULL && p->set == NULL) {
1888 error_print (GOB_ERROR, p->line_no,
1889 "Property has no getter nor setter");
1893 if (p->flags != NULL)
1894 error_print (GOB_WARN, p->line_no,
1895 "Overridden property, flags ignored");
1896 if (p->nick != NULL)
1897 error_print (GOB_WARN, p->line_no,
1898 "Overridden property, nick ignored");
1899 if (p->blurb != NULL)
1900 error_print (GOB_WARN, p->line_no,
1901 "Overridden property, blurb ignored");
1902 if (p->minimum != NULL)
1903 error_print (GOB_WARN, p->line_no,
1904 "Overridden property, minimum ignored");
1905 if (p->maximum != NULL)
1906 error_print (GOB_WARN, p->line_no,
1907 "Overridden property, maximum ignored");
1908 if (p->default_value != NULL)
1909 error_print (GOB_WARN, p->line_no,
1910 "Overridden property, default_value ignored");
1912 s = g_strdup (p->name);
1914 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1916 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1921 char *argflags[] = {
1929 flags = g_string_new ("(GParamFlags)(");
1931 if (p->get != NULL && p->set != NULL)
1932 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1933 else if (p->get != NULL)
1934 g_string_append (flags, "G_PARAM_READABLE");
1936 g_string_append (flags, "G_PARAM_WRITABLE");
1939 for (l = p->flags; l != NULL; l = l->next) {
1940 char *flag = l->data;
1942 if(strcmp (flag, "READABLE") == 0 ||
1943 strcmp (flag, "WRITABLE") == 0) {
1944 error_print(GOB_WARN, p->line_no,
1946 "WRITABLE argument flags are "
1947 "set automatically");
1950 for(i = 0; argflags[i]; i++) {
1951 if(strcmp(argflags[i], flag)==0)
1954 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1957 g_string_append (flags, ")");
1959 if (strcmp (p->gtktype, "CHAR") == 0) {
1960 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1961 "\t\t(\"%s\" /* name */,\n"
1962 "\t\t %s /* nick */,\n"
1963 "\t\t %s /* blurb */,\n"
1964 "\t\t %s /* minimum */,\n"
1965 "\t\t %s /* maximum */,\n"
1966 "\t\t %s /* default_value */,\n"
1968 value_for_print (p->canonical_name, p->name),
1969 value_for_print (p->nick, "NULL"),
1970 value_for_print (p->blurb, "NULL"),
1971 value_for_print (p->minimum, "-128"),
1972 value_for_print (p->maximum, "127"),
1973 value_for_print (p->default_value, "0"),
1975 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1976 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1977 "\t\t(\"%s\" /* name */,\n"
1978 "\t\t %s /* nick */,\n"
1979 "\t\t %s /* blurb */,\n"
1980 "\t\t %s /* minimum */,\n"
1981 "\t\t %s /* maximum */,\n"
1982 "\t\t %s /* default_value */,\n"
1984 value_for_print (p->canonical_name, p->name),
1985 value_for_print (p->nick, "NULL"),
1986 value_for_print (p->blurb, "NULL"),
1987 value_for_print (p->minimum, "0"),
1988 value_for_print (p->maximum, "0xFF"),
1989 value_for_print (p->default_value, "0"),
1991 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1992 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1993 "\t\t(\"%s\" /* name */,\n"
1994 "\t\t %s /* nick */,\n"
1995 "\t\t %s /* blurb */,\n"
1996 "\t\t %s /* default_value */,\n"
1998 value_for_print (p->canonical_name, p->name),
1999 value_for_print (p->nick, "NULL"),
2000 value_for_print (p->blurb, "NULL"),
2001 value_for_print (p->default_value, "FALSE"),
2003 } else if (strcmp (p->gtktype, "INT") == 0) {
2004 out_printf (out, "\tparam_spec = g_param_spec_int\n"
2005 "\t\t(\"%s\" /* name */,\n"
2006 "\t\t %s /* nick */,\n"
2007 "\t\t %s /* blurb */,\n"
2008 "\t\t %s /* minimum */,\n"
2009 "\t\t %s /* maximum */,\n"
2010 "\t\t %s /* default_value */,\n"
2012 value_for_print (p->canonical_name, p->name),
2013 value_for_print (p->nick, "NULL"),
2014 value_for_print (p->blurb, "NULL"),
2015 value_for_print (p->minimum, "G_MININT"),
2016 value_for_print (p->maximum, "G_MAXINT"),
2017 value_for_print (p->default_value, "0"),
2019 } else if (strcmp (p->gtktype, "UINT") == 0) {
2020 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
2021 "\t\t(\"%s\" /* name */,\n"
2022 "\t\t %s /* nick */,\n"
2023 "\t\t %s /* blurb */,\n"
2024 "\t\t %s /* minimum */,\n"
2025 "\t\t %s /* maximum */,\n"
2026 "\t\t %s /* default_value */,\n"
2028 value_for_print (p->canonical_name, p->name),
2029 value_for_print (p->nick, "NULL"),
2030 value_for_print (p->blurb, "NULL"),
2031 value_for_print (p->minimum, "0"),
2032 value_for_print (p->maximum, "G_MAXUINT"),
2033 value_for_print (p->default_value, "0"),
2035 } else if (strcmp (p->gtktype, "LONG") == 0) {
2036 out_printf (out, "\tparam_spec = g_param_spec_long\n"
2037 "\t\t(\"%s\" /* name */,\n"
2038 "\t\t %s /* nick */,\n"
2039 "\t\t %s /* blurb */,\n"
2040 "\t\t %s /* minimum */,\n"
2041 "\t\t %s /* maximum */,\n"
2042 "\t\t %s /* default_value */,\n"
2044 value_for_print (p->canonical_name, p->name),
2045 value_for_print (p->nick, "NULL"),
2046 value_for_print (p->blurb, "NULL"),
2047 value_for_print (p->minimum, "G_MINLONG"),
2048 value_for_print (p->maximum, "G_MAXLONG"),
2049 value_for_print (p->default_value, "0"),
2051 } else if (strcmp (p->gtktype, "ULONG") == 0) {
2052 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
2053 "\t\t(\"%s\" /* name */,\n"
2054 "\t\t %s /* nick */,\n"
2055 "\t\t %s /* blurb */,\n"
2056 "\t\t %s /* minimum */,\n"
2057 "\t\t %s /* maximum */,\n"
2058 "\t\t %s /* default_value */,\n"
2060 value_for_print (p->canonical_name, p->name),
2061 value_for_print (p->nick, "NULL"),
2062 value_for_print (p->blurb, "NULL"),
2063 value_for_print (p->minimum, "0"),
2064 value_for_print (p->maximum, "G_MAXULONG"),
2065 value_for_print (p->default_value, "0"),
2067 } else if (strcmp (p->gtktype, "INT64") == 0) {
2068 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
2069 "\t\t(\"%s\" /* name */,\n"
2070 "\t\t %s /* nick */,\n"
2071 "\t\t %s /* blurb */,\n"
2072 "\t\t %s /* minimum */,\n"
2073 "\t\t %s /* maximum */,\n"
2074 "\t\t %s /* default_value */,\n"
2076 value_for_print (p->canonical_name, p->name),
2077 value_for_print (p->nick, "NULL"),
2078 value_for_print (p->blurb, "NULL"),
2079 value_for_print (p->minimum, "G_MININT64"),
2080 value_for_print (p->maximum, "G_MAXINT64"),
2081 value_for_print (p->default_value, "0"),
2083 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2084 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2085 "\t\t(\"%s\" /* name */,\n"
2086 "\t\t %s /* nick */,\n"
2087 "\t\t %s /* blurb */,\n"
2088 "\t\t %s /* minimum */,\n"
2089 "\t\t %s /* maximum */,\n"
2090 "\t\t %s /* default_value */,\n"
2092 value_for_print (p->canonical_name, p->name),
2093 value_for_print (p->nick, "NULL"),
2094 value_for_print (p->blurb, "NULL"),
2095 value_for_print (p->minimum, "0"),
2096 value_for_print (p->maximum, "G_MAXUINT64"),
2097 value_for_print (p->default_value, "0"),
2099 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2100 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2101 "\t\t(\"%s\" /* name */,\n"
2102 "\t\t %s /* nick */,\n"
2103 "\t\t %s /* blurb */,\n"
2104 "\t\t %s /* default_value */,\n"
2106 value_for_print (p->canonical_name, p->name),
2107 value_for_print (p->nick, "NULL"),
2108 value_for_print (p->blurb, "NULL"),
2109 value_for_print (p->default_value, "0"),
2111 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2112 char *type = make_me_type (p->extra_gtktype,
2114 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2115 "\t\t(\"%s\" /* name */,\n"
2116 "\t\t %s /* nick */,\n"
2117 "\t\t %s /* blurb */,\n"
2118 "\t\t %s /* enum_type */,\n"
2119 "\t\t %s /* default_value */,\n"
2121 value_for_print (p->canonical_name, p->name),
2122 value_for_print (p->nick, "NULL"),
2123 value_for_print (p->blurb, "NULL"),
2125 value_for_print (p->default_value, "0"),
2128 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2129 char *type = make_me_type (p->extra_gtktype,
2131 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2132 "\t\t(\"%s\" /* name */,\n"
2133 "\t\t %s /* nick */,\n"
2134 "\t\t %s /* blurb */,\n"
2135 "\t\t %s /* flags_type */,\n"
2136 "\t\t %s /* default_value */,\n"
2138 value_for_print (p->canonical_name, p->name),
2139 value_for_print (p->nick, "NULL"),
2140 value_for_print (p->blurb, "NULL"),
2142 value_for_print (p->default_value, "0"),
2145 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2146 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2147 "\t\t(\"%s\" /* name */,\n"
2148 "\t\t %s /* nick */,\n"
2149 "\t\t %s /* blurb */,\n"
2150 "\t\t %s /* minimum */,\n"
2151 "\t\t %s /* maximum */,\n"
2152 "\t\t %s /* default_value */,\n"
2154 value_for_print (p->canonical_name, p->name),
2155 value_for_print (p->nick, "NULL"),
2156 value_for_print (p->blurb, "NULL"),
2157 value_for_print (p->minimum, "-G_MAXFLOAT"),
2158 value_for_print (p->maximum, "G_MAXFLOAT"),
2159 value_for_print (p->default_value, "0.0"),
2161 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2162 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2163 "\t\t(\"%s\" /* name */,\n"
2164 "\t\t %s /* nick */,\n"
2165 "\t\t %s /* blurb */,\n"
2166 "\t\t %s /* minimum */,\n"
2167 "\t\t %s /* maximum */,\n"
2168 "\t\t %s /* default_value */,\n"
2170 value_for_print (p->canonical_name, p->name),
2171 value_for_print (p->nick, "NULL"),
2172 value_for_print (p->blurb, "NULL"),
2173 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2174 value_for_print (p->maximum, "G_MAXDOUBLE"),
2175 value_for_print (p->default_value, "0.0"),
2177 } else if (strcmp (p->gtktype, "STRING") == 0) {
2178 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2179 "\t\t(\"%s\" /* name */,\n"
2180 "\t\t %s /* nick */,\n"
2181 "\t\t %s /* blurb */,\n"
2182 "\t\t %s /* default_value */,\n"
2184 value_for_print (p->canonical_name, p->name),
2185 value_for_print (p->nick, "NULL"),
2186 value_for_print (p->blurb, "NULL"),
2187 value_for_print (p->default_value, "NULL"),
2189 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2190 char *type = make_me_type (p->extra_gtktype,
2192 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2193 "\t\t(\"%s\" /* name */,\n"
2194 "\t\t %s /* nick */,\n"
2195 "\t\t %s /* blurb */,\n"
2196 "\t\t %s /* param_type */,\n"
2198 value_for_print (p->canonical_name, p->name),
2199 value_for_print (p->nick, "NULL"),
2200 value_for_print (p->blurb, "NULL"),
2204 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2205 char *type = make_me_type (p->extra_gtktype,
2207 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2208 "\t\t(\"%s\" /* name */,\n"
2209 "\t\t %s /* nick */,\n"
2210 "\t\t %s /* blurb */,\n"
2211 "\t\t %s /* boxed_type */,\n"
2213 value_for_print (p->canonical_name, p->name),
2214 value_for_print (p->nick, "NULL"),
2215 value_for_print (p->blurb, "NULL"),
2219 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2220 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2221 "\t\t(\"%s\" /* name */,\n"
2222 "\t\t %s /* nick */,\n"
2223 "\t\t %s /* blurb */,\n"
2225 value_for_print (p->canonical_name, p->name),
2226 value_for_print (p->nick, "NULL"),
2227 value_for_print (p->blurb, "NULL"),
2229 /* FIXME: VALUE_ARRAY */
2230 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2231 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2232 "\t\t(\"%s\" /* name */,\n"
2233 "\t\t %s /* nick */,\n"
2234 "\t\t %s /* blurb */,\n"
2236 value_for_print (p->canonical_name, p->name),
2237 value_for_print (p->nick, "NULL"),
2238 value_for_print (p->blurb, "NULL"),
2240 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2241 char *type = make_me_type (p->extra_gtktype,
2243 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2244 "\t\t(\"%s\" /* name */,\n"
2245 "\t\t %s /* nick */,\n"
2246 "\t\t %s /* blurb */,\n"
2247 "\t\t %s /* object_type */,\n"
2249 value_for_print (p->canonical_name, p->name),
2250 value_for_print (p->nick, "NULL"),
2251 value_for_print (p->blurb, "NULL"),
2256 error_printf (GOB_ERROR, p->line_no,
2257 "%s type is not supported by properties",
2261 s = g_strdup (p->name);
2263 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2265 "\t\tparam_spec);\n", s);
2268 g_string_free (flags, TRUE);
2273 make_arguments(Class *c)
2276 if (get_properties > 0)
2277 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2278 if (set_properties > 0)
2279 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2280 out_printf (out, " {\n");
2281 for (li = c->nodes; li != NULL; li = li->next) {
2283 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2284 || n->type == ARGUMENT_NODE) {
2285 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2290 for (li = c->nodes; li != NULL; li = li->next) {
2292 if (n->type == PROPERTY_NODE)
2293 make_property ((Property *)n);
2294 else if (n->type == ARGUMENT_NODE)
2295 make_argument ((Argument *)n);
2297 out_printf(out, " }\n");
2301 print_initializer(Method *m, Variable *v)
2308 if(v->initializer == NULL)
2311 if(v->scope == PRIVATE_SCOPE)
2312 root = g_strconcat(((FuncArg *)m->args->data)->name,
2315 root = g_strdup(((FuncArg *)m->args->data)->name);
2317 if(v->initializer_line > 0)
2318 out_addline_infile(out, v->initializer_line);
2320 if (v->initializer_simple)
2321 out_printf(out, "\t%s->%s = %s;\n",
2322 root, v->id, v->initializer);
2323 else if (strcmp(v->id, "_glade_xml") == 0)
2324 /* This is OK, this v->initializer string is set internally
2325 and it will eat exactly one string! */
2326 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2328 out_printf(out, "%s", v->initializer);
2330 if(v->initializer_line > 0)
2331 out_addline_outfile(out);
2337 print_glade_widget(Method *m, Variable *v)
2342 if(!v->glade_widget)
2345 if(v->scope == PRIVATE_SCOPE)
2346 root = g_strconcat(((FuncArg *)m->args->data)->name,
2349 root = g_strdup(((FuncArg *)m->args->data)->name);
2351 cast = get_type(v->vtype, FALSE);
2352 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2353 root, v->id, cast, root, v->id);
2359 print_destructor (Variable *v)
2363 if(v->destructor == NULL)
2366 if(v->scope == PRIVATE_SCOPE)
2367 root = "self->_priv";
2371 if(v->destructor_simple) {
2372 if(v->destructor_line > 0)
2373 out_addline_infile(out, v->destructor_line);
2376 out_printf(out, "\tif(%s->%s) { "
2377 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2378 "%s->%s = NULL; }\n",
2379 root, v->id, v->destructor, root, v->id,
2382 out_printf(out, "\tif(%s->%s) { "
2383 "%s ((gpointer) %s->%s); "
2384 "%s->%s = NULL; }\n",
2385 root, v->id, v->destructor, root, v->id,
2389 if(v->destructor_line > 0)
2390 out_addline_outfile(out);
2392 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2393 out_printf(out, "#define VAR %s\n", v->id);
2394 out_printf(out, "\t{\n");
2395 if(v->destructor_line > 0)
2396 out_addline_infile(out, v->destructor_line);
2398 out_printf(out, "\t%s}\n", v->destructor);
2400 if(v->destructor_line > 0)
2401 out_addline_outfile(out);
2402 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2404 out_printf(out, "#undef VAR\n");
2405 out_printf(out, "#undef %s\n", v->id);
2410 add_constructor (Class *c)
2412 out_printf(out, "\nstatic GObject *\n"
2413 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2416 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2419 out_printf(out, "\tGObject *obj_self;\n");
2420 out_printf(out, "\t%s *self;\n", typebase);
2422 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2423 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2425 if (user_constructor->line_no > 0)
2426 out_addline_infile (out, user_constructor->line_no);
2427 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2428 if (user_constructor->line_no > 0)
2429 out_addline_outfile (out);
2431 out_printf(out, "\treturn obj_self;\n");
2432 out_printf(out, "}\n"
2433 "#undef __GOB_FUNCTION__\n\n");
2437 print_unreftors (Class *c)
2440 for(li = ((Class *)class)->nodes;
2444 Variable *v = (Variable *)n;
2445 if (n->type == VARIABLE_NODE &&
2446 v->scope != CLASS_SCOPE &&
2447 v->destructor_unref)
2448 print_destructor (v);
2453 add_dispose (Class *c)
2455 out_printf(out, "\nstatic void\n"
2456 "___dispose (GObject *obj_self)\n"
2459 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2462 if (unreftors > 0 || user_dispose_method != NULL) {
2463 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2465 ! no_gnu ? " G_GNUC_UNUSED" : "",
2469 if (dispose_handler != NULL) {
2470 if (unreftors > 0) {
2471 print_unreftors (c);
2474 /* so we get possible bad argument warning */
2475 if (dispose_handler->line_no > 0)
2476 out_addline_infile (out, dispose_handler->line_no);
2477 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2478 (guint)dispose_handler->unique_id, funcbase);
2479 if (dispose_handler->line_no > 0)
2480 out_addline_outfile (out);
2482 if (user_dispose_method != NULL) {
2483 if (user_dispose_method->line_no > 0)
2484 out_addline_infile (out, user_dispose_method->line_no);
2485 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2486 if (user_dispose_method->line_no > 0)
2487 out_addline_outfile (out);
2490 if (unreftors > 0) {
2491 print_unreftors (c);
2495 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2496 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2499 out_printf(out, "}\n"
2500 "#undef __GOB_FUNCTION__\n\n");
2504 print_destructors (Class *c)
2507 for (li = ((Class *)class)->nodes;
2511 Variable *v = (Variable *)n;
2512 if (n->type == VARIABLE_NODE &&
2513 v->scope != CLASS_SCOPE &&
2514 ! v->destructor_unref)
2515 print_destructor (v);
2520 add_finalize (Class *c)
2524 "___finalize(GObject *obj_self)\n"
2527 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2532 user_finalize_method != NULL) {
2533 const char *unused = "";
2535 unused = " G_GNUC_UNUSED";
2536 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2537 typebase, unused, macrobase);
2540 const char *unused = "";
2542 unused = " G_GNUC_UNUSED";
2543 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2547 if(finalize_handler) {
2548 if (destructors > 0) {
2549 print_destructors (c);
2552 /* so we get possible bad argument warning */
2553 if(finalize_handler->line_no > 0)
2554 out_addline_infile(out, finalize_handler->line_no);
2555 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2556 (guint)finalize_handler->unique_id, funcbase);
2557 if(finalize_handler->line_no > 0)
2558 out_addline_outfile(out);
2560 if (user_finalize_method != NULL) {
2561 if (user_finalize_method->line_no > 0)
2562 out_addline_infile (out, user_finalize_method->line_no);
2563 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2564 if (user_finalize_method->line_no > 0)
2565 out_addline_outfile (out);
2568 if (destructors > 0) {
2569 print_destructors (c);
2573 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2574 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2577 out_printf(out, "}\n"
2578 "#undef __GOB_FUNCTION__\n\n");
2582 make_bonobo_object_epv (Class *c, const char *classname)
2585 gboolean added_line = FALSE;
2587 for (li = c->nodes; li != NULL; li = li->next) {
2589 Method *m = (Method *)n;
2590 if(n->type != METHOD_NODE ||
2591 m->method == OVERRIDE_METHOD)
2594 if (m->bonobo_object_func) {
2595 if(m->line_no > 0) {
2596 out_addline_infile(out, m->line_no);
2598 } else if (m->line_no == 0 &&
2600 out_addline_outfile(out);
2603 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2604 classname, m->id, m->id);
2608 out_addline_outfile(out);
2611 static void add_class_private(Class *c, Method *m)
2613 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2618 out_printf(out, "\n#if !defined(G_DEFINE%s_TYPE_EXTENDED)"
2619 " || !defined(G_ADD_PRIVATE%s)\n"
2620 "\tg_type_class_add_private(%s, sizeof(%sPrivate));\n"
2623 ((FuncArg *)m->args->data)->name, typebase);
2626 static void get_instance_private(Class *c, Method *m)
2628 const char *self = ((FuncArg *)m->args->data)->name;
2629 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2632 if (always_private_struct) {
2633 out_printf(out, "\t%s->_priv = NULL;\n", self);
2639 out_printf(out, "\t%s->_priv = (%sPrivate *)\n"
2640 "#if defined(G_DEFINE%s_TYPE_EXTENDED)"
2641 " && defined(G_ADD_PRIVATE%s)\n"
2642 "\t\t%s_get_instance_private(%s);\n"
2644 "\t\tG_TYPE_INSTANCE_GET_PRIVATE\n"
2647 "\t\t\t, %sPrivate\n"
2653 self, macrotype, typebase);
2659 const char *unused = "";
2663 unused = " G_GNUC_UNUSED";
2665 for(li=c->nodes;li;li=g_list_next(li)) {
2669 if(n->type != METHOD_NODE)
2672 if(m->method == INIT_METHOD) {
2674 out_addline_infile(out, m->line_no);
2675 print_method(out, "static ", "\n", "", " ", "", "\n",
2676 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2678 out_printf(out, "{\n");
2680 out_addline_outfile(out);
2682 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2685 get_instance_private(c, m);
2687 if(initializers > 0) {
2689 for(li = ((Class *)class)->nodes;
2693 Variable *v = (Variable *)n;
2694 if(n->type != VARIABLE_NODE ||
2695 v->scope == CLASS_SCOPE)
2697 print_initializer(m, v);
2700 if(glade_widgets > 0) {
2702 for(li = ((Class *)class)->nodes;
2706 Variable *v = (Variable *)n;
2707 if(n->type != VARIABLE_NODE ||
2708 v->scope == CLASS_SCOPE)
2710 print_glade_widget(m, v);
2713 } else if(m->method == CLASS_INIT_METHOD) {
2714 gboolean did_base_obj = FALSE;
2717 out_addline_infile(out, m->line_no);
2718 print_method(out, "static ", "\n", "", " ", "", "\n",
2719 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2721 out_printf(out, "{\n");
2723 out_addline_outfile(out);
2725 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2727 if (set_properties > 0 ||
2728 get_properties > 0 ||
2735 "g_object_class%s = "
2736 "(GObjectClass*) %s;\n",
2738 ((FuncArg *)m->args->data)->name);
2739 did_base_obj = TRUE;
2744 ((FuncArg *)m->args->data)->name,
2747 add_class_private(c, m);
2749 if (initializers > 0) {
2751 for(li = ((Class *)class)->nodes;
2755 Variable *v = (Variable *)n;
2756 if(n->type == VARIABLE_NODE &&
2757 v->scope == CLASS_SCOPE)
2758 print_initializer(m, v);
2762 out_printf(out, "\n\tparent_class = ");
2764 out_printf(out, "(%sClass *)", ptypebase);
2765 out_printf(out, "g_type_class_ref (%s);\n",
2771 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2773 /* if there are no handlers for these things, we
2774 * need to set them up here */
2775 if(need_constructor)
2776 out_printf(out, "\tg_object_class->constructor "
2777 "= ___constructor;\n");
2778 if(need_dispose && !dispose_handler)
2779 out_printf(out, "\tg_object_class->dispose "
2781 if(need_finalize && !finalize_handler)
2782 out_printf(out, "\tg_object_class->finalize = "
2785 if(get_properties > 0 || set_properties > 0)
2788 if (c->bonobo_object_class != NULL) {
2789 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2795 out_printf(out, " {\n");
2796 out_addline_infile(out, m->ccode_line);
2797 out_printf(out, "%s\n", m->cbuf);
2798 out_addline_outfile(out);
2799 out_printf(out, " }\n");
2801 out_printf(out, "}\n"
2802 "#undef __GOB_FUNCTION__\n");
2807 add_argument (Argument *a, gboolean is_set)
2811 char *the_type_lower;
2816 line_no = a->set_line;
2819 line_no = a->get_line;
2823 s = g_strdup(a->name);
2825 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2827 the_type_lower = g_strdup (a->gtktype);
2828 gob_strdown (the_type_lower);
2830 /* HACK because there is no g_value_set/get for unichar */
2831 if (strcmp (the_type_lower, "unichar") == 0) {
2832 g_free (the_type_lower);
2833 the_type_lower = g_strdup ("uint");
2838 const char *unused = "";
2840 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2841 unused = " G_GNUC_UNUSED";
2844 if (a->atype != NULL &&
2845 /* gcc -Wbad-function-cast is wanking stupid, moronic
2846 and otherwise evil so we should just use a (gint)
2847 or (guint) cast, not the specific type cast */
2849 (strcmp (a->gtktype, "ENUM") != 0 &&
2850 strcmp (a->gtktype, "FLAGS") != 0)))
2851 cast = get_type (a->atype, TRUE);
2853 cast = g_strdup (get_cast (a->gtktype, FALSE));
2855 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2856 cast, unused, cast, the_type_lower);
2859 } else if ( ! is_set) {
2862 if (a->atype != NULL)
2863 cast = get_type (a->atype, TRUE);
2865 cast = g_strdup (get_cast (a->gtktype, FALSE));
2866 out_printf (out, "\t%s ARG;\n"
2867 "\tmemset (&ARG, 0, sizeof (%s));\n",
2873 out_printf(out, "\t\t{\n");
2875 out_addline_infile (out, line_no);
2876 out_printf (out, "%s\n", cbuf);
2878 out_addline_outfile (out);
2879 out_printf (out, "\t\t}\n");
2881 if (strcmp (a->gtktype, "OBJECT") == 0)
2882 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2885 out_printf (out, "\t\t"
2886 "g_value_set_%s (VAL, ARG);\n",
2889 g_free (the_type_lower);
2892 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2893 out_printf (out, "\t\tif (&ARG) break;\n");
2896 out_printf (out, "\t\tbreak;\n");
2898 out_printf (out, "\t}\n");
2902 add_property (Property *p, gboolean is_set)
2905 char *the_type_lower;
2911 line_no = p->set_line;
2914 line_no = p->get_line;
2919 name_upper = g_strdup (p->name);
2920 gob_strup (name_upper);
2921 the_type_lower = g_strdup (p->gtktype);
2922 gob_strdown (the_type_lower);
2924 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2926 out_printf(out, "\t\t{\n");
2928 out_addline_infile (out, line_no);
2929 out_printf (out, "%s\n", cbuf);
2931 out_addline_outfile (out);
2932 out_printf (out, "\t\t}\n");
2934 g_free (name_upper);
2935 g_free (the_type_lower);
2937 out_printf (out, "\t\tbreak;\n");
2941 add_getset_arg(Class *c, gboolean is_set)
2944 const char *unused = "";
2945 const char *hack_unused = "";
2947 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2948 unused = " G_GNUC_UNUSED";
2950 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2953 out_printf(out, "\nstatic void\n"
2954 "___object_%s_property (GObject *object,\n"
2955 "\tguint property_id,\n"
2956 "\t%sGValue *VAL%s,\n"
2957 "\tGParamSpec *pspec%s)\n"
2958 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2961 "\tself = %s (object);\n\n"
2962 "\tswitch (property_id) {\n",
2963 is_set ? "set" : "get",
2964 is_set ? "const " : "",
2968 is_set ? "set" : "get",
2973 for (li = c->nodes; li != NULL; li = li->next) {
2975 if (n->type == PROPERTY_NODE)
2976 add_property ((Property *)n, is_set);
2977 else if (n->type == ARGUMENT_NODE)
2978 add_argument ((Argument *)n, is_set);
2980 out_printf (out, "\tdefault:\n"
2981 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2982 "#ifndef __PRETTY_FUNCTION__\n"
2983 "# undef G_STRLOC\n"
2984 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2986 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2987 "\t\t%sbreak;\n\t}\n"
2989 "#undef __GOB_FUNCTION__\n", hack_unused);
2993 print_checks (Method *m, FuncArg *fa)
2997 gboolean checked_null = FALSE;
2998 is_void = (strcmp(m->mtype->name, "void")==0 &&
2999 m->mtype->pointer == NULL);
3001 for(li = fa->checks; li != NULL; li = li->next) {
3002 Check *ch = li->data;
3004 /* point to the method prot in .gob for failed checks */
3006 out_addline_infile(out, m->line_no);
3008 out_printf(out, "\tg_return_if_fail (");
3010 out_printf(out, "\tg_return_val_if_fail (");
3011 switch(ch->chtype) {
3013 out_printf(out, "%s != NULL", fa->name);
3014 checked_null = TRUE;
3017 s = make_pre_macro(fa->atype->name, "IS");
3019 out_printf(out, "%s (%s)", s, fa->name);
3021 /* if not check null, null may be valid */
3022 out_printf(out, "!(%s) || %s (%s)", fa->name,
3027 out_printf(out, "%s < %s", fa->name, ch->number);
3030 out_printf(out, "%s > %s", fa->name, ch->number);
3033 out_printf(out, "%s <= %s", fa->name, ch->number);
3036 out_printf(out, "%s >= %s", fa->name, ch->number);
3039 out_printf(out, "%s == %s", fa->name, ch->number);
3042 out_printf(out, "%s != %s", fa->name, ch->number);
3046 out_printf(out, ");\n");
3048 out_printf(out, ", (");
3049 print_type(out, m->mtype, TRUE);
3050 out_printf(out, ")%s);\n",
3051 m->onerror?m->onerror:"0");
3057 print_preconditions(Method *m)
3061 for(li=m->args;li;li=g_list_next(li)) {
3062 FuncArg *fa = li->data;
3064 print_checks(m, fa);
3067 out_addline_outfile(out);
3071 print_method_body (Method *m, gboolean pre, gboolean unused_self)
3073 out_printf(out, "{\n");
3075 out_addline_outfile(out);
3076 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
3077 ((Class *)class)->otype,
3080 print_preconditions(m);
3084 (no_gnu || for_cpp) &&
3086 ((FuncArg *)(m->args->data))->name != NULL &&
3087 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
3088 out_printf (out, "\tif (&self) { ; }\n");
3091 /* Note: the trailing }'s are on one line, this is so
3092 that we get the no return warning correctly and point to
3093 the correct line in the .gob file, yes this is slightly
3094 ugly in the .c file, but that is not supposed to be
3095 human readable anyway. */
3097 out_printf(out, "{\n");
3099 out_addline_infile(out, m->ccode_line);
3100 out_printf(out, "\t%s}", m->cbuf);
3103 /* Note, there is no \n between the last } and this } so that
3104 * errors/warnings reported on the end of the body get pointed to the
3105 * right line in the .gob source */
3106 out_printf(out, "}\n");
3109 out_addline_outfile(out);
3110 out_printf(out, "#undef __GOB_FUNCTION__\n");
3114 put_signal_args (Method *m)
3120 if (m->args->next == NULL)
3123 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3124 li != NULL && ali != NULL;
3125 li = li->next, ali = ali->next, i++) {
3126 FuncArg *fa = li->data;
3127 char *str = ali->data;
3128 char *cast = g_strdup (get_cast (str, FALSE));
3129 /* FIXME: This code is so fucking ugly it hurts */
3130 gboolean do_static =
3131 (strcmp (str, "STRING") == 0 ||
3132 strcmp (str, "BOXED") == 0 ||
3133 strncmp (str, "BOXED_", 6) == 0);
3138 cast = get_type (fa->atype, TRUE);
3140 /* we should have already proved before that
3141 the we know all the types */
3142 g_assert (cast != NULL);
3144 if (strncmp (str, "BOXED_", 6) == 0)
3145 t = g_strdup (&(str[6]));
3147 t = g_strconcat ("G_TYPE_", str, NULL);
3150 "\t___param_values[%d].g_type = 0;\n"
3151 "\tg_value_init (&___param_values[%d], %s);\n",
3155 if (strcmp (str, "UNICHAR") == 0)
3156 /* hack because glib is braindamaged */
3157 set_func = g_strdup ("g_value_set_uint");
3158 else if (strncmp (str, "BOXED_", 6) == 0)
3159 set_func = g_strdup ("g_value_set_static_boxed");
3161 set_func = g_strdup_printf ("g_value_set%s_%s",
3162 do_static ? "_static" : "",
3164 gob_strdown (set_func);
3166 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3167 set_func, i, cast, fa->name);
3175 clear_signal_args (Method *m)
3180 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3182 if (m->args->next == NULL)
3185 for (li = m->args->next, i = 1;
3187 li = li->next, i++) {
3189 "\tg_value_unset (&___param_values[%d]);\n", i);
3194 get_arg_names_for_macro (Method *m)
3198 GString *gs = g_string_new(NULL);
3200 for(li=m->args;li;li=g_list_next(li)) {
3201 FuncArg *arg = li->data;
3202 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
3205 return g_string_free (gs, FALSE);
3208 static gboolean method_is_void(Method *m)
3210 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3213 static const char *method_err_retval(Method *m)
3215 if (method_is_void(m))
3223 put_interface_parent_handler(Method *m)
3225 const char *errval = method_err_retval(m);
3226 char *name = replace_sep(m->interface, '_');
3227 char *args = get_arg_names_for_macro(m);
3229 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3230 "\t? %s_parent_iface->%s(%s) \\\n"
3231 "\t: %s)\n", args, name, name, m->id, args, errval);
3238 put_method(Method *m)
3240 char *s, *args, *doc;
3242 is_void = (strcmp(m->mtype->name, "void")==0 &&
3243 m->mtype->pointer == NULL);
3244 out_printf(out, "\n");
3245 if(m->method != OVERRIDE_METHOD) {
3246 doc = get_gtk_doc(m->id);
3248 out_printf(out, "%s", doc);
3254 case REGULAR_METHOD:
3256 out_addline_infile(out, m->line_no);
3257 if(m->scope == PRIVATE_SCOPE)
3258 print_method(out, "static ", "\n", "", " ", "", "\n",
3259 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3260 else /* PUBLIC, PROTECTED */
3261 print_method(out, "", "\n", "", " ", "", "\n",
3262 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3265 out_addline_outfile(out);
3266 put_interface_parent_handler(m);
3269 print_method_body(m, TRUE, TRUE);
3272 out_printf(out, "#undef PARENT_HANDLER\n");
3275 /* the outfile line was added above */
3277 case SIGNAL_FIRST_METHOD:
3278 case SIGNAL_LAST_METHOD:
3280 out_addline_infile(out, m->line_no);
3281 if(m->scope == PRIVATE_SCOPE)
3282 print_method(out, "static ", "\n", "", " ", "", "\n",
3283 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3284 else /* PUBLIC, PROTECTED */
3285 print_method(out, "", "\n", "", " ", "", "\n",
3286 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3287 out_printf (out, "{\n");
3289 out_addline_outfile (out);
3292 "\tGValue ___param_values[%d];\n"
3293 "\tGValue ___return_val;\n\n"
3294 "memset (&___return_val, 0, "
3295 "sizeof (___return_val));\n"
3296 "memset (&___param_values, 0, "
3297 "sizeof (___param_values));\n\n",
3298 g_list_length (m->args));
3300 print_preconditions (m);
3303 "\n\t___param_values[0].g_type = 0;\n"
3304 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3305 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3306 ((FuncArg *)m->args->data)->name,
3307 ((FuncArg *)m->args->data)->name);
3309 put_signal_args (m);
3311 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3312 const char *defret = NULL;
3314 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3315 (char *)m->gtktypes->data);
3317 if (m->defreturn != NULL)
3318 defret = m->defreturn;
3319 else if (m->onerror != NULL)
3320 defret = m->onerror;
3322 if (defret != NULL) {
3324 /* FIXME: This code is so fucking ugly it hurts */
3325 gboolean do_static =
3326 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3327 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3328 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3330 cast = get_type (m->mtype, TRUE);
3332 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3333 /* hack because glib is braindamaged */
3334 set_func = g_strdup ("g_value_set_uint");
3336 set_func = g_strdup_printf ("g_value_set%s_%s",
3337 do_static ? "_static" : "",
3338 (char *)m->gtktypes->data);
3339 gob_strdown (set_func);
3341 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3342 set_func, cast, defret);
3347 out_printf (out, "\n");
3350 s = g_strdup (m->id);
3353 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3354 "\t\tobject_signals[%s_SIGNAL],\n"
3355 "\t\t0 /* detail */,\n"
3356 "\t\t&___return_val);\n", s);
3360 clear_signal_args (m);
3362 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3363 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3365 /* Hack because glib is very very braindead */
3367 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3368 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3369 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3370 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3372 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3373 /* hack because glib is braindamaged */
3374 getfunc = g_strdup ("g_value_get_uint");
3376 getfunc = g_strdup_printf ("g_value_%s_%s",
3377 do_dup ? "dup" : "get",
3378 (char *)m->gtktypes->data);
3379 gob_strdown (getfunc);
3382 cast = get_type (m->mtype, TRUE);
3387 print_type (out, m->mtype, TRUE);
3389 " ___ret = (%s) %s (&___return_val);\n"
3390 "\t\tg_value_unset (&___return_val);\n"
3391 "\t\treturn ___ret;\n"
3398 out_printf(out, "}\n");
3403 out_addline_infile(out, m->line_no);
3404 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3405 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3406 print_method_body(m, FALSE, TRUE);
3407 /* the outfile line was added above */
3409 case VIRTUAL_METHOD:
3411 out_addline_infile(out, m->line_no);
3412 if(m->scope==PRIVATE_SCOPE)
3413 print_method(out, "static ", "\n", "", " ", "", "\n",
3414 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3415 else /* PUBLIC, PROTECTED */
3416 print_method(out, "", "\n", "", " ", "", "\n",
3417 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3418 out_printf(out, "{\n");
3419 out_addline_outfile(out);
3420 out_printf(out, "\t%sClass *klass;\n", typebase);
3421 print_preconditions(m);
3422 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3423 "\tif(klass->%s)\n",
3424 macrobase, ((FuncArg *)m->args->data)->name,
3426 if(strcmp(m->mtype->name, "void") == 0 &&
3427 m->mtype->pointer == NULL) {
3429 out_printf(out, "\t\t(*klass->%s)(%s",
3431 ((FuncArg *)m->args->data)->name);
3432 for(li=m->args->next;li;li=g_list_next(li)) {
3433 FuncArg *fa = li->data;
3434 out_printf(out, ",%s", fa->name);
3436 out_printf(out, ");\n}\n");
3439 out_printf(out, "\t\treturn (*klass->%s)(%s",
3441 ((FuncArg *)m->args->data)->name);
3442 for(li=m->args->next;li;li=g_list_next(li)) {
3443 FuncArg *fa = li->data;
3444 out_printf(out, ",%s", fa->name);
3446 out_printf(out, ");\n"
3449 print_type(out, m->mtype, TRUE);
3451 out_printf(out, ")(%s);\n}\n", m->defreturn);
3453 out_printf(out, ")(%s);\n}\n", m->onerror);
3455 out_printf(out, ")(0);\n}\n");
3461 out_addline_infile(out, m->line_no);
3462 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3463 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3464 print_method_body(m, FALSE, TRUE);
3465 /* the outfile line was added above */
3467 case OVERRIDE_METHOD:
3471 out_addline_infile(out, m->line_no);
3472 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3473 print_method(out, "static ", s, "", " ", "", "\n",
3474 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3476 out_addline_outfile(out);
3477 s = replace_sep(m->otype, '_');
3479 args = get_arg_names_for_macro(m);
3481 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3482 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3483 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3484 args, s, m->id, s, m->id, args);
3486 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3487 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3488 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3490 args, s, m->id, s, m->id, args);
3491 out_printf(out, "(");
3492 print_type(out, m->mtype, TRUE);
3493 out_printf(out, ")%s))\n",
3494 m->onerror?m->onerror:"0");
3498 print_method_body(m, TRUE, TRUE);
3499 /* the outfile line was added above */
3500 out_printf(out, "#undef PARENT_HANDLER\n");
3502 case CONSTRUCTOR_METHOD:
3503 case DISPOSE_METHOD:
3504 case FINALIZE_METHOD:
3506 out_addline_infile(out, m->line_no);
3507 print_method(out, "static ", "\n", "", " ", "", "\n",
3508 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3509 print_method_body(m, TRUE, TRUE);
3510 /* the outfile line was added above */
3519 char *outfile, *outfileh, *outfileph;
3521 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3522 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3524 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3525 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3527 if ((privates > 0 || protecteds > 0 ||
3528 private_header == PRIVATE_HEADER_ALWAYS) &&
3529 private_header != PRIVATE_HEADER_NEVER) {
3530 char sep[2] = {0,0};
3533 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3534 outfileph = g_strconcat (outfilephbase, no_touch_headers ? "#gob#" : "", NULL);
3536 outfilephbase = NULL;
3542 out = fopen (outfile, "w");
3544 error_printf (GOB_ERROR, 0,
3545 "Cannot open outfile: %s", outfile);
3547 outh = fopen (outfileh, "w");
3549 error_printf (GOB_ERROR, 0,
3550 "Cannot open outfile: %s", outfileh);
3552 if (outfileph != NULL) {
3553 outph = fopen (outfileph, "w");
3554 if (outph == NULL) {
3555 error_printf (GOB_ERROR, 0,
3556 "Cannot open outfile: %s",
3564 put_argument_nongnu_wrappers (Class *c)
3568 if (get_properties < 0 && set_properties < 0)
3571 for (li = c->nodes; li != NULL; li = li->next) {
3573 const char *name, *gtktype;
3579 if (n->type == ARGUMENT_NODE) {
3580 Argument *a = (Argument *)n;
3582 gtktype = a->gtktype;
3584 get = a->get != NULL;
3585 set = a->set != NULL;
3586 } else if (n->type == PROPERTY_NODE) {
3587 Property *p = (Property *)n;
3589 gtktype = p->gtktype;
3591 get = p->get != NULL;
3592 set = p->set != NULL;
3597 aname = g_strdup (name);
3601 cast = get_type (atype, TRUE);
3603 cast = g_strdup (get_cast (gtktype, TRUE));
3607 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3608 "\"%s\",(%s)(arg)\n",
3609 macrobase, aname, name, cast);
3611 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3612 "\"%s\",(%s*)(arg)\n",
3613 macrobase, aname, name, cast);
3616 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3618 macrobase, aname, name);
3620 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3622 macrobase, aname, name);
3630 put_argument_gnu_wrappers(Class *c)
3634 if(get_properties < 0 && set_properties < 0)
3637 for (li = c->nodes; li != NULL; li = li->next) {
3639 const char *name, *gtktype;
3645 if (n->type == ARGUMENT_NODE) {
3646 Argument *a = (Argument *)n;
3648 gtktype = a->gtktype;
3650 get = a->get != NULL;
3651 set = a->set != NULL;
3652 } else if (n->type == PROPERTY_NODE) {
3653 Property *p = (Property *)n;
3655 gtktype = p->gtktype;
3657 get = p->get != NULL;
3658 set = p->set != NULL;
3663 aname = g_strdup (name);
3667 cast = get_type (atype, TRUE);
3669 cast = g_strdup (get_cast (gtktype, TRUE));
3673 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3674 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3675 macrobase, aname, name, cast);
3677 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3678 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3679 macrobase, aname, name, cast);
3682 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3684 macrobase, aname, name);
3686 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3688 macrobase, aname, name);
3696 print_ccode_block(CCode *cc)
3699 switch(cc->cctype) {
3701 /* HT code is printed exactly like normal header
3702 code but is printed before */
3705 out_printf(fp, "\n");
3708 /* AT code is printed exactly like normal 'all'
3709 code but is printed before */
3712 out_printf(outph, "\n");
3713 out_printf(outph, "%s\n", cc->cbuf);
3714 out_addline_infile(outph, cc->line_no);
3715 out_addline_outfile(outph);
3717 out_printf(outh, "\n");
3718 out_printf(outh, "%s\n", cc->cbuf);
3720 out_printf(fp, "\n");
3721 out_addline_infile(fp, cc->line_no);
3727 out_printf(fp, "\n");
3728 out_addline_infile(fp, cc->line_no);
3735 out_printf(fp, "\n");
3736 out_addline_infile(fp, cc->line_no);
3739 out_printf(fp, "%s\n", cc->cbuf);
3740 if(cc->cctype == C_CCODE ||
3741 cc->cctype == AD_CCODE ||
3742 cc->cctype == A_CCODE ||
3743 cc->cctype == AT_CCODE ||
3744 cc->cctype == PH_CCODE)
3745 out_addline_outfile(fp);
3749 print_class_block(Class *c)
3753 gboolean printed_private = FALSE;
3757 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3758 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3762 out_printf(out, "/* utility types we may need */\n");
3763 if(special_array[SPECIAL_2POINTER])
3764 out_printf(out, "typedef struct { "
3765 "gpointer a; gpointer b; "
3766 "} ___twopointertype;\n");
3767 if(special_array[SPECIAL_3POINTER])
3768 out_printf(out, "typedef struct { "
3769 "gpointer a; gpointer b; "
3771 "} ___threepointertype;\n");
3772 if(special_array[SPECIAL_INT_POINTER])
3773 out_printf(out, "typedef struct { "
3774 "gint a; gpointer b; "
3775 "} ___intpointertype;\n");
3776 out_printf(out, "\n");
3779 out_printf(outh, "\n/*\n"
3780 " * Type checking and casting macros\n"
3782 out_printf(outh, "#define %s\t"
3783 "(%s_get_type())\n",
3784 macrotype, funcbase);
3785 out_printf(outh, "#define %s(obj)\t"
3786 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3787 macrobase, funcbase, typebase);
3788 out_printf(outh, "#define %s_CONST(obj)\t"
3789 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3790 macrobase, funcbase, typebase);
3791 out_printf(outh, "#define %s_CLASS(klass)\t"
3792 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3793 macrobase, funcbase, typebase);
3794 out_printf(outh, "#define %s(obj)\t"
3795 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3798 "#define %s_GET_CLASS(obj)\t"
3799 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3800 macrobase, funcbase, typebase);
3802 if ( ! no_self_alias) {
3803 out_printf(out, "/* self casting macros */\n");
3804 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3805 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3806 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3807 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3808 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3810 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3813 out_printf(out, "/* self typedefs */\n");
3814 out_printf(out, "typedef %s Self;\n", typebase);
3815 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3819 always_private_struct) {
3820 out_printf (outh, "\n/* Private structure type */\n");
3821 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3822 typebase, typebase);
3824 out_printf (outh, "/* There are no privates, this "
3825 "structure is thus never defined */\n");
3828 out_printf (outh, "\n/*\n"
3829 " * Main object structure\n"
3831 s = replace_sep (c->otype, '_');
3833 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3834 "#define __TYPEDEF_%s__\n", s, s);
3836 out_printf (outh, "typedef struct _%s %s;\n"
3837 "#endif\n", typebase, typebase);
3838 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3839 typebase, ptypebase);
3840 for (li = c->nodes; li; li=li->next) {
3841 static gboolean printed_public = FALSE;
3843 Variable *v = (Variable *)n;
3844 if(n->type == VARIABLE_NODE &&
3845 v->scope == PUBLIC_SCOPE) {
3846 if( ! printed_public) {
3847 out_printf(outh, "\t/*< public >*/\n");
3848 printed_public = TRUE;
3850 put_variable((Variable *)n, outh);
3853 /* put protecteds always AFTER publics */
3854 for (li = c->nodes; li != NULL; li = li->next) {
3856 Variable *v = (Variable *)n;
3857 if (n->type == VARIABLE_NODE &&
3858 v->scope == PROTECTED_SCOPE) {
3859 if ( ! printed_private) {
3860 out_printf (outh, "\t/*< private >*/\n");
3861 printed_private = TRUE;
3863 put_variable ((Variable *)n, outh);
3867 always_private_struct) {
3868 if ( ! printed_private)
3869 out_printf (outh, "\t/*< private >*/\n");
3870 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3872 out_printf (outh, "};\n");
3877 /* if we are to stick this into the private
3878 header, if not stick it directly into the
3885 out_printf (outfp, "struct _%sPrivate {\n",
3889 for(li=c->nodes; li; li=li->next) {
3891 Variable *v = (Variable *)n;
3892 if(n->type == VARIABLE_NODE &&
3893 v->scope == PRIVATE_SCOPE) {
3894 out_addline_infile(outfp, v->line_no);
3895 put_variable(v, outfp);
3898 out_addline_outfile(outfp);
3900 out_printf(outfp, "};\n");
3903 out_printf(outh, "\n/*\n"
3904 " * Class definition\n"
3906 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3907 typebase, typebase);
3909 "struct _%sClass {\n\t%sClass __parent__;\n",
3910 typebase, ptypebase);
3911 for(li = c->nodes; li != NULL; li = li->next) {
3913 if(n->type == METHOD_NODE)
3914 put_vs_method((Method *)n);
3916 /* If BonoboX type class put down the epv */
3917 if (c->bonobo_object_class != NULL) {
3919 "\t/* Bonobo object epv */\n"
3920 "\tPOA_%s__epv _epv;\n",
3921 c->bonobo_object_class);
3923 /* put class scope variables */
3924 for (li = c->nodes; li != NULL; li = li->next) {
3926 Variable *v = (Variable *)n;
3927 if (n->type == VARIABLE_NODE &&
3928 v->scope == CLASS_SCOPE)
3929 put_variable ((Variable *)n, outh);
3931 out_printf (outh, "};\n\n");
3933 out_printf (out, "/* here are local prototypes */\n");
3934 if (set_properties > 0) {
3935 out_printf (out, "static void ___object_set_property "
3936 "(GObject *object, guint property_id, "
3937 "const GValue *value, GParamSpec *pspec);\n");
3939 if (get_properties > 0) {
3940 out_printf (out, "static void ___object_get_property "
3941 "(GObject *object, guint property_id, "
3942 "GValue *value, GParamSpec *pspec);\n");
3945 out_printf (outh, "\n/*\n"
3946 " * Public methods\n"
3949 if (!overrode_get_type && !no_gnu) {
3951 * For ordinary "static" types it should be safe to mark the
3952 * get_type implementation as const, since the get_type
3953 * function return really is constant at the call boundary
3954 * (even though there is an initial setup on the first call).
3955 * But for dynamic types, since the registration is explicitly
3956 * separated, we need to settle for "pure" as the results of
3957 * get_type differ before and after type registration.
3959 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3960 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3964 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3968 for(li = c->nodes; li != NULL; li = li->next) {
3970 if(n->type == METHOD_NODE) {
3971 put_pub_method((Method *)n);
3972 put_prot_method((Method *)n);
3973 put_priv_method_prot((Method *)n);
3977 /* this idea is less and less apealing to me */
3979 out_printf (outh, "\n/*\n"
3980 " * Signal connection wrapper macros\n"
3983 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3984 put_signal_macros (c, TRUE);
3985 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3986 put_signal_macros (c, FALSE);
3987 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3989 put_signal_macros (c, FALSE);
3990 out_printf(outh, "\n");
3993 out_printf (out, "\n/*\n"
3994 " * Signal connection wrapper macro shortcuts\n"
3996 put_local_signal_macros (c);
3997 out_printf(outh, "\n");
4000 /* argument wrapping macros */
4001 if(get_properties > 0 || set_properties > 0) {
4002 out_printf(outh, "\n/*\n"
4003 " * Argument wrapping macros\n"
4006 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
4007 put_argument_gnu_wrappers(c);
4008 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
4009 put_argument_nongnu_wrappers(c);
4010 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
4012 put_argument_nongnu_wrappers(c);
4017 for(li = c->nodes; li != NULL; li = li->next) {
4019 if(n->type == METHOD_NODE)
4020 add_signal_prots((Method *)n);
4026 if(any_method_to_alias(c)) {
4027 out_printf (out, "/* Short form macros */\n");
4028 make_method_aliases (c);
4031 add_interface_inits (c);
4033 if (!overrode_get_type) {
4034 if (c->bonobo_object_class != NULL)
4035 add_bonobo_object_get_type();
4036 else if (c->dynamic)
4037 add_dynamic_get_type();
4042 out_printf (out, "/* a macro for creating a new object of our type */\n");
4044 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
4045 typebase, funcbase);
4047 out_printf (out, "/* a function for creating a new object of our type */\n");
4048 out_printf (out, "#include <stdarg.h>\n");
4050 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
4051 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
4052 "{\n\t%s *ret;\n\tva_list ap;\n"
4053 "\tva_start (ap, first);\n"
4054 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
4057 "\treturn ret;\n}\n\n",
4059 no_gnu ? "" : " G_GNUC_UNUSED",
4060 typebase, typebase, typebase, funcbase);
4064 out_printf (out, "/* a function to connect glade callback */\n");
4065 out_printf (out,"static void\n"
4066 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
4067 "GObject *object,\n"
4068 "const gchar *signal_name,\n"
4069 "const gchar *signal_data,\n"
4070 "GObject *connect_object,\n"
4072 "gpointer user_data)\n"
4074 "\tstatic GModule * allsymbols = NULL;\n"
4076 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
4077 "\tif (allsymbols) {\n"
4078 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
4079 "\t\tGCallback func;\n"
4081 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
4082 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
4083 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
4084 "\t\t\t\tg_free(func_name);\n"
4089 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
4091 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
4092 "\t\tg_free(func_name);\n"
4099 for (li = nodes; li != NULL; li = li->next) {
4100 Node *node = li->data;
4101 if (node->type == CCODE_NODE) {
4102 CCode *cc = (CCode *)node;
4103 if (cc->cctype == AD_CCODE)
4104 print_ccode_block (cc);
4108 if (need_constructor)
4109 add_constructor (c);
4119 if(set_properties > 0) {
4120 add_getset_arg(c, TRUE);
4123 if(get_properties > 0) {
4124 add_getset_arg(c, FALSE);
4127 for(li = c->nodes; li != NULL; li = li->next) {
4129 if(n->type == METHOD_NODE)
4130 put_method((Method *)n);
4133 add_bad_hack_to_avoid_unused_warnings(c);
4137 print_useful_macros(void)
4139 int major = 0, minor = 0, pl = 0;
4142 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4143 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4144 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4145 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4147 /* Useful priv macro thingie */
4148 /* FIXME: this should be done the same way that priv is, as a var,
4150 out_printf (out, "#define selfp (self->_priv)\n\n");
4154 print_more_useful_macros (void)
4157 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4158 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4160 out_printf (out, "#ifdef G_LIKELY\n");
4161 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4162 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4163 out_printf (out, "#else /* ! G_LIKELY */\n");
4164 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4165 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4166 out_printf (out, "#endif /* G_LIKELY */\n");
4171 print_file_comments(void)
4173 out_printf(outh, "/* Generated by GOB (v%s)"
4174 " (do not edit directly) */\n\n", VERSION);
4176 out_printf(outph, "/* Generated by GOB (v%s)"
4177 " (do not edit directly) */\n\n", VERSION);
4178 out_printf(out, "/* Generated by GOB (v%s)"
4179 " (do not edit directly) */\n\n", VERSION);
4181 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4185 print_includes(void)
4187 gboolean found_header;
4190 /* We may need string.h for memset */
4191 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4192 out_printf(out, "#include <string.h> /* memset() */\n\n");
4195 p = g_strconcat(filebase, ".h", NULL);
4196 found_header = TRUE;
4197 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4198 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4199 found_header = FALSE;
4203 /* if we are creating a private header see if it was included */
4205 char sep[2] = {0,0};
4208 p = g_strconcat(filebase, sep, "private.h", NULL);
4209 if( ! g_list_find_custom(include_files, p,
4210 (GCompareFunc)strcmp)) {
4211 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4215 error_printf(GOB_WARN, 0,
4216 "Implicit private header include "
4218 "\tsource file, while public "
4219 "header is at a custom location, "
4221 "\texplicitly include "
4222 "the private header below the "
4230 print_header_prefixes(void)
4234 p = replace_sep(((Class *)class)->otype, '_');
4236 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4238 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4239 "#define __%s_PRIVATE_H__\n\n"
4240 "#include \"%s.h\"\n\n", p, p, filebase);
4243 if( ! no_extern_c) {
4244 out_printf(outh, "#ifdef __cplusplus\n"
4246 "#endif /* __cplusplus */\n\n");
4248 out_printf(outph, "#ifdef __cplusplus\n"
4250 "#endif /* __cplusplus */\n\n");
4255 print_header_postfixes(void)
4258 out_printf(outh, "\n#ifdef __cplusplus\n"
4260 "#endif /* __cplusplus */\n");
4261 out_printf(outh, "\n#endif\n");
4264 out_printf(outph, "\n#ifdef __cplusplus\n"
4266 "#endif /* __cplusplus */\n");
4267 out_printf(outph, "\n#endif\n");
4276 /* print the AT_CCODE and CT_CCODE blocks */
4277 for(li = nodes; li != NULL; li = li->next) {
4278 Node *node = li->data;
4279 if(node->type == CCODE_NODE) {
4280 CCode *cc = (CCode *)node;
4281 if (cc->cctype == AT_CCODE ||
4282 cc->cctype == CT_CCODE)
4283 print_ccode_block((CCode *)node);
4289 print_header_top(void)
4293 /* mandatory includes */
4294 out_printf (outh, "#include <glib.h>\n");
4295 out_printf (outh, "#include <glib-object.h>\n");
4297 /* print the HT_CCODE blocks */
4298 for (li = nodes; li != NULL; li = li->next) {
4299 Node *node = li->data;
4300 if (node->type == CCODE_NODE) {
4301 CCode *cc = (CCode *)node;
4302 if (cc->cctype == HT_CCODE)
4303 print_ccode_block ((CCode *)node);
4309 print_enum (EnumDef *enode)
4316 funcprefix = replace_sep (enode->etype, '_');
4317 gob_strdown (funcprefix);
4318 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4320 type = remove_sep (enode->etype);
4322 out_printf (outh, "\ntypedef enum {\n");
4324 for (li = enode->values; li != NULL; li = li->next) {
4325 EnumValue *value = li->data;
4327 char *sname = gob_strdown (g_strdup (value->name));
4329 while ((p = strchr (sname, '_')) != NULL)
4332 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4333 if (value->value != NULL)
4334 out_printf (outh, " = %s", value->value);
4335 if (li->next != NULL)
4336 out_printf (outh, ",\n");
4338 out_printf (outh, "\n");
4340 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4341 enode->prefix, value->name,
4342 enode->prefix, value->name,
4348 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4350 out_printf (outh, "} %s;\n", type);
4352 str = make_pre_macro (enode->etype, "TYPE");
4353 out_printf (outh, "#define %s ", str);
4356 out_printf (outh, "%s_get_type()\n", funcprefix);
4357 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4358 funcprefix, no_gnu ? "": " G_GNUC_CONST");
4361 "GType\n%s_get_type (void)\n"
4363 "\tstatic GType type = 0;\n"
4364 "\tif ___GOB_UNLIKELY(type == 0)\n"
4365 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4368 funcprefix, type, funcprefix);
4370 g_free (funcprefix);
4375 print_flags (Flags *fnode)
4383 funcprefix = replace_sep (fnode->ftype, '_');
4384 gob_strdown (funcprefix);
4385 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4387 type = remove_sep (fnode->ftype);
4389 out_printf (outh, "\ntypedef enum {\n");
4391 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4392 const char *name = li->data;
4394 char *sname = gob_strdown (g_strdup (name));
4396 while ((p = strchr (sname, '_')) != NULL)
4399 out_printf (outh, "\t%s_%s = 1<<%d",
4400 fnode->prefix, name, i);
4401 if (li->next != NULL)
4402 out_printf (outh, ",\n");
4404 out_printf (outh, "\n");
4406 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4407 fnode->prefix, name,
4408 fnode->prefix, name,
4414 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4416 out_printf (outh, "} %s;\n", type);
4418 str = make_pre_macro (fnode->ftype, "TYPE");
4419 out_printf (outh, "#define %s ", str);
4422 out_printf (outh, "%s_get_type()\n", funcprefix);
4423 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4424 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4427 "GType\n%s_get_type (void)\n"
4429 "\tstatic GType type = 0;\n"
4430 "\tif ___GOB_UNLIKELY(type == 0)\n"
4431 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4434 funcprefix, type, funcprefix);
4436 g_free (funcprefix);
4441 print_error (Error *enode)
4448 funcprefix = replace_sep (enode->etype, '_');
4449 gob_strdown (funcprefix);
4450 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4452 type = remove_sep (enode->etype);
4454 out_printf (outh, "\ntypedef enum {\n");
4456 for (li = enode->values; li != NULL; li = li->next) {
4457 const char *name = li->data;
4459 char *sname = gob_strdown (g_strdup (name));
4461 while ((p = strchr (sname, '_')) != NULL)
4464 out_printf (outh, "\t%s_%s", enode->prefix, name);
4465 if (li->next != NULL)
4466 out_printf (outh, ",\n");
4468 out_printf (outh, "\n");
4470 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4471 enode->prefix, name,
4472 enode->prefix, name,
4478 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4480 out_printf (outh, "} %s;\n", type);
4482 str = make_pre_macro (enode->etype, "TYPE");
4483 out_printf (outh, "#define %s ", str);
4486 out_printf (outh, "%s_get_type ()\n", funcprefix);
4487 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4488 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4491 "GType\n%s_get_type (void)\n"
4493 "\tstatic GType type = 0;\n"
4494 "\tif ___GOB_UNLIKELY(type == 0)\n"
4495 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4498 funcprefix, type, funcprefix);
4500 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4501 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4503 str = replace_sep (enode->etype, '-');
4507 "GQuark\n%s_quark (void)\n"
4509 "\tstatic GQuark q = 0;\n"
4511 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4518 g_free (funcprefix);
4523 generate_outfiles(void)
4527 print_file_comments();
4533 print_header_prefixes();
4535 print_useful_macros();
4539 print_more_useful_macros ();
4541 for (li = nodes; li != NULL; li = li->next) {
4542 Node *node = li->data;
4543 if (node->type == CCODE_NODE) {
4544 CCode *cc = (CCode *)node;
4545 if (cc->cctype != HT_CCODE &&
4546 cc->cctype != AT_CCODE &&
4547 cc->cctype != AD_CCODE)
4548 print_ccode_block ((CCode *)node);
4549 } else if (node->type == CLASS_NODE) {
4550 print_class_block ((Class *)node);
4551 } else if (node->type == ENUMDEF_NODE) {
4552 print_enum ((EnumDef *)node);
4553 } else if (node->type == FLAGS_NODE) {
4554 print_flags ((Flags *)node);
4555 } else if (node->type == ERROR_NODE) {
4556 print_error ((Error *)node);
4558 g_assert_not_reached();
4562 print_header_postfixes();
4565 static void print_version(void)
4567 printf("%s (%s) %s\n", PACKAGE_NAME, PACKAGE_TARNAME, PACKAGE_VERSION);
4569 puts("Copyright (C) 2013 George (Jiri) Lebl et al.");
4570 puts("Copyright (C) 2020 Nick Bowler");
4571 puts("License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl.html>.");
4572 puts("This is free software: you are free to change and redistribute it.");
4573 puts("There is NO WARRANTY, to the extent permitted by law.");
4577 static void print_usage(FILE *f)
4579 fprintf(f, "Usage: %s [options] file.gob\n", g_get_prgname());
4581 fprintf(f, "Try '%s --help' for more information.\n",
4589 print_usage(stdout);
4592 "This is \"GObject Builder\": a simple preprocessor to help with\n"
4593 "implementing GObject types in C.\n"
4597 puts(" --help,-h,-? Display this help\n"
4598 " --version Display version\n"
4599 " --exit-on-warn,-w Exit with an error on warnings\n"
4600 " --no-exit-on-warn Don't exit on warnings [default]\n"
4601 " --for-cpp Create C++ files\n"
4602 " --no-extern-c Never print extern \"C\" into the "
4604 " --no-gnu Never use GNU extentions\n"
4605 " --no-touch Don't touch output files unless they "
4607 " changed (implies --no-touch-headers)\n"
4608 " --no-touch-headers Don't touch headers unless they "
4610 " --always-private-header Always create a private header "
4612 " even if it would be empty\n"
4613 " --ondemand-private-header Create private header only when "
4616 " --no-private-header Don't create a private header, "
4618 " structure and protected "
4619 "prototypes inside c file\n"
4620 " --always-private-struct Always create a private pointer "
4622 " the object structure\n"
4623 " --m4 Preprocess source with m4. "
4624 "Following args will\n"
4625 " be passed to m4\n"
4626 " --m4-dir Print directory that will be "
4629 " --no-write,-n Don't write output files, just "
4631 " --no-lines Don't print '#line' to output\n"
4632 " --no-self-alias Don't create self type and macro "
4634 " --no-kill-underscores Ignored for compatibility\n"
4635 " -o,--output-dir The directory where output "
4636 "should be placed\n"
4637 " --file-sep[=c] replace default \'-\' file "
4638 "name separator\n\n"
4639 " --gtk3 Use gtk+3\n"
4642 puts("End world hunger, donate to the World Food Programme: https://www.wfp.org/");
4646 * Called after getopt_long receives an --m4 argument. Immediately stop
4647 * processing options. Then all non-option arguments seen so far together
4648 * with all remaining arguments are appended to M4_COMMANDLINE. If m4_clean
4649 * is false, then M4_FLAGS is inserted before the first non-option argument,
4652 * The resulting string is returned, which should be freed by the caller.
4654 static char *parse_m4_options(int argc, char **argv, gboolean m4_clean)
4656 char **nonopt = NULL, *save_argv0, *ret;
4659 /* First, conclude getopt run and reset with remaining args */
4660 getopt_long(optind, argv, sopts, lopts, NULL);
4665 save_argv0 = argv[0];
4666 argv[0] = M4_COMMANDLINE;
4669 ret = g_strjoinv(" ", argv);
4670 argv[0] = save_argv0;
4674 /* Locate first non-option argument, if any. */
4675 while ((opt = getopt_long(argc, argv, "-", NULL, NULL)) != -1) {
4677 nonopt = &argv[optind-2];
4682 /* If there is a non-option but the above didn't see it, must be "--" */
4683 if (!nonopt && argv[optind])
4684 nonopt = &argv[optind-2];
4687 /* Found non-option, insert M4_FLAGS just before it. */
4688 char *save_argv[3] = { nonopt[0], nonopt[1], nonopt[2] };
4690 nonopt[1] = M4_FLAGS;
4692 nonopt[0] = g_strjoinv(" ", argv);
4694 nonopt[1] = save_argv[1];
4695 nonopt[2] = save_argv[2];
4696 ret = g_strjoinv(" ", nonopt);
4699 nonopt[0] = save_argv[0];
4701 /* Only options, not inserting M4_FLAGS. */
4702 ret = g_strjoinv(" ", argv);
4705 argv[0] = save_argv0;
4709 static int parse_options(int argc, char **argv)
4711 gboolean show_m4_dir = FALSE, m4_clean = FALSE;
4712 char *raw_file_sep = "-";
4716 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
4722 output_dir = optarg;
4725 exit_on_warn = TRUE;
4728 raw_file_sep = optarg ? optarg : "";
4734 no_touch = no_touch_headers = TRUE;
4740 m4_commandline = parse_m4_options(argc, argv, m4_clean);
4746 if (optopt == '?') {
4752 /* Rewind getopt to get internal error messages. */
4753 optind = 0, opterr = 1;
4754 while (getopt_long(argc, argv, sopts, lopts, NULL)
4757 case 0: /* no-op or option set by flag */;
4761 filename = argv[optind];
4762 if (argc > optind+1) {
4763 char *s = g_strjoinv(" ", argv+optind+1);
4764 fprintf(stderr, "%s: Warning: excess arguments ignored: %s\n",
4765 g_get_prgname(), s);
4771 file_sep = raw_file_sep[0];
4772 if (raw_file_sep[0] && raw_file_sep[1]) {
4773 fprintf(stderr, "%s: Warning: --file-sep characters beyond the first are ignored\n",
4780 printf("%s\n", M4_INCLUDE_DIR);
4788 compare_and_move (const char *old_filename)
4790 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4792 gboolean equal = FALSE;
4794 old_f = fopen (old_filename, "r");
4797 gboolean error = FALSE;
4799 new_f = fopen (new_filename, "r");
4808 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4809 if (ferror (new_f)) {
4811 error_printf (GOB_ERROR, 0,
4812 "Can't read %s: %s",
4814 g_strerror (errno));
4818 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4820 || feof (new_f) != feof (old_f)
4822 || memcmp (new_buf, old_buf, new_n) != 0)
4831 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4832 new_filename, g_strerror (errno));
4840 if (! equal && unlink (old_filename) != 0) {
4841 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4842 old_filename, g_strerror (errno));
4848 if (unlink (new_filename) != 0)
4849 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4850 new_filename, g_strerror (errno));
4852 if (rename (new_filename, old_filename) != 0)
4853 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4854 new_filename, old_filename,
4855 g_strerror (errno));
4859 g_free (new_filename);
4863 main(int argc, char *argv[])
4867 g_set_prgname(argc > 0 ? argv[0] : "gob2");
4869 rc = parse_options(argc, argv);
4871 print_usage(stderr);
4872 return EXIT_FAILURE;
4873 } else if (rc > 0) {
4874 return EXIT_SUCCESS;
4878 yyin = popen(m4_commandline, "r");
4880 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4884 } else if(filename) {
4885 yyin = fopen(filename, "r");
4887 fprintf(stderr, "Error: can't open file '%s'\n",
4896 /* This is where parsing is done */
4899 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4901 /* close input file */
4902 if(use_m4) pclose(yyin);
4907 error_print (GOB_ERROR, 0, "no class defined");
4910 exit_on_error = FALSE;
4912 signals = count_signals ((Class *)class);
4913 set_properties = count_set_properties ((Class *)class) +
4914 count_set_arguments ((Class *)class);
4915 get_properties = count_get_properties ((Class *)class) +
4916 count_get_arguments ((Class *)class);
4917 overrides = count_overrides ((Class *)class);
4918 privates = count_privates ((Class *)class);
4919 protecteds = count_protecteds ((Class *)class);
4920 unreftors = count_unreftors ((Class *)class);
4921 destructors = count_destructors ((Class *)class);
4922 initializers = count_initializers ((Class *)class);
4923 glade_widgets = count_glade_widgets ((Class *)class);
4924 overrode_get_type = find_get_type ((Class *)class);
4927 make_inits ((Class *)class);
4929 find_constructor ((Class *)class);
4930 if (user_constructor != NULL)
4931 need_constructor = TRUE;
4933 find_dispose ((Class *)class);
4934 if (unreftors > 0 ||
4935 dispose_handler != NULL ||
4936 user_dispose_method != NULL)
4937 need_dispose = TRUE;
4939 find_finalize ((Class *)class);
4940 if (destructors > 0 ||
4942 user_finalize_method != NULL) {
4943 need_finalize = TRUE;
4946 check_bad_symbols ((Class *)class);
4947 check_duplicate_symbols ((Class *)class);
4948 check_duplicate_overrides ((Class *)class);
4949 check_duplicate_signals_args ((Class *)class);
4950 check_public_new ((Class *)class);
4951 check_vararg ((Class *)class);
4952 check_firstarg ((Class *)class);
4953 check_nonvoidempty ((Class *)class);
4954 check_signal_args ((Class *)class);
4955 check_property_types ((Class *)class);
4956 check_argument_types ((Class *)class);
4957 check_func_arg_checks ((Class *)class);
4958 check_func_attrs ((Class *)class);
4959 check_for_class_destructors ((Class *)class);
4961 exit_on_error = TRUE;
4966 any_special = setup_special_array ((Class *)class, special_array);
4970 generate_outfiles ();
4981 compare_and_move(outfilebase);
4983 if (no_touch_headers) {
4984 compare_and_move(outfilehbase);
4986 compare_and_move(outfilephbase);