]> git.draconx.ca Git - gob-dx.git/blob - src/util.c
Release 0.93.1
[gob-dx.git] / src / util.c
1 /* GOB C Preprocessor
2  * Copyright (C) 1999-2000 the Free Software Foundation.
3  *
4  * Author: George Lebl
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the  Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19  * USA.
20  */
21
22 #include "config.h"
23 #include <string.h>
24 #include <stdio.h>
25 #include <glib.h>
26
27 #include "tree.h"
28 #include "main.h"
29
30 #include "util.h"
31
32 void
33 print_error(gboolean is_warn, char *error, int line)
34 {
35         char *w;
36         if(is_warn)
37                 w = "Warning:";
38         else {
39                 w = "Error:";
40                 got_error = TRUE;
41         }
42         if(line>0)
43                 fprintf(stderr, "%s:%d: %s %s\n", filename, line, w, error);
44         else
45                 fprintf(stderr, "%s: %s %s\n", filename, w, error);
46         if((!is_warn || exit_on_warn) && exit_on_error)
47                 exit(1);
48 }
49
50 char *
51 remove_sep(char *base)
52 {
53         char *p;
54         char *s = g_strdup(base);
55         while((p=strchr(s,':')))
56                 strcpy(p,p+1);
57         return s;
58 }
59
60 char *
61 replace_sep(char *base, char r)
62 {
63         char *p;
64         char *s = g_strdup(base);
65         while((p=strchr(s,':')))
66                 *p = r;
67         if(*s == r) {
68                 p = g_strdup(s+1);
69                 g_free(s);
70                 return p;
71         }
72         return s;
73 }
74
75 /*separate the namespace part and then replace rest of
76   separators with r*/
77 void
78 separns_replace_sep(char *base, char **ns, char **name, char r)
79 {
80         char *p;
81         char *s = g_strdup(base);
82         *ns = NULL;
83         if((p=strchr(s,':')) && p!=s) {
84                 *p = '\0';
85                 *ns = g_strdup(s);
86                 p = g_strdup(p+1);
87                 g_free(s);
88                 s = p;
89         }
90         while((p=strchr(s,':')))
91                 *p = r;
92         if(*s == r) {
93                 *name = g_strdup(s+1);
94                 g_free(s);
95         } else
96                 *name = s;
97 }
98
99 /* make a macro with some prefix before the name but after
100    namespace */
101 char *
102 make_pre_macro(char *base, char *pre)
103 {
104         char *s1,*s2;
105         char *s;
106
107         separns_replace_sep(base,&s1,&s2,'_');
108         if(s1)
109                 s = g_strconcat(s1,"_",pre,"_",s2,NULL);
110         else
111                 s = g_strconcat(pre,"_",s2,NULL);
112
113         g_strup(s);
114         
115         g_free(s1);
116         g_free(s2);
117
118         return s;
119 }
120
121 /* here we will find out how inconsistent gtk really is :) */
122 /* the commented out types mean that these types don't actually
123    exist. so we "emulate them" with an equivalent */
124 typedef struct _OurGtkType OurGtkType;
125 struct _OurGtkType {
126         gboolean simple;
127         char *gtkname;
128         char *typename;
129         int special;
130 };
131 const OurGtkType our_gtk_type_table[] = {
132         { TRUE, "NONE",         "void ", -1 },
133         { TRUE, "CHAR",         "gchar ", -1 },
134         { TRUE, "UCHAR",        "guchar ", -1 },
135         { TRUE, "BOOL",         "gboolean ", -1 },
136         { TRUE, "INT",          "gint ", -1 },
137         { TRUE, "UINT",         "guint ", -1 },
138         { TRUE, "LONG",         "glong ", -1 },
139         { TRUE, "ULONG",        "gulong ", -1 },
140         { TRUE, "FLOAT",        "gfloat ", -1 },
141         { TRUE, "DOUBLE",       "gdouble ", -1 },
142         { TRUE, "STRING",       /*"GtkString"*/"gchar *", -1 },
143         { TRUE, "ENUM",         /*"GtkEnum"*/"gint ", -1 },
144         { TRUE, "FLAGS",        /*"GtkFlags"*/"guint ", -1 },
145         { TRUE, "BOXED",        /*"GtkBoxed"*/"gpointer ", -1 },
146         { TRUE, "POINTER",      "gpointer ", -1 },
147         { TRUE, "OBJECT",       "GtkObject *", -1 },
148         { FALSE, "SIGNAL",      /*"GtkSignal"*/"___twopointertype ",
149                 SPECIAL_2POINTER },
150         { FALSE, "ARGS",        /*"GtkArgs"*/"___intpointertype ",
151                 SPECIAL_INT_POINTER },
152         { FALSE, "CALLBACK",    /*"GtkCallback"*/"___threepointertype ",
153                 SPECIAL_3POINTER },
154         { FALSE, "C_CALLBACK",  /*"GtkCCallback"*/"___twopointertype ",
155                 SPECIAL_2POINTER },
156         { FALSE, "FOREIGN",     /*"GtkForeign"*/"___twopointertype ",
157                 SPECIAL_2POINTER },
158
159         { FALSE, NULL, NULL }
160 };
161
162 static GHashTable *type_hash = NULL;
163
164 static void
165 init_type_hash(void)
166 {
167         int i;
168
169         if(type_hash) return;
170
171         type_hash = g_hash_table_new(g_str_hash, g_str_equal);
172
173         for(i=0; our_gtk_type_table[i].gtkname; i++)
174                 g_hash_table_insert(type_hash,
175                                     our_gtk_type_table[i].gtkname,
176                                     (gpointer)&our_gtk_type_table[i]);
177 }
178
179 const char *
180 get_cast(char *type, gboolean simple_only)
181 {
182         OurGtkType *gtype;
183
184         init_type_hash();
185
186         gtype = g_hash_table_lookup(type_hash, type);
187
188         if(!gtype ||
189            (simple_only &&
190             !gtype->simple))
191                 return NULL;
192
193         return gtype->typename;
194 }
195
196 static void
197 mask_special_array(char *type, gboolean *special_array, gboolean *any_special)
198 {
199         OurGtkType *gtype;
200
201         init_type_hash();
202
203         gtype = g_hash_table_lookup(type_hash, type);
204
205         if(gtype && gtype->special >= 0) {
206                 special_array[gtype->special] = TRUE;
207                 *any_special = TRUE;
208         }
209 }
210
211 gboolean
212 setup_special_array(Class *c, gboolean *special_array)
213 {
214         GList *li;
215         gboolean any_special = FALSE;
216
217         memset(special_array, 0, sizeof(gboolean)*SPECIAL_LAST);
218
219         for(li=c->nodes; li; li=g_list_next(li)) {
220                 Node *n = li->data;
221                 if(n->type == METHOD_NODE) {
222                         Method *m = (Method *)n;
223                         GList *l;
224                         if(m->method != SIGNAL_LAST_METHOD &&
225                            m->method != SIGNAL_FIRST_METHOD)
226                                 continue;
227
228                         for(l=m->gtktypes; l; l=l->next)
229                                 mask_special_array(l->data, special_array,
230                                                    &any_special);
231                 } else if(n->type == ARGUMENT_NODE) {
232                         Argument *a = (Argument *)n;
233                         mask_special_array(a->gtktype, special_array,
234                                            &any_special);
235                 }
236         }
237
238         return any_special;
239 }