]> git.draconx.ca Git - gob-dx.git/blobdiff - src/util.c
Release 2.0.13
[gob-dx.git] / src / util.c
index a6cff4e8bfa8f5baeaf3f98ba1f03fd34e6bf47f..4d424402cfd651ef259f60408e37f580ed7f505f 100644 (file)
@@ -1,5 +1,6 @@
 /* GOB C Preprocessor
  * Copyright (C) 1999-2000 the Free Software Foundation.
+ * Copyright (C) 2000 Eazel, Inc.
  *
  * Author: George Lebl
  *
  */
 
 #include "config.h"
+#include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <glib.h>
 
-#include "tree.h"
+#include "treefuncs.h"
 #include "main.h"
 
 #include "util.h"
 
 void
-print_error(gboolean is_warn, char *error, int line)
+error_print(int type, int line, const char *error)
 {
-       char *w;
-       if(is_warn)
+       const char *w = NULL;
+       const char *fname = NULL;
+
+       switch(type) {
+       case GOB_WARN:
                w = "Warning:";
-       else {
+               if (exit_on_warn)
+                       got_error = TRUE;
+               break;
+       case GOB_ERROR:
                w = "Error:";
                got_error = TRUE;
+               break;
+       default:
+               g_assert_not_reached();
        }
-       if(line>0)
-               fprintf(stderr, "%s:%d: %s %s\n", filename, line, w, error);
+       fname = filename;
+       if (fname == NULL)
+               fname = "gob2";
+       if (line > 0)
+               fprintf(stderr, "%s:%d: %s %s\n", fname, line, w, error);
        else
-               fprintf(stderr, "%s: %s %s\n", filename, w, error);
-       if((!is_warn || exit_on_warn) && exit_on_error)
+               fprintf(stderr, "%s: %s %s\n", fname, w, error);
+       if (exit_on_error && got_error)
                exit(1);
 }
 
+void
+error_printf(int type, int line, const char *error, ...)
+{
+       va_list ap;
+       char *s;
+
+       va_start(ap, error);
+       s = g_strdup_vprintf(error, ap);
+       va_end(ap);
+
+       error_print(type, line, s);
+
+       g_free(s);
+}
+
 char *
-remove_sep(char *base)
+remove_sep(const char *base)
 {
        char *p;
        char *s = g_strdup(base);
-       while((p=strchr(s,':')))
-               strcpy(p,p+1);
+
+       /* don't eat C++ :: thingies */
+       if (for_cpp && strstr (s, "::") != NULL)
+               return s;
+
+       while((p = strchr(s, ':')))
+               strcpy(p, p+1);
        return s;
 }
 
 char *
-replace_sep(char *base, char r)
+replace_sep(const char *base, char r)
 {
        char *p;
        char *s = g_strdup(base);
-       while((p=strchr(s,':')))
-               *p = r;
+
+       /* don't eat C++ :: thingies */
+       if (for_cpp && strstr (s, "::") != NULL)
+               return s;
+
+       if (r == '\0') {
+               while ((p=strchr(s,':')) != NULL) {
+                       char *t = p;
+                       while (*t != '\0') {
+                               *t = *(t+1);
+                               t++;
+                       }
+               }
+       } else {
+               while ((p=strchr(s,':')) != NULL)
+                       *p = r;
+       }
        if(*s == r) {
                p = g_strdup(s+1);
                g_free(s);
@@ -75,11 +124,19 @@ replace_sep(char *base, char r)
 /*separate the namespace part and then replace rest of
   separators with r*/
 void
-separns_replace_sep(char *base, char **ns, char **name, char r)
+separns_replace_sep(const char *base, char **ns, char **name, char r)
 {
        char *p;
        char *s = g_strdup(base);
+
        *ns = NULL;
+       
+       /* don't eat C++ :: thingies */
+       if (for_cpp && strstr (s, "::") != NULL) {
+               *name = s;
+               return;
+       }
+
        if((p=strchr(s,':')) && p!=s) {
                *p = '\0';
                *ns = g_strdup(s);
@@ -99,21 +156,35 @@ separns_replace_sep(char *base, char **ns, char **name, char r)
 /* make a macro with some prefix before the name but after
    namespace */
 char *
-make_pre_macro(char *base, char *pre)
+make_pre_macro(const char *base, const char *pre)
 {
-       char *s1,*s2;
+       char *ns, *name;
        char *s;
+       char **v = NULL;
+
+       if(strchr(base, ' ')) {
+               int i;
+               v = g_strsplit(base, " ", 0);
+               for(i = 0; v[i] != NULL; i++) {
+                       if(*v[i] && strcmp(v[i], "const") != 0) {
+                               base = v[i];
+                               break;
+                       }
+               }
+       }
 
-       separns_replace_sep(base,&s1,&s2,'_');
-       if(s1)
-               s = g_strconcat(s1,"_",pre,"_",s2,NULL);
+       separns_replace_sep(base, &ns, &name, '_');
+       if(ns)
+               s = g_strconcat(ns, "_", pre, "_", name,NULL);
        else
-               s = g_strconcat(pre,"_",s2,NULL);
+               s = g_strconcat(pre, "_", name, NULL);
 
-       g_strup(s);
+       gob_strup (s);
        
-       g_free(s1);
-       g_free(s2);
+       g_free(ns);
+       g_free(name);
+
+       g_strfreev(v);
 
        return s;
 }
@@ -125,26 +196,39 @@ typedef struct _OurGtkType OurGtkType;
 struct _OurGtkType {
        gboolean simple;
        char *gtkname;
-       char *typename;
+       char *cast;
+       char *type_name;
+       char *type_pointer;
        int special;
 };
 const OurGtkType our_gtk_type_table[] = {
-       { TRUE, "NONE",         "void ", -1 },
-       { TRUE, "CHAR",         "gchar ", -1 },
-       { TRUE, "UCHAR",        "guchar ", -1 },
-       { TRUE, "BOOL",         "gboolean ", -1 },
-       { TRUE, "INT",          "gint ", -1 },
-       { TRUE, "UINT",         "guint ", -1 },
-       { TRUE, "LONG",         "glong ", -1 },
-       { TRUE, "ULONG",        "gulong ", -1 },
-       { TRUE, "FLOAT",        "gfloat ", -1 },
-       { TRUE, "DOUBLE",       "gdouble ", -1 },
-       { TRUE, "STRING",       /*"GtkString"*/"gchar *", -1 },
-       { TRUE, "ENUM",         /*"GtkEnum"*/"gint ", -1 },
-       { TRUE, "FLAGS",        /*"GtkFlags"*/"guint ", -1 },
-       { TRUE, "BOXED",        /*"GtkBoxed"*/"gpointer ", -1 },
-       { TRUE, "POINTER",      "gpointer ", -1 },
-       { TRUE, "OBJECT",       "GtkObject *", -1 },
+       { TRUE, "NONE",         "void ",        "void",         NULL,   -1 },
+       { TRUE, "CHAR",         "gchar ",       "gchar",        NULL,   -1 },
+       { TRUE, "UCHAR",        "guchar ",      "guchar",       NULL,   -1 },
+       { TRUE, "UNICHAR",      "gunichar ",    "gunichar",     NULL,   -1 },
+       { TRUE, "BOOLEAN",      "gboolean ",    "gboolean",     NULL,   -1 },
+       { TRUE, "INT",          "gint ",        "gint",         NULL,   -1 },
+       { TRUE, "UINT",         "guint ",       "guint",        NULL,   -1 },
+       { TRUE, "LONG",         "glong ",       "glong",        NULL,   -1 },
+       { TRUE, "ULONG",        "gulong ",      "gulong",       NULL,   -1 },
+       { TRUE, "INT64",        "gint64 ",      "gint64",       NULL,   -1 },
+       { TRUE, "UINT64",       "guint64 ",     "guint64",      NULL,   -1 },
+       { TRUE, "ENUM",         /*"enum"*/"gint ", "gint",      NULL,   -1 },
+       { TRUE, "FLAGS",        /*"flags"*/"guint ", "guint",   NULL,   -1 },
+       { TRUE, "FLOAT",        "gfloat ",      "gfloat",       NULL,   -1 },
+       { TRUE, "DOUBLE",       "gdouble ",     "gdouble",      NULL,   -1 },
+       { TRUE, "STRING",       /*"string"*/"gchar *", "gchar", "*",    -1 },
+       { TRUE, "POINTER",      "gpointer ",    "gpointer",     NULL,   -1 },
+       { TRUE, "BOXED",        /*"boxed"*/"gpointer ", "gpointer", NULL, -1 },
+       { TRUE, "OBJECT",       "GObject *",    "GObject",      "*",    -1 },
+       { TRUE, "PARAM",        "GParamSpec *", "GParamSpec",   "*",    -1 },
+
+       /* FIXME: VALUE_ARRAY, CLOSURE */
+       /* Note that those have some issues with g_value_ calls etc... so
+        * we can't just add them */
+
+       /* Do we need this??? */
+#if 0
        { FALSE, "SIGNAL",      /*"GtkSignal"*/"___twopointertype ",
                SPECIAL_2POINTER },
        { FALSE, "ARGS",        /*"GtkArgs"*/"___intpointertype ",
@@ -155,6 +239,7 @@ const OurGtkType our_gtk_type_table[] = {
                SPECIAL_2POINTER },
        { FALSE, "FOREIGN",     /*"GtkForeign"*/"___twopointertype ",
                SPECIAL_2POINTER },
+#endif
 
        { FALSE, NULL, NULL }
 };
@@ -177,24 +262,50 @@ init_type_hash(void)
 }
 
 const char *
-get_cast(char *type, gboolean simple_only)
+get_cast (const char *type, gboolean simple_only)
 {
        OurGtkType *gtype;
 
-       init_type_hash();
+       init_type_hash ();
 
-       gtype = g_hash_table_lookup(type_hash, type);
+       if(strncmp(type, "BOXED_", 6) == 0)      
+         gtype = g_hash_table_lookup (type_hash, "BOXED");
+       else
+         gtype = g_hash_table_lookup (type_hash, type);
+
+       if (gtype == NULL ||
+           (simple_only &&
+            ! gtype->simple))
+               return NULL;
+
+       return gtype->cast;
+}
 
-       if(!gtype ||
-          (simple_only &&
-           !gtype->simple))
+Type *
+get_tree_type (const char *type, gboolean simple_only)
+{
+       OurGtkType *gtype;
+       Node *node;
+
+       init_type_hash ();
+
+       gtype = g_hash_table_lookup (type_hash, type);
+
+       if (gtype == NULL ||
+           (simple_only &&
+            ! gtype->simple))
                return NULL;
 
-       return gtype->typename;
+       node = node_new (TYPE_NODE,
+                        "name", gtype->type_name,
+                        "pointer", gtype->type_pointer,
+                        NULL);
+
+       return (Type *)node;
 }
 
 static void
-mask_special_array(char *type, gboolean *special_array, gboolean *any_special)
+mask_special_array (const char *type, gboolean *special_array, gboolean *any_special)
 {
        OurGtkType *gtype;
 
@@ -237,3 +348,72 @@ setup_special_array(Class *c, gboolean *special_array)
 
        return any_special;
 }
+
+char *
+get_type (const Type *t, gboolean postfix_to_stars)
+{
+       char *s;
+       int i;
+       int extra;
+       GString *gs;
+
+       s = remove_sep(t->name);
+       gs = g_string_new(s);
+       g_free(s);
+
+       extra = 0;
+       if (postfix_to_stars) {
+               const char *p;
+               /*XXX: this is ugly perhaps we can do this whole postfix thing
+                 in a nicer way, we just count the number of '[' s and from
+                 that we deduce the number of dimensions, so that we can print
+                 that many stars */
+               for (p = t->postfix; p && *p; p++)
+                       if(*p == '[') extra++;
+       }
+       g_string_append_c(gs, ' ');
+
+       if (t->pointer != NULL) {
+               g_string_append (gs, t->pointer);
+               for (i=0; i < extra; i++)
+                       g_string_append_c (gs, '*');
+               g_string_append_c (gs, ' ');
+       }
+       
+       return g_string_free (gs, FALSE);
+}
+
+char *
+gob_strup (char *str)
+{
+       char *s;
+       for (s = str; *s; s++)
+               *s = g_ascii_toupper (*s);
+
+       return str;
+}
+
+char *
+gob_strdown (char *str)
+{
+       char *s;
+       for (s = str; *s; s++)
+               *s = g_ascii_tolower (*s);
+
+       return str;
+}
+
+char *
+make_me_type (const char *type, const char *alt)
+{
+       if (type == NULL)
+               return g_strdup (alt);
+       /* HACK!  just in case someone made this
+        * work with 2.0.0 by using the TYPE
+        * macro directly */
+       if ((strstr (type, "_TYPE_") != NULL ||
+            strstr (type, "TYPE_") == type) &&
+           strchr (type, ':') == NULL)
+               return g_strdup (type);
+       return make_pre_macro (type, "TYPE");
+}