r15445 - gnucash/trunk - Add a few functions from GLib 2.8 in lib/glib28.

Andreas Köhler andi5 at cvs.gnucash.org
Sun Jan 28 00:13:55 EST 2007


Author: andi5
Date: 2007-01-28 00:13:54 -0500 (Sun, 28 Jan 2007)
New Revision: 15445
Trac: http://svn.gnucash.org/trac/changeset/15445

Added:
   gnucash/trunk/lib/glib28/
   gnucash/trunk/lib/glib28/Makefile.am
   gnucash/trunk/lib/glib28/dummy.c
   gnucash/trunk/lib/glib28/gfileutils-2.8.c
   gnucash/trunk/lib/glib28/gfileutils-2.8.h
   gnucash/trunk/lib/glib28/gstdio-2.8.h
   gnucash/trunk/lib/glib28/gwin32-2.8.c
   gnucash/trunk/lib/glib28/gwin32-2.8.h
Removed:
   gnucash/trunk/lib/glib26/
Modified:
   gnucash/trunk/configure.in
   gnucash/trunk/lib/Makefile.am
   gnucash/trunk/src/backend/file/gnc-backend-file.c
   gnucash/trunk/src/import-export/qif-import/druid-qif-import.c
Log:
Add a few functions from GLib 2.8 in lib/glib28.

Remove empty directory lib/glib26. Add lib/glib28 instead with the
necessary sources and headers to have the following functions even on a
GLib 2.6 system (!defined(HAVE_GLIB_2_8))
- g_access, g_chmod,
- g_file_set_contents,
- g_win32_locale_filename_from_utf8.
Make use of them, improving r15429 and r15430.


Modified: gnucash/trunk/configure.in
===================================================================
--- gnucash/trunk/configure.in	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/configure.in	2007-01-28 05:13:54 UTC (rev 15445)
@@ -193,6 +193,25 @@
   AC_MSG_ERROR([Cannot find glib. Check config.log])
 fi
 
+AC_MSG_CHECKING(for GLIB - version >= 2.8.0)
+if $PKG_CONFIG 'glib-2.0 >= 2.8.0'
+then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_GLIB_2_8,1,[System has glib 2.8.0 or better])
+  HAVE_GLIB_2_8=yes
+else
+  AC_MSG_RESULT(no)
+  if test "x${native_win32}" = "xyes"; then
+    AC_MSG_ERROR([*** GLIB >= 2.8 is required to build Gnucash on Windows.])
+  else
+    GLIB26_LIBS="$GLIB_LIBS"
+    GLIB_LIBS="\${top_builddir}/lib/glib28/libgnc-glib.la $GLIB_LIBS"
+    GLIB_CFLAGS="-I\${top_srcdir}/lib/glib28 $GLIB_CFLAGS"
+    AC_SUBST(GLIB26_LIBS)
+  fi
+fi
+AM_CONDITIONAL(HAVE_GLIB_2_8, test "x$HAVE_GLIB_2_8" = "xyes")
+
 AC_MSG_CHECKING(for GLIB - version >= 2.9.0)
 if $PKG_CONFIG 'glib-2.0 >= 2.9.0'
 then
@@ -2050,6 +2069,7 @@
           doc/examples/Makefile
           intl-scm/Makefile
           lib/Makefile
+          lib/glib28/Makefile
           lib/guile-www/Makefile
           lib/srfi/Makefile
           lib/libc/Makefile

Modified: gnucash/trunk/lib/Makefile.am
===================================================================
--- gnucash/trunk/lib/Makefile.am	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/lib/Makefile.am	2007-01-28 05:13:54 UTC (rev 15445)
@@ -1,5 +1,5 @@
-SUBDIRS = libc guile-www srfi
-DIST_SUBDIRS = libc guile-www srfi libgsf-1.12.3 goffice-0.0.4 libqof
+SUBDIRS = libc glib28 guile-www srfi
+DIST_SUBDIRS = libc glib28 guile-www srfi libgsf-1.12.3 goffice-0.0.4 libqof
 
 if !HAVE_GOFFICE
 if !HAVE_LIBGSF


Property changes on: gnucash/trunk/lib/glib28
___________________________________________________________________
Name: svn:ignore
   + *.lo
*.la
.deps
.libs
Makefile
Makefile.in
semantic.cache
TAGS


Added: gnucash/trunk/lib/glib28/Makefile.am
===================================================================
--- gnucash/trunk/lib/glib28/Makefile.am	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/lib/glib28/Makefile.am	2007-01-28 05:13:54 UTC (rev 15445)
@@ -0,0 +1,18 @@
+noinst_LTLIBRARIES = libgnc-glib.la
+
+DUMMYSRCS = dummy.c
+REALSRCS = gfileutils-2.8.c gwin32-2.8.c
+REALHDRS = gfileutils-2.8.h gstdio-2.8.h gwin32-2.8.h
+
+if HAVE_GLIB_2_8
+libgnc_glib_la_SOURCES = ${DUMMYSRCS}
+else
+libgnc_glib_la_SOURCES = ${REALSRCS}
+noinst_HEADERS = ${REALHDRS}
+endif
+
+libgnc_glib_la_LIBADD = ${GLIB26_LIBS}
+
+AM_CFLAGS = ${GLIB_CFLAGS}
+
+EXTRA_DIST = $(DUMMYSRCS) ${REALSRCS} $(REALHDRS)

Added: gnucash/trunk/lib/glib28/dummy.c
===================================================================
--- gnucash/trunk/lib/glib28/dummy.c	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/lib/glib28/dummy.c	2007-01-28 05:13:54 UTC (rev 15445)
@@ -0,0 +1,6 @@
+void g_my_dummy_function (void);
+
+void
+g_my_dummy_function (void)
+{
+}

Added: gnucash/trunk/lib/glib28/gfileutils-2.8.c
===================================================================
--- gnucash/trunk/lib/glib28/gfileutils-2.8.c	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/lib/glib28/gfileutils-2.8.c	2007-01-28 05:13:54 UTC (rev 15445)
@@ -0,0 +1,433 @@
+/* gfileutils.c - File utility functions
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+/* Contains all #includes, but otherwise only relevant differences between
+ * GLib 2.6 and GLib 2.8 */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifndef G_OS_WIN32
+#include <sys/wait.h>
+#endif
+#include <fcntl.h>
+#include <stdlib.h>
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <io.h>
+#endif /* G_OS_WIN32 */
+
+#ifndef S_ISLNK
+#define S_ISLNK(x) 0
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include <glib/gstdio.h>
+
+
+static gboolean
+rename_file (const char *old_name,
+	     const char *new_name,
+	     GError **err)
+{
+  errno = 0;
+  if (g_rename (old_name, new_name) == -1)
+    {
+      int save_errno = errno;
+      gchar *display_old_name = g_filename_display_name (old_name);
+      gchar *display_new_name = g_filename_display_name (new_name);
+
+      g_set_error (err,
+		   G_FILE_ERROR,
+		   g_file_error_from_errno (save_errno),
+		   "Failed to rename file '%s' to '%s': g_rename() failed: %s",
+		   display_old_name,
+		   display_new_name,
+		   g_strerror (save_errno));
+
+      g_free (display_old_name);
+      g_free (display_new_name);
+      
+      return FALSE;
+    }
+  
+  return TRUE;
+}
+
+static gboolean
+set_umask_permissions (int	     fd,
+		       GError      **err)
+{
+#ifdef G_OS_WIN32
+
+  return TRUE;
+
+#else
+  /* All of this function is just to work around the fact that
+   * there is no way to get the umask without changing it.
+   *
+   * We can't just change-and-reset the umask because that would
+   * lead to a race condition if another thread tried to change
+   * the umask in between the getting and the setting of the umask.
+   * So we have to do the whole thing in a child process.
+   */
+
+  int save_errno;
+  pid_t pid;
+
+  pid = fork ();
+  
+  if (pid == -1)
+    {
+      save_errno = errno;
+      g_set_error (err,
+		   G_FILE_ERROR,
+		   g_file_error_from_errno (save_errno),
+		   _("Could not change file mode: fork() failed: %s"),
+		   g_strerror (save_errno));
+      
+      return FALSE;
+    }
+  else if (pid == 0)
+    {
+      /* child */
+      mode_t mask = umask (0666);
+
+      errno = 0;
+      if (fchmod (fd, 0666 & ~mask) == -1)
+	_exit (errno);
+      else
+	_exit (0);
+
+      return TRUE; /* To quiet gcc */
+    }
+  else
+    { 
+      /* parent */
+      int status;
+
+      errno = 0;
+      if (waitpid (pid, &status, 0) == -1)
+	{
+	  save_errno = errno;
+
+	  g_set_error (err,
+		       G_FILE_ERROR,
+		       g_file_error_from_errno (save_errno),
+		       _("Could not change file mode: waitpid() failed: %s"),
+		       g_strerror (save_errno));
+
+	  return FALSE;
+	}
+
+      if (WIFEXITED (status))
+	{
+	  save_errno = WEXITSTATUS (status);
+
+	  if (save_errno == 0)
+	    {
+	      return TRUE;
+	    }
+	  else
+	    {
+	      g_set_error (err,
+			   G_FILE_ERROR,
+			   g_file_error_from_errno (save_errno),
+			   _("Could not change file mode: chmod() failed: %s"),
+			   g_strerror (save_errno));
+      
+	      return FALSE;
+	    }
+	}
+      else if (WIFSIGNALED (status))
+	{
+	  g_set_error (err,
+		       G_FILE_ERROR,
+		       G_FILE_ERROR_FAILED,
+		       _("Could not change file mode: Child terminated by signal: %s"),
+		       g_strsignal (WTERMSIG (status)));
+		       
+	  return FALSE;
+	}
+      else
+	{
+	  /* This shouldn't happen */
+	  g_set_error (err,
+		       G_FILE_ERROR,
+		       G_FILE_ERROR_FAILED,
+		       _("Could not change file mode: Child terminated abnormally"));
+	  return FALSE;
+	}
+    }
+#endif
+}
+
+static gchar *
+write_to_temp_file (const gchar *contents,
+		    gssize length,
+		    const gchar *template,
+		    GError **err)
+{
+  gchar *tmp_name;
+  gchar *display_name;
+  gchar *retval;
+  FILE *file;
+  gint fd;
+  int save_errno;
+
+  retval = NULL;
+  
+  tmp_name = g_strdup_printf ("%s.XXXXXX", template);
+
+  errno = 0;
+  fd = g_mkstemp (tmp_name);
+  display_name = g_filename_display_name (tmp_name);
+      
+  if (fd == -1)
+    {
+      save_errno = errno;
+      g_set_error (err,
+		   G_FILE_ERROR,
+		   g_file_error_from_errno (save_errno),
+		   "Failed to create file '%s': %s",
+		   display_name, g_strerror (save_errno));
+      
+      goto out;
+    }
+
+  if (!set_umask_permissions (fd, err))
+    {
+      close (fd);
+      g_unlink (tmp_name);
+
+      goto out;
+    }
+  
+  errno = 0;
+  file = fdopen (fd, "wb");
+  if (!file)
+    {
+      save_errno = errno;
+      g_set_error (err,
+		   G_FILE_ERROR,
+		   g_file_error_from_errno (save_errno),
+		   "Failed to open file '%s' for writing: fdopen() failed: %s",
+		   display_name,
+		   g_strerror (save_errno));
+
+      close (fd);
+      g_unlink (tmp_name);
+      
+      goto out;
+    }
+
+  if (length > 0)
+    {
+      size_t n_written;
+      
+      errno = 0;
+
+      n_written = fwrite (contents, 1, length, file);
+
+      if (n_written < length)
+	{
+	  save_errno = errno;
+      
+ 	  g_set_error (err,
+		       G_FILE_ERROR,
+		       g_file_error_from_errno (save_errno),
+		       "Failed to write file '%s': fwrite() failed: %s",
+		       display_name,
+		       g_strerror (save_errno));
+
+	  fclose (file);
+	  g_unlink (tmp_name);
+	  
+	  goto out;
+	}
+    }
+   
+  errno = 0;
+  if (fclose (file) == EOF)
+    { 
+      save_errno = 0;
+      
+      g_set_error (err,
+		   G_FILE_ERROR,
+		   g_file_error_from_errno (save_errno),
+		   "Failed to close file '%s': fclose() failed: %s",
+		   display_name, 
+		   g_strerror (save_errno));
+
+      g_unlink (tmp_name);
+      
+      goto out;
+    }
+
+  retval = g_strdup (tmp_name);
+  
+ out:
+  g_free (tmp_name);
+  g_free (display_name);
+  
+  return retval;
+}
+
+/**
+ * g_file_set_contents:
+ * @filename: name of a file to write @contents to, in the GLib file name
+ *   encoding
+ * @contents: string to write to the file
+ * @length: length of @contents, or -1 if @contents is a nul-terminated string
+ * @error: return location for a #GError, or %NULL
+ *
+ * Writes all of @contents to a file named @filename, with good error checking.
+ * If a file called @filename already exists it will be overwritten.
+ *
+ * This write is atomic in the sense that it is first written to a temporary
+ * file which is then renamed to the final name. Notes:
+ * <itemizedlist>
+ * <listitem>
+ *    On Unix, if @filename already exists hard links to @filename will break.
+ *    Also since the file is recreated, existing permissions, access control
+ *    lists, metadata etc. may be lost. If @filename is a symbolic link,
+ *    the link itself will be replaced, not the linked file.
+ * </listitem>
+ * <listitem>
+ *   On Windows renaming a file will not remove an existing file with the
+ *   new name, so on Windows there is a race condition between the existing
+ *   file being removed and the temporary file being renamed.
+ * </listitem>
+ * <listitem>
+ *   On Windows there is no way to remove a file that is open to some
+ *   process, or mapped into memory. Thus, this function will fail if
+ *   @filename already exists and is open.
+ * </listitem>
+ * </itemizedlist>
+ *
+ * If the call was sucessful, it returns %TRUE. If the call was not successful,
+ * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR.
+ * Possible error codes are those in the #GFileError enumeration.
+ *
+ * Return value: %TRUE on success, %FALSE if an error occurred
+ *
+ * Since: 2.8
+ **/
+gboolean
+g_file_set_contents (const gchar *filename,
+		     const gchar *contents,
+		     gssize	     length,
+		     GError	   **error)
+{
+  gchar *tmp_filename;
+  gboolean retval;
+  GError *rename_error = NULL;
+  
+  g_return_val_if_fail (filename != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  g_return_val_if_fail (contents != NULL || length == 0, FALSE);
+  g_return_val_if_fail (length >= -1, FALSE);
+  
+  if (length == -1)
+    length = strlen (contents);
+
+  tmp_filename = write_to_temp_file (contents, length, filename, error);
+  
+  if (!tmp_filename)
+    {
+      retval = FALSE;
+      goto out;
+    }
+
+  if (!rename_file (tmp_filename, filename, &rename_error))
+    {
+#ifndef G_OS_WIN32
+
+      g_unlink (tmp_filename);
+      g_propagate_error (error, rename_error);
+      retval = FALSE;
+      goto out;
+
+#else /* G_OS_WIN32 */
+      
+      /* Renaming failed, but on Windows this may just mean
+       * the file already exists. So if the target file
+       * exists, try deleting it and do the rename again.
+       */
+      if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+	{
+	  g_unlink (tmp_filename);
+	  g_propagate_error (error, rename_error);
+	  retval = FALSE;
+	  goto out;
+	}
+
+      g_error_free (rename_error);
+      
+      if (g_unlink (filename) == -1)
+	{
+          gchar *display_filename = g_filename_display_name (filename);
+
+	  int save_errno = errno;
+	  
+	  g_set_error (error,
+		       G_FILE_ERROR,
+		       g_file_error_from_errno (save_errno),
+		       "Existing file '%s' could not be removed: g_unlink() failed: %s",
+		       display_filename,
+		       g_strerror (save_errno));
+
+	  g_free (display_filename);
+	  g_unlink (tmp_filename);
+	  retval = FALSE;
+	  goto out;
+	}
+      
+      if (!rename_file (tmp_filename, filename, error))
+	{
+	  g_unlink (tmp_filename);
+	  retval = FALSE;
+	  goto out;
+	}
+
+#endif
+    }
+
+  retval = TRUE;
+  
+ out:
+  g_free (tmp_filename);
+  return retval;
+}

Added: gnucash/trunk/lib/glib28/gfileutils-2.8.h
===================================================================
--- gnucash/trunk/lib/glib28/gfileutils-2.8.h	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/lib/glib28/gfileutils-2.8.h	2007-01-28 05:13:54 UTC (rev 15445)
@@ -0,0 +1,34 @@
+/* gfileutils.h - File utility functions
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* Contains only relevant differences between GLib 2.6 and GLib 2.8 */
+
+#ifndef __G_FILEUTILS_2_8_H__
+#define __G_FILEUTILS_2_8_H__
+
+G_BEGIN_DECLS
+
+gboolean g_file_set_contents (const gchar *filename,
+			      const gchar *contents,
+			      gssize	     length,
+			      GError	   **error);
+
+G_END_DECLS
+
+#endif /* __G_FILEUTILS_2_8_H__ */

Added: gnucash/trunk/lib/glib28/gstdio-2.8.h
===================================================================
--- gnucash/trunk/lib/glib28/gstdio-2.8.h	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/lib/glib28/gstdio-2.8.h	2007-01-28 05:13:54 UTC (rev 15445)
@@ -0,0 +1,38 @@
+/* gstdio.h - GFilename wrappers for C library functions
+ *
+ * Copyright 2004 Tor Lillqvist
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* Contains only relevant differences between GLib 2.6 and GLib 2.8 */
+
+#ifndef __G_STDIO_28_H__
+#define __G_STDIO_28_H__
+
+#ifdef G_OS_WIN32
+#error "On Windows HAVE_GLIB_2_8 must be defined and gstdio28.h not included."
+#endif
+
+G_BEGIN_DECLS
+
+#define g_access  access
+#define g_chmod   chmod
+#define g_creat   creat
+#define g_chdir   chdir
+
+G_END_DECLS
+
+#endif /* __G_STDIO_H__ */

Added: gnucash/trunk/lib/glib28/gwin32-2.8.c
===================================================================
--- gnucash/trunk/lib/glib28/gwin32-2.8.c	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/lib/glib28/gwin32-2.8.c	2007-01-28 05:13:54 UTC (rev 15445)
@@ -0,0 +1,101 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Copyright (C) 1998-1999  Tor Lillqvist
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* Contains all #includes, but otherwise only relevant differences between
+ * GLib 2.6 and GLib 2.8 */
+
+#include "config.h"
+
+#include <glibconfig.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include <errno.h>
+
+#define STRICT			/* Strict typing, please */
+#include <windows.h>
+#undef STRICT
+#ifndef G_WITH_CYGWIN
+#include <direct.h>
+#endif
+#include <errno.h>
+#include <ctype.h>
+#ifdef _MSC_VER
+#  include <io.h>
+#endif /* _MSC_VER */
+
+#include <glib.h>
+
+
+/**
+ * g_win32_locale_filename_from_utf8:
+ * @utf8filename: a UTF-8 encoded filename.
+ *
+ * Converts a filename from UTF-8 to the system codepage.
+ *
+ * On NT-based Windows, on NTFS file systems, file names are in
+ * Unicode. It is quite possible that Unicode file names contain
+ * characters not representable in the system codepage. (For instance,
+ * Greek or Cyrillic characters on Western European or US Windows
+ * installations, or various less common CJK characters on CJK Windows
+ * installations.)
+ *
+ * In such a case, and if the filename refers to an existing file, and
+ * the file system stores alternate short (8.3) names for directory
+ * entries, the short form of the filename is returned. Note that the
+ * "short" name might in fact be longer than the Unicode name if the
+ * Unicode name has very short pathname components containing
+ * non-ASCII characters. If no system codepage name for the file is
+ * possible, %NULL is returned.
+ *
+ * The return value is dynamically allocated and should be freed with
+ * g_free() when no longer needed.
+ *
+ * Return value: The converted filename, or %NULL on conversion
+ * failure and lack of short names.
+ *
+ * Since: 2.8
+ */
+gchar *
+g_win32_locale_filename_from_utf8 (const gchar *utf8filename)
+{
+  gchar *retval = g_locale_from_utf8 (utf8filename, -1, NULL, NULL, NULL);
+
+  if (retval == NULL && G_WIN32_HAVE_WIDECHAR_API ())
+    {
+      /* Conversion failed, so convert to wide chars, check if there
+       * is a 8.3 version, and use that.
+       */
+      wchar_t *wname = g_utf8_to_utf16 (utf8filename, -1, NULL, NULL, NULL);
+      if (wname != NULL)
+	{
+	  wchar_t wshortname[MAX_PATH + 1];
+	  if (GetShortPathNameW (wname, wshortname, G_N_ELEMENTS (wshortname)))
+	    {
+	      gchar *tem = g_utf16_to_utf8 (wshortname, -1, NULL, NULL, NULL);
+	      retval = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
+	      g_free (tem);
+	    }
+	  g_free (wname);
+	}
+    }
+  return retval;
+}

Added: gnucash/trunk/lib/glib28/gwin32-2.8.h
===================================================================
--- gnucash/trunk/lib/glib28/gwin32-2.8.h	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/lib/glib28/gwin32-2.8.h	2007-01-28 05:13:54 UTC (rev 15445)
@@ -0,0 +1,30 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* Contains only relevant differences between GLib 2.6 and GLib 2.8 */
+
+#ifndef __G_WIN32_2_8_H__
+#define __G_WIN32_2_8_H__
+
+G_BEGIN_DECLS
+
+gchar*          g_win32_locale_filename_from_utf8 (const gchar *utf8filename);
+
+G_END_DECLS
+
+#endif /* __G_WIN32_2_8_H__ */

Modified: gnucash/trunk/src/backend/file/gnc-backend-file.c
===================================================================
--- gnucash/trunk/src/backend/file/gnc-backend-file.c	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/src/backend/file/gnc-backend-file.c	2007-01-28 05:13:54 UTC (rev 15445)
@@ -33,9 +33,11 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
+#ifndef HAVE_GLIB_2_8
+#include <gstdio-2.8.h>
+#endif
 #include <libintl.h>
 #include <locale.h>
-#include <stdio.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <sys/stat.h>
@@ -288,18 +290,7 @@
 #ifdef G_OS_WIN32
 	/* On windows, we need to allow write-access before
 	   g_unlink() can succeed */
-	wchar_t *wlock = g_utf8_to_utf16 (be->lockfile, -1, NULL, NULL, NULL);
-	if (wlock) {
-	    rv = _wchmod (wlock, _S_IWRITE);
-	} else {
-	    errno = EINVAL;
-	    rv = 1;
-	}
-	if (rv) {
-	    PWARN("Error on chmod(%s): %d: %s", be->lockfile,
-		  errno, strerror(errno) ? strerror(errno) : "");
-	}
-	g_free (wlock);
+	rv = g_chmod (be->lockfile, S_IWRITE | S_IREAD);
 #endif
 	rv = g_unlink (be->lockfile);
 	if (rv) {

Modified: gnucash/trunk/src/import-export/qif-import/druid-qif-import.c
===================================================================
--- gnucash/trunk/src/import-export/qif-import/druid-qif-import.c	2007-01-28 04:17:36 UTC (rev 15444)
+++ gnucash/trunk/src/import-export/qif-import/druid-qif-import.c	2007-01-28 05:13:54 UTC (rev 15445)
@@ -26,8 +26,11 @@
 
 #include <gnome.h>
 #include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#ifndef HAVE_GLIB_2_8
+#include <gstdio-2.8.h>
+#endif
 #include <libguile.h>
-#include <stdio.h>
 #include <sys/time.h>
 #include <unistd.h>
 
@@ -477,17 +480,7 @@
     gnc_error_dialog(wind->window, _("Please select a file to load."));
     return TRUE;
   }
-
-#ifdef G_OS_WIN32
-  {
-    wchar_t *wpath = g_utf8_to_utf16(path_to_load, -1, NULL, NULL, NULL);
-    rv = wpath ? _waccess(wpath, R_OK) : -1;
-    g_free(wpath);
-  }
-#else
-  rv = access(path_to_load, R_OK);
-#endif
-  if (rv < 0) {
+  else if (g_access(path_to_load, R_OK) < 0) {
     /* stay here if bad file */
     gnc_error_dialog(wind->window, 
 		     _("File not found or read permission denied. "



More information about the gnucash-changes mailing list