2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
32 #include "treefuncs.h"
40 char *filename = NULL;
49 extern GList *include_files;
51 extern GHashTable *gtk_doc_hash;
54 static char *funcbase;
55 static char *pfuncbase;
56 static char *macrobase;
58 static char *macrotype;
59 static char *typebase;
60 static char *ptypebase;
62 static int signals = 0; /* number of signals */
63 static int set_arguments = 0; /* number of named (set) arguments */
64 static int get_arguments = 0; /* number of named (get) arguments */
65 static int overrides = 0; /* number of override methods */
66 static int privates = 0; /* number of private data members */
67 static int protecteds = 0; /* number of protected methods */
68 static int destructors = 0; /* number of variable destructors */
69 static int initializers = 0; /* number of variable initializers */
70 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
72 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
73 and need the REALLY UGLY HACK to
76 /* the special variable types we need to define */
77 static gboolean special_array[SPECIAL_LAST] = {0};
78 static gboolean any_special = FALSE;
80 static gboolean need_destroy = FALSE;
81 static Method * destroy_handler = NULL;
83 static gboolean need_finalize = FALSE;
84 static Method * finalize_handler = NULL;
91 gboolean no_touch_headers = FALSE;
92 gboolean for_cpp = FALSE;
93 gboolean no_gnu = FALSE;
94 gboolean exit_on_warn = FALSE;
95 gboolean exit_on_error = TRUE;
96 gboolean got_error = FALSE;
97 gint private_header = PRIVATE_HEADER_ONDEMAND;
98 gboolean no_extern_c = FALSE;
99 gboolean no_write = FALSE;
100 gboolean no_lines = FALSE;
101 gboolean no_self_alias = FALSE;
102 gboolean no_kill_underscores = FALSE;
103 gboolean always_private_struct = FALSE;
105 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
106 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
107 char *m4_commandline = NULL;
108 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
109 #define M4_BASE_FILENAME "gobm4.m4"
110 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
111 #define M4_COMMANDLINE "m4"
113 int method_unique_id = 1;
118 filebase = replace_sep(((Class *)class)->otype, '-');
121 funcbase = replace_sep(((Class *)class)->otype, '_');
124 pfuncbase = replace_sep(((Class *)class)->ptype, '_');
125 g_strdown(pfuncbase);
127 macrobase = replace_sep(((Class *)class)->otype, '_');
130 macrois = make_pre_macro(((Class *)class)->otype, "IS");
131 macrotype = make_pre_macro(((Class *)class)->otype, "TYPE");
133 typebase = remove_sep(((Class *)class)->otype);
135 ptypebase = remove_sep(((Class *)class)->ptype);
139 get_type(const Type *t, gboolean postfix_to_stars)
146 s = remove_sep(t->name);
147 gs = g_string_new(s);
151 if(postfix_to_stars) {
153 /*XXX: this is ugly perhaps we can do this whole postfix thing
154 in a nicer way, we just count the number of '[' s and from
155 that we deduce the number of dimensions, so that we can print
157 for(p=t->postfix; p && *p; p++)
158 if(*p == '[') extra++;
160 g_string_append_c(gs, ' ');
163 g_string_append(gs, t->pointer);
164 for(i=0; i < extra; i++)
165 g_string_append_c(gs, '*');
166 g_string_append_c(gs, ' ');
170 g_string_free(gs, FALSE);
175 get_gtk_doc(const char *id)
182 val = g_hash_table_lookup(gtk_doc_hash, id);
184 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
185 funcbase, get_real_id(id), val);
186 val = g_hash_table_lookup(gtk_doc_hash, get_real_id(id));
188 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
189 funcbase, get_real_id(id), val);
194 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
198 s = get_type(t, postfix_to_stars);
199 out_printf(fp, "%s", s);
205 print_method (FILE *fp,
206 const char *typeprefix,
207 const char *nameprefix,
208 const char *subnameprefix,
209 const char *namepostfix,
210 const char *afterargs,
213 gboolean one_arg_per_line,
214 gboolean no_funcbase,
215 gboolean kill_underscore)
220 out_printf(fp, "%s", typeprefix);
221 print_type(fp, m->mtype, TRUE);
224 id = get_real_id(m->id);
229 out_printf(fp, "%s%s%s%s(",
230 nameprefix, subnameprefix, id, namepostfix);
232 out_printf(fp, "%s%s_%s%s%s(",
233 nameprefix, funcbase, subnameprefix, id,
237 for(li=m->args; li; li=g_list_next(li)) {
238 FuncArg *arg = li->data;
239 print_type(fp, arg->atype, FALSE);
241 out_printf(fp, "%s%s,%s", arg->name,
242 arg->atype->postfix ?
243 arg->atype->postfix : "",
244 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
246 out_printf(fp, "%s%s", arg->name,
247 arg->atype->postfix ?
248 arg->atype->postfix : "");
251 out_printf(fp, ",%s...",
252 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
254 out_printf(fp, "void");
256 out_printf(fp, "%s)%s", afterargs, postfix);
260 any_method_to_alias(Class *c)
264 for(li=c->nodes;li;li=g_list_next(li)) {
265 Node *node = li->data;
266 if(node->type == METHOD_NODE) {
267 Method *m = (Method *)node;
269 if(m->method == INIT_METHOD ||
270 m->method == CLASS_INIT_METHOD ||
271 m->method == OVERRIDE_METHOD)
281 /* just the vararg macros, we use the same func pointers for these as in non-gnu */
283 make_method_gnu_aliases(Class *c)
287 for(li = c->nodes; li != NULL; li = li->next) {
288 Node *node = li->data;
289 if(node->type == METHOD_NODE) {
290 Method *m = (Method *)node;
292 if(m->method == INIT_METHOD ||
293 m->method == CLASS_INIT_METHOD ||
294 m->method == OVERRIDE_METHOD)
297 /* in C++ mode don't alias new */
298 if(for_cpp && strcmp(m->id, "new")==0)
302 out_printf(out, "#define %s(args...) "
303 "%s_%s(args)\n", m->id,
304 funcbase, get_real_id(m->id));
306 out_printf(out, "#define %s() "
308 funcbase, get_real_id(m->id));
310 /* for compatibility with gob2 */
312 out_printf(out, "#define self_%s(args...) "
313 "%s_%s(args)\n", m->id,
314 funcbase, get_real_id(m->id));
316 out_printf(out, "#define self_%s() "
318 funcbase, get_real_id(m->id));
324 make_method_nongnu_aliases(Class *c)
328 gboolean local_made_aliases = FALSE;
330 for(li=c->nodes; li; li=g_list_next(li)) {
331 Node *node = li->data;
332 if(node->type == METHOD_NODE) {
333 Method *m = (Method *)node;
335 if(m->method == INIT_METHOD ||
336 m->method == CLASS_INIT_METHOD ||
337 m->method == OVERRIDE_METHOD)
340 /* in C++ mode don't alias new */
341 if(for_cpp && strcmp(m->id, "new")==0)
344 if( ! local_made_aliases)
345 out_printf(out, "\n/* Short form pointers */\n");
347 print_method(out, "static ", "(* const ", "", ") ",
349 m, FALSE, TRUE, FALSE);
350 out_printf(out, " = %s_%s;\n", funcbase,
353 /* for compatibility with gob2 */
354 print_method(out, "static ", "(* const self_", "", ") ",
356 m, FALSE, TRUE, FALSE);
357 out_printf(out, " = %s_%s;\n", funcbase,
360 local_made_aliases = TRUE;
363 if(local_made_aliases) {
364 out_printf(out, "\n");
370 add_bad_hack_to_avoid_unused_warnings(Class *c)
374 /* if we haven't had any methods, just return */
379 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
381 "/*REALLY BAD HACK\n"
382 " This is to avoid unused warnings if you don't call\n"
383 " some method. I need to find a better way to do\n"
384 " this, not needed in GCC since we use some gcc\n"
385 " extentions to make saner, faster code */\n"
387 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
389 for(li=c->nodes;li;li=g_list_next(li)) {
390 Node *node = li->data;
391 if(node->type == METHOD_NODE) {
392 Method *m = (Method *)node;
394 if(m->method == INIT_METHOD ||
395 m->method == CLASS_INIT_METHOD ||
396 m->method == OVERRIDE_METHOD)
399 /* in C++ mode we don't alias new */
400 if(for_cpp && strcmp(m->id, "new")==0)
403 out_printf(out, "\t((void (*)(void))%s)();\n", m->id);
406 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
409 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
411 out_printf(out, "}\n\n");
415 put_variable(Variable *v, FILE *fp)
417 out_printf(fp, "\t");
418 print_type(fp, v->vtype, FALSE);
419 out_printf(fp, "%s%s;", v->id,
421 v->vtype->postfix:"");
422 if(v->scope == PROTECTED_SCOPE)
423 out_printf(fp, " /* protected */");
424 out_printf(fp, "\n");
428 put_vs_method(const Method *m)
430 if(m->method != SIGNAL_LAST_METHOD &&
431 m->method != SIGNAL_FIRST_METHOD &&
432 m->method != VIRTUAL_METHOD)
435 /* if a signal mark it as such */
436 if(m->method != VIRTUAL_METHOD)
437 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
438 m, FALSE, TRUE, TRUE);
440 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
441 m, FALSE, TRUE, TRUE);
445 put_pub_method(const Method *m)
447 if(m->scope != PUBLIC_SCOPE)
450 print_method(outh, "", "\t", "", "\t", "", ";\n", m, TRUE, FALSE, TRUE);
454 put_signal_macro (const Method *m, gboolean gnu)
458 if(m->method != SIGNAL_LAST_METHOD &&
459 m->method != SIGNAL_FIRST_METHOD)
462 id = g_strdup (m->id);
466 out_printf (outh, "#define %s_SIGNAL_%s(func)\t"
467 "\"%s\",GTK_SIGNAL_FUNC(func)\n",
468 macrobase, id, get_real_id (m->id));
470 out_printf (outh, "#define %s_SIGNAL_%s(func)\t"
471 "\"%s\",GTK_SIGNAL_FUNC(({",
472 macrobase, id, get_real_id (m->id));
473 print_method (outh, "", "(* ___", "", ") ", ", gpointer data ",
474 " = func; ", m, FALSE, TRUE, TRUE);
475 out_printf (outh, "___%s; }))\n", get_real_id (m->id));
482 put_signal_macros (const Class *c, gboolean gnu)
489 for (li = c->nodes; li != NULL; li = li->next) {
490 const Node *n = li->data;
491 if (n->type == METHOD_NODE)
492 put_signal_macro ((Method *)n, gnu);
498 put_prot_method(const Method *m)
500 if(m->scope != PROTECTED_SCOPE)
504 print_method(outph, "", "\t", "", "\t", "", ";\n",
505 m, FALSE, FALSE, TRUE);
507 print_method(out, "", "\t", "", "\t", "", ";\n",
508 m, FALSE, FALSE, TRUE);
512 put_priv_method_prot(Method *m)
514 if(m->method == SIGNAL_LAST_METHOD ||
515 m->method == SIGNAL_FIRST_METHOD ||
516 m->method == VIRTUAL_METHOD) {
519 "static ", "___real_", "", " ", "", ";\n",
520 m, FALSE, FALSE, TRUE);
522 /* no else, here, it might still have a private prototype, it's not
525 if((m->method == OVERRIDE_METHOD &&
528 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
529 print_method(out, "static ", s, "", " ", "",
530 no_gnu?";\n":" G_GNUC_UNUSED;\n",
531 m, FALSE, FALSE, FALSE);
533 } else if(m->scope == PRIVATE_SCOPE ||
534 m->method == INIT_METHOD ||
535 m->method == CLASS_INIT_METHOD)
536 print_method(out, "static ", "", "", " ", "",
537 no_gnu?";\n":" G_GNUC_UNUSED;\n",
538 m, FALSE, FALSE, TRUE);
542 make_func_arg(char *typename, int is_class, char *name)
549 tn = g_strconcat(typename, ":Class", NULL);
551 tn = g_strdup(typename);
553 type = new_type(tn, g_strdup("*"), NULL);
554 node = new_funcarg((Type *)type, name, NULL);
555 return g_list_prepend(NULL, node);
559 make_inits(Class *cl)
561 int got_class_init = FALSE;
562 int got_init = FALSE;
565 for(li=cl->nodes;li;li=g_list_next(li)) {
567 if(n->type == METHOD_NODE) {
568 Method *m = (Method *)n;
569 if(m->method == INIT_METHOD) {
571 error_print(GOB_ERROR, m->line_no, "init defined more then once");
573 } else if(m->method == CLASS_INIT_METHOD) {
575 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
576 got_class_init = TRUE;
580 if(!got_class_init) {
581 node = new_method(NO_SCOPE, CLASS_INIT_METHOD,
582 (Type *)new_type(g_strdup("void"),
584 NULL, NULL, NULL, g_strdup("class_init"),
585 make_func_arg(cl->otype, TRUE, g_strdup("c")),
586 NULL, NULL, NULL, 0, 0, FALSE,
588 FALSE /*bonobo_x_func*/);
589 cl->nodes = g_list_prepend(cl->nodes, node);
592 node = new_method(NO_SCOPE, INIT_METHOD,
593 (Type *)new_type(g_strdup("void"),
595 NULL, NULL, NULL, g_strdup("init"),
596 make_func_arg(cl->otype, FALSE, g_strdup("o")),
597 NULL, NULL, NULL, 0, 0, FALSE,
599 FALSE /*bonobo_x_func*/);
600 cl->nodes = g_list_prepend(cl->nodes, node);
605 find_destroy(Class *cl)
609 destroy_handler = NULL;
610 for(li=cl->nodes;li;li=g_list_next(li)) {
612 if(n->type == METHOD_NODE) {
613 Method *m = (Method *)n;
614 if(m->method == OVERRIDE_METHOD &&
615 strcmp(m->id, "destroy")==0) {
616 if(strcmp(m->otype, "Gtk:Object") != 0) {
617 error_print(GOB_ERROR, m->line_no,
618 "destroy method override "
619 "of class other then "
622 if(g_list_length(m->args) != 1) {
623 error_print(GOB_ERROR, m->line_no,
624 "destroy method override "
625 "with more then one "
636 find_finalize(Class *cl)
640 finalize_handler = NULL;
641 for(li=cl->nodes;li;li=g_list_next(li)) {
643 if(n->type == METHOD_NODE) {
644 Method *m = (Method *)n;
645 if(m->method == OVERRIDE_METHOD &&
646 strcmp(m->id, "finalize")==0) {
647 if(strcmp(m->otype, "Gtk:Object") != 0 &&
648 strcmp(m->otype, "G:Object") != 0) {
649 error_print(GOB_ERROR, m->line_no,
650 "finalize method override "
651 "of class other then "
652 "Gtk:Object (or G:Object"
655 if(g_list_length(m->args) != 1) {
656 error_print(GOB_ERROR, m->line_no,
657 "finalize method override "
658 "with more then one "
661 finalize_handler = m;
669 /* hash of method -> name of signal prototype */
670 static GHashTable *marsh = NULL;
672 /* list of methods with different signal prototypes,
673 we check this list if we can use a signal prototype of a
674 previous signal method, there are only uniques here */
675 static GList *eq_signal_methods = NULL;
677 /* compare a list of strings */
679 is_list_equal(GList *a, GList *b)
681 for(;a && b; a=a->next, b=b->next) {
682 if(strcmp(a->data, b->data)!=0) {
686 /* the the lists were different length */
693 find_same_type_signal(Method *m)
696 for(li=eq_signal_methods;li;li=li->next) {
697 Method *mm = li->data;
698 if(is_list_equal(mm->gtktypes, m->gtktypes))
705 print_signal_marsal_args_gtk1 (Method *m)
707 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
710 for(i=0, li=m->gtktypes->next;li;
711 i++, li=g_list_next(li)) {
713 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
714 (char *)li->data, i);
716 out_printf(out, ",\n\t\t(%s)"
717 "GTK_VALUE_%s(args[%d])",
718 get_cast(li->data, FALSE),
719 (char *)li->data, i);
723 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
727 add_marshal_gtk1 (Method *m, const char *mname)
729 out_printf(out, "\nstatic void\n"
730 "___marshal_%s (GtkObject * object,\n"
731 "\tGtkSignalFunc func,\n"
732 "\tgpointer func_data,\n"
736 if(strcmp(m->gtktypes->data, "NONE")==0) {
737 out_printf(out, "\t___%s rfunc;\n\n"
738 "\trfunc = (___%s)func;\n\n"
739 "\t(*rfunc)((%s *)object", mname, mname, typebase);
741 const char *retcast = get_cast(m->gtktypes->data, FALSE);
742 gboolean is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
746 "\trfunc = (___%s)func;\n\n"
747 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
748 "\t*retval = (*rfunc)((%s *)object",
749 mname, retcast, mname,
750 (char *)m->gtktypes->data,
751 g_list_length(m->gtktypes) - (is_none ? 2 : 1),
754 print_signal_marsal_args_gtk1 (m);
758 gtk2_debool (const char *s)
760 if (strcmp (s, "BOOL") == 0)
767 print_signal_marsal_args_gtk2 (Method *m)
769 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
772 for (i = 0, li = m->gtktypes->next;
774 i++, li = li->next) {
775 char *get_func = g_strdup_printf
777 (char *)gtk2_debool (li->data));
778 g_strdown (get_func);
779 out_printf (out, ",\n\t\t(%s) "
780 "%s (param_values + %d)",
781 get_cast (li->data, FALSE),
786 out_printf (out, ",\n\t\tdata2);\n");
790 add_marshal_gtk2 (Method *m, const char *mname)
793 gboolean arglist_none;
796 ret_none = strcmp (m->gtktypes->data, "NONE") == 0;
797 arglist_none = strcmp (m->gtktypes->next->data, "NONE") == 0;
802 retcast = get_cast (m->gtktypes->data, FALSE);
804 out_printf (out, "\nstatic void\n"
805 "___marshal_%s (GClosure *closure,\n"
806 "\tGValue *return_value,\n"
807 "\tguint n_param_values,\n"
808 "\tconst GValue *param_values,\n"
809 "\tgpointer invocation_hint,\n"
810 "\tgpointer marshal_data)\n"
814 out_printf (out, "\t%s v_return;\n", retcast);
816 out_printf (out, "\tregister ___%s callback;\n"
817 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
818 "\tregister gpointer data1, data2;\n\n",
821 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
822 arglist_none ? 1 : g_list_length (m->gtktypes));
825 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
826 "\t\tdata1 = closure->data;\n"
827 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
829 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
830 "\t\tdata2 = closure->data;\n"
833 out_printf (out, "\tcallback = (___%s) "
834 "(marshal_data != NULL ? marshal_data : cc->callback);"
838 out_printf (out, "\tcallback ((%s *)data1", typebase);
840 out_printf (out, "\tv_return = callback ((%s *)data1",
844 print_signal_marsal_args_gtk2 (m);
847 /* FIXME: This code is so fucking ugly it hurts */
848 gboolean take_ownership =
849 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
850 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
851 char *set_func = g_strdup_printf ("g_value_set_%s%s",
852 (char *)gtk2_debool (m->gtktypes->data),
854 "_take_ownership" : "");
855 g_strdown (set_func);
857 out_printf (out, "\n\t%s (return_value, v_return);\n",
862 out_printf (out, "}\n\n");
868 add_signal_prots(Method *m)
875 if(m->method != SIGNAL_LAST_METHOD &&
876 m->method != SIGNAL_FIRST_METHOD)
880 marsh = g_hash_table_new(NULL, NULL);
882 if(strcmp(m->gtktypes->data, "NONE")==0 &&
883 strcmp(m->gtktypes->next->data, "NONE")==0)
886 /* if we already did a signal prototype just use that */
887 mm = find_same_type_signal(m);
889 s = g_hash_table_lookup(marsh, mm);
890 g_hash_table_insert(marsh, m, s);
894 s = g_strdup_printf("Sig%d", sig++);
896 g_hash_table_insert(marsh, m, s);
897 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
899 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
900 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
901 get_cast(m->gtktypes->data, FALSE), s, typebase);
903 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
904 for (li = m->gtktypes->next; li != NULL; li = li->next)
905 out_printf(out, "%s, ", get_cast(li->data, FALSE));
907 out_printf (out, "gpointer);\n");
910 out_printf (out, "\n#ifdef G_OBJECT_CLASS\n");
911 add_marshal_gtk2 (m, s);
912 out_printf (out, "#else /* ! G_OBJECT_CLASS */\n");
913 add_marshal_gtk1 (m, s);
914 out_printf (out, "#endif /* G_OBJECT_CLASS */\n\n");
921 out_printf(out, "\n");
923 out_printf(out, "enum {\n");
924 for(li=c->nodes;li;li=g_list_next(li)) {
926 if(n->type == METHOD_NODE) {
927 Method *m = (Method *)n;
928 if(m->method == SIGNAL_LAST_METHOD ||
929 m->method == SIGNAL_FIRST_METHOD) {
930 char *s = g_strdup(get_real_id(m->id));
932 out_printf(out, "\t%s_SIGNAL,\n", s);
937 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
939 if(set_arguments > 0 || get_arguments > 0) {
940 out_printf(out, "enum {\n\tARG_0");
941 for(li=c->nodes;li;li=g_list_next(li)) {
943 if(n->type == ARGUMENT_NODE) {
944 Argument *a = (Argument *)n;
945 char *s = g_strdup(a->name);
947 out_printf(out, ",\n\tARG_%s", s);
951 out_printf(out, "\n};\n\n");
956 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
958 out_printf(out, "/* pointer to the class of our parent */\n");
959 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
965 char *chunk_size = ((Class*)class)->chunk_size;
969 "%s_get_type (void)\n"
971 "\tstatic GtkType type = 0;\n\n"
972 "\tif (type == 0) {\n"
973 "\t\tstatic const GtkTypeInfo info = {\n"
975 "\t\t\tsizeof (%s),\n"
976 "\t\t\tsizeof (%sClass),\n"
977 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
978 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
979 "\t\t\t/* reserved_1 */ NULL,\n"
980 "\t\t\t/* reserved_2 */ NULL,\n"
981 "\t\t\t(GtkClassInitFunc) NULL\n"
983 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n",
984 funcbase, typebase, typebase, typebase,
985 funcbase, funcbase, pfuncbase);
989 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
991 chunk_size, chunk_size);
1000 add_bonobo_x_get_type (void)
1002 char *chunk_size = ((Class*)class)->chunk_size;
1006 "%s_get_type (void)\n"
1008 "\tstatic GtkType type = 0;\n\n"
1009 "\tif (type == 0) {\n"
1010 "\t\tstatic const GtkTypeInfo info = {\n"
1012 "\t\t\tsizeof (%s),\n"
1013 "\t\t\tsizeof (%sClass),\n"
1014 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
1015 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
1016 "\t\t\t/* reserved_1 */ NULL,\n"
1017 "\t\t\t/* reserved_2 */ NULL,\n"
1018 "\t\t\t(GtkClassInitFunc) NULL\n"
1020 "\t\ttype = bonobo_x_type_unique\n"
1021 "\t\t\t(%s_get_type (),\n"
1022 "\t\t\tPOA_%s__init, NULL,\n"
1023 "\t\t\tGTK_STRUCT_OFFSET (%sClass, _epv),\n"
1025 funcbase, typebase, typebase, typebase,
1026 funcbase, funcbase, pfuncbase,
1027 ((Class*)class)->bonobo_x_class,
1032 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1034 chunk_size, chunk_size);
1043 add_overrides(Class *c, const char *oname, gboolean did_base_obj)
1049 done = g_hash_table_new(g_str_hash, g_str_equal);
1051 s = g_strdup("GtkObject"); /* This was already done */
1052 g_hash_table_insert(done, s, s);
1053 s = g_strdup("GObject"); /* This was probably already done as well (if using Gtk/Glib 1.3/2.0) */
1054 g_hash_table_insert(done, s, s);
1056 for(li=c->nodes; li; li=g_list_next(li)) {
1059 Method *m = (Method *)n;
1060 if(n->type != METHOD_NODE ||
1061 m->method != OVERRIDE_METHOD)
1064 s = remove_sep(m->otype);
1066 if(g_hash_table_lookup(done, s)) {
1070 g_hash_table_insert(done, s, s);
1072 f = replace_sep(m->otype, '_');
1075 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1080 g_hash_table_foreach(done, (GHFunc)g_free, NULL);
1081 g_hash_table_destroy(done);
1085 make_run_signal_flags(Method *m, gboolean last)
1099 gs = g_string_new(NULL);
1102 g_string_assign(gs, "GTK_RUN_LAST");
1104 g_string_assign(gs, "GTK_RUN_FIRST");
1106 if(m->scope == PUBLIC_SCOPE)
1107 g_string_append(gs, " | GTK_RUN_ACTION");
1109 for(li = m->flags; li; li = li->next) {
1110 char *flag = li->data;
1112 for(i=0;flags[i];i++) {
1113 if(strcmp(flags[i], flag)==0)
1116 /* if we haven't found it in our list */
1118 error_printf(GOB_WARN, m->line_no,
1119 "Unknown flag '%s' used, "
1120 "perhaps it was misspelled",
1123 g_string_sprintfa(gs, " | GTK_RUN_%s", flag);
1127 char *ret = gs->str;
1128 g_string_free(gs, FALSE);
1135 add_signals(Class *c)
1139 out_printf(out, "\n");
1140 for(li=c->nodes;li;li=g_list_next(li)) {
1142 char *mar, *sig, *flags;
1143 gboolean is_none, last = FALSE;
1144 Method *m = (Method *)n;
1146 if(n->type != METHOD_NODE ||
1147 (m->method != SIGNAL_FIRST_METHOD &&
1148 m->method != SIGNAL_LAST_METHOD))
1151 if(m->method == SIGNAL_FIRST_METHOD)
1156 if(g_hash_table_lookup(marsh, m))
1157 mar = g_strconcat("___marshal_",
1158 (char *)g_hash_table_lookup(marsh, m),
1161 mar = g_strdup("gtk_signal_default_marshaller");
1163 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1165 sig = g_strdup(get_real_id(m->id));
1167 flags = make_run_signal_flags(m, last);
1168 out_printf(out, "\tobject_signals[%s_SIGNAL] =\n"
1169 "\t\tgtk_signal_new (\"%s\",\n"
1170 "\t\t\t(GtkSignalRunType)(%s),\n"
1171 "\t\t\tGTK_CLASS_TYPE(gtk_object_class),\n"
1172 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
1174 "\t\t\tGTK_TYPE_%s, %d",
1175 sig, get_real_id(m->id),
1177 typebase, get_real_id(m->id), mar,
1178 (char *)m->gtktypes->data,
1179 is_none ? 0 : g_list_length(m->gtktypes->next));
1186 for(l = m->gtktypes->next; l != NULL; l = l->next)
1187 out_printf(out, ",\n\t\t\tGTK_TYPE_%s",
1191 out_printf(out, ");\n");
1193 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1197 out_printf(out, "\tif(");
1198 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1199 out_printf(out, "%s sizeof(", sep);
1200 print_type(out, m->mtype, FALSE);
1201 out_printf(out, "%s",
1203 m->mtype->postfix : "");
1204 out_printf(out, ") != sizeof(%s)",
1205 get_cast(m->gtktypes->data, FALSE));
1210 for(al = m->args->next, gl = m->gtktypes->next;
1211 al != NULL && gl != NULL;
1212 al = al->next, gl = gl->next) {
1213 FuncArg *arg = al->data;
1214 char *gtkarg = gl->data;
1216 out_printf(out, "%ssizeof(", sep);
1217 print_type(out, arg->atype, FALSE);
1218 out_printf(out, "%s",
1219 arg->atype->postfix ?
1220 arg->atype->postfix : "");
1221 out_printf(out, ") != sizeof(%s)",
1222 get_cast(gtkarg, FALSE));
1226 out_printf(out, ") {\n"
1227 "\t\tg_error(\"%s line %d: Type mismatch "
1228 "of \\\"%s\\\" signal signature\");\n"
1230 filename, m->line_no, get_real_id(m->id));
1234 out_printf (out, "#ifndef G_OBJECT_CLASS\n");
1235 out_printf (out, "\tgtk_object_class_add_signals (gtk_object_class,\n"
1236 "\t\tobject_signals, LAST_SIGNAL);\n");
1237 out_printf (out, "#endif /* ! G_OBJECT_CLASS */\n\n");
1241 set_def_handlers(Class *c, const char *oname)
1244 gboolean set_line = FALSE;
1246 out_printf(out, "\n");
1247 for(li = c->nodes; li; li = g_list_next(li)) {
1249 Method *m = (Method *)n;
1251 if(n->type != METHOD_NODE ||
1252 (m->method != SIGNAL_FIRST_METHOD &&
1253 m->method != SIGNAL_LAST_METHOD &&
1254 m->method != VIRTUAL_METHOD &&
1255 m->method != OVERRIDE_METHOD))
1258 if(m->line_no > 0 && m->cbuf) {
1259 out_addline_infile(out, m->line_no);
1261 } else if(set_line) {
1262 out_addline_outfile(out);
1267 if(m->method == OVERRIDE_METHOD) {
1269 s = replace_sep(m->otype, '_');
1274 strcmp(get_real_id(m->id), "destroy") == 0)
1275 out_printf(out, "\tgtk_object_class->destroy "
1277 else if(need_finalize &&
1279 strcmp(get_real_id(m->id), "finalize") == 0)
1281 "#ifdef G_OBJECT_CLASS\n"
1282 "\tg_object_class->finalize = ___finalize;\n"
1283 "#else /* !G_OBJECT_CLASS */\n"
1284 "\tgtk_object_class->finalize = ___finalize;\n"
1285 "#endif /* G_OBJECT_CLASS */\n");
1288 "\t%s_class->%s = ___%x_%s_%s;\n",
1289 s, get_real_id(m->id), (guint)m->unique_id,
1290 funcbase, get_real_id(m->id));
1292 out_printf(out, "\t%s_class->%s = NULL;\n",
1293 s, get_real_id(m->id));
1296 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1297 oname, get_real_id(m->id),
1298 funcbase, get_real_id(m->id));
1300 out_printf(out, "\t%s->%s = NULL;\n",
1301 oname, get_real_id(m->id));
1305 out_addline_outfile(out);
1309 make_arguments(Class *c)
1312 char *argflags[] = {
1320 out_printf(out, "\n");
1321 for(li=c->nodes;li;li=g_list_next(li)) {
1327 if(n->type != ARGUMENT_NODE)
1332 if(a->get && a->set)
1333 flags = g_string_new("GTK_ARG_READWRITE");
1335 flags = g_string_new("GTK_ARG_READABLE");
1337 flags = g_string_new("GTK_ARG_WRITABLE");
1339 g_assert(a->get || a->set);
1341 for(l=a->flags;l;l=g_list_next(l)) {
1342 char *flag = l->data;
1344 if(strcmp(flag, "READWRITE")==0 ||
1345 strcmp(flag, "READABLE")==0 ||
1346 strcmp(flag, "WRITABLE")==0) {
1347 error_print(GOB_WARN, a->line_no,
1348 "READWRITE, READABLE and "
1349 "WRITABLE argument flags are "
1350 "set automatically");
1353 for(i = 0; argflags[i]; i++) {
1354 if(strcmp(argflags[i], flag)==0)
1357 /* if we haven't found it in our list */
1358 if( ! argflags[i]) {
1359 error_printf(GOB_WARN, a->line_no,
1360 "Unknown flag '%s' used, "
1361 "perhaps it was misspelled", flag);
1363 g_string_sprintfa(flags, " | GTK_ARG_%s", flag);
1366 s = g_strdup(a->name);
1368 out_printf(out, "\tgtk_object_add_arg_type(\"%s::%s\",\n"
1369 "\t\tGTK_TYPE_%s,\n"
1372 typebase, a->name, a->gtktype, flags->str, s);
1374 g_string_free(flags, TRUE);
1377 out_printf(out, "\n");
1378 if(get_arguments > 0)
1379 out_printf(out, "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1380 if(set_arguments > 0)
1381 out_printf(out, "\tgtk_object_class->set_arg = ___object_set_arg;\n");
1385 print_initializer(Method *m, Variable *v)
1389 if(v->initializer == NULL)
1392 if(v->scope == PRIVATE_SCOPE)
1393 root = g_strconcat(((FuncArg *)m->args->data)->name,
1396 root = g_strdup(((FuncArg *)m->args->data)->name);
1398 if(v->initializer_line > 0)
1399 out_addline_infile(out, v->initializer_line);
1401 out_printf(out, "\t%s->%s = %s;\n",
1402 root, v->id, v->initializer);
1404 if(v->initializer_line > 0)
1405 out_addline_outfile(out);
1411 print_destructor(Variable *v)
1415 if(v->destructor == NULL)
1418 if(v->scope == PRIVATE_SCOPE)
1419 root = "self->_priv";
1423 if(v->destructor_simple) {
1424 if(v->destructor_line > 0)
1425 out_addline_infile(out, v->destructor_line);
1427 out_printf(out, "\tif(%s->%s) { "
1428 "((*(void (*)(void *))%s)) (%s->%s); "
1429 "%s->%s = NULL; }\n",
1430 root, v->id, v->destructor, root, v->id,
1433 if(v->destructor_line > 0)
1434 out_addline_outfile(out);
1436 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1437 out_printf(out, "\t{\n");
1438 if(v->destructor_line > 0)
1439 out_addline_infile(out, v->destructor_line);
1441 out_printf(out, "\t%s}\n", v->destructor);
1443 if(v->destructor_line > 0)
1444 out_addline_outfile(out);
1445 out_printf(out, "\tmemset(&VAR, 0, sizeof(VAR));\n");
1446 out_printf(out, "#undef VAR\n");
1451 add_destroy(Class *c)
1453 out_printf(out, "\nstatic void\n"
1454 "___destroy(GtkObject *obj_self)\n"
1457 "#define __GOB_FUNCTION__ \"%s::destroy\"\n",
1460 if(destructors > 0) {
1461 out_printf(out, "\t%s *self = %s (obj_self);\n",
1462 typebase, macrobase);
1465 if(destroy_handler) {
1466 /* so we get possible bad argument warning */
1467 if(destroy_handler->line_no > 0)
1468 out_addline_infile(out, destroy_handler->line_no);
1469 out_printf(out, "\t___%x_%s_destroy(obj_self);\n",
1470 (guint)destroy_handler->unique_id, funcbase);
1471 if(destroy_handler->line_no > 0)
1472 out_addline_outfile(out);
1475 "\tif(GTK_OBJECT_CLASS(parent_class)->destroy) \\\n"
1476 "\t\t(* GTK_OBJECT_CLASS(parent_class)->destroy)(obj_self);\n");
1479 if(destructors > 0) {
1481 for(li = ((Class *)class)->nodes;
1485 Variable *v = (Variable *)n;
1486 if(n->type == VARIABLE_NODE &&
1487 v->scope != CLASS_SCOPE)
1488 print_destructor(v);
1492 out_printf(out, "\treturn;\n");
1494 out_printf(out, "\tself = NULL;\n");
1495 out_printf(out, "}\n"
1496 "#undef __GOB_FUNCTION__\n\n");
1500 add_finalize(Class *c)
1502 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1504 "\n#ifdef G_OBJECT_CLASS\n"
1506 "___finalize(GObject *obj_self)\n"
1507 "#else /* !G_OBJECT_CLASS */\n"
1509 "___finalize(GtkObject *obj_self)\n"
1510 "#endif /* G_OBJECT_CLASS */\n"
1513 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
1517 out_printf(out, "\t%s *self = %s (obj_self);\n",
1518 typebase, macrobase);
1519 out_printf(out, "\tgpointer priv = self->_priv;\n");
1522 if(finalize_handler) {
1523 /* so we get possible bad argument warning */
1524 if(finalize_handler->line_no > 0)
1525 out_addline_infile(out, finalize_handler->line_no);
1526 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
1527 (guint)finalize_handler->unique_id, funcbase);
1528 if(finalize_handler->line_no > 0)
1529 out_addline_outfile(out);
1531 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1533 "#ifdef G_OBJECT_CLASS\n"
1534 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
1535 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1536 "#else /* !G_OBJECT_CLASS */\n"
1537 "\tif(GTK_OBJECT_CLASS(parent_class)->finalize) \\\n"
1538 "\t\t(* GTK_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1539 "#endif /* G_OBJECT_CLASS */\n");
1543 out_printf(out, "\tg_free(priv);\n");
1546 out_printf(out, "}\n"
1547 "#undef __GOB_FUNCTION__\n\n");
1551 make_bonobo_x_epv (Class *c, const char *classname)
1554 gboolean added_line = FALSE;
1556 for (li = c->nodes; li != NULL; li = li->next) {
1558 Method *m = (Method *)n;
1559 if(n->type != METHOD_NODE ||
1560 m->method == OVERRIDE_METHOD)
1563 if (m->bonobo_x_func) {
1564 if(m->line_no > 0) {
1565 out_addline_infile(out, m->line_no);
1567 } else if (m->line_no == 0 &&
1569 out_addline_outfile(out);
1572 out_printf (out, "\t%s->_epv.%s = %s;\n",
1573 classname, m->id, m->id);
1577 out_addline_outfile(out);
1584 for(li=c->nodes;li;li=g_list_next(li)) {
1588 gboolean add_unused_class = FALSE;
1590 if(n->type != METHOD_NODE)
1593 if(m->method == INIT_METHOD) {
1595 out_addline_infile(out, m->line_no);
1596 print_method(out, "static ", "\n", "", " ", "", "\n",
1597 m, FALSE, FALSE, TRUE);
1599 out_addline_outfile(out);
1600 out_printf(out, "{\n"
1601 "#define __GOB_FUNCTION__ \"%s::init\"\n",
1604 out_printf(out, "\t%s->_priv = "
1605 "g_new0 (%sPrivate, 1);\n",
1606 ((FuncArg *)m->args->data)->name,
1608 } else if(always_private_struct) {
1609 out_printf(out, "\t%s->_priv = NULL;\n",
1610 ((FuncArg *)m->args->data)->name);
1612 if(initializers > 0) {
1614 for(li = ((Class *)class)->nodes;
1618 Variable *v = (Variable *)n;
1619 if(n->type != VARIABLE_NODE ||
1620 v->scope == CLASS_SCOPE)
1622 print_initializer(m, v);
1625 } else if(m->method == CLASS_INIT_METHOD) {
1626 gboolean did_base_obj = FALSE;
1629 out_addline_infile(out, m->line_no);
1630 print_method(out, "static ", "\n", "", " ", "", "\n",
1631 m, FALSE, FALSE, TRUE);
1633 out_addline_outfile(out);
1634 out_printf(out, "{\n"
1635 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
1638 set_arguments > 0 ||
1639 get_arguments > 0 ||
1642 add_unused_class = TRUE;
1644 "\tGtkObjectClass *"
1645 "gtk_object_class = "
1646 "(GtkObjectClass*) %s;\n",
1647 ((FuncArg *)m->args->data)->name);
1649 "#ifdef G_OBJECT_CLASS\n"
1652 "(GObjectClass*) %s;\n"
1653 "#endif /* G_OBJECT_CLASS */\n",
1654 ((FuncArg *)m->args->data)->name);
1655 did_base_obj = TRUE;
1660 ((FuncArg *)m->args->data)->name,
1663 if(initializers > 0) {
1665 for(li = ((Class *)class)->nodes;
1669 Variable *v = (Variable *)n;
1670 if(n->type == VARIABLE_NODE &&
1671 v->scope == CLASS_SCOPE)
1672 print_initializer(m, v);
1676 out_printf(out, "\n\tparent_class = ");
1678 out_printf(out, "(%sClass *)", ptypebase);
1679 out_printf(out, "gtk_type_class (%s_get_type ());\n",
1685 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1687 /* if there are no handlers for these things, we
1688 * need to set them up here */
1689 if(need_destroy && !destroy_handler)
1690 out_printf(out, "\tgtk_object_class->destroy "
1692 if(need_finalize && !finalize_handler)
1694 "#ifdef G_OBJECT_CLASS\n"
1695 "\tg_object_class->finalize = ___finalize;\n"
1696 "#else /* !G_OBJECT_CLASS */\n"
1697 "\tgtk_object_class->finalize = ___finalize;\n"
1698 "#endif /* G_OBJECT_CLASS */\n");
1700 if(get_arguments > 0 || set_arguments > 0)
1703 if (c->bonobo_x_class != NULL) {
1704 make_bonobo_x_epv (c, ((FuncArg *)m->args->data)->name);
1710 out_printf(out, " {\n");
1711 out_addline_infile(out, m->ccode_line);
1712 out_printf(out, "%s\n", m->cbuf);
1713 out_addline_outfile(out);
1714 out_printf(out, " }\n");
1716 out_printf(out, "\treturn;\n");
1719 ((FuncArg *)m->args->data)->name);
1720 if(add_unused_class) {
1722 "\tgtk_object_class = NULL;\n"
1723 "#ifdef G_OBJECT_CLASS\n"
1724 "\tg_object_class = NULL;\n"
1725 "#endif /* G_OBJECT_CLASS */\n");
1727 out_printf(out, "}\n"
1728 "#undef __GOB_FUNCTION__\n");
1733 add_getset_arg(Class *c, gboolean is_set)
1736 out_printf(out, "\nstatic void\n"
1737 "___object_%s_arg (GtkObject *object,\n"
1740 "#define __GOB_FUNCTION__ \"%s::%s_arg\"\n"
1743 "\tself = %s (object);\n\n"
1744 "\tswitch (arg_id) {\n",
1745 is_set ? "set" : "get",
1746 c->otype, is_set ? "set" : "get",
1747 typebase, macrobase);
1749 for(li=c->nodes;li;li=g_list_next(li)) {
1755 if(n->type != ARGUMENT_NODE)
1760 line_no = a->set_line;
1763 line_no = a->get_line;
1767 s = g_strdup(a->name);
1769 out_printf(out, "\tcase ARG_%s:\n", s);
1770 if(is_set && a->atype) {
1771 char *cast = get_type(a->atype, TRUE);
1772 if(no_gnu || for_cpp) {
1773 out_printf(out, "#define ARG "
1774 "((%s)GTK_VALUE_%s(*arg))\n",
1777 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
1778 if(strcmp(a->gtktype, "OBJECT")==0) {
1779 out_printf(out, "#define ARG "
1781 "GTK_VALUE_POINTER(*arg); "
1785 out_printf(out, "#define ARG "
1787 "GTK_VALUE_%s(*arg); "
1791 out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
1792 out_printf(out, "#define ARG "
1793 "((%s)GTK_VALUE_%s(*arg))\n",
1795 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
1797 out_printf(out, "\t\t{\n");
1799 } else if(!is_set && strcmp(a->gtktype, "OBJECT")==0) {
1801 "#define ARG (GTK_VALUE_POINTER(*arg))\n"
1805 "#define ARG (GTK_VALUE_%s(*arg))\n"
1811 out_addline_infile(out, line_no);
1812 out_printf(out, "%s\n", cbuf);
1814 out_addline_outfile(out);
1815 out_printf(out, "\t\t}\n\t\tbreak;\n"
1818 out_printf(out, "\tdefault:\n\t\tbreak;\n\t}\n"
1819 "\treturn;\n\tself = NULL;\n\targ = NULL;\n}\n"
1820 "#undef __GOB_FUNCTION__\n");
1824 print_checks(Method *m, FuncArg *fa)
1828 gboolean checked_null = FALSE;
1829 is_void = (strcmp(m->mtype->name, "void")==0 &&
1830 m->mtype->pointer == NULL);
1832 for(li = fa->checks; li; li = g_list_next(li)) {
1833 Check *ch = li->data;
1835 /* point to the method prot in .gob for failed checks */
1837 out_addline_infile(out, m->line_no);
1839 out_printf(out, "\tg_return_if_fail (");
1841 out_printf(out, "\tg_return_val_if_fail (");
1842 switch(ch->chtype) {
1844 out_printf(out, "%s != NULL", fa->name);
1845 checked_null = TRUE;
1848 s = make_pre_macro(fa->atype->name, "IS");
1850 out_printf(out, "%s (%s)", s, fa->name);
1852 /* if not check null, null may be valid */
1853 out_printf(out, "!(%s) || %s (%s)", fa->name,
1858 out_printf(out, "%s < %s", fa->name, ch->number);
1861 out_printf(out, "%s > %s", fa->name, ch->number);
1864 out_printf(out, "%s <= %s", fa->name, ch->number);
1867 out_printf(out, "%s >= %s", fa->name, ch->number);
1870 out_printf(out, "%s == %s", fa->name, ch->number);
1873 out_printf(out, "%s != %s", fa->name, ch->number);
1877 out_printf(out, ");\n");
1879 out_printf(out, ", (");
1880 print_type(out, m->mtype, TRUE);
1881 out_printf(out, ")%s);\n",
1882 m->onerror?m->onerror:"0");
1888 print_preconditions(Method *m)
1892 for(li=m->args;li;li=g_list_next(li)) {
1893 FuncArg *fa = li->data;
1895 print_checks(m, fa);
1898 out_addline_outfile(out);
1902 print_method_body(Method *m, int pre)
1905 out_addline_outfile(out);
1906 out_printf(out, "{\n"
1907 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
1908 ((Class *)class)->otype,
1909 get_real_id(m->id));
1911 print_preconditions(m);
1913 /* Note: the trailing }'s are on one line, this is so
1914 that we get the no return warning correctly and point to
1915 the correct line in the .gob file, yes this is slightly
1916 ugly in the .c file, but that is not supposed to be
1917 human readable anyway. */
1919 out_printf(out, "{\n");
1921 out_addline_infile(out, m->ccode_line);
1922 out_printf(out, "\t%s}", m->cbuf);
1925 /* Note, there is no \n between the last } and this } so that
1926 * errors/warnings reported on the end of the body get pointed to the
1927 * right line in the .gob source */
1928 out_printf(out, "}\n");
1931 out_addline_outfile(out);
1932 out_printf(out, "#undef __GOB_FUNCTION__\n");
1936 put_signal_args(Method *m)
1940 for(ali = m->gtktypes->next, li=m->args->next;
1942 li=li->next, ali=ali->next) {
1943 FuncArg *fa = li->data;
1944 const char *cast = get_cast(ali->data, FALSE);
1945 /* we should have already proved before that
1946 the we know all the types */
1949 out_printf(out, ",\n\t\t(%s)%s", cast,
1955 get_arg_names_for_macro(Method *m)
1959 GString *gs = g_string_new(NULL);
1961 for(li=m->args;li;li=g_list_next(li)) {
1962 FuncArg *arg = li->data;
1963 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1967 g_string_free(gs, FALSE);
1972 put_method(Method *m)
1974 char *s, *args, *doc;
1976 is_void = (strcmp(m->mtype->name, "void")==0 &&
1977 m->mtype->pointer == NULL);
1978 out_printf(out, "\n");
1979 if(m->method != OVERRIDE_METHOD) {
1980 doc = get_gtk_doc(m->id);
1982 out_printf(out, "%s", doc);
1987 case REGULAR_METHOD:
1989 out_addline_infile(out, m->line_no);
1990 if(m->scope == PRIVATE_SCOPE)
1991 print_method(out, "static ", "\n", "", " ", "", "\n",
1992 m, FALSE, FALSE, TRUE);
1993 else /* PUBLIC, PROTECTED */
1994 print_method(out, "", "\n", "", " ", "", "\n",
1995 m, FALSE, FALSE, TRUE);
1996 print_method_body(m, TRUE);
1997 /* the outfile line was added above */
1999 case SIGNAL_FIRST_METHOD:
2000 case SIGNAL_LAST_METHOD:
2002 out_addline_infile(out, m->line_no);
2003 if(m->scope == PRIVATE_SCOPE)
2004 print_method(out, "static ", "\n", "", " ", "", "\n",
2005 m, FALSE, FALSE, TRUE);
2006 else /* PUBLIC, PROTECTED */
2007 print_method(out, "", "\n", "", " ", "", "\n",
2008 m, FALSE, FALSE, TRUE);
2009 out_addline_outfile(out);
2010 out_printf(out, "{\n");
2011 s = g_strdup(get_real_id(m->id));
2013 if(strcmp(m->mtype->name, "void") == 0 &&
2014 m->mtype->pointer == NULL) {
2015 print_preconditions(m);
2016 if(((FuncArg *)m->args->data)->name)
2017 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
2018 "\t\tobject_signals[%s_SIGNAL]",
2019 ((FuncArg *)m->args->data)->name, s);
2021 out_printf(out, ");\n}\n");
2023 out_printf(out, "\t");
2024 print_type(out, m->mtype, TRUE);
2025 out_printf(out, "return_val = (");
2026 print_type(out, m->mtype, TRUE);
2028 out_printf(out, ")(%s);\n", m->defreturn);
2030 out_printf(out, ")(%s);\n", m->onerror);
2032 out_printf(out, ")(0);\n");
2033 print_preconditions(m);
2034 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
2035 "\t\tobject_signals[%s_SIGNAL]",
2036 ((FuncArg *)m->args->data)->name, s);
2038 out_printf(out, ",\n\t\t&return_val);\n"
2039 "\treturn return_val;\n}\n");
2045 out_addline_infile(out, m->line_no);
2046 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2047 m, FALSE, FALSE, TRUE);
2048 print_method_body(m, FALSE);
2049 /* the outfile line was added above */
2051 case VIRTUAL_METHOD:
2053 out_addline_infile(out, m->line_no);
2054 if(m->scope==PRIVATE_SCOPE)
2055 print_method(out, "static ", "\n", "", " ", "", "\n",
2056 m, FALSE, FALSE, TRUE);
2057 else /* PUBLIC, PROTECTED */
2058 print_method(out, "", "\n", "", " ", "", "\n",
2059 m, FALSE, FALSE, TRUE);
2060 out_addline_outfile(out);
2061 out_printf(out, "{\n"
2062 "\t%sClass *klass;\n", typebase);
2063 print_preconditions(m);
2064 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2065 "\tif(klass->%s)\n",
2066 macrobase, ((FuncArg *)m->args->data)->name,
2067 get_real_id(m->id));
2068 if(strcmp(m->mtype->name, "void") == 0 &&
2069 m->mtype->pointer == NULL) {
2071 out_printf(out, "\t\t(*klass->%s)(%s",
2073 ((FuncArg *)m->args->data)->name);
2074 for(li=m->args->next;li;li=g_list_next(li)) {
2075 FuncArg *fa = li->data;
2076 out_printf(out, ",%s", fa->name);
2078 out_printf(out, ");\n}\n");
2081 out_printf(out, "\t\treturn (*klass->%s)(%s",
2083 ((FuncArg *)m->args->data)->name);
2084 for(li=m->args->next;li;li=g_list_next(li)) {
2085 FuncArg *fa = li->data;
2086 out_printf(out, ",%s", fa->name);
2088 out_printf(out, ");\n"
2091 print_type(out, m->mtype, TRUE);
2093 out_printf(out, ")(%s);\n}\n", m->defreturn);
2095 out_printf(out, ")(%s);\n}\n", m->onerror);
2097 out_printf(out, ")(0);\n}\n");
2103 out_addline_infile(out, m->line_no);
2104 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2105 m, FALSE, FALSE, TRUE);
2106 print_method_body(m, FALSE);
2107 /* the outfile line was added above */
2109 case OVERRIDE_METHOD:
2113 out_addline_infile(out, m->line_no);
2114 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2115 print_method(out, "static ", s, "", " ", "", "\n",
2116 m, FALSE, FALSE, FALSE);
2118 out_addline_outfile(out);
2119 s = replace_sep(m->otype, '_');
2121 args = get_arg_names_for_macro(m);
2123 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2124 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2125 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2126 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
2128 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2129 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2130 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2132 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
2133 out_printf(out, "(");
2134 print_type(out, m->mtype, TRUE);
2135 out_printf(out, ")%s))\n",
2136 m->onerror?m->onerror:"0");
2140 print_method_body(m, TRUE);
2141 /* the outfile line was added above */
2142 out_printf(out, "#undef PARENT_HANDLER\n");
2152 char *outfile, *outfileh, *outfileph;
2155 outfile = g_strconcat(filebase, ".c", NULL);
2157 outfile = g_strconcat(filebase, ".cc", NULL);
2158 if(no_touch_headers)
2159 outfileh = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2161 outfileh = g_strconcat(filebase, ".h", NULL);
2163 if((privates > 0 || protecteds > 0 ||
2164 private_header == PRIVATE_HEADER_ALWAYS) &&
2165 private_header != PRIVATE_HEADER_NEVER)
2166 outfileph = g_strconcat(filebase, "-private.h", NULL);
2172 devnull = fopen("/dev/null", "w");
2174 g_error("Cannot open null device");
2180 out = fopen(outfile, "w");
2182 g_error("Cannot open outfile: %s", outfile);
2184 outh = fopen(outfileh, "w");
2186 g_error("Cannot open outfile: %s", outfileh);
2188 outph = fopen(outfileph, "w");
2190 g_error("Cannot open outfile: %s", outfileh);
2196 put_argument_nongnu_wrappers(Class *c)
2200 if(get_arguments < 0 && set_arguments < 0)
2203 for(li=c->nodes;li;li=g_list_next(li)) {
2205 Argument *a = (Argument *)n;
2209 if(n->type != ARGUMENT_NODE)
2212 aname = g_strdup(a->name);
2216 cast = get_type(a->atype, TRUE);
2218 cast = g_strdup(get_cast(a->gtktype, TRUE));
2222 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2223 "\"%s\",(%s)(arg)\n",
2224 macrobase, aname, a->name, cast);
2226 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2227 "\"%s\",(%s*)(arg)\n",
2228 macrobase, aname, a->name, cast);
2231 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2233 macrobase, aname, a->name);
2235 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2237 macrobase, aname, a->name);
2245 put_argument_gnu_wrappers(Class *c)
2249 if(get_arguments < 0 && set_arguments < 0)
2252 for(li=c->nodes;li;li=g_list_next(li)) {
2254 Argument *a = (Argument *)n;
2257 if(n->type != ARGUMENT_NODE)
2259 s = g_strdup(a->name);
2262 cast = get_type(a->atype, TRUE);
2264 cast = g_strdup(get_cast(a->gtktype, TRUE));
2267 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2268 "\"%s\",({%sz = (arg); z;})\n",
2269 macrobase, s, a->name, cast);
2271 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2272 "\"%s\",({%s*z = (arg); z;})\n",
2273 macrobase, s, a->name, cast);
2276 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2278 macrobase, s, a->name);
2280 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2282 macrobase, s, a->name);
2290 print_ccode_block(CCode *cc)
2293 switch(cc->cctype) {
2295 /* HT code is printed exactly like normal header
2296 code but is printed before */
2299 out_printf(fp, "\n");
2302 /* AT code is printed exactly like normal 'all'
2303 code but is printed before */
2306 out_printf(outph, "\n");
2307 out_printf(outph, "%s\n", cc->cbuf);
2308 out_addline_infile(outph, cc->line_no);
2309 out_addline_outfile(outph);
2311 out_printf(outh, "\n");
2312 out_printf(outh, "%s\n", cc->cbuf);
2314 out_printf(fp, "\n");
2315 out_addline_infile(fp, cc->line_no);
2320 out_printf(fp, "\n");
2321 out_addline_infile(fp, cc->line_no);
2328 out_printf(fp, "\n");
2329 out_addline_infile(fp, cc->line_no);
2332 out_printf(fp, "%s\n", cc->cbuf);
2333 if(cc->cctype == C_CCODE ||
2334 cc->cctype == A_CCODE ||
2335 cc->cctype == AT_CCODE ||
2336 cc->cctype == PH_CCODE)
2337 out_addline_outfile(fp);
2341 print_class_block(Class *c)
2345 gboolean printed_private = FALSE;
2348 out_printf(out, "/* utility types we may need */\n");
2349 if(special_array[SPECIAL_2POINTER])
2350 out_printf(out, "typedef struct { "
2351 "gpointer a; gpointer b; "
2352 "} ___twopointertype;\n");
2353 if(special_array[SPECIAL_3POINTER])
2354 out_printf(out, "typedef struct { "
2355 "gpointer a; gpointer b; "
2357 "} ___threepointertype;\n");
2358 if(special_array[SPECIAL_INT_POINTER])
2359 out_printf(out, "typedef struct { "
2360 "gint a; gpointer b; "
2361 "} ___intpointertype;\n");
2362 out_printf(out, "\n");
2365 out_printf(outh, "\n/*\n"
2366 " * Type checking and casting macros\n"
2368 out_printf(outh, "#define %s\t"
2369 "(%s_get_type())\n",
2370 macrotype, funcbase);
2371 out_printf(outh, "#define %s(obj)\t"
2372 "GTK_CHECK_CAST((obj), %s_get_type(), %s)\n",
2373 macrobase, funcbase, typebase);
2374 out_printf(outh, "#define %s_CONST(obj)\t"
2375 "GTK_CHECK_CAST((obj), %s_get_type(), %s const)\n",
2376 macrobase, funcbase, typebase);
2377 out_printf(outh, "#define %s_CLASS(klass)\t"
2378 "GTK_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
2379 macrobase, funcbase, typebase);
2380 out_printf(outh, "#define %s(obj)\t"
2381 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
2383 out_printf(outh, "#ifdef GTK_CHECK_GET_CLASS\n"
2384 "#define %s_GET_CLASS(obj)\t"
2385 "GTK_CHECK_GET_CLASS((obj), %s_get_type(), %sClass)\n",
2386 macrobase, funcbase, typebase);
2387 out_printf(outh, "#else /* !GTK_CHECK_GET_CLASS */\n"
2388 "#define %s_GET_CLASS(obj)\t"
2389 "((%sClass *)GTK_OBJECT(obj)->klass)\n"
2390 "#endif /* GTK_CHECK_GET_CLASS */\n",
2391 macrobase, typebase);
2393 if( ! no_self_alias) {
2394 out_printf(out, "/* self casting macros */\n");
2395 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
2396 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
2397 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
2398 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
2399 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
2401 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
2404 out_printf(out, "/* self typedefs */\n");
2405 out_printf(out, "typedef %s Self;\n", typebase);
2406 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
2409 out_printf(out, "/* GTK_CLASS_TYPE for 1.2<->1.3/2.0 GTK+ compatibility */\n");
2411 "#ifndef GTK_CLASS_TYPE\n"
2412 "#define GTK_CLASS_TYPE(x) (GTK_OBJECT_CLASS(x)->type)\n"
2413 "#endif /* GTK_CLASS_TYPE */\n\n");
2415 if(privates > 0 || always_private_struct) {
2416 out_printf(outh, "\n/* Private structure type */\n");
2417 out_printf(outh, "typedef struct _%sPrivate %sPrivate;\n",
2418 typebase, typebase);
2420 out_printf(outh, "/* There are no privates, this "
2421 "structure is thus never defined */\n");
2424 out_printf(outh, "\n/*\n"
2425 " * Main object structure\n"
2427 s = replace_sep(c->otype, '_');
2429 out_printf(outh, "#ifndef __TYPEDEF_%s__\n"
2430 "#define __TYPEDEF_%s__\n", s, s);
2432 out_printf(outh, "typedef struct _%s %s;\n"
2433 "#endif\n", typebase, typebase);
2434 out_printf(outh, "struct _%s {\n\t%s __parent__;\n",
2435 typebase, ptypebase);
2436 for(l=c->nodes; l; l=g_list_next(l)) {
2437 static gboolean printed_public = FALSE;
2439 Variable *v = (Variable *)n;
2440 if(n->type == VARIABLE_NODE &&
2441 v->scope == PUBLIC_SCOPE) {
2442 if( ! printed_public) {
2443 out_printf(outh, "\t/*< public >*/\n");
2444 printed_public = TRUE;
2446 put_variable((Variable *)n, outh);
2449 /* put protecteds always AFTER publics */
2450 for(l=c->nodes; l; l=g_list_next(l)) {
2452 Variable *v = (Variable *)n;
2453 if(n->type == VARIABLE_NODE &&
2454 v->scope == PROTECTED_SCOPE) {
2455 if( ! printed_private) {
2456 out_printf(outh, "\t/*< private >*/\n");
2457 printed_private = TRUE;
2459 put_variable((Variable *)n, outh);
2462 if(privates > 0 || always_private_struct) {
2463 if( ! printed_private)
2464 out_printf(outh, "\t/*< private >*/\n");
2465 out_printf(outh, "\t%sPrivate *_priv;\n", typebase);
2467 out_printf(outh, "};\n");
2472 /* if we are to stick this into the private
2473 header, if not stick it directly into the
2480 out_printf(outfp, "struct _%sPrivate {\n",
2482 for(l=c->nodes; l; l=l->next) {
2484 Variable *v = (Variable *)n;
2485 if(n->type == VARIABLE_NODE &&
2486 v->scope == PRIVATE_SCOPE) {
2487 out_addline_infile(outfp, v->line_no);
2488 put_variable(v, outfp);
2491 out_addline_outfile(outfp);
2492 out_printf(outfp, "};\n");
2495 out_printf(outh, "\n/*\n"
2496 " * Class definition\n"
2498 out_printf(outh, "typedef struct _%sClass %sClass;\n",
2499 typebase, typebase);
2501 "struct _%sClass {\n\t%sClass __parent__;\n",
2502 typebase, ptypebase);
2503 for(l = c->nodes; l != NULL; l = l->next) {
2505 if(n->type == METHOD_NODE)
2506 put_vs_method((Method *)n);
2508 /* If BonoboX type class put down the epv */
2509 if (c->bonobo_x_class != NULL) {
2511 "\t/* Bonobo object epv */\n"
2512 "\tPOA_%s__epv _epv;\n",
2515 /* put class scope variables */
2516 for(l = c->nodes; l != NULL; l = l->next) {
2518 Variable *v = (Variable *)n;
2519 if(n->type == VARIABLE_NODE &&
2520 v->scope == CLASS_SCOPE)
2521 put_variable((Variable *)n, outh);
2523 out_printf(outh, "};\n\n");
2525 out_printf(out, "/* here are local prototypes */\n");
2526 if(set_arguments > 0) {
2527 out_printf(out, "static void ___object_set_arg "
2528 "(GtkObject *object, GtkArg *arg, "
2529 "guint arg_id);\n");
2531 if(get_arguments > 0) {
2532 out_printf(out, "static void ___object_get_arg "
2533 "(GtkObject *object, GtkArg *arg, "
2534 "guint arg_id);\n");
2537 out_printf(outh, "\n/*\n"
2538 " * Public methods\n"
2541 if ( ! overrode_get_type) {
2542 out_printf(outh, "GtkType\t%s_get_type\t(void)", funcbase);
2544 out_printf(outh, " G_GNUC_CONST;\n");
2546 out_printf(outh, ";\n");
2550 for(l = c->nodes; l != NULL; l = l->next) {
2552 if(n->type == METHOD_NODE) {
2553 put_pub_method((Method *)n);
2554 put_prot_method((Method *)n);
2555 put_priv_method_prot((Method *)n);
2559 /* this idea is less and less apealing to me */
2561 out_printf (outh, "\n/*\n"
2562 " * Signal connection wrapper macros\n"
2565 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2566 put_signal_macros (c, TRUE);
2567 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2568 put_signal_macros (c, FALSE);
2569 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2571 put_signal_macros (c, FALSE);
2575 /* argument wrapping macros */
2576 if(get_arguments > 0 || set_arguments > 0) {
2577 out_printf(outh, "\n/*\n"
2578 " * Argument wrapping macros\n"
2581 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2582 put_argument_gnu_wrappers(c);
2583 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2584 put_argument_nongnu_wrappers(c);
2585 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2587 put_argument_nongnu_wrappers(c);
2592 for(l = c->nodes; l != NULL; l = l->next) {
2594 if(n->type == METHOD_NODE)
2595 add_signal_prots((Method *)n);
2601 if ( ! overrode_get_type) {
2602 if (c->bonobo_x_class != NULL)
2603 add_bonobo_x_get_type ();
2608 if(any_method_to_alias(c)) {
2610 out_printf(out, "/* Short form macros */\n");
2611 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2612 make_method_gnu_aliases(c);
2613 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
2615 make_method_nongnu_aliases(c);
2618 out_printf(out, "/* a macro for creating a new object of our type */\n");
2620 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
2621 typebase, funcbase);
2631 if(set_arguments > 0) {
2632 add_getset_arg(c, TRUE);
2635 if(get_arguments > 0) {
2636 add_getset_arg(c, FALSE);
2639 for(l = c->nodes; l != NULL; l = l->next) {
2641 if(n->type == METHOD_NODE)
2642 put_method((Method *)n);
2645 add_bad_hack_to_avoid_unused_warnings(c);
2649 print_version_macros(void)
2651 int major=0, minor=0, pl=0;
2652 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2654 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2655 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2656 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2660 print_file_comments(void)
2664 out_printf(outh, "/* Generated by GOB (v%s)"
2665 " (do not edit directly) */\n\n", VERSION);
2667 out_printf(outph, "/* Generated by GOB (v%s)"
2668 " (do not edit directly) */\n\n", VERSION);
2669 out_printf(out, "/* Generated by GOB (v%s) on %s"
2670 " (do not edit directly) */\n\n",
2671 VERSION, ctime(&curtime));
2673 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
2677 print_includes(void)
2679 gboolean found_header;
2682 /* We may need string.h for memset */
2683 if(destructors > 0 &&
2684 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
2685 out_printf(out, "#include <string.h> /* memset() */\n\n");
2688 p = g_strconcat(filebase, ".h", NULL);
2689 found_header = TRUE;
2690 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2691 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2692 found_header = FALSE;
2696 /* if we are creating a private header see if it was included */
2698 p = g_strconcat(filebase, "-private.h", NULL);
2699 if( ! g_list_find_custom(include_files, p,
2700 (GCompareFunc)strcmp)) {
2701 out_printf(out, "#include \"%s-private.h\"\n\n",
2704 error_printf(GOB_WARN, 0,
2705 "Implicit private header include "
2707 "\tsource file, while public "
2708 "header is at a custom location, "
2710 "\texplicitly include "
2711 "the private header below the "
2719 print_header_prefixes(void)
2723 p = replace_sep(((Class *)class)->otype, '_');
2725 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2727 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2728 "#define __%s_PRIVATE_H__\n\n"
2729 "#include \"%s.h\"\n\n", p, p, filebase);
2732 if( ! no_extern_c) {
2733 out_printf(outh, "#ifdef __cplusplus\n"
2735 "#endif /* __cplusplus */\n\n");
2737 out_printf(outph, "#ifdef __cplusplus\n"
2739 "#endif /* __cplusplus */\n\n");
2744 print_header_postfixes(void)
2747 out_printf(outh, "\n#ifdef __cplusplus\n"
2749 "#endif /* __cplusplus */\n");
2750 out_printf(outh, "\n#endif\n");
2753 out_printf(outph, "\n#ifdef __cplusplus\n"
2755 "#endif /* __cplusplus */\n");
2756 out_printf(outph, "\n#endif\n");
2765 /* print the AT_CCODE blocks */
2766 for(li = nodes; li != NULL; li = li->next) {
2767 Node *node = li->data;
2768 if(node->type == CCODE_NODE) {
2769 CCode *cc = (CCode *)node;
2770 if(cc->cctype == AT_CCODE)
2771 print_ccode_block((CCode *)node);
2777 print_header_top(void)
2781 /* mandatory include */
2782 out_printf(outh, "#include <gtk/gtk.h>\n\n");
2784 /* print the HT_CCODE blocks */
2785 for(li=nodes;li;li=g_list_next(li)) {
2786 Node *node = li->data;
2787 if(node->type == CCODE_NODE) {
2788 CCode *cc = (CCode *)node;
2789 if(cc->cctype == HT_CCODE)
2790 print_ccode_block((CCode *)node);
2796 generate_outfiles(void)
2800 print_file_comments();
2806 print_header_prefixes();
2808 print_version_macros();
2812 for(li=nodes;li;li=g_list_next(li)) {
2813 Node *node = li->data;
2814 if(node->type == CCODE_NODE) {
2815 CCode *cc = (CCode *)node;
2816 if(cc->cctype != HT_CCODE &&
2817 cc->cctype != AT_CCODE)
2818 print_ccode_block((CCode *)node);
2819 } else if(node->type == CLASS_NODE) {
2820 print_class_block((Class *)node);
2822 g_assert_not_reached();
2825 print_header_postfixes();
2831 fprintf(stderr, "Gob version %s\n\n", VERSION);
2832 fprintf(stderr, "gob [options] file.gob\n\n");
2833 fprintf(stderr, "Options:\n"
2834 "\t--help,-h,-? Display this help\n"
2835 "\t--version Display version\n"
2836 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2837 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2838 "\t--for-cpp Create C++ files\n"
2839 "\t--no-extern-c Never print extern \"C\" into the "
2841 "\t--no-gnu Never use GNU extentions\n"
2842 "\t--no-touch-headers Don't touch headers unless they "
2844 "\t--always-private-header Always create a private header "
2846 "\t even if it would be empty "
2848 "\t--ondemand-private-header Create private header only when "
2850 "\t--no-private-header Don't create a private header, "
2852 "\t structure and protected "
2853 "prototypes inside c file\n"
2854 "\t--always-private-struct Always create a private pointer "
2856 "\t the object structure\n"
2857 "\t--m4 Preprocess source with m4. "
2858 "Following args will\n"
2859 "\t be passed to m4\n"
2860 "\t--m4-dir Print directory that will be "
2863 "\t--no-write,-n Don't write output files, just "
2865 "\t--no-lines Don't print '#line' to output\n"
2866 "\t--no-self-alias Don't create self type and macro "
2868 "\t--no-kill-underscores Don't remove the leading underscore "
2870 "\t short id names\n");
2874 parse_options(int argc, char *argv[])
2877 int got_file = FALSE;
2878 int no_opts = FALSE;
2879 int m4_opts = FALSE; /* if we are just passing on args to m4 */
2883 for(i = 1 ; i < argc; i++) {
2885 char *new_commandline;
2886 g_assert(m4_commandline!=NULL);
2888 /* check whether this one looks like the filename */
2889 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
2891 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
2895 /* insert flags before the filename */
2896 new_commandline=g_strconcat(m4_commandline,
2904 /* just an ordinary option */
2906 new_commandline=g_strconcat(m4_commandline,
2911 /* free old commandline */
2912 g_free(m4_commandline);
2913 m4_commandline=new_commandline;
2915 } else if(no_opts ||
2916 argv[i][0] != '-') {
2919 fprintf(stderr, "Specify only one file!\n");
2925 } else if(strcmp(argv[i], "--help")==0) {
2928 } else if(strcmp(argv[i], "--version")==0) {
2929 fprintf(stderr, "Gob version %s\n", VERSION);
2931 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2932 exit_on_warn = TRUE;
2933 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2934 exit_on_warn = FALSE;
2935 } else if(strcmp(argv[i], "--for-cpp")==0) {
2937 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2938 no_touch_headers = TRUE;
2939 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
2940 private_header = PRIVATE_HEADER_ONDEMAND;
2941 } else if(strcmp(argv[i], "--always-private-header")==0) {
2942 private_header = PRIVATE_HEADER_ALWAYS;
2943 } else if(strcmp(argv[i], "--no-private-header")==0) {
2944 private_header = PRIVATE_HEADER_NEVER;
2945 } else if(strcmp(argv[i], "--no-gnu")==0) {
2947 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2949 } else if(strcmp(argv[i], "--no-write")==0) {
2951 } else if(strcmp(argv[i], "--no-lines")==0) {
2953 } else if(strcmp(argv[i], "--no-self-alias")==0) {
2954 no_self_alias = TRUE;
2955 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
2956 no_kill_underscores = TRUE;
2957 } else if(strcmp(argv[i], "--always-private-struct")==0) {
2958 always_private_struct = TRUE;
2959 } else if(strcmp(argv[i], "--m4-dir")==0) {
2960 printf("%s\n",M4_INCLUDE_DIR);
2962 } else if(strcmp(argv[i], "--m4")==0) {
2966 m4_commandline=g_strdup(M4_COMMANDLINE);
2967 } else if(strcmp(argv[i], "--m4-clean")==0) {
2971 m4_commandline=g_strdup(M4_COMMANDLINE);
2972 } else if(strcmp(argv[i], "--")==0) {
2973 /*further arguments are files*/
2975 } else if(strncmp(argv[i], "--", 2)==0) {
2976 /*unknown long option*/
2977 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2981 /*by now we know we have a string starting with
2982 - which is a short option string*/
2984 for(p = argv[i] + 1; *p; p++) {
2998 "Unknown option '%c'!\n", *p);
3007 /* if we are using m4, and got no filename, append m4 flags now */
3008 if(!got_file && use_m4 && !use_m4_clean) {
3009 char *new_commandline;
3010 new_commandline=g_strconcat(m4_commandline,
3014 g_free(m4_commandline);
3015 m4_commandline=new_commandline;
3020 /* this is a somewhat ugly hack, but it appears to work */
3022 compare_and_move_header(void)
3024 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
3025 char *hf = g_strconcat(filebase, ".h", NULL);
3027 if(stat(hf, &s) == 0) {
3029 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
3030 if(system(s) == 0) {
3031 if(unlink(hfnew) != 0)
3032 error_printf(GOB_ERROR, 0,
3033 "Can't remove new header file");
3041 error_printf(GOB_ERROR, 0,
3042 "Can't remove old header file");
3044 if(rename(hfnew, hf) != 0)
3045 error_printf(GOB_ERROR, 0,
3046 "Can't rename new header file");
3052 main(int argc, char *argv[])
3054 parse_options(argc, argv);
3057 yyin = popen(m4_commandline, "r");
3059 fprintf(stderr, "Error: can't open pipe from '%s'\n",
3063 } else if(filename) {
3064 yyin = fopen(filename, "r");
3066 fprintf(stderr, "Error: can't open file '%s'\n",
3075 /* This is where parsing is done */
3078 g_error("Parsing errors, quitting");
3080 /* close input file */
3081 if(use_m4) pclose(yyin);
3086 error_print(GOB_ERROR, 0, " no class defined");
3089 exit_on_error = FALSE;
3091 signals = count_signals((Class *)class);
3092 set_arguments = count_set_arguments((Class *)class);
3093 get_arguments = count_get_arguments((Class *)class);
3094 overrides = count_overrides((Class *)class);
3095 privates = count_privates((Class *)class);
3096 protecteds = count_protecteds((Class *)class);
3097 destructors = count_destructors((Class *)class);
3098 initializers = count_initializers((Class *)class);
3099 overrode_get_type = find_get_type((Class *)class);
3102 make_inits((Class *)class);
3103 if(destructors > 0) {
3104 need_destroy = TRUE;
3105 find_destroy((Class *)class);
3108 need_finalize = TRUE;
3109 find_finalize((Class *)class);
3111 check_bad_symbols((Class *)class);
3112 check_duplicate_symbols((Class *)class);
3113 check_duplicate_overrides((Class *)class);
3114 check_duplicate_signals_args((Class *)class);
3115 check_public_new((Class *)class);
3116 check_vararg((Class *)class);
3117 check_firstarg((Class *)class);
3118 check_nonvoidempty((Class *)class);
3119 check_signal_args((Class *)class);
3120 check_argument_types((Class *)class);
3121 check_func_arg_checks((Class *)class);
3123 exit_on_error = TRUE;
3128 any_special = setup_special_array((Class *)class, special_array);
3132 generate_outfiles();
3143 if(no_touch_headers &&
3145 compare_and_move_header();