[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: branch: master updated (1.1.2.20070818-139-ga146b68)



The branch, master has been updated
       via  a146b68dfbffe227f3ab89af2beefb7627e26daa (commit)
       via  405e7a33706d1e82d53c8d607aad11f9be8ad559 (commit)
       via  22b3fde6c98fc0219e54bf7edfcd8dcb33c5fe92 (commit)
       via  668ada22ec0f2a48adffcc62daacc6876108ee71 (commit)
       via  c8a8611f87b3031e5fe1abb1a8602401ed459c97 (commit)
       via  e0dda20b072897d6c00fddeddf729cab283a2810 (commit)
       via  b635ebb641383360e5e7864830d42d13cf7f4d12 (commit)
       via  be301530f468e4d0057b3be68e218ac444c2d2be (commit)
       via  9998632193573058a18c9dc96c7e9a3b1aa0dcc3 (commit)
       via  2d60c8fd165dbfd577199c2237d44e33655eb8c1 (commit)
       via  3dc89aa9635b6eac150e837f24b51811c7504e88 (commit)
      from  53cbd813e6d601f86618aa083d656d7aeccb7705 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 gattrib/src/s_toplevel.c      |   10 ++-
 gnetlist/src/gnetlist.c       |    7 +-
 gschem/include/prototype.h    |    4 +-
 gschem/include/x_log.h        |    1 -
 gschem/src/o_undo.c           |    2 +-
 gschem/src/x_log.c            |   65 +++++++++++--
 gschem/src/x_preview.c        |    2 +-
 gschem/src/x_window.c         |   20 ++++-
 gsymcheck/include/prototype.h |    3 +-
 gsymcheck/src/globals.c       |    3 +-
 gsymcheck/src/gsymcheck.c     |   36 +++-----
 libgeda/include/defines.h     |   21 +----
 libgeda/include/prototype.h   |    9 +-
 libgeda/src/a_basic.c         |   45 ++++-----
 libgeda/src/f_basic.c         |  202 ++++++++++++++++++++++++++++-------------
 libgeda/src/o_attrib.c        |    2 +-
 libgeda/src/o_basic.c         |    9 +-
 libgeda/src/o_complex_basic.c |   29 ++----
 libgeda/src/o_text_basic.c    |   21 ++++-
 libgeda/src/s_hierarchy.c     |    8 +-
 libgeda/src/s_log.c           |   15 ++-
 libgeda/src/s_page.c          |   11 +--
 libgeda/src/s_textbuffer.c    |    3 +-
 libgeda/src/s_toplevel.c      |    5 +-
 libgeda/src/u_basic.c         |    3 +-
 utils/gschlas/gschlas.c       |   29 +++----
 26 files changed, 342 insertions(+), 223 deletions(-)


=================
 Commit Messages
=================

commit a146b68dfbffe227f3ab89af2beefb7627e26daa
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Sat Dec 8 14:57:33 2007 +0000

    libgeda: Clean g_assert() usage.
    
    g_assert() is a heavy-handed approach to sanity checking because it
    kills the user application on failure.  It's better to use
    less-destructive methods.

:100644 100644 f796f82... 6bfa546... M	libgeda/src/a_basic.c
:100644 100644 b8ea3f0... 077c8c5... M	libgeda/src/o_attrib.c
:100644 100644 aaafc3a... 513d0a9... M	libgeda/src/o_basic.c
:100644 100644 d1d841f... 2d25300... M	libgeda/src/o_complex_basic.c
:100644 100644 d3d2ceb... 36dcea1... M	libgeda/src/o_text_basic.c
:100644 100644 5ce865e... dccb806... M	libgeda/src/s_textbuffer.c
:100644 100644 e97a298... 75101c6... M	libgeda/src/s_toplevel.c
:100644 100644 2a80673... 743a3fa... M	libgeda/src/u_basic.c

commit 405e7a33706d1e82d53c8d607aad11f9be8ad559
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:43 2007 +0000

    General log handler improvements
    
    - Handle all messages above "debug" level
    - Send all messages which are neither "message" nor "warning" levels
      to console using default log handler
    - Don't print to console from the gschem log handler

:100644 100644 350fef1... ba72022... M	gschem/src/x_log.c
:100644 100644 7297b3c... 401080b... M	libgeda/src/s_log.c

commit 22b3fde6c98fc0219e54bf7edfcd8dcb33c5fe92
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:18 2007 +0000

    gschem: Show log in pretty colours.

:100644 100644 e5fa5de... fb2fd4b... M	gschem/include/x_log.h
:100644 100644 ac5362c... 350fef1... M	gschem/src/x_log.c

commit 668ada22ec0f2a48adffcc62daacc6876108ee71
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:17 2007 +0000

    Pass all log info to x_log_update_func
    
    In order to enable applications to do interesting things with log
    messages, they need to have all of the log info (including severity
    and log domain).

:100644 100644 4fbf87b... 1f54e69... M	gschem/include/prototype.h
:100644 100644 2c6ac85... ac5362c... M	gschem/src/x_log.c
:100644 100644 03d5ea0... 1e675e3... M	gsymcheck/include/prototype.h
:100644 100644 7236d9e... 1baeaf7... M	gsymcheck/src/globals.c
:100644 100644 45c5b1d... 7297b3c... M	libgeda/src/s_log.c

commit c8a8611f87b3031e5fe1abb1a8602401ed459c97
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Thu Nov 29 16:55:39 2007 +0000

    libgeda: define s_log_message -> g_message
    
    s_log_message was a verbatim copy of the definition of the g_message
    macro from GLib's gmessages.h.  However, we're actually always going
    to include that header anyway -- this patch removes the unnecessary
    duplication of code.

:100644 100644 d127c36... 873346d... M	libgeda/include/defines.h

commit e0dda20b072897d6c00fddeddf729cab283a2810
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:17 2007 +0000

    gschem: Show an informative message dialog when loading a file fails.

:100644 100644 471de9e... b2c4079... M	gschem/src/x_window.c

commit b635ebb641383360e5e7864830d42d13cf7f4d12
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:17 2007 +0000

    Print useful messages when f_open() fails.
    
    This reinstates error messages removed by the patch which modified
    f_open() to use GError for error reporting.

:100644 100644 3bfac8c... ca3177e... M	gattrib/src/s_toplevel.c
:100644 100644 febb220... 5adc653... M	gnetlist/src/gnetlist.c
:100644 100644 6669d09... 7ddc4e2... M	gsymcheck/src/gsymcheck.c
:100644 100644 4af2e91... 6b553ac... M	utils/gschlas/gschlas.c

commit be301530f468e4d0057b3be68e218ac444c2d2be
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 17:20:55 2007 +0000

    Make libgeda's f_open() & f_open_flags use GError.
    
    This patch actually *removes* error message output from file loading
    errors is some cases.  This is for the sake of keeping the patch
    concise, and will be addressed in later patches.

:100644 100644 fdf2023... 3bfac8c... M	gattrib/src/s_toplevel.c
:100644 100644 b992fd4... febb220... M	gnetlist/src/gnetlist.c
:100644 100644 1d9ab68... 307d6a1... M	gschem/src/o_undo.c
:100644 100644 086dd48... e8b23c5... M	gschem/src/x_preview.c
:100644 100644 b77fc11... 471de9e... M	gschem/src/x_window.c
:100644 100644 e7c76f7... 6669d09... M	gsymcheck/src/gsymcheck.c
:100644 100644 f91eace... 44cb601... M	libgeda/include/prototype.h
:100644 100644 412a6e4... 6ba69e6... M	libgeda/src/f_basic.c
:100644 100644 49d4e84... b7295e5... M	libgeda/src/s_hierarchy.c
:100644 100644 03184c0... 4af2e91... M	utils/gschlas/gschlas.c

commit 9998632193573058a18c9dc96c7e9a3b1aa0dcc3
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 17:19:57 2007 +0000

    libgeda: Make o_read() use GError.

:100644 100644 01f184a... f91eace... M	libgeda/include/prototype.h
:100644 100644 f802ed2... f796f82... M	libgeda/src/a_basic.c
:100644 100644 a2a4e91... 412a6e4... M	libgeda/src/f_basic.c
:100644 100644 77a33db... d3d2ceb... M	libgeda/src/o_text_basic.c

commit 2d60c8fd165dbfd577199c2237d44e33655eb8c1
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Thu Dec 6 21:08:32 2007 +0000

    libgeda: Add f_has_active_autosave()
    
    Add a helper function for checking if a file has an unresolved
    autosave file.

:100644 100644 52579f1... 01f184a... M	libgeda/include/prototype.h
:100644 100644 9844005... a2a4e91... M	libgeda/src/f_basic.c

commit 3dc89aa9635b6eac150e837f24b51811c7504e88
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Tue Dec 4 23:00:35 2007 +0000

    libgeda: Add f_get_autosave_filename()
    
    Add helper function for getting the autosave filename for a given file.

:100644 100644 6e21ef1... 52579f1... M	libgeda/include/prototype.h
:100644 100644 d4de2a7... 9844005... M	libgeda/src/f_basic.c
:100644 100644 bf22f76... 89ce467... M	libgeda/src/s_page.c

=========
 Changes
=========

commit a146b68dfbffe227f3ab89af2beefb7627e26daa
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Sat Dec 8 14:57:33 2007 +0000

    libgeda: Clean g_assert() usage.
    
    g_assert() is a heavy-handed approach to sanity checking because it
    kills the user application on failure.  It's better to use
    less-destructive methods.

diff --git a/libgeda/src/a_basic.c b/libgeda/src/a_basic.c
index f796f82..6bfa546 100644
--- a/libgeda/src/a_basic.c
+++ b/libgeda/src/a_basic.c
@@ -105,7 +105,7 @@ gchar *o_save_objects (OBJECT *object_list)
   GString *acc;
   gboolean already_wrote = FALSE;
 
-  g_assert (object_list != NULL);
+  g_return_val_if_fail ((object_list != NULL), NULL);
 
   acc = g_string_new("");
 
@@ -175,10 +175,15 @@ gchar *o_save_objects (OBJECT *object_list)
 	    break;
 
           default:
-            g_assert_not_reached();
-            fprintf(stderr, "Error type!\n");
-            exit(-1);
-            break;
+            /*! \todo Maybe we can continue instead of just failing
+             *  completely? In any case, failing gracefully is better
+             *  than killing the program, which is what this used to
+             *  do... */
+            g_critical ("o_save_objects: object %p has unknown type '%c'\n",
+                        o_current, o_current->type);
+            /* Dump string built so far */
+            g_string_free (acc, TRUE);
+            return NULL;
         }
 
         /* output the line */
@@ -273,13 +278,9 @@ OBJECT *o_read_buffer(TOPLEVEL *toplevel, OBJECT *object_list,
   /* fill version with default file format version (the current one) */
   current_fileformat_ver = FILEFORMAT_VERSION;
 
-  if (buffer == NULL) {
-    s_log_message("o_read_buffer: Received NULL buffer\n");
-    return(NULL);
-  }
+  g_return_val_if_fail ((buffer != NULL), NULL);
 
   tb = s_textbuffer_new (buffer, size);
-  g_assert (tb != NULL);
 
   while (1) {
 
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index b8ea3f0..077c8c5 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -326,7 +326,7 @@ void o_attrib_remove(GList **list, OBJECT *remove)
   GList *a_iter;
   ATTRIB *a_current;
 
-  g_assert (remove != NULL);
+  g_return_if_fail (remove != NULL);
 
   a_iter = *list;
   while (a_iter != NULL) {
diff --git a/libgeda/src/o_basic.c b/libgeda/src/o_basic.c
index aaafc3a..513d0a9 100644
--- a/libgeda/src/o_basic.c
+++ b/libgeda/src/o_basic.c
@@ -290,7 +290,8 @@ void o_translate_world (TOPLEVEL *toplevel, gint dx, gint dy, OBJECT *object)
       case OBJ_PIN:     func = o_pin_translate_world;     break;
       case OBJ_ARC:     func = o_arc_translate_world;     break;
       default:
-        g_assert_not_reached ();
+        g_critical ("o_translate_world: object %p has bad type '%c'\n",
+                    object, object->type);
   }
 
   if (func != NULL) {
@@ -328,7 +329,8 @@ void o_rotate_world (TOPLEVEL *toplevel, int world_centerx, int world_centery, i
       case OBJ_PIN:     func = o_pin_rotate_world;        break;
       case OBJ_ARC:     func = o_arc_rotate_world;        break;
       default:
-        g_assert_not_reached ();
+        g_critical ("o_translate_world: object %p has bad type '%c'\n",
+                    object, object->type);
   }
 
   if (func != NULL) {
@@ -365,7 +367,8 @@ void o_mirror_world (TOPLEVEL *toplevel, int world_centerx, int world_centery, O
       case OBJ_PIN:     func = o_pin_mirror_world;        break;
       case OBJ_ARC:     func = o_arc_mirror_world;        break;
       default:
-        g_assert_not_reached ();
+        g_critical ("o_translate_world: object %p has bad type '%c'\n",
+                    object, object->type);
   }
 
   if (func != NULL) {
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index d1d841f..2d25300 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -782,23 +782,12 @@ char *o_complex_save(OBJECT *object)
     basename = g_strdup_printf ("%s%s",
 				object->complex_embedded ? "EMBEDDED" : "",
 				object->complex_basename);
-    switch (object->type) {
-    case OBJ_COMPLEX:
-      buf = g_strdup_printf("%c %d %d %d %d %d %s", object->type,
-			    object->complex->x, object->complex->y, 
-			    selectable, object->complex->angle, 
-			    object->complex->mirror, basename);
-      break;
-    case OBJ_PLACEHOLDER:
-      /* write 'C' manually */
-      buf = g_strdup_printf("C %d %d %d %d %d %s",
-			    object->complex->x, object->complex->y, 
-			    selectable, object->complex->angle, 
-			    object->complex->mirror, basename);
-      break;
-    default:
-      g_assert_not_reached();
-    }
+    /* We force the object type to be output as OBJ_COMPLEX for both
+     * these object types. */
+    buf = g_strdup_printf("%c %d %d %d %d %d %s", OBJ_COMPLEX,
+                          object->complex->x, object->complex->y,
+                          selectable, object->complex->angle,
+                          object->complex->mirror, basename);
     g_free (basename);
   }
 
@@ -1254,9 +1243,9 @@ void o_complex_rotate_world(TOPLEVEL *toplevel,
   int x, y;
   int newx, newy;
 
-  g_assert(object != NULL);
-  g_assert(((object->type == OBJ_COMPLEX) ||
-            (object->type == OBJ_PLACEHOLDER)));
+  g_return_if_fail (object!=NULL);
+  g_return_if_fail ((object->type == OBJ_COMPLEX) ||
+                    (object->type == OBJ_PLACEHOLDER));
 
   x = object->complex->x + (-centerx);
   y = object->complex->y + (-centery);
diff --git a/libgeda/src/o_text_basic.c b/libgeda/src/o_text_basic.c
index d3d2ceb..36dcea1 100644
--- a/libgeda/src/o_text_basic.c
+++ b/libgeda/src/o_text_basic.c
@@ -1193,7 +1193,12 @@ void o_text_set_info_font(char buf[])
   buf_ptr = (gchar*)string;
   /*   - type */
   type = *buf_ptr++;
-  g_assert (type == INFO_FONT);
+  if (type != INFO_FONT) {
+    g_critical ("o_text_set_info_font: Bad font type '%c', expected '%c'\n",
+                type, INFO_FONT);
+    return;
+  }
+
   while (buf_ptr != NULL && *buf_ptr == ' ') buf_ptr++;
   /*   - character */
   if (buf_ptr != NULL && *buf_ptr != '\0') {
@@ -1770,8 +1775,8 @@ void o_text_rotate_world(TOPLEVEL *toplevel,
   int x, y;
   int newx, newy;
 
-  g_assert(object != NULL);
-  g_assert(object->type == OBJ_TEXT);
+  g_return_if_fail(object != NULL);
+  g_return_if_fail(object->type == OBJ_TEXT);
 
   object->text->angle = ( object->text->angle + angle ) % 360;
 
diff --git a/libgeda/src/s_textbuffer.c b/libgeda/src/s_textbuffer.c
index 5ce865e..dccb806 100644
--- a/libgeda/src/s_textbuffer.c
+++ b/libgeda/src/s_textbuffer.c
@@ -73,7 +73,8 @@ TextBuffer *s_textbuffer_new (gchar *data, const gint size)
   TextBuffer *result;
   gsize realsize;
 
-  g_assert (data != NULL);
+  g_return_val_if_fail ((data != NULL),
+                        NULL);
 
   if (size < 0)
     realsize = strlen(data);
diff --git a/libgeda/src/s_toplevel.c b/libgeda/src/s_toplevel.c
index e97a298..75101c6 100644
--- a/libgeda/src/s_toplevel.c
+++ b/libgeda/src/s_toplevel.c
@@ -181,9 +181,8 @@ TOPLEVEL *s_toplevel_new (void)
 void s_toplevel_delete (TOPLEVEL *toplevel)
 {
   if (toplevel->auto_save_timeout != 0) {
-    gboolean ret;
-    ret = g_source_remove (toplevel->auto_save_timeout);
-    g_assert (ret);
+    /* Assume this works */
+    g_source_remove (toplevel->auto_save_timeout);
   }
 
   g_free (toplevel->internal_symbol_name);
diff --git a/libgeda/src/u_basic.c b/libgeda/src/u_basic.c
index 2a80673..743a3fa 100644
--- a/libgeda/src/u_basic.c
+++ b/libgeda/src/u_basic.c
@@ -58,7 +58,8 @@ char *u_basic_breakup_string(char *string, char delimiter, int count)
   int done=FALSE;
   char *return_value;
 
-  g_assert(string != NULL);
+  g_return_val_if_fail ((string != NULL),
+                        NULL);
 
   /* skip over any leading white space */
   while(string[i] == ' ' && !string[i]) {

commit 405e7a33706d1e82d53c8d607aad11f9be8ad559
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:43 2007 +0000

    General log handler improvements
    
    - Handle all messages above "debug" level
    - Send all messages which are neither "message" nor "warning" levels
      to console using default log handler
    - Don't print to console from the gschem log handler

diff --git a/gschem/src/x_log.c b/gschem/src/x_log.c
index 350fef1..ba72022 100644
--- a/gschem/src/x_log.c
+++ b/gschem/src/x_log.c
@@ -134,8 +134,6 @@ void x_log_message (const gchar *log_domain, GLogLevelFlags log_level,
   g_return_if_fail (log_dialog != NULL);
 
   if (log_level & (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR)) {
-    /* Print to console too */
-    g_log_default_handler (log_domain, log_level, message, NULL);
     style = "critical";
   } else if (log_level & G_LOG_LEVEL_WARNING) {
     style = "warning";
diff --git a/libgeda/src/s_log.c b/libgeda/src/s_log.c
index 7297b3c..401080b 100644
--- a/libgeda/src/s_log.c
+++ b/libgeda/src/s_log.c
@@ -56,6 +56,10 @@
 #include <dmalloc.h>
 #endif
 
+#define CATCH_LOG_LEVELS (G_LOG_LEVEL_MASK ^ \
+                          (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO))
+#define PRINT_LOG_LEVELS (CATCH_LOG_LEVELS ^ \
+                          (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE))
 
 static void s_log_handler (const gchar *log_domain,
                            GLogLevelFlags log_level,
@@ -90,7 +94,7 @@ void s_log_init (const gchar *filename)
 
   /* install the log handler */
   log_handler_id = g_log_set_handler (NULL,
-                                      G_LOG_LEVEL_MESSAGE,
+                                      CATCH_LOG_LEVELS,
                                       s_log_handler,
                                       NULL);
 
@@ -187,8 +191,11 @@ static void s_log_handler (const gchar *log_domain,
   status = write (logfile_fd, message, strlen (message));
   if (status == -1) {
     fprintf(stderr, "Could not write message to log file\n");
-    fprintf(stderr, "Message was: %s\n", message);
-    fprintf(stderr, "Errno was: %d\n", errno);
+  }
+  if ((status == -1) || (log_level & PRINT_LOG_LEVELS)) {
+    /* If messages are serious or writing to file failed, call the
+     * default handler to write to the console. */
+    g_log_default_handler (log_domain, log_level, message, NULL);
   }
 
   if (x_log_update_func) {

commit 22b3fde6c98fc0219e54bf7edfcd8dcb33c5fe92
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:18 2007 +0000

    gschem: Show log in pretty colours.

diff --git a/gschem/include/x_log.h b/gschem/include/x_log.h
index e5fa5de..fb2fd4b 100644
--- a/gschem/include/x_log.h
+++ b/gschem/include/x_log.h
@@ -50,4 +50,3 @@ struct _Log {
 
 GType log_get_type (void);
 
-void log_message (Log *log, const gchar *message);
diff --git a/gschem/src/x_log.c b/gschem/src/x_log.c
index ac5362c..350fef1 100644
--- a/gschem/src/x_log.c
+++ b/gschem/src/x_log.c
@@ -51,6 +51,12 @@
 static void x_log_callback_response (GtkDialog *dialog,
                                      gint arg1,
                                      gpointer user_data);
+static void log_message (Log *log, 
+                         const gchar *message, 
+                         const gchar *style);
+
+static void log_class_init (LogClass *class);
+static void log_init       (Log *log);
 
 static GtkWidget *log_dialog = NULL;
 
@@ -85,7 +91,7 @@ void x_log_open ()
       return;
     }
 
-    log_message (LOG (log_dialog), contents);
+    log_message (LOG (log_dialog), contents, "old");
     g_free (contents);
 
     x_log_update_func = x_log_message;
@@ -124,11 +130,20 @@ void x_log_close ()
 void x_log_message (const gchar *log_domain, GLogLevelFlags log_level,
                     const gchar *message)
 {
+  gchar *style;
   g_return_if_fail (log_dialog != NULL);
-  
-  g_assert (IS_LOG (log_dialog));
-  log_message ((Log*)log_dialog, message);
-    
+
+  if (log_level & (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR)) {
+    /* Print to console too */
+    g_log_default_handler (log_domain, log_level, message, NULL);
+    style = "critical";
+  } else if (log_level & G_LOG_LEVEL_WARNING) {
+    style = "warning";
+  } else {
+    style = "message";
+  }
+
+  log_message (LOG(log_dialog), message, style);
 }
 
 /*! \todo Finish function documentation!!!
@@ -152,15 +167,13 @@ static void x_log_callback_response (GtkDialog *dialog,
   
 }
 
-static void log_class_init (LogClass *class);
-static void log_init       (Log *log);
-
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
  * 
  */
-void log_message (Log *log, const gchar *message)
+static void log_message (Log *log, const gchar *message, 
+                         const gchar *style)
 {
   GtkTextBuffer *buffer;
   GtkTextIter iter;
@@ -170,7 +183,10 @@ void log_message (Log *log, const gchar *message)
 
   buffer = gtk_text_view_get_buffer (log->textview);
   gtk_text_buffer_get_end_iter (buffer, &iter);
-  gtk_text_buffer_insert(buffer, &iter, message, -1);
+  /* Apply the "plain" tag before the level-specific tag in order to
+   * reset the formatting */
+  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, message, -1, 
+                                            "plain", style, NULL);
 
   mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE);
   gtk_text_view_scroll_to_mark (log->textview, mark, 0, TRUE, 0, 1);
@@ -258,6 +274,34 @@ static void log_init (Log *log)
   /* create the text buffer */
   text_buffer = GTK_TEXT_BUFFER (g_object_new (GTK_TYPE_TEXT_BUFFER,
                                                NULL));
+
+  /* Add some tags for highlighting log messages to the buffer */
+  gtk_text_buffer_create_tag (text_buffer, "plain",
+                              "foreground", "black",
+                              "foreground-set", TRUE,
+                              "weight", PANGO_WEIGHT_NORMAL,
+                              "weight-set", TRUE,
+                              NULL);
+  /* The default "message" style is plain */
+  gtk_text_buffer_create_tag (text_buffer, "message", NULL);
+  /* "old" messages are in dark grey */
+  gtk_text_buffer_create_tag (text_buffer, "old",
+                              "foreground", "#404040",
+                              "foreground-set", TRUE,
+			      NULL);
+  /* "warning" messages are printed in red */
+  gtk_text_buffer_create_tag (text_buffer, "warning",
+                              "foreground", "red",
+                              "foreground-set", TRUE,
+                              NULL);
+  /* "critical" messages are bold red */
+  gtk_text_buffer_create_tag (text_buffer, "critical",
+                              "foreground", "red",
+                              "foreground-set", TRUE,
+                              "weight", PANGO_WEIGHT_BOLD,
+                              "weight-set", TRUE,
+                              NULL);
+
   /* create the text view and attach the buffer to it */
   text_view = GTK_WIDGET (g_object_new (GTK_TYPE_TEXT_VIEW,
                                         /* GtkTextView */

commit 668ada22ec0f2a48adffcc62daacc6876108ee71
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:17 2007 +0000

    Pass all log info to x_log_update_func
    
    In order to enable applications to do interesting things with log
    messages, they need to have all of the log info (including severity
    and log domain).

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 4fbf87b..1f54e69 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -799,7 +799,9 @@ GdkPixbuf *x_image_get_pixbuf (GSCHEM_TOPLEVEL *w_current);
 /* x_log.c */
 void x_log_open ();
 void x_log_close ();
-void x_log_message (const gchar *message);
+void x_log_message (const gchar *log_domain,
+                    GLogLevelFlags log_level,
+                    const gchar *message);
 /* x_menus.c */
 void get_main_menu(GtkWidget **menubar);
 GtkWidget *get_main_popup(GSCHEM_TOPLEVEL *w_current);
diff --git a/gschem/src/x_log.c b/gschem/src/x_log.c
index 2c6ac85..ac5362c 100644
--- a/gschem/src/x_log.c
+++ b/gschem/src/x_log.c
@@ -121,7 +121,8 @@ void x_log_close ()
  *  \par Function Description
  * 
  */
-void x_log_message (const gchar *message)
+void x_log_message (const gchar *log_domain, GLogLevelFlags log_level,
+                    const gchar *message)
 {
   g_return_if_fail (log_dialog != NULL);
   
diff --git a/gsymcheck/include/prototype.h b/gsymcheck/include/prototype.h
index 03d5ea0..1e675e3 100644
--- a/gsymcheck/include/prototype.h
+++ b/gsymcheck/include/prototype.h
@@ -4,7 +4,8 @@ SCM g_rc_gsymcheck_version(SCM version);
 void g_register_funcs(void);
 SCM g_quit(void);
 /* globals.c */
-void s_log_update(char *buf);
+void s_log_update(const gchar *log_domain, GLogLevelFlags log_level,
+                  const gchar *buf);
 /* gsymcheck.c */
 void gsymcheck_quit(void);
 void main_prog(void *closure, int argc, char *argv[]);
diff --git a/gsymcheck/src/globals.c b/gsymcheck/src/globals.c
index 7236d9e..1baeaf7 100644
--- a/gsymcheck/src/globals.c
+++ b/gsymcheck/src/globals.c
@@ -63,7 +63,8 @@ int verbose_mode=FALSE;
 int interactive_mode=FALSE;
 int quiet_mode=FALSE;
 
-void s_log_update(char *buf)
+void s_log_update(const gchar *log_domain, GLogLevelFlags log_level,
+                  const gchar *buf)
 {
   if (do_logging == FALSE) {
     return;
diff --git a/libgeda/src/s_log.c b/libgeda/src/s_log.c
index 45c5b1d..7297b3c 100644
--- a/libgeda/src/s_log.c
+++ b/libgeda/src/s_log.c
@@ -192,7 +192,7 @@ static void s_log_handler (const gchar *log_domain,
   }
 
   if (x_log_update_func) {
-    (*x_log_update_func) (message);
+    (*x_log_update_func) (log_domain, log_level, message);
   }
 
 }

commit c8a8611f87b3031e5fe1abb1a8602401ed459c97
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Thu Nov 29 16:55:39 2007 +0000

    libgeda: define s_log_message -> g_message
    
    s_log_message was a verbatim copy of the definition of the g_message
    macro from GLib's gmessages.h.  However, we're actually always going
    to include that header anyway -- this patch removes the unnecessary
    duplication of code.

diff --git a/libgeda/include/defines.h b/libgeda/include/defines.h
index d127c36..873346d 100644
--- a/libgeda/include/defines.h
+++ b/libgeda/include/defines.h
@@ -342,26 +342,7 @@
 #endif
 
 /* Logs a normal message. */
-/* inspired of GLib's g_message() (gmessages.h) - LGPL */
-#ifdef G_HAVE_ISO_VARARGS
-#define s_log_message(...)  g_log (G_LOG_DOMAIN,         \
-                                   G_LOG_LEVEL_MESSAGE,  \
-                                   __VA_ARGS__)
-#elif defined(G_HAVE_GNUC_VARARGS)
-#define s_log_message(format...)    g_log (G_LOG_DOMAIN,         \
-                                           G_LOG_LEVEL_MESSAGE,  \
-                                           format)
-#else   /* no varargs macros */
-static void
-s_log_message (const gchar *format,
-               ...)
-{
-  va_list args;
-  va_start (args, format);
-  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args);
-  va_end (args);
-}
-#endif  /* !__GNUC__ */
+#define s_log_message g_message
 
 /* Backup filename creation string */
 #define AUTOSAVE_BACKUP_FILENAME_STRING "#%s#"

commit e0dda20b072897d6c00fddeddf729cab283a2810
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:17 2007 +0000

    gschem: Show an informative message dialog when loading a file fails.

diff --git a/gschem/src/x_window.c b/gschem/src/x_window.c
index 471de9e..b2c4079 100644
--- a/gschem/src/x_window.c
+++ b/gschem/src/x_window.c
@@ -801,11 +801,27 @@ x_window_open_page (GSCHEM_TOPLEVEL *w_current, const gchar *filename)
 
   /* Load from file if necessary, otherwise just print a message */
   if (filename != NULL) {
+    GError *err = NULL;
     if (!quiet_mode)
       s_log_message (_("Loading schematic [%s]\n"), fn);
 
-    f_open (toplevel, (gchar *) fn, NULL);
-    recent_files_add (fn);
+    if (!f_open (toplevel, (gchar *) fn, &err)) {
+      GtkWidget *dialog;
+
+      g_warning ("%s\n", err->message);
+      dialog = gtk_message_dialog_new (GTK_WINDOW (w_current->main_window),
+                                       GTK_DIALOG_DESTROY_WITH_PARENT,
+                                       GTK_MESSAGE_ERROR,
+                                       GTK_BUTTONS_CLOSE,
+                                       "%s",
+                                       err->message);
+      gtk_window_set_title (GTK_WINDOW (dialog), _("Failed to load file"));
+      gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_widget_destroy (dialog);
+      g_error_free (err);
+    } else {
+      recent_files_add (fn);
+    }
   } else {
     if (!quiet_mode)
       s_log_message (_("New file [%s]\n"),

commit b635ebb641383360e5e7864830d42d13cf7f4d12
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 21:48:17 2007 +0000

    Print useful messages when f_open() fails.
    
    This reinstates error messages removed by the patch which modified
    f_open() to use GError for error reporting.

diff --git a/gattrib/src/s_toplevel.c b/gattrib/src/s_toplevel.c
index 3bfac8c..ca3177e 100644
--- a/gattrib/src/s_toplevel.c
+++ b/gattrib/src/s_toplevel.c
@@ -57,12 +57,20 @@
 int s_toplevel_read_page(char *filename)
 {
   int file_return_code;
+  GError *err = NULL;
     
   /* Set the new filename */
   pr_current->page_current->page_filename = g_strdup(filename);
   
   /* read in and fill out pr_current using f_open and its callees */
-  file_return_code = f_open(pr_current, filename, NULL);
+  file_return_code = f_open(pr_current, filename, &err);
+
+  /* If an error occurred, print message */
+  if (err != NULL) {
+    g_warning (err->message);
+    g_error_free (err);
+  }
+
   return file_return_code;
 }
 
diff --git a/gnetlist/src/gnetlist.c b/gnetlist/src/gnetlist.c
index febb220..5adc653 100644
--- a/gnetlist/src/gnetlist.c
+++ b/gnetlist/src/gnetlist.c
@@ -226,6 +226,7 @@ void main_prog(void *closure, int argc, char *argv[])
     i = argv_index;
     while (argv[i] != NULL) {
       gchar *filename; 
+      GError *err = NULL;
 
       if (g_path_is_absolute(argv[i]))
       {
@@ -243,7 +244,9 @@ void main_prog(void *closure, int argc, char *argv[])
       s_page_goto (pr_current, s_page_new (pr_current, filename));
       
       if (!f_open (pr_current, filename, NULL)) {
-        fprintf (stderr, "Couldn't load schematic [%s]\n", filename);
+        g_warning ("%s\n", err->message);
+        fprintf (stderr, "%s\n", err->message);
+        g_error_free (err);
       }
       
       i++;
diff --git a/gsymcheck/src/gsymcheck.c b/gsymcheck/src/gsymcheck.c
index 6669d09..7ddc4e2 100644
--- a/gsymcheck/src/gsymcheck.c
+++ b/gsymcheck/src/gsymcheck.c
@@ -50,9 +50,8 @@ main_prog(void *closure, int argc, char *argv[])
   int i;
   int argv_index;
   int exit_status;
-  int fopen_status;
   char *cwd;
-  struct stat buf;
+
   char *logfile;
   
   TOPLEVEL *pr_current;
@@ -106,6 +105,8 @@ main_prog(void *closure, int argc, char *argv[])
   while (argv[i] != NULL) {
 
     gchar *filename;
+    GError *err = NULL;
+
     if (g_path_is_absolute(argv[i]))
     {
       /* Path is already absolute so no need to do any concat of cwd */
@@ -114,29 +115,19 @@ main_prog(void *closure, int argc, char *argv[])
       filename = g_build_path (G_DIR_SEPARATOR_S, cwd, argv[i], NULL);
     }
 
-    if (stat(filename, &buf) != 0) {
+    s_page_goto (pr_current,
+                 s_page_new (pr_current, filename));
+
+    if (!f_open (pr_current,
+                 pr_current->page_current->page_filename,
+                 &err)) {
+      /* Not being able to load a file is apparently a fatal error */
       logging_dest = STDOUT_TTY;
-      s_log_message("Could not open [%s]\n", filename);
-      s_log_message("Exiting...\n");
-      exit(2); /* error */
+      g_warning ("%s\n", err->message);
+      g_error_free (err);
+      exit(2);
     } else {
-      if (verbose_mode) {
-        s_log_message("Loading file [%s]\n", filename);
-      }
-
-      s_page_goto (pr_current,
-                   s_page_new (pr_current, filename));
-      
-      fopen_status = f_open (pr_current, 
-                             pr_current->page_current->page_filename,
-                             NULL);
-
-      if (!fopen_status) {
-        s_log_message("gsymcheck: Could not load [%s]\n", 
-                      pr_current->page_current->page_filename);
-        s_log_message("Exiting...\n");
-        exit(2); /* error */
-      }
+      g_message ("Loaded file [%s]\n", filename);
     }
     i++;
     g_free (filename);
diff --git a/utils/gschlas/gschlas.c b/utils/gschlas/gschlas.c
index 4af2e91..6b553ac 100644
--- a/utils/gschlas/gschlas.c
+++ b/utils/gschlas/gschlas.c
@@ -106,6 +106,8 @@ main_prog(void *closure, int argc, char *argv[])
   while (argv[i] != NULL) {
 
     gchar *filename;
+    GError *err = NULL;
+
     if (g_path_is_absolute(argv[i]))
     {
       /* Path is already absolute so no need to do any concat of cwd */
@@ -114,25 +116,18 @@ main_prog(void *closure, int argc, char *argv[])
       filename = g_build_path (G_DIR_SEPARATOR_S, cwd, argv[i], NULL);
     }
 
-    if (stat(filename, &buf) != 0) {
-      s_log_message("Could not open [%s]\n", filename);
-      s_log_message("Exiting...\n");
-      exit(2); /* error */
+    if (!f_open (pr_current,
+                 pr_current->page_current->page_filename,
+                 &err)) {
+      /* Not being able to load a file is apparently a fatal error */
+      logging_dest = STDOUT_TTY;
+      g_warning ("%s\n", err->message);
+      g_error_free (err);
+      exit(2);
     } else {
-      if (verbose_mode) {
-        s_log_message("Loading file [%s]\n", filename);
-      }
-
-      s_page_goto (pr_current,
-                   s_page_new (pr_current, filename));
-      
-      if (!f_open(pr_current, filename, NULL)) {
-        s_log_message("gsymcheck: Could not load [%s]\n", filename);
-        s_log_message("Exiting...\n");
-        exit(2); // error
-      }
+      g_message ("Loaded file [%s]\n", filename);
     }
-    
+
     i++;
     g_free (filename);
   }

commit be301530f468e4d0057b3be68e218ac444c2d2be
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 17:20:55 2007 +0000

    Make libgeda's f_open() & f_open_flags use GError.
    
    This patch actually *removes* error message output from file loading
    errors is some cases.  This is for the sake of keeping the patch
    concise, and will be addressed in later patches.

diff --git a/gattrib/src/s_toplevel.c b/gattrib/src/s_toplevel.c
index fdf2023..3bfac8c 100644
--- a/gattrib/src/s_toplevel.c
+++ b/gattrib/src/s_toplevel.c
@@ -62,7 +62,7 @@ int s_toplevel_read_page(char *filename)
   pr_current->page_current->page_filename = g_strdup(filename);
   
   /* read in and fill out pr_current using f_open and its callees */
-  file_return_code = f_open(pr_current, filename);
+  file_return_code = f_open(pr_current, filename, NULL);
   return file_return_code;
 }
 
diff --git a/gnetlist/src/gnetlist.c b/gnetlist/src/gnetlist.c
index b992fd4..febb220 100644
--- a/gnetlist/src/gnetlist.c
+++ b/gnetlist/src/gnetlist.c
@@ -242,7 +242,7 @@ void main_prog(void *closure, int argc, char *argv[])
 
       s_page_goto (pr_current, s_page_new (pr_current, filename));
       
-      if (!f_open (pr_current, filename)) {
+      if (!f_open (pr_current, filename, NULL)) {
         fprintf (stderr, "Couldn't load schematic [%s]\n", filename);
       }
       
diff --git a/gschem/src/o_undo.c b/gschem/src/o_undo.c
index 1d9ab68..307d6a1 100644
--- a/gschem/src/o_undo.c
+++ b/gschem/src/o_undo.c
@@ -380,7 +380,7 @@ void o_undo_callback(GSCHEM_TOPLEVEL *w_current, int type)
 
   if (w_current->undo_type == UNDO_DISK && u_current->filename) {
 
-    f_open(toplevel, u_current->filename);
+    f_open(toplevel, u_current->filename, NULL);
 
     x_manual_resize(w_current);
     toplevel->page_current->page_control = u_current->page_control;
diff --git a/gschem/src/x_preview.c b/gschem/src/x_preview.c
index 086dd48..e8b23c5 100644
--- a/gschem/src/x_preview.c
+++ b/gschem/src/x_preview.c
@@ -247,7 +247,7 @@ preview_update (Preview *preview)
     if (preview->filename != NULL) {
       /* open up file in current page */
       f_open_flags (preview_toplevel, preview->filename,
-                    F_OPEN_RC | F_OPEN_RESTORE_CWD);
+                    F_OPEN_RC | F_OPEN_RESTORE_CWD, NULL);
       /* test value returned by f_open... - Fix me */
       /* we should display something if there an error occured - Fix me */
     }
diff --git a/gschem/src/x_window.c b/gschem/src/x_window.c
index b77fc11..471de9e 100644
--- a/gschem/src/x_window.c
+++ b/gschem/src/x_window.c
@@ -804,7 +804,7 @@ x_window_open_page (GSCHEM_TOPLEVEL *w_current, const gchar *filename)
     if (!quiet_mode)
       s_log_message (_("Loading schematic [%s]\n"), fn);
 
-    f_open (toplevel, (gchar *) fn);
+    f_open (toplevel, (gchar *) fn, NULL);
     recent_files_add (fn);
   } else {
     if (!quiet_mode)
diff --git a/gsymcheck/src/gsymcheck.c b/gsymcheck/src/gsymcheck.c
index e7c76f7..6669d09 100644
--- a/gsymcheck/src/gsymcheck.c
+++ b/gsymcheck/src/gsymcheck.c
@@ -128,7 +128,8 @@ main_prog(void *closure, int argc, char *argv[])
                    s_page_new (pr_current, filename));
       
       fopen_status = f_open (pr_current, 
-                             pr_current->page_current->page_filename);
+                             pr_current->page_current->page_filename,
+                             NULL);
 
       if (!fopen_status) {
         s_log_message("gsymcheck: Could not load [%s]\n", 
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index f91eace..44cb601 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -11,9 +11,9 @@ void o_scale(TOPLEVEL *toplevel, OBJECT *list, int x_scale, int y_scale);
 /* f_basic.c */
 gchar *f_get_autosave_filename (const gchar *filename);
 gboolean f_has_active_autosave (const gchar *filename, GError **err);
-int f_open(TOPLEVEL *toplevel, const gchar *filename);
+int f_open(TOPLEVEL *toplevel, const gchar *filename, GError **err);
 int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
-                 const gint flags);
+                 const gint flags, GError **err);
 void f_close(TOPLEVEL *toplevel);
 void f_save_close(TOPLEVEL *toplevel, char *filename);
 int f_save(TOPLEVEL *toplevel, const char *filename);
diff --git a/libgeda/src/f_basic.c b/libgeda/src/f_basic.c
index 412a6e4..6ba69e6 100644
--- a/libgeda/src/f_basic.c
+++ b/libgeda/src/f_basic.c
@@ -153,12 +153,15 @@ gboolean f_has_active_autosave (const gchar *filename, GError **err)
  *  \param [in,out] toplevel  The TOPLEVEL object to load the schematic into.
  *  \param [in]      filename  A character string containing the file name
  *                             to open.
+ *  \param [in,out] err  #GError structure for error reporting, or
+ *                       NULL to disable error reporting
+ *
  *  \return 0 on failure, 1 on success.
  */
-int f_open(TOPLEVEL *toplevel, const gchar *filename)
+int f_open(TOPLEVEL *toplevel, const gchar *filename, GError **err)
 {
   return f_open_flags (toplevel, filename,
-                       F_OPEN_RC | F_OPEN_CHECK_BACKUP);
+                       F_OPEN_RC | F_OPEN_CHECK_BACKUP, err);
 }
 
 /*! \brief Opens the schematic file with fine-grained control over behaviour.
@@ -175,10 +178,13 @@ int f_open(TOPLEVEL *toplevel, const gchar *filename)
  *  \param [in]     filename   A character string containing the file name
  *                             to open.
  *  \param [in]     flags      Combination of #FOpenFlags values.
+ *  \param [in,out] err  #GError structure for error reporting, or
+ *                       NULL to disable error reporting
+ *
  *  \return 0 on failure, 1 on success.
  */
 int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
-                 const gint flags)
+                 const gint flags, GError **err)
 {
   int opened=FALSE;
   char *full_filename = NULL;
@@ -187,7 +193,7 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
   char *saved_cwd = NULL;
   char *backup_filename = NULL;
   char load_backup_file = 0;
-  GError *err = NULL;
+  GError *tmp_err = NULL;
 
   /* has the head been freed yet? */
   /* probably not hack PAGE */
@@ -235,14 +241,14 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
   if (flags & F_OPEN_CHECK_BACKUP) {
     /* Check if there is a newer autosave backup file */
     GString *message;
-    gboolean active_backup = f_has_active_autosave (filename, &err);
+    gboolean active_backup = f_has_active_autosave (filename, &tmp_err);
     backup_filename = f_get_autosave_filename (filename);
 
-    if (err != NULL) g_warning ("%s\n", err->message);
+    if (tmp_err != NULL) g_warning ("%s\n", tmp_err->message);
     if (active_backup) {
       message = g_string_new ("");
       g_string_append_printf(message, "\nWARNING: Found an autosave backup file:\n  %s.\n\n", backup_filename);
-      if (err != NULL) {
+      if (tmp_err != NULL) {
         g_string_append(message, "I could not guess if it is newer, so you have to"
                         "do it manually.\n");
       } else {
@@ -262,7 +268,7 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
       }
       g_string_free (message, TRUE);
     }
-    if (err != NULL) g_error_free (err);
+    if (tmp_err != NULL) g_error_free (tmp_err);
   }
 
   /* Now that we have set the current directory and read
@@ -271,21 +277,18 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
     /* Load the backup file */
     toplevel->page_current->object_tail = (OBJECT *)
     o_read(toplevel, toplevel->page_current->object_tail,
-	   backup_filename, &err);
+	   backup_filename, err);
   } else {
     /* Load the original file */
     toplevel->page_current->object_tail = (OBJECT *)
     o_read(toplevel, toplevel->page_current->object_tail,
-	   full_filename, &err);
+	   full_filename, err);
   }
 
   if (toplevel->page_current->object_tail != NULL) {
-    s_log_message("Opened file [%s]\n", full_filename);
     opened = TRUE;
   } else {
     /* Failed to open page */
-    g_message ("f_open_flags: %s\n", err->message);
-    g_error_free (err);
     opened = FALSE;	 
   }
 
@@ -319,11 +322,7 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
     g_free(saved_cwd);
   }
 
-  if (!opened) {
-    return (FALSE);
-  } else {
-    return (TRUE);
-  }
+  return opened;
 }
 
 /*! \brief Closes the schematic file
diff --git a/libgeda/src/s_hierarchy.c b/libgeda/src/s_hierarchy.c
index 49d4e84..b7295e5 100644
--- a/libgeda/src/s_hierarchy.c
+++ b/libgeda/src/s_hierarchy.c
@@ -112,7 +112,7 @@ int s_hierarchy_down_schematic_single(TOPLEVEL *toplevel,
       found = s_page_new (toplevel, string);
       s_page_goto (toplevel, found);
       
-      f_open (toplevel, found->page_filename);
+      f_open (toplevel, found->page_filename, NULL);
     }
     break;
 
@@ -120,7 +120,7 @@ int s_hierarchy_down_schematic_single(TOPLEVEL *toplevel,
     {
       PAGE *page = s_page_new (toplevel, string);
       s_page_goto (toplevel, page);
-      f_open (toplevel, page->page_filename);
+      f_open (toplevel, page->page_filename, NULL);
     }
     break;
   }
@@ -173,7 +173,7 @@ void s_hierarchy_down_schematic_multiple (TOPLEVEL *toplevel,
       return;
     }
 
-    f_open(toplevel, toplevel->page_current->page_filename);
+    f_open(toplevel, toplevel->page_current->page_filename, NULL);
 
     if (loaded_schematics == 0) {
       page_control_counter++;
@@ -233,7 +233,7 @@ void s_hierarchy_down_symbol (TOPLEVEL *toplevel,
 
   s_page_goto (toplevel, page);
 
-  f_open(toplevel, page->page_filename);
+  f_open(toplevel, page->page_filename, NULL);
 
   page->up = parent->pid;
   page_control_counter++;
diff --git a/utils/gschlas/gschlas.c b/utils/gschlas/gschlas.c
index 03184c0..4af2e91 100644
--- a/utils/gschlas/gschlas.c
+++ b/utils/gschlas/gschlas.c
@@ -126,7 +126,7 @@ main_prog(void *closure, int argc, char *argv[])
       s_page_goto (pr_current,
                    s_page_new (pr_current, filename));
       
-      if (!f_open(pr_current, filename)) {
+      if (!f_open(pr_current, filename, NULL)) {
         s_log_message("gsymcheck: Could not load [%s]\n", filename);
         s_log_message("Exiting...\n");
         exit(2); // error

commit 9998632193573058a18c9dc96c7e9a3b1aa0dcc3
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Dec 7 17:19:57 2007 +0000

    libgeda: Make o_read() use GError.

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 01f184a..f91eace 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -5,7 +5,7 @@ const gchar *o_file_format_header();
 gchar *o_save_buffer(TOPLEVEL *toplevel);
 int o_save(TOPLEVEL *toplevel, const char *filename);
 OBJECT *o_read_buffer(TOPLEVEL *toplevel, OBJECT *object_list, char *buffer, const int size, const char *name);
-OBJECT *o_read(TOPLEVEL *toplevel, OBJECT *object_list, char *filename);
+OBJECT *o_read(TOPLEVEL *toplevel, OBJECT *object_list, char *filename, GError **err);
 void o_scale(TOPLEVEL *toplevel, OBJECT *list, int x_scale, int y_scale);
 
 /* f_basic.c */
diff --git a/libgeda/src/a_basic.c b/libgeda/src/a_basic.c
index f802ed2..f796f82 100644
--- a/libgeda/src/a_basic.c
+++ b/libgeda/src/a_basic.c
@@ -506,28 +506,24 @@ OBJECT *o_read_buffer(TOPLEVEL *toplevel, OBJECT *object_list,
  *  \param [in,out] toplevel    The current TOPLEVEL structure.
  *  \param [in]     object_list  The object_list to read data to.
  *  \param [in]     filename     The filename to read from.
+ *  \param [in,out] err          #GError structure for error reporting, or
+ *                               NULL to disable error reporting
  *  \return object_list if successful read, or NULL on error.
  */
-OBJECT *o_read(TOPLEVEL *toplevel, OBJECT *object_list, char *filename)
+OBJECT *o_read(TOPLEVEL *toplevel, OBJECT *object_list, char *filename,
+               GError **err)
 {
-  GError *err = NULL;
   char *buffer = NULL;
   size_t size;
   OBJECT *result = NULL;
 
-  g_file_get_contents(filename, &buffer, &size, &err);
+  /* Return NULL if error reporting is enabled and the return location
+   * for an error isn't NULL. */
+  g_return_val_if_fail (err == NULL || *err == NULL, NULL);
 
-  g_assert ((buffer == NULL && err != NULL) 
-	    || (buffer != NULL && err == NULL));
-
-  if (err != NULL)
-    {
-      /* Report error to user, and free error */
-      g_assert (buffer == NULL);
-      fprintf (stderr, "o_read: %s\n", err->message);
-      g_error_free (err);
-      return NULL;
-    } 
+  if (!g_file_get_contents(filename, &buffer, &size, err)) {
+    return NULL;
+  } 
 
   /* Parse file contents */
   g_assert (buffer != NULL);
diff --git a/libgeda/src/f_basic.c b/libgeda/src/f_basic.c
index a2a4e91..412a6e4 100644
--- a/libgeda/src/f_basic.c
+++ b/libgeda/src/f_basic.c
@@ -187,6 +187,7 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
   char *saved_cwd = NULL;
   char *backup_filename = NULL;
   char load_backup_file = 0;
+  GError *err = NULL;
 
   /* has the head been freed yet? */
   /* probably not hack PAGE */
@@ -234,7 +235,6 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
   if (flags & F_OPEN_CHECK_BACKUP) {
     /* Check if there is a newer autosave backup file */
     GString *message;
-    GError *err = NULL;
     gboolean active_backup = f_has_active_autosave (filename, &err);
     backup_filename = f_get_autosave_filename (filename);
 
@@ -271,12 +271,12 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
     /* Load the backup file */
     toplevel->page_current->object_tail = (OBJECT *)
     o_read(toplevel, toplevel->page_current->object_tail,
-	   backup_filename);
+	   backup_filename, &err);
   } else {
     /* Load the original file */
     toplevel->page_current->object_tail = (OBJECT *)
     o_read(toplevel, toplevel->page_current->object_tail,
-	   full_filename);
+	   full_filename, &err);
   }
 
   if (toplevel->page_current->object_tail != NULL) {
@@ -284,6 +284,8 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
     opened = TRUE;
   } else {
     /* Failed to open page */
+    g_message ("f_open_flags: %s\n", err->message);
+    g_error_free (err);
     opened = FALSE;	 
   }
 
diff --git a/libgeda/src/o_text_basic.c b/libgeda/src/o_text_basic.c
index 77a33db..d3d2ceb 100644
--- a/libgeda/src/o_text_basic.c
+++ b/libgeda/src/o_text_basic.c
@@ -156,6 +156,7 @@ OBJECT *o_text_load_font(TOPLEVEL *toplevel, gunichar needed_char)
   OBJECT *temp_parent, *o_font_set;
   int not_found = FALSE;
   gchar *aux_str2;
+  GError *err = NULL;
 
   /* retrieve the name of the file where the char is defined */
   aux_str2 = g_hash_table_lookup (font_char_to_file,
@@ -235,7 +236,14 @@ OBJECT *o_text_load_font(TOPLEVEL *toplevel, gunichar needed_char)
   toplevel->page_current->object_parent = o_font_set->font_prim_objs;
 
   o_font_set->font_prim_objs = o_read(toplevel, o_font_set->font_prim_objs,
-				      temp_string);
+				      temp_string, &err);
+  if (o_font_set->font_prim_objs == NULL) {
+    g_assert (err != NULL);
+    g_warning ("o_text_basic.c: Failed to read font file: %s\n",
+               err->message);
+    g_error_free (err);
+  }
+
   toplevel->page_current->object_parent = temp_parent;
 
   o_font_set->font_prim_objs = return_head(o_font_set->font_prim_objs);

commit 2d60c8fd165dbfd577199c2237d44e33655eb8c1
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Thu Dec 6 21:08:32 2007 +0000

    libgeda: Add f_has_active_autosave()
    
    Add a helper function for checking if a file has an unresolved
    autosave file.

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 52579f1..01f184a 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -1,3 +1,4 @@
+
 /* a_basic.c */
 gchar *o_save_objects(OBJECT *object_list);
 const gchar *o_file_format_header();
@@ -9,6 +10,7 @@ void o_scale(TOPLEVEL *toplevel, OBJECT *list, int x_scale, int y_scale);
 
 /* f_basic.c */
 gchar *f_get_autosave_filename (const gchar *filename);
+gboolean f_has_active_autosave (const gchar *filename, GError **err);
 int f_open(TOPLEVEL *toplevel, const gchar *filename);
 int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
                  const gint flags);
diff --git a/libgeda/src/f_basic.c b/libgeda/src/f_basic.c
index 9844005..a2a4e91 100644
--- a/libgeda/src/f_basic.c
+++ b/libgeda/src/f_basic.c
@@ -29,6 +29,9 @@
 #include <limits.h>
 #include <stdlib.h>
 #include <time.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -73,6 +76,75 @@ gchar *f_get_autosave_filename (const gchar *filename)
   return result;
 }
 
+/*! \brief Check if a file has an active autosave file
+ *  \par Function Description
+ *  Checks whether an autosave file exists for the \a filename passed
+ *  which has a modification time newer than the file itself.  If the
+ *  check fails, sets \a err with the reason.  N.b. if the autosave
+ *  file exists but it was not possible to get its modification time,
+ *  returns TRUE.
+ *
+ *  \param [in] filename File to check
+ *  \param [in,out] err  #GError structure for error reporting, or
+ *                       NULL to disable error reporting
+ *
+ *  \returns TRUE if autosave active, FALSE otherwise
+ */
+gboolean f_has_active_autosave (const gchar *filename, GError **err)
+{
+  gboolean result = FALSE;
+  gchar *auto_filename;
+  gint file_err = 0;
+  gint auto_err = 0;
+  GFileError g_errcode = 0;
+  struct stat file_stat, auto_stat;
+
+  auto_filename = f_get_autosave_filename (filename);
+  if (stat (filename, &file_stat) != 0) {
+    file_err = errno;
+  }
+  if (stat (auto_filename, &auto_stat) != 0) {
+    auto_err = errno;
+  }
+
+  /* A valid use of goto! (checks for raptors) */
+  if (auto_err & ENOENT) {
+    /* The autosave file does not exist. */
+    result = FALSE;
+    goto check_autosave_finish;
+  }
+  if (auto_err) {
+    g_errcode = g_file_error_from_errno (auto_err);
+    g_set_error (err, G_FILE_ERROR, g_errcode,
+                 "Failed to stat [%s]: %s",
+                 auto_filename, g_strerror (auto_err));
+    result = TRUE;
+    goto check_autosave_finish;
+  }
+  if (file_err & ENOENT) {
+    /* The autosave file exists, but the actual file does not. */
+    result = TRUE;
+    goto check_autosave_finish;
+  }
+  if (file_err) {
+    g_errcode = g_file_error_from_errno (file_err);
+    g_set_error (err, G_FILE_ERROR, g_errcode,
+                 "Failed to stat [%s]: %s",
+                 auto_filename, g_strerror (file_err));
+    result = TRUE;
+    goto check_autosave_finish;
+  }
+  /* If we got this far, both files exist and we have managed to get
+   * their stat info. */
+  if (difftime (file_stat.st_mtime, auto_stat.st_mtime) < 0) {
+    result = TRUE;
+  }
+
+ check_autosave_finish:
+  g_free (auto_filename);
+  return result;
+}
+
 /*! \brief Opens the schematic file.
  *  \par Function Description
  *  Opens the schematic file by calling f_open_flags() with the
@@ -161,57 +233,36 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
 
   if (flags & F_OPEN_CHECK_BACKUP) {
     /* Check if there is a newer autosave backup file */
-    backup_filename = f_get_autosave_filename (full_filename);
-
-    if ( g_file_test (backup_filename, G_FILE_TEST_EXISTS) && 
-         (! g_file_test (backup_filename, G_FILE_TEST_IS_DIR))) {
-      /* An autosave backup file exists. Check if it's newer */
-      struct stat stat_backup;
-      struct stat stat_file;
-      char error_stat = 0;
-      GString *message;
-    
-      if (stat (backup_filename, &stat_backup) != 0) {
-        s_log_message ("f_open: Unable to get stat information of backup file %s.", 
-                       backup_filename);
-        error_stat = 1 ;
-      }
-      if (stat (full_filename, &stat_file) != 0) {
-        s_log_message ("f_open: Unable to get stat information of file %s.", 
-                       full_filename);
-        error_stat = 1;
+    GString *message;
+    GError *err = NULL;
+    gboolean active_backup = f_has_active_autosave (filename, &err);
+    backup_filename = f_get_autosave_filename (filename);
+
+    if (err != NULL) g_warning ("%s\n", err->message);
+    if (active_backup) {
+      message = g_string_new ("");
+      g_string_append_printf(message, "\nWARNING: Found an autosave backup file:\n  %s.\n\n", backup_filename);
+      if (err != NULL) {
+        g_string_append(message, "I could not guess if it is newer, so you have to"
+                        "do it manually.\n");
+      } else {
+        g_string_append(message, "The backup copy is newer than the schematic, so it seems you should load it instead of the original file.\n");
       }
-      if ((difftime (stat_file.st_ctime, stat_backup.st_ctime) < 0) ||
-          (error_stat == 1))
-        {
-          /* Found an autosave backup. It's newer if error_stat is 0 */
-          message = g_string_new ("");
-          g_string_append_printf(message, "\nWARNING: Found an autosave backup file:\n  %s.\n\n", backup_filename);
-          if (error_stat == 1) {
-            g_string_append(message, "I could not guess if it is newer, so you have to"
-                            "do it manually.\n");
-          }
-          else {
-            g_string_append(message, "The backup copy is newer than the schematic, so it seems you should load it instead of the original file.\n");
-          }
-          g_string_append (message, "Gschem usually makes backup copies automatically, and this situation happens when it crashed or it was forced to exit abruptly.\n");
-          if (toplevel->page_current->load_newer_backup_func == NULL) {
-            s_log_message(message->str);
-            s_log_message("\nRun gschem and correct the situation.\n\n");
-            fprintf(stderr, message->str);
-            fprintf(stderr, "\nRun gschem and correct the situation.\n\n");
-          }
-          else {
-            /* Ask the user if load the backup or the original file */
-            if (toplevel->page_current->load_newer_backup_func
-                (toplevel, message)) {
-              /* Load the backup file */
-              load_backup_file = 1;
-            }
-          }
-          g_string_free (message, TRUE);
+      g_string_append (message, "Gschem usually makes backup copies automatically, and this situation happens when it crashed or it was forced to exit abruptly.\n");
+      if (toplevel->page_current->load_newer_backup_func == NULL) {
+        g_warning (message->str);
+        g_warning ("\nRun gschem and correct the situation.\n\n");
+      } else {
+        /* Ask the user if load the backup or the original file */
+        if (toplevel->page_current->load_newer_backup_func
+            (toplevel, message)) {
+          /* Load the backup file */
+          load_backup_file = 1;
         }
+      }
+      g_string_free (message, TRUE);
     }
+    if (err != NULL) g_error_free (err);
   }
 
   /* Now that we have set the current directory and read

commit 3dc89aa9635b6eac150e837f24b51811c7504e88
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Tue Dec 4 23:00:35 2007 +0000

    libgeda: Add f_get_autosave_filename()
    
    Add helper function for getting the autosave filename for a given file.

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 6e21ef1..52579f1 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -8,6 +8,7 @@ OBJECT *o_read(TOPLEVEL *toplevel, OBJECT *object_list, char *filename);
 void o_scale(TOPLEVEL *toplevel, OBJECT *list, int x_scale, int y_scale);
 
 /* f_basic.c */
+gchar *f_get_autosave_filename (const gchar *filename);
 int f_open(TOPLEVEL *toplevel, const gchar *filename);
 int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
                  const gint flags);
diff --git a/libgeda/src/f_basic.c b/libgeda/src/f_basic.c
index d4de2a7..9844005 100644
--- a/libgeda/src/f_basic.c
+++ b/libgeda/src/f_basic.c
@@ -48,6 +48,31 @@
 #include <dmalloc.h>
 #endif
 
+/*! \brief Get the autosave filename for a file
+ *  \par Function description
+ *  Returns the expected autosave filename for the \a filename passed.
+ *
+ *  \warning The result should be freed when no longer needed.
+ *
+ *  \param [in] filename The filename to create an autosave filename for.
+ *  \return A newly allocated string buffer.
+ */
+gchar *f_get_autosave_filename (const gchar *filename)
+{
+  gchar *result, *basename, *new_basename, *dirname;
+  basename = g_path_get_basename(filename);
+  dirname = g_path_get_dirname(filename);
+  new_basename = g_strdup_printf(AUTOSAVE_BACKUP_FILENAME_STRING,
+                                 basename);
+  result = g_build_filename(dirname, new_basename, NULL);
+
+  g_free(basename);
+  g_free(new_basename);
+  g_free(dirname);
+
+  return result;
+}
+
 /*! \brief Opens the schematic file.
  *  \par Function Description
  *  Opens the schematic file by calling f_open_flags() with the
@@ -132,14 +157,11 @@ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename,
     g_rc_parse_specified_rc(toplevel, full_rcfilename);
   }
 
+  g_free (file_directory);
+
   if (flags & F_OPEN_CHECK_BACKUP) {
     /* Check if there is a newer autosave backup file */
-    backup_filename 
-      = g_strdup_printf("%s%c"AUTOSAVE_BACKUP_FILENAME_STRING,
-                        file_directory, G_DIR_SEPARATOR, 
-                        g_path_get_basename(full_filename));
-
-    g_free (file_directory);
+    backup_filename = f_get_autosave_filename (full_filename);
 
     if ( g_file_test (backup_filename, G_FILE_TEST_EXISTS) && 
          (! g_file_test (backup_filename, G_FILE_TEST_IS_DIR))) {
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index bf22f76..89ce467 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -155,8 +155,6 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
   PAGE *tmp;
   gchar *backup_filename;
   gchar *real_filename;
-  gchar *only_filename;
-  gchar *dirname;
 
   /* we need to play with page_current because s_delete_list_fromstart() */
   /* make use of it (see s_tile_remove_object_all) */
@@ -177,12 +175,7 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
     fprintf (stderr, "s_page_delete: Can't get the real filename of %s.\n", page->page_filename);
   }
   else {
-    /* Get the directory in which the real filename lives */
-    dirname = g_path_get_dirname (real_filename);
-    only_filename = g_path_get_basename(real_filename);  
-    
-    backup_filename = g_strdup_printf("%s%c"AUTOSAVE_BACKUP_FILENAME_STRING,
-				      dirname, G_DIR_SEPARATOR, only_filename);
+    backup_filename = f_get_autosave_filename (real_filename);
 
     /* Delete the backup file */
     if ( (g_file_test (backup_filename, G_FILE_TEST_EXISTS)) && 
@@ -191,8 +184,6 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
       if (unlink(backup_filename) != 0) {
 	s_log_message("s_page_delete: Unable to delete backup file %s.", backup_filename);      }
     }
-    g_free (dirname);
-    g_free (only_filename);
     g_free (backup_filename);
   }
   g_free(real_filename);




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs