]> git.draconx.ca Git - gob-dx.git/blobdiff - src/main.c
Release 2.0.13
[gob-dx.git] / src / main.c
index a353061207aca83f582af43990a7ea5db4715280..186ac59cd794a3828e0a2a968fea8dfed9c1ae17 100644 (file)
@@ -25,6 +25,7 @@
 #include <glib.h>
 #include <time.h>
 #include <stdio.h>
+#include <errno.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -54,6 +55,9 @@ extern GHashTable *gtk_doc_hash;
 
 char *filebase;
 char *fullfilebase;
+static char *outfilebase;
+static char *outfilehbase;
+static char *outfilephbase;
 static char *funcbase;
 static char *pfuncbase;
 static char *macrobase;
@@ -99,6 +103,7 @@ FILE *outh = NULL;
 FILE *outph = NULL;
 FILE *devnull = NULL;
 
+gboolean no_touch = FALSE;
 gboolean no_touch_headers = FALSE;
 gboolean for_cpp = FALSE;
 gboolean no_gnu = FALSE;
@@ -737,6 +742,8 @@ print_signal_marsal_args (const Method *m)
                        if (strcmp (li->data, "UNICHAR") == 0)
                                /* hack because glib is braindamaged */
                                get_func = g_strdup ("g_value_get_uint");
+                       else if (strncmp(li->data, "BOXED_", 6) == 0)
+                               get_func = g_strdup ("g_value_get_boxed");
                        else
                                get_func = g_strdup_printf
                                        ("g_value_get_%s", (char *)li->data);
@@ -1081,8 +1088,8 @@ add_get_type(void)
        add_interface_infos ();
 
        out_printf (out,
-                   "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)0);\n",
-                   pmacrotype, typebase);
+                   "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
+                   pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
 
        add_interfaces ();
 
@@ -1308,9 +1315,16 @@ add_signals(Class *c)
                
                if( ! is_none) {
                        GList *l;
-                       for(l = m->gtktypes->next; l != NULL; l = l->next)
-                               out_printf(out, ",\n\t\t\tG_TYPE_%s",
-                                       (char *)l->data);
+                       char  *t;
+                       for(l = m->gtktypes->next; l != NULL; l = l->next) {
+                               char *str = l->data;
+                               if (strncmp (str, "BOXED_", 6) == 0)
+                                       t = g_strdup (&(str[6]));
+                               else
+                                       t = g_strconcat ("G_TYPE_", str, NULL);
+                               out_printf (out, ",\n\t\t\t%s", t);
+                               g_free (t);
+                       }
                }
 
                out_printf(out, ");\n");
@@ -2001,6 +2015,9 @@ static void
 print_initializer(Method *m, Variable *v)
 {
        char *root;
+       
+       if(v->glade_widget)
+               return;
 
        if(v->initializer == NULL)
                return;
@@ -2017,6 +2034,8 @@ print_initializer(Method *m, Variable *v)
        if (v->initializer_simple)
                out_printf(out, "\t%s->%s = %s;\n",
                   root, v->id, v->initializer);
+       else if (!strcmp(v->id, "_glade_xml"))
+               out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
        else
                out_printf(out,v->initializer);
 
@@ -2712,12 +2731,15 @@ put_signal_args (Method *m)
             li != NULL && ali != NULL;
             li = li->next, ali = ali->next, i++) {
                FuncArg *fa = li->data;
-               char *cast = g_strdup (get_cast (ali->data, FALSE));
+               char *str = ali->data;
+               char *cast = g_strdup (get_cast (str, FALSE));
                /* FIXME: This code is so fucking ugly it hurts */
                gboolean do_static = 
-                       (strcmp ((char *)ali->data, "STRING") == 0 ||
-                        strcmp ((char *)ali->data, "BOXED") == 0);
+                       (strcmp  (str, "STRING") == 0 ||
+                        strcmp  (str, "BOXED") == 0 ||
+                        strncmp (str, "BOXED_", 6) == 0);
                char *set_func;
+               char *t;
 
                if (cast == NULL) {
                        cast = get_type (fa->atype, TRUE);
@@ -2726,18 +2748,26 @@ put_signal_args (Method *m)
                   the we know all the types */
                g_assert (cast != NULL);
 
+               if (strncmp (str, "BOXED_", 6) == 0)
+                       t = g_strdup (&(str[6]));
+               else
+                       t = g_strconcat ("G_TYPE_", str, NULL);
+
                out_printf (out,
                            "\t___param_values[%d].g_type = 0;\n"
-                           "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
-                           i, i, (char *)ali->data);
+                           "\tg_value_init (&___param_values[%d], %s);\n",
+                           i, i, t);
+               g_free (t);
 
-               if (strcmp (ali->data, "UNICHAR") == 0)
+               if (strcmp (str, "UNICHAR") == 0)
                        /* hack because glib is braindamaged */
                        set_func = g_strdup ("g_value_set_uint");
+               else if (strncmp (str, "BOXED_", 6) == 0)
+                       set_func = g_strdup ("g_value_set_static_boxed");
                else
                        set_func = g_strdup_printf ("g_value_set%s_%s",
                                                    do_static ? "_static" : "",
-                                                   (char *)ali->data);
+                                                   str);
                gob_strdown (set_func);
 
                out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
@@ -3045,14 +3075,11 @@ open_files(void)
 {
        char *outfile, *outfileh, *outfileph;
 
-       if ( ! for_cpp)
-               outfile = g_strconcat (fullfilebase, ".c", NULL);
-       else
-               outfile = g_strconcat (fullfilebase, ".cc", NULL);
-       if (no_touch_headers)
-               outfileh = g_strconcat (fullfilebase, ".h#gob#", NULL);
-       else
-               outfileh = g_strconcat (fullfilebase, ".h", NULL);
+       outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
+       outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
+
+       outfilehbase = g_strconcat (fullfilebase, ".h");
+       outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
 
        if ((privates > 0 || protecteds > 0 ||
             private_header == PRIVATE_HEADER_ALWAYS) &&
@@ -3060,8 +3087,10 @@ open_files(void)
                char sep[2] = {0,0};
                if (file_sep != 0)
                        sep[0] = file_sep;
-               outfileph = g_strconcat (fullfilebase, sep, "private.h", NULL);
+               outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
+               outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
        } else {
+               outfilephbase = NULL;
                outfileph = NULL;
        }
 
@@ -3675,16 +3704,13 @@ print_more_useful_macros (void)
 static void
 print_file_comments(void)
 {
-       time_t curtime;
-       time(&curtime);
        out_printf(outh, "/* Generated by GOB (v%s)"
                   "   (do not edit directly) */\n\n", VERSION);
        if(outph)
                out_printf(outph, "/* Generated by GOB (v%s)"
                           "   (do not edit directly) */\n\n", VERSION);
-       out_printf(out, "/* Generated by GOB (v%s) on %s"
-                  "   (do not edit directly) */\n\n",
-                  VERSION, ctime(&curtime));
+       out_printf(out, "/* Generated by GOB (v%s)"
+                  "   (do not edit directly) */\n\n", VERSION);
 
        out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
 }
@@ -4075,6 +4101,9 @@ print_help(void)
                "\t--no-extern-c           Never print extern \"C\" into the "
                                          "header\n"
                "\t--no-gnu                Never use GNU extentions\n"
+               "\t--no-touch              Don't touch output files unless they "
+                                         "really\n"
+               "\t                        changed (implies --no-touch-headers)\n"
                "\t--no-touch-headers      Don't touch headers unless they "
                                          "really changed\n"
                "\t--always-private-header Always create a private header "
@@ -4172,6 +4201,9 @@ parse_options(int argc, char *argv[])
                        exit_on_warn = FALSE;
                } else if(strcmp(argv[i], "--for-cpp")==0) {
                        for_cpp = TRUE;
+               } else if(strcmp(argv[i], "--no-touch")==0) {
+                       no_touch = TRUE;
+                       no_touch_headers = TRUE;
                } else if(strcmp(argv[i], "--no-touch-headers")==0) {
                        no_touch_headers = TRUE;
                } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
@@ -4283,35 +4315,79 @@ parse_options(int argc, char *argv[])
 #endif
 }
 
-/* this is a somewhat ugly hack, but it appears to work */
 static void
-compare_and_move_header(void)
+compare_and_move (const char *old_filename)
 {
-       char *hfnew = g_strconcat(fullfilebase, ".h#gob#", NULL);
-       char *hf = g_strconcat(fullfilebase, ".h", NULL);
-       struct stat s;
-       if(stat(hf, &s) == 0) {
-               char *s;
-               s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
-               if(system(s) == 0) {
-                       if(unlink(hfnew) != 0)
-                               error_printf(GOB_ERROR, 0,
-                                            "Can't remove new header file");
-                       g_free(hfnew);
-                       g_free(hf);
-                       g_free(s);
-                       return;
+       char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
+       FILE *old_f;
+       gboolean equal = FALSE;
+
+       old_f = fopen (old_filename, "r");
+       if (old_f) {
+               FILE *new_f;
+               gboolean error = FALSE;
+
+               new_f = fopen (new_filename, "r");
+               if (new_f) {
+                       char new_buf[1024];
+                       char old_buf[1024];
+
+                       while (TRUE) {
+                               size_t new_n;
+                               size_t old_n;
+
+                               new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
+                               if (ferror (new_f)) {
+                                       error = TRUE;
+                                       error_printf (GOB_ERROR, 0,
+                                                     "Can't read %s: %s",
+                                                     new_filename,
+                                                     g_strerror (errno));
+                                       break;
+                               }
+
+                               old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
+                               if (ferror (old_f)
+                                   || feof (new_f) != feof (old_f)
+                                   || new_n != old_n
+                                   || memcmp (new_buf, old_buf, new_n) != 0)
+                                       break;
+
+                               if (feof (new_f)) {
+                                       equal = TRUE;
+                                       break;
+                               }
+                       }
+               } else
+                       error_printf (GOB_ERROR, 0, "Can't open %s: %s",
+                                     new_filename, g_strerror (errno));
+
+               fclose (old_f);
+               fclose (new_f);
+
+               if (error)
+                       goto end;
+
+               if (! equal && unlink (old_filename) != 0) {
+                       error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
+                                     old_filename, g_strerror (errno));
+                       goto end;
                }
-               g_free(s);
-               if(unlink(hf) != 0)
-                       error_printf(GOB_ERROR, 0,
-                                    "Can't remove old header file");
        }
-       if(rename(hfnew, hf) != 0)
-               error_printf(GOB_ERROR, 0,
-                            "Can't rename new header file");
-       g_free(hfnew);
-       g_free(hf);
+
+       if (equal) {
+               if (unlink (new_filename) != 0)
+                       error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
+                                     new_filename, g_strerror (errno));
+       } else {
+               if (rename (new_filename, old_filename) != 0)
+                       error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
+                                     new_filename, old_filename,
+                                     g_strerror (errno));
+       }
+
+ end:
+       g_free (new_filename);
 }
 
 int
@@ -4413,9 +4489,15 @@ main(int argc, char *argv[])
                        fclose (outph);
        }
 
-       if (no_touch_headers &&
-           ! no_write)
-               compare_and_move_header ();
+       if (! no_write) {
+               if (no_touch) {
+                       compare_and_move (outfilebase);
+                       if (outfilephbase)
+                               compare_and_move (outfilephbase);
+               }
+               if (no_touch_headers)
+                       compare_and_move (outfilehbase);
+       }
        
        return 0;
 }