]> git.draconx.ca Git - gob-dx.git/blob - src/util.c
Release 1.0.2
[gob-dx.git] / src / util.c
1 /* GOB C Preprocessor
2  * Copyright (C) 1999-2000 the Free Software Foundation.
3  * Copyright (C) 2000 Eazel, Inc.
4  *
5  * Author: George Lebl
6  *
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.
11  *
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.
16  *
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,
20  * USA.
21  */
22
23 #include "config.h"
24 #include <string.h>
25 #include <stdio.h>
26 #include <glib.h>
27
28 #include "treefuncs.h"
29 #include "main.h"
30
31 #include "util.h"
32
33 void
34 print_error(gboolean is_warn, char *error, int line)
35 {
36         char *w;
37         if(is_warn)
38                 w = "Warning:";
39         else {
40                 w = "Error:";
41                 got_error = TRUE;
42         }
43         if(line>0)
44                 fprintf(stderr, "%s:%d: %s %s\n", filename, line, w, error);
45         else
46                 fprintf(stderr, "%s: %s %s\n", filename, w, error);
47         if((!is_warn || exit_on_warn) && exit_on_error)
48                 exit(1);
49 }
50
51 char *
52 remove_sep(char *base)
53 {
54         char *p;
55         char *s = g_strdup(base);
56         while((p = strchr(s, ':')))
57                 strcpy(p,p+1);
58         return s;
59 }
60
61 char *
62 replace_sep(const char *base, char r)
63 {
64         char *p;
65         char *s = g_strdup(base);
66         while((p=strchr(s,':')))
67                 *p = r;
68         if(*s == r) {
69                 p = g_strdup(s+1);
70                 g_free(s);
71                 return p;
72         }
73         return s;
74 }
75
76 /*separate the namespace part and then replace rest of
77   separators with r*/
78 void
79 separns_replace_sep(const char *base, char **ns, char **name, char r)
80 {
81         char *p;
82         char *s = g_strdup(base);
83         *ns = NULL;
84         if((p=strchr(s,':')) && p!=s) {
85                 *p = '\0';
86                 *ns = g_strdup(s);
87                 p = g_strdup(p+1);
88                 g_free(s);
89                 s = p;
90         }
91         while((p=strchr(s,':')))
92                 *p = r;
93         if(*s == r) {
94                 *name = g_strdup(s+1);
95                 g_free(s);
96         } else
97                 *name = s;
98 }
99
100 /* make a macro with some prefix before the name but after
101    namespace */
102 char *
103 make_pre_macro(const char *base, const char *pre)
104 {
105         char *ns, *name;
106         char *s;
107         char **v = NULL;
108
109         if(strchr(base, ' ')) {
110                 int i;
111                 v = g_strsplit(base, " ", 0);
112                 for(i = 0; v[i] != NULL; i++) {
113                         if(*v[i] && strcmp(v[i], "const") != 0) {
114                                 base = v[i];
115                                 break;
116                         }
117                 }
118         }
119
120         separns_replace_sep(base, &ns, &name, '_');
121         if(ns)
122                 s = g_strconcat(ns, "_", pre, "_", name,NULL);
123         else
124                 s = g_strconcat(pre, "_", name, NULL);
125
126         g_strup(s);
127         
128         g_free(ns);
129         g_free(name);
130
131         g_strfreev(v);
132
133         return s;
134 }
135
136 /* here we will find out how inconsistent gtk really is :) */
137 /* the commented out types mean that these types don't actually
138    exist. so we "emulate them" with an equivalent */
139 typedef struct _OurGtkType OurGtkType;
140 struct _OurGtkType {
141         gboolean simple;
142         char *gtkname;
143         char *typename;
144         int special;
145 };
146 const OurGtkType our_gtk_type_table[] = {
147         { TRUE, "NONE",         "void ", -1 },
148         { TRUE, "CHAR",         "gchar ", -1 },
149         { TRUE, "UCHAR",        "guchar ", -1 },
150         { TRUE, "BOOL",         "gboolean ", -1 },
151         { TRUE, "INT",          "gint ", -1 },
152         { TRUE, "UINT",         "guint ", -1 },
153         { TRUE, "LONG",         "glong ", -1 },
154         { TRUE, "ULONG",        "gulong ", -1 },
155         { TRUE, "FLOAT",        "gfloat ", -1 },
156         { TRUE, "DOUBLE",       "gdouble ", -1 },
157         { TRUE, "STRING",       /*"GtkString"*/"gchar *", -1 },
158         { TRUE, "ENUM",         /*"GtkEnum"*/"gint ", -1 },
159         { TRUE, "FLAGS",        /*"GtkFlags"*/"guint ", -1 },
160         { TRUE, "BOXED",        /*"GtkBoxed"*/"gpointer ", -1 },
161         { TRUE, "POINTER",      "gpointer ", -1 },
162         { TRUE, "OBJECT",       "GtkObject *", -1 },
163         { FALSE, "SIGNAL",      /*"GtkSignal"*/"___twopointertype ",
164                 SPECIAL_2POINTER },
165         { FALSE, "ARGS",        /*"GtkArgs"*/"___intpointertype ",
166                 SPECIAL_INT_POINTER },
167         { FALSE, "CALLBACK",    /*"GtkCallback"*/"___threepointertype ",
168                 SPECIAL_3POINTER },
169         { FALSE, "C_CALLBACK",  /*"GtkCCallback"*/"___twopointertype ",
170                 SPECIAL_2POINTER },
171         { FALSE, "FOREIGN",     /*"GtkForeign"*/"___twopointertype ",
172                 SPECIAL_2POINTER },
173
174         { FALSE, NULL, NULL }
175 };
176
177 static GHashTable *type_hash = NULL;
178
179 static void
180 init_type_hash(void)
181 {
182         int i;
183
184         if(type_hash) return;
185
186         type_hash = g_hash_table_new(g_str_hash, g_str_equal);
187
188         for(i=0; our_gtk_type_table[i].gtkname; i++)
189                 g_hash_table_insert(type_hash,
190                                     our_gtk_type_table[i].gtkname,
191                                     (gpointer)&our_gtk_type_table[i]);
192 }
193
194 const char *
195 get_cast(char *type, gboolean simple_only)
196 {
197         OurGtkType *gtype;
198
199         init_type_hash();
200
201         gtype = g_hash_table_lookup(type_hash, type);
202
203         if(!gtype ||
204            (simple_only &&
205             !gtype->simple))
206                 return NULL;
207
208         return gtype->typename;
209 }
210
211 static void
212 mask_special_array(char *type, gboolean *special_array, gboolean *any_special)
213 {
214         OurGtkType *gtype;
215
216         init_type_hash();
217
218         gtype = g_hash_table_lookup(type_hash, type);
219
220         if(gtype && gtype->special >= 0) {
221                 special_array[gtype->special] = TRUE;
222                 *any_special = TRUE;
223         }
224 }
225
226 gboolean
227 setup_special_array(Class *c, gboolean *special_array)
228 {
229         GList *li;
230         gboolean any_special = FALSE;
231
232         memset(special_array, 0, sizeof(gboolean)*SPECIAL_LAST);
233
234         for(li=c->nodes; li; li=g_list_next(li)) {
235                 Node *n = li->data;
236                 if(n->type == METHOD_NODE) {
237                         Method *m = (Method *)n;
238                         GList *l;
239                         if(m->method != SIGNAL_LAST_METHOD &&
240                            m->method != SIGNAL_FIRST_METHOD)
241                                 continue;
242
243                         for(l=m->gtktypes; l; l=l->next)
244                                 mask_special_array(l->data, special_array,
245                                                    &any_special);
246                 } else if(n->type == ARGUMENT_NODE) {
247                         Argument *a = (Argument *)n;
248                         mask_special_array(a->gtktype, special_array,
249                                            &any_special);
250                 }
251         }
252
253         return any_special;
254 }
255
256 /* get the id without the first underscore, but only if we're removing them */
257 char *
258 get_real_id(char *id)
259 {
260         if(!no_kill_underscores &&
261            id[0] == '_' &&
262            id[1] != '\0')
263                 return &id[1];
264         else
265                 return id;
266 }