[nautilus-actions: 34/45] Implement na_gnome_vfs_uri_parse() function



commit 35166956b9a2909618c70549add88350625075a0
Author: Pierre Wieser <pwieser trychlos org>
Date:   Wed Jul 29 21:46:01 2009 +0200

    Implement na_gnome_vfs_uri_parse() function

 ChangeLog                                |   18 +
 INSTALL                                  |  253 ++++++---
 TODO                                     |    8 +
 configure.ac                             |    3 +-
 m4/na-log-domains.m4                     |    3 +
 src/Makefile.am                          |    1 +
 src/common/Makefile.am                   |    2 +
 src/common/na-action-profile.c           |   21 +-
 src/common/na-gnome-vfs-uri.c            |  935 ++++++++++++++++++++++++++++++
 src/common/na-gnome-vfs-uri.h            |  108 ++++
 src/common/na-xml-names.h                |    6 +-
 src/nact/nautilus-actions-config-tool.ui |   20 +-
 src/test/Makefile.am                     |   47 ++
 src/test/test-parse-uris                 |  Bin 0 -> 27074 bytes
 src/test/test-parse-uris.c               |   71 +++
 src/utils/nautilus-actions-new.c         |    2 +-
 src/utils/nautilus-actions-schema.c      |    2 +-
 17 files changed, 1400 insertions(+), 100 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 1de6cf0..a33218a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2009-07-29 Pierre Wieser <pwieser trychlos org>
+
+	* m4/na-log-domains.m4:
+	Define a new log domain for test programs.
+
+	* src/common/na-gnome-vfs-uri.c:
+	* src/common/na-gnome-vfs-uri.h: New files.
+
+	* src/common/na-action-profile.c:
+	Take advantage of new na_gnome_vfs_uri_parse() function.
+
+	* src/test/test-parse-uris.c:
+	* src/test/test-parse-uris.h: New files.
+
+	* src/common/na-xml-names.h:
+	* src/nact/nautilus-actions-config-tool.ui:
+	Remove all mentions of GnomeVFS or GVfs.
+
 2009-07-28 Pierre Wieser <pwieser trychlos org>
 
 	* src/common/na-iio-provider.c:
diff --git a/INSTALL b/INSTALL
index e3ca83d..2550dab 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,55 +1,54 @@
 Installation Instructions
-=========================
+*************************
 
-To install nautilus-actions, simply run :
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
-./configure
-make
-make install
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
 
-If configure script failed to find nautilus extensions dir, it means you 
-don't have the last nautilus 2.11/2.12 version. So retry and set it manually.
-The default should be :
-
-./configure --with-nautilus-extdir=/usr/lib/nautilus/extensions-1.0
-make
-make install
-
-Generic Basic Installation
-==========================
+Basic Installation
+==================
 
-   These are generic installation instructions.
+   Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
 those values to create a `Makefile' in each directory of the package.
 It may also create one or more `.h' files containing system-dependent
 definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, a file
-`config.cache' that saves the results of its tests to speed up
-reconfiguring, and a file `config.log' containing compiler output
-(useful mainly for debugging `configure').
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
 
    If you need to do unusual things to compile the package, please try
 to figure out how `configure' could check whether to do them, and mail
 diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If at some point `config.cache'
-contains results you don't want to keep, you may remove or edit it.
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
 
-   The file `configure.in' is used to create `configure' by a program
-called `autoconf'.  You only need `configure.in' if you want to change
-it or regenerate `configure' using a newer version of `autoconf'.
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
 
 The simplest way to compile this package is:
 
   1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.  If you're
-     using `csh' on an old version of System V, you might need to type
-     `sh ./configure' instead to prevent `csh' from trying to execute
-     `configure' itself.
+     `./configure' to configure the package for your system.
 
-     Running `configure' takes awhile.  While running, it prints some
-     messages telling which features it is checking for.
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
 
   2. Type `make' to compile the package.
 
@@ -68,52 +67,69 @@ The simplest way to compile this package is:
      all sorts of other programs in order to regenerate files that came
      with the distribution.
 
+  6. Often, you can also type `make uninstall' to remove the installed
+     files again.
+
 Compilers and Options
 =====================
 
    Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  You can give `configure'
-initial values for variables by setting them in the environment.  Using
-a Bourne-compatible shell, you can do that on the command line like
-this:
-     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
 
-Or on systems that have the `env' program, you can do it like this:
-     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+   *Note Defining Variables::, for more details.
 
 Compiling For Multiple Architectures
 ====================================
 
    You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+own directory.  To do this, you can use GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
 the `configure' script.  `configure' automatically checks for the
 source code in the directory that `configure' is in and in `..'.
 
-   If you have to use a `make' that does not supports the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory.  After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
 
 Installation Names
 ==================
 
-   By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
 
    You can specify separate installation prefixes for
 architecture-specific files and architecture-independent files.  If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
 
    In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
+options like `--bindir=DIR' to specify different values for particular
 kinds of files.  Run `configure --help' for a list of the directories
 you can set and what kinds of files go in them.
 
@@ -136,25 +152,68 @@ find the X include and library files automatically, but if it doesn't,
 you can use the `configure' options `--x-includes=DIR' and
 `--x-libraries=DIR' to specify their locations.
 
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
 Specifying the System Type
 ==========================
 
-   There may be some features `configure' can not figure out
-automatically, but needs to determine by the type of host the package
-will run on.  Usually `configure' can figure that out, but if it prints
-a message saying it can not guess the host type, give it the
-`--host=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name with three fields:
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
      CPU-COMPANY-SYSTEM
 
-See the file `config.sub' for the possible values of each field.  If
+where SYSTEM can have one of these forms:
+
+     OS
+     KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
 `config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
 
-   If you are building compiler tools for cross-compiling, you can also
-use the `--target=TYPE' option to select the type of system they will
-produce code for and the `--build=TYPE' option to select the type of
-system on which you are compiling the package.
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
 
 Sharing Defaults
 ================
@@ -167,19 +226,55 @@ default values for variables like `CC', `cache_file', and `prefix'.
 `CONFIG_SITE' environment variable to the location of the site script.
 A warning: not all `configure' scripts look for a site script.
 
-Operation Controls
+Defining Variables
 ==================
 
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
    `configure' recognizes the following options to control how it
 operates.
 
+`--help'
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
 `--cache-file=FILE'
-     Use and save the results of the tests in FILE instead of
-     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
-     debugging `configure'.
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
 
-`--help'
-     Print a summary of the options to `configure', and exit.
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
 
 `--quiet'
 `--silent'
@@ -192,8 +287,16 @@ operates.
      Look for the package's source code in directory DIR.  Usually
      `configure' can determine that directory automatically.
 
-`--version'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *Note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
 
-`configure' also accepts some other, not widely useful, options.
diff --git a/TODO b/TODO
index 79786c4..4abe60c 100644
--- a/TODO
+++ b/TODO
@@ -21,3 +21,11 @@ like the scheme list, it seems.
 
 - allow users to upload/download actions directly from a web repository
   (REST services ?)
+
+- NAUTILUS_ACTIONS_CONFIG_GCONF_BASEDIR has nothing to do in configure.ac
+  (not a configuration variable)
+
+- remove option to build or not utilities : always build all
+
+- configure.ac: distinguish between common, nautilus extension or gtk
+  program to build nautilus_actions_flags/libs
diff --git a/configure.ac b/configure.ac
index c239e76..e2b6b5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,8 +49,9 @@ AC_CONFIG_FILES([
 	src/Makefile
 	src/common/Makefile
 	src/nact/Makefile
-	src/utils/Makefile
 	src/plugin/Makefile
+	src/test/Makefile
+	src/utils/Makefile
 	po/Makefile.in
 ])
 
diff --git a/m4/na-log-domains.m4 b/m4/na-log-domains.m4
index c03ec05..789ccf7 100644
--- a/m4/na-log-domains.m4
+++ b/m4/na-log-domains.m4
@@ -14,6 +14,9 @@ AC_DEFUN([NA_LOG_DOMAINS],[
 	AC_SUBST([NA_LOGDOMAIN_NACT],[NA-nact])
 	AC_DEFINE_UNQUOTED([NA_LOGDOMAIN_NACT],["NA-nact"],[Log domain of NACT user interface])
 
+	AC_SUBST([NA_LOGDOMAIN_TEST],[NA-test])
+	AC_DEFINE_UNQUOTED([NA_LOGDOMAIN_TEST],["NA-test"],[Log domain of test programs])
+
 	AC_SUBST([NA_LOGDOMAIN_UTILS],[NA-utils])
 	AC_DEFINE_UNQUOTED([NA_LOGDOMAIN_UTILS],["NA-utils"],[Log domain of utilities])
 ])
diff --git a/src/Makefile.am b/src/Makefile.am
index 75ebe69..a339fbd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,5 +30,6 @@ SUBDIRS = \
 	common						\
 	nact						\
 	plugin						\
+	test						\
 	$(OPTIONAL_SUBDIR)			\
 	$(NULL)
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 83867d9..0ae64ff 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -44,6 +44,8 @@ libnact_la_SOURCES = \
 	na-gconf.c									\
 	na-gconf.h									\
 	na-gconf-keys.h								\
+	na-gnome-vfs-uri.c							\
+	na-gnome-vfs-uri.h							\
 	na-iduplicable.c							\
 	na-iduplicable.h							\
 	na-iio-provider.c							\
diff --git a/src/common/na-action-profile.c b/src/common/na-action-profile.c
index ffa233c..183c062 100644
--- a/src/common/na-action-profile.c
+++ b/src/common/na-action-profile.c
@@ -40,6 +40,7 @@
 #include "na-action.h"
 #include "na-action-profile.h"
 #include "na-utils.h"
+#include "na-gnome-vfs-uri.h"
 
 /* private class data
  */
@@ -1264,12 +1265,12 @@ na_action_profile_is_candidate( const NAActionProfile *profile, GList* files )
  *
  * %d : base dir of the (first) selected file(s)/folder(s)
  * %f : the name of the (first) selected file/folder
- * %h : hostname of the (first) GVfs URI
+ * %h : hostname of the (first) URI
  * %m : list of the basename of the selected files/directories separated by space.
  * %M : list of the selected files/directories with their complete path separated by space.
- * %s : scheme of the (first) GVfs URI
- * %u : (first) GVfs URI
- * %U : username of the (first) GVfs URI
+ * %s : scheme of the (first) URI
+ * %u : (first)  URI
+ * %U : username of the (first) URI
  * %% : a percent sign
  */
 gchar *
@@ -1289,6 +1290,7 @@ na_action_profile_parse_parameters( const NAActionProfile *profile, GList* files
 	gchar *username = NULL;
 	GString *basename_list, *pathname_list;
 	gchar *tmp;
+	NAGnomeVFSURI *vfs;
 
 	g_return_val_if_fail( NA_IS_ACTION_PROFILE( profile ), NULL );
 
@@ -1304,6 +1306,9 @@ na_action_profile_parse_parameters( const NAActionProfile *profile, GList* files
 		ipath = g_file_get_path( iloc );
 		ibname = g_file_get_basename( iloc );
 
+		vfs = g_new0( NAGnomeVFSURI, 1 );
+		na_gnome_vfs_uri_parse( vfs, iuri );
+
 		if( first ){
 
 			uri = g_strdup( iuri );
@@ -1311,11 +1316,8 @@ na_action_profile_parse_parameters( const NAActionProfile *profile, GList* files
 			scheme = nautilus_file_info_get_uri_scheme(( NautilusFileInfo * ) ifi->data );
 			filename = g_strdup( ibname );
 
-			/*hostname = g_strdup( gnome_vfs_uri_get_host_name( gvfs_uri ));
-			username = g_strdup( gnome_vfs_uri_get_user_name( gvfs_uri ));*/
-			/* TODO get hostname or username from GFile uri */
-			hostname = NULL;
-			username = NULL;
+			hostname = g_strdup( vfs->host_name );
+			username = g_strdup( vfs->user_name );
 
 			first = FALSE;
 		}
@@ -1329,6 +1331,7 @@ na_action_profile_parse_parameters( const NAActionProfile *profile, GList* files
 		g_string_append_printf( pathname_list, " %s", tmp );
 		g_free( tmp );
 
+		na_gnome_vfs_uri_free( vfs );
 		g_free( ibname );
 		g_free( ipath );
 		g_object_unref( iloc );
diff --git a/src/common/na-gnome-vfs-uri.c b/src/common/na-gnome-vfs-uri.c
new file mode 100644
index 0000000..ed2830a
--- /dev/null
+++ b/src/common/na-gnome-vfs-uri.c
@@ -0,0 +1,935 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+/*
+ * pwi 2009-07-29
+ * shamelessly pull out of GnomeVFS (gnome-vfs-uri and consorts)
+ */
+
+/* gnome-vfs-uri.h - URI handling for the GNOME Virtual File System.
+
+   Copyright (C) 1999 Free Software Foundation
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Ettore Perazzoli <ettore comm2000 it> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "na-gnome-vfs-uri.h"
+
+#define HEX_ESCAPE '%'
+
+static void         collapse_slash_runs (char *path, int from_offset);
+static int          find_next_slash (const char *path, int current_offset);
+static int          find_slash_before_offset (const char *path, int to);
+static const gchar *get_method_string (const gchar *substring, gchar **method_string);
+static gchar *      gnome_vfs_canonicalize_pathname (gchar *path);
+static char        *gnome_vfs_escape_set(const char *string, const char *match_set);
+static void         gnome_vfs_remove_optional_escapes (char *uri);
+static char *       gnome_vfs_unescape_string (const gchar *escaped_string, const gchar *illegal_characters);
+static int          hex_to_int (gchar c);
+static void         set_uri_element (NAGnomeVFSURI *vfs, const gchar *text, guint len);
+static gchar       *split_toplevel_uri (const gchar *path, guint path_len,
+												gchar **host_return, gchar **user_return,
+												guint *port_return, gchar **password_return);
+static int          unescape_character (const char *scanner);
+
+void
+na_gnome_vfs_uri_parse( NAGnomeVFSURI *vfs, const gchar *text_uri )
+{
+	const gchar *method_scanner;
+	gchar *extension_scanner;
+
+	vfs->uri = NULL;
+	vfs->scheme = NULL;
+	vfs->host_name = NULL;
+	vfs->host_port = 0;
+	vfs->user_name = NULL;
+	vfs->password = NULL;
+
+	if (text_uri[0] == '\0') {
+		return;
+	}
+
+	method_scanner = get_method_string(text_uri, &vfs->scheme );
+	if (strcmp (vfs->scheme, "pipe") == 0 ){
+		return;
+	}
+
+	extension_scanner = strchr (method_scanner, GNOME_VFS_URI_MAGIC_CHR);
+	if (extension_scanner == NULL) {
+		set_uri_element (vfs, method_scanner, strlen (method_scanner));
+		return;
+	}
+
+	/* handle '#' */
+	set_uri_element (vfs, method_scanner, extension_scanner - method_scanner);
+
+	if (strchr (extension_scanner, ':') == NULL) {
+		/* extension is a fragment identifier */
+		/*uri->fragment_id = g_strdup (extension_scanner + 1);*/
+		return;
+	}
+}
+
+void
+na_gnome_vfs_uri_free( NAGnomeVFSURI *vfs )
+{
+	g_free( vfs->scheme );
+	g_free( vfs->host_name );
+	g_free( vfs->user_name );
+	g_free( vfs->password );
+	g_free( vfs );
+}
+
+static void
+collapse_slash_runs (char *path, int from_offset)
+{
+	int i;
+	/* Collapse multiple `/'s in a row. */
+	for (i = from_offset;; i++) {
+		if (path[i] != GNOME_VFS_URI_PATH_CHR) {
+			break;
+		}
+	}
+
+	if (from_offset < i) {
+		memmove (path + from_offset, path + i, strlen (path + i) + 1);
+		i = from_offset + 1;
+	}
+}
+
+static int
+find_next_slash (const char *path, int current_offset)
+{
+	const char *match;
+
+	g_assert (current_offset <= strlen (path));
+
+	match = strchr (path + current_offset, GNOME_VFS_URI_PATH_CHR);
+	return match == NULL ? -1 : match - path;
+}
+
+static int
+find_slash_before_offset (const char *path, int to)
+{
+	int result;
+	int next_offset;
+
+	result = -1;
+	next_offset = 0;
+	for (;;) {
+		next_offset = find_next_slash (path, next_offset);
+		if (next_offset < 0 || next_offset >= to) {
+			break;
+		}
+		result = next_offset;
+		next_offset++;
+	}
+	return result;
+}
+
+static const gchar *
+get_method_string (const gchar *substring, gchar **method_string)
+{
+	const gchar *p;
+	char *method;
+
+	for (p = substring;
+	     g_ascii_isalnum (*p) || *p == '+' || *p == '-' || *p == '.';
+	     p++)
+		;
+
+	if (*p == ':'
+#ifdef G_OS_WIN32
+	              &&
+	    !(p == substring + 1 && g_ascii_isalpha (*substring))
+#endif
+								 ) {
+		/* Found toplevel method specification.  */
+		method = g_strndup (substring, p - substring);
+		*method_string = g_ascii_strdown (method, -1);
+		g_free (method);
+		p++;
+	} else {
+		*method_string = g_strdup ("file");
+		p = substring;
+	}
+	return p;
+}
+
+/* Canonicalize path, and return a new path.  Do everything in situ.  The new
+   path differs from path in:
+
+     Multiple `/'s are collapsed to a single `/'.
+     Leading `./'s and trailing `/.'s are removed.
+     Non-leading `../'s and trailing `..'s are handled by removing
+     portions of the path.  */
+static gchar *
+gnome_vfs_canonicalize_pathname (gchar *path)
+{
+	int i, marker;
+
+	if (path == NULL || strlen (path) == 0) {
+		return "";
+	}
+
+	/* Walk along path looking for things to compact. */
+	for (i = 0, marker = 0;;) {
+		if (!path[i])
+			break;
+
+		/* Check for `../', `./' or trailing `.' by itself. */
+		if (path[i] == '.') {
+			/* Handle trailing `.' by itself. */
+			if (path[i + 1] == '\0') {
+				if (i > 1 && path[i - 1] == GNOME_VFS_URI_PATH_CHR) {
+					/* strip the trailing /. */
+					path[i - 1] = '\0';
+				} else {
+					/* convert path "/." to "/" */
+					path[i] = '\0';
+				}
+				break;
+			}
+
+			/* Handle `./'. */
+			if (path[i + 1] == GNOME_VFS_URI_PATH_CHR) {
+				memmove (path + i, path + i + 2,
+					 strlen (path + i + 2) + 1);
+				if (i == 0) {
+					/* don't leave leading '/' for paths that started
+					 * as relative (.//foo)
+					 */
+					collapse_slash_runs (path, i);
+					marker = 0;
+				}
+				continue;
+			}
+
+			/* Handle `../' or trailing `..' by itself.
+			 * Remove the previous xxx/ part
+			 */
+			if (path[i + 1] == '.'
+			    && (path[i + 2] == GNOME_VFS_URI_PATH_CHR
+				|| path[i + 2] == '\0')) {
+
+				/* ignore ../ at the beginning of a path */
+				if (i != 0) {
+					marker = find_slash_before_offset (path, i - 1);
+
+					/* Either advance past '/' or point to the first character */
+					marker ++;
+					if (path [i + 2] == '\0' && marker > 1) {
+						/* If we are looking at a /.. at the end of the uri and we
+						 * need to eat the last '/' too.
+						 */
+						 marker--;
+					}
+					g_assert(marker < i);
+
+					if (path[i + 2] == GNOME_VFS_URI_PATH_CHR) {
+						/* strip the entire ../ string */
+						i++;
+					}
+
+					memmove (path + marker, path + i + 2,
+						 strlen (path + i + 2) + 1);
+					i = marker;
+				} else {
+					i = 2;
+					if (path[i] == GNOME_VFS_URI_PATH_CHR) {
+						i++;
+					}
+				}
+				collapse_slash_runs (path, i);
+				continue;
+			}
+		}
+
+		/* advance to the next '/' */
+		i = find_next_slash (path, i);
+
+		/* If we didn't find any slashes, then there is nothing left to do. */
+		if (i < 0) {
+			break;
+		}
+
+		marker = i++;
+		collapse_slash_runs (path, i);
+	}
+	return path;
+}
+
+/*  Escape undesirable characters using %
+ *  -------------------------------------
+ *
+ * This function takes a pointer to a string in which
+ * some characters may be unacceptable unescaped.
+ * It returns a string which has these characters
+ * represented by a '%' character followed by two hex digits.
+ *
+ * This routine returns a g_malloced string.
+ */
+
+static const gchar hex[16] = "0123456789ABCDEF";
+
+/**
+ * gnome_vfs_escape_set:
+ * @string: string to be escaped.
+ * @match_set: a string containing all characters to be escaped in @string.
+ *
+ * Escapes all characters in @string which are listed in @match_set.
+ *
+ * Return value: a newly allocated string equivalent to @string but
+ * with characters in @match_string escaped.
+ */
+static char *
+gnome_vfs_escape_set (const char *string,
+	              const char *match_set)
+{
+	char *result;
+	const char *scanner;
+	char *result_scanner;
+	int escape_count;
+
+	escape_count = 0;
+
+	if (string == NULL) {
+		return NULL;
+	}
+
+	if (match_set == NULL) {
+		return g_strdup (string);
+	}
+
+	for (scanner = string; *scanner != '\0'; scanner++) {
+		if (strchr(match_set, *scanner) != NULL) {
+			/* this character is in the set of characters
+			 * we want escaped.
+			 */
+			escape_count++;
+		}
+	}
+
+	if (escape_count == 0) {
+		return g_strdup (string);
+	}
+
+	/* allocate two extra characters for every character that
+	 * needs escaping and space for a trailing zero
+	 */
+	result = g_malloc (scanner - string + escape_count * 2 + 1);
+	for (scanner = string, result_scanner = result; *scanner != '\0'; scanner++) {
+		if (strchr(match_set, *scanner) != NULL) {
+			/* this character is in the set of characters
+			 * we want escaped.
+			 */
+			*result_scanner++ = HEX_ESCAPE;
+			*result_scanner++ = hex[*scanner >> 4];
+			*result_scanner++ = hex[*scanner & 15];
+
+		} else {
+			*result_scanner++ = *scanner;
+		}
+	}
+
+	*result_scanner = '\0';
+
+	return result;
+}
+
+/**
+ * gnome_vfs_remove_optional_escapes:
+ * @uri: an escaped uri.
+ *
+ * Scans the @uri and converts characters that do not have to be
+ * escaped into an un-escaped form. The characters that get treated this
+ * way are defined as unreserved by the RFC.
+ *
+ * Return value: an error value if the @uri is found to be malformed.
+ */
+
+enum {
+	RESERVED = 1,
+	UNRESERVED,
+	DELIMITERS,
+	UNWISE,
+	CONTROL,
+	SPACE
+};
+
+static const guchar uri_character_kind[128] =
+{
+    CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,
+    CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,
+    CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,
+    CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,
+    /* ' '        !          "          #          $          %          &          '      */
+    SPACE     ,UNRESERVED,DELIMITERS,DELIMITERS,RESERVED  ,DELIMITERS,RESERVED  ,UNRESERVED,
+    /*  (         )          *          +          ,          -          .          /      */
+    UNRESERVED,UNRESERVED,UNRESERVED,RESERVED  ,RESERVED  ,UNRESERVED,UNRESERVED,RESERVED  ,
+    /*  0         1          2          3          4          5          6          7      */
+    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
+    /*  8         9          :          ;          <          =          >          ?      */
+    UNRESERVED,UNRESERVED,RESERVED  ,RESERVED  ,DELIMITERS,RESERVED  ,DELIMITERS,RESERVED  ,
+    /*  @         A          B          C          D          E          F          G      */
+    RESERVED  ,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
+    /*  H         I          J          K          L          M          N          O      */
+    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
+    /*  P         Q          R          S          T          U          V          W      */
+    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
+    /*  X         Y          Z          [          \          ]          ^          _      */
+    UNRESERVED,UNRESERVED,UNRESERVED,UNWISE    ,UNWISE    ,UNWISE    ,UNWISE    ,UNRESERVED,
+    /*  `         a          b          c          d          e          f          g      */
+    UNWISE    ,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
+    /*  h         i          j          k          l          m          n          o      */
+    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
+    /*  p         q          r          s          t          u          v          w      */
+    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
+    /*  x         y          z         {           |          }          ~         DEL     */
+    UNRESERVED,UNRESERVED,UNRESERVED,UNWISE    ,UNWISE    ,UNWISE    ,UNRESERVED,CONTROL
+};
+
+static void
+gnome_vfs_remove_optional_escapes (char *uri)
+{
+	guchar *scanner;
+	int character;
+	int length;
+
+	if (uri == NULL) {
+		return;
+	}
+
+	length = strlen (uri);
+
+	for (scanner = (guchar *)uri; *scanner != '\0'; scanner++, length--) {
+		if (*scanner == HEX_ESCAPE) {
+			character = unescape_character ((char *)scanner + 1);
+			if (character < 0) {
+				/* invalid hexadecimal character */
+				return;
+			}
+
+			if (uri_character_kind [character] == UNRESERVED) {
+				/* This character does not need to be escaped, convert it
+				 * to a non-escaped form.
+				 */
+				*scanner = (guchar)character;
+				g_assert (length >= 3);
+
+				/* Shrink the string covering up the two extra digits of the
+				 * escaped character. Include the trailing '\0' in the copy
+				 * to keep the string terminated.
+				 */
+				memmove (scanner + 1, scanner + 3, length - 2);
+			} else {
+				/* This character must stay escaped, skip the entire
+				 * escaped sequence
+				 */
+				scanner += 2;
+			}
+			length -= 2;
+
+		} else if (*scanner > 127
+			|| uri_character_kind [*scanner] == DELIMITERS
+			|| uri_character_kind [*scanner] == UNWISE
+			|| uri_character_kind [*scanner] == CONTROL) {
+			/* It is illegal for this character to be in an un-escaped form
+			 * in the uri.
+			 */
+			return;
+		}
+	}
+}
+
+static int
+hex_to_int (gchar c)
+{
+	return  c >= '0' && c <= '9' ? c - '0'
+		: c >= 'A' && c <= 'F' ? c - 'A' + 10
+		: c >= 'a' && c <= 'f' ? c - 'a' + 10
+		: -1;
+}
+
+static int
+unescape_character (const char *scanner)
+{
+	int first_digit;
+	int second_digit;
+
+	first_digit = hex_to_int (*scanner++);
+	if (first_digit < 0) {
+		return -1;
+	}
+
+	second_digit = hex_to_int (*scanner++);
+	if (second_digit < 0) {
+		return -1;
+	}
+
+	return (first_digit << 4) | second_digit;
+}
+
+/**
+ * gnome_vfs_unescape_string:
+ * @escaped_string: an escaped uri, path, or other string.
+ * @illegal_characters: a string containing a sequence of characters
+ * considered "illegal" to be escaped, '\0' is automatically in this list.
+ *
+ * Decodes escaped characters (i.e. PERCENTxx sequences) in @escaped_string.
+ * Characters are encoded in PERCENTxy form, where xy is the ASCII hex code
+ * for character 16x+y.
+ *
+ * Return value: a newly allocated string with the unescaped
+ * equivalents, or %NULL if @escaped_string contained an escaped
+ * encoding of one of the characters in @illegal_characters.
+ */
+static char *
+gnome_vfs_unescape_string (const gchar *escaped_string,
+			   const gchar *illegal_characters)
+{
+	const gchar *in;
+	gchar *out, *result;
+	gint character;
+
+	if (escaped_string == NULL) {
+		return NULL;
+	}
+
+	result = g_malloc (strlen (escaped_string) + 1);
+
+	out = result;
+	for (in = escaped_string; *in != '\0'; in++) {
+		character = *in;
+		if (*in == HEX_ESCAPE) {
+			character = unescape_character (in + 1);
+
+			/* Check for an illegal character. We consider '\0' illegal here. */
+			if (character <= 0
+			    || (illegal_characters != NULL
+				&& strchr (illegal_characters, (char)character) != NULL)) {
+				g_free (result);
+				return NULL;
+			}
+			in += 2;
+		}
+		*out++ = (char)character;
+	}
+
+	*out = '\0';
+	g_assert (out - result <= strlen (escaped_string));
+	return result;
+
+}
+
+static void
+set_uri_element (NAGnomeVFSURI *vfs,
+		 const gchar *text,
+		 guint len)
+{
+	char *escaped_text;
+
+	if (text == NULL || len == 0) {
+		vfs->uri = g_strdup ("/");
+		return;
+	}
+
+	if ( text[0] == '/' && text[1] == '/') {
+		vfs->uri = split_toplevel_uri (text + 2, len - 2,
+						&vfs->host_name,
+						&vfs->user_name,
+						&vfs->host_port,
+						&vfs->password);
+	} else {
+		vfs->uri = g_strndup (text, len);
+	}
+
+	/* FIXME: this should be handled/supported by the specific method.
+	 * This is a quick and dirty hack to minimize the amount of changes
+	 * right before a milestone release.
+	 *
+	 * Do some method specific escaping. This for instance converts
+	 * '?' to %3F in every method except "http" where it has a special
+	 * meaning.
+	 */
+	if ( ! (strcmp (vfs->scheme, "http") == 0
+	        || strcmp (vfs->scheme, "https") == 0
+		|| strcmp (vfs->scheme, "dav") == 0
+		|| strcmp (vfs->scheme, "davs") == 0
+	        || strcmp (vfs->scheme, "ghelp") == 0
+	        || strcmp (vfs->scheme, "gnome-help") == 0
+	        || strcmp (vfs->scheme, "help") == 0
+		)) {
+
+		escaped_text = gnome_vfs_escape_set (vfs->uri, ";?&=+$,");
+		g_free (vfs->uri);
+		vfs->uri = escaped_text;
+	}
+
+	gnome_vfs_remove_optional_escapes (vfs->uri);
+	gnome_vfs_canonicalize_pathname (vfs->uri);
+}
+
+/*
+   split_toplevel_uri
+
+   Extract hostname and username from "path" with length "path_len"
+
+   examples:
+       sunsite.unc.edu/pub/linux
+       miguel sphinx nuclecu unam mx/c/nc
+       tsx-11.mit.edu:8192/
+       joe foo edu:11321/private
+       joe:password foo se
+
+   This function implements the following regexp: (whitespace for clarity)
+
+   ( ( ([^:@/]*) (:[^@/]*)? @ )? ([^/:]*) (:([0-9]*)?) )?  (/.*)?
+   ( ( ( user  ) (  pw  )?   )?   (host)    (port)?   )? (path <return value>)?
+
+  It returns NULL if neither <host> nor <path> could be matched.
+
+  port is checked to ensure that it does not exceed 0xffff.
+
+  return value is <path> or is "/" if the path portion is not present
+  All other arguments are set to 0 or NULL if their portions are not present
+
+  pedantic: this function ends up doing an unbounded lookahead, making it
+  potentially O(n^2) instead of O(n).  This could be avoided.  Realistically, though,
+  its just the password field.
+
+  Differences between the old and the new implemention:
+
+                     Old                     New
+  localhost:8080     host="localhost:8080"   host="localhost" port=8080
+  /Users/mikef       host=""                 host=NULL
+
+*/
+
+
+#define URI_MOVE_PAST_DELIMITER \
+	do {							\
+		cur_tok_start = (++cur);			\
+		if (path_end == cur) {				\
+			success = FALSE;			\
+			goto done;				\
+		}						\
+	} while (0);
+
+
+#define uri_strlen_to(from, to)  ( (to) - (from) )
+#define uri_strdup_to(from, to)  g_strndup ((from), uri_strlen_to((from), (to)))
+
+typedef struct {
+	const char *chrs;
+	gboolean primed;
+	char bv[32];
+} UriStrspnSet;
+
+static UriStrspnSet uri_strspn_sets[] = {
+	{":@]" GNOME_VFS_URI_PATH_STR, FALSE, ""},
+	{"@" GNOME_VFS_URI_PATH_STR, FALSE, ""},
+	{":" GNOME_VFS_URI_PATH_STR, FALSE, ""},
+	{"]" GNOME_VFS_URI_PATH_STR, FALSE, ""}
+};
+
+#define URI_DELIMITER_ALL_SET (uri_strspn_sets + 0)
+#define URI_DELIMITER_USER_SET (uri_strspn_sets + 1)
+#define URI_DELIMITER_HOST_SET (uri_strspn_sets + 2)
+#define URI_DELIMITER_IPV6_SET (uri_strspn_sets + 3)
+
+#define BV_SET(bv, idx) (bv)[((guchar)(idx))>>3] |= (1 << ( (idx) & 7) )
+#define BV_IS_SET(bv, idx) ((bv)[((guchar)(idx))>>3] & (1 << ( (idx) & 7)))
+
+static const char *
+uri_strspn_to(const char *str, UriStrspnSet *set, const char *path_end)
+{
+	const char *cur;
+	const char *cur_chr;
+
+	if (!set->primed) {
+		memset (set->bv, 0, sizeof(set->bv));
+
+		for (cur_chr = set->chrs; '\0' != *cur_chr; cur_chr++) {
+			BV_SET (set->bv, *cur_chr);
+		}
+
+		BV_SET (set->bv, '\0');
+		set->primed = TRUE;
+	}
+
+	for (cur = str; cur < path_end && ! BV_IS_SET (set->bv, *cur); cur++)
+		;
+
+	if (cur >= path_end || '\0' == *cur) {
+		return NULL;
+	}
+
+	return cur;
+}
+
+static gchar *
+split_toplevel_uri (const gchar *path, guint path_len,
+		    gchar **host_return, gchar **user_return,
+		    guint *port_return, gchar **password_return)
+{
+	const char *path_end;
+	const char *cur_tok_start;
+	const char *cur;
+	const char *next_delimiter;
+	char *ret;
+	char *host;
+	gboolean success;
+
+	g_assert (host_return != NULL);
+	g_assert (user_return != NULL);
+	g_assert (port_return != NULL);
+	g_assert (password_return != NULL);
+
+	*host_return = NULL;
+	*user_return = NULL;
+	*port_return = 0;
+	*password_return = NULL;
+	ret = NULL;
+
+	success = FALSE;
+
+	if (path == NULL || path_len == 0) {
+		return g_strdup ("/");
+	}
+
+
+	path_end = path + path_len;
+
+	cur_tok_start = path;
+	cur = uri_strspn_to (cur_tok_start, URI_DELIMITER_ALL_SET, path_end);
+
+	if (cur != NULL) {
+		const char *tmp;
+
+		if (*cur == ':') {
+			/* This ':' belongs to username or IPv6 address.*/
+			tmp = uri_strspn_to (cur_tok_start, URI_DELIMITER_USER_SET, path_end);
+
+			if (tmp == NULL || *tmp != '@') {
+				tmp = uri_strspn_to (cur_tok_start, URI_DELIMITER_IPV6_SET, path_end);
+
+				if (tmp != NULL && *tmp == ']') {
+					cur = tmp;
+				}
+			}
+		}
+	}
+
+	if (cur != NULL) {
+
+		/* Check for IPv6 address. */
+		if (*cur == ']') {
+
+			/*  No username:password in the URI  */
+			/*  cur points to ']'  */
+
+			cur = uri_strspn_to (cur, URI_DELIMITER_HOST_SET, path_end);
+		}
+	}
+
+	if (cur != NULL) {
+		next_delimiter = uri_strspn_to (cur, URI_DELIMITER_USER_SET, path_end);
+	} else {
+		next_delimiter = NULL;
+	}
+
+	if (cur != NULL
+		&& (*cur == '@'
+		    || (next_delimiter != NULL && *next_delimiter != '/' ))) {
+
+		/* *cur == ':' or '@' and string contains a @ before a / */
+
+		if (uri_strlen_to (cur_tok_start, cur) > 0) {
+			char *tmp;
+			tmp = uri_strdup_to (cur_tok_start,cur);
+			*user_return = gnome_vfs_unescape_string (tmp, NULL);
+			g_free (tmp);
+		}
+
+		if (*cur == ':') {
+			URI_MOVE_PAST_DELIMITER;
+
+			cur = uri_strspn_to(cur_tok_start, URI_DELIMITER_USER_SET, path_end);
+
+			if (cur == NULL || *cur != '@') {
+				success = FALSE;
+				goto done;
+			} else if (uri_strlen_to (cur_tok_start, cur) > 0) {
+				char *tmp;
+				tmp = uri_strdup_to (cur_tok_start,cur);
+				*password_return = gnome_vfs_unescape_string (tmp, NULL);
+				g_free (tmp);
+			}
+		}
+
+		if (*cur != '/') {
+			URI_MOVE_PAST_DELIMITER;
+
+			/* Move cur to point to ':' after ']' */
+			cur = uri_strspn_to (cur_tok_start, URI_DELIMITER_IPV6_SET, path_end);
+
+			if (cur != NULL && *cur == ']') {  /* For IPv6 address */
+				cur = uri_strspn_to (cur, URI_DELIMITER_HOST_SET, path_end);
+			} else {
+				cur = uri_strspn_to (cur_tok_start, URI_DELIMITER_HOST_SET, path_end);
+			}
+		} else {
+			cur_tok_start = cur;
+		}
+	}
+
+	if (cur == NULL) {
+		/* [^:/]+$ */
+		if (uri_strlen_to (cur_tok_start, path_end) > 0) {
+			*host_return = uri_strdup_to (cur_tok_start, path_end);
+			if (*(path_end - 1) == GNOME_VFS_URI_PATH_CHR) {
+				ret = g_strdup (GNOME_VFS_URI_PATH_STR);
+			} else {
+				ret = g_strdup ("");
+			}
+			success = TRUE;
+		} else { /* No host, no path */
+			success = FALSE;
+		}
+
+		goto done;
+
+	} else if (*cur == ':') {
+		guint port;
+		/* [^:/]*:.* */
+
+		if (uri_strlen_to (cur_tok_start, cur) > 0) {
+			*host_return = uri_strdup_to (cur_tok_start, cur);
+		} else {
+			success = FALSE;
+			goto done;	/*No host but a port?*/
+		}
+
+		URI_MOVE_PAST_DELIMITER;
+
+		port = 0;
+
+		for ( ; cur < path_end && g_ascii_isdigit (*cur); cur++) {
+			port *= 10;
+			port += *cur - '0';
+		}
+
+		/* We let :(/.*)$ be treated gracefully */
+		if (*cur != '\0' && *cur != GNOME_VFS_URI_PATH_CHR) {
+			success = FALSE;
+			goto done;	/* ...but this would be an error */
+		}
+
+		if (port > 0xffff) {
+			success = FALSE;
+			goto done;
+		}
+
+		*port_return = port;
+
+		cur_tok_start = cur;
+
+	} else /* GNOME_VFS_URI_PATH_CHR == *cur */ {
+		/* ^[^:@/]+/.*$ */
+
+		if (uri_strlen_to (cur_tok_start, cur) > 0) {
+			*host_return = uri_strdup_to (cur_tok_start, cur);
+		}
+
+		cur_tok_start = cur;
+	}
+
+	if (*cur_tok_start != '\0' && uri_strlen_to (cur_tok_start, path_end) > 0) {
+		ret = uri_strdup_to(cur, path_end);
+	} else if (*host_return != NULL) {
+		ret = g_strdup (GNOME_VFS_URI_PATH_STR);
+	}
+
+	success = TRUE;
+
+done:
+	if (*host_return != NULL) {
+
+		/* Check for an IPv6 address in square brackets.*/
+		if (strchr (*host_return, '[') && strchr (*host_return, ']') && strchr (*host_return, ':')) {
+
+			/* Extract the IPv6 address from square braced string. */
+			host = g_ascii_strdown ((*host_return) + 1, strlen (*host_return) - 2);
+		} else {
+			host = g_ascii_strdown (*host_return, -1);
+		}
+
+		g_free (*host_return);
+		*host_return = host;
+
+	}
+
+	/* If we didn't complete our mission, discard all the partials */
+	if (!success) {
+		g_free (*host_return);
+		g_free (*user_return);
+		g_free (*password_return);
+		g_free (ret);
+
+		*host_return = NULL;
+		*user_return = NULL;
+		*port_return = 0;
+		*password_return = NULL;
+		ret = NULL;
+	}
+
+	return ret;
+}
diff --git a/src/common/na-gnome-vfs-uri.h b/src/common/na-gnome-vfs-uri.h
new file mode 100644
index 0000000..411040b
--- /dev/null
+++ b/src/common/na-gnome-vfs-uri.h
@@ -0,0 +1,108 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NA_GNOME_VFS_URI_H__
+#define __NA_GNOME_VFS_URI_H__
+
+/*
+ * pwi 2009-07-29
+ * shamelessly pull out of GnomeVFS (gnome-vfs-uri and consorts)
+ */
+
+/* gnome-vfs-uri.h - URI handling for the GNOME Virtual File System.
+
+   Copyright (C) 1999 Free Software Foundation
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Ettore Perazzoli <ettore comm2000 it> */
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+	gchar *uri;
+	gchar *scheme;
+	gchar *host_name;
+	guint  host_port;
+	gchar *user_name;
+	gchar *password;
+}
+	NAGnomeVFSURI;
+
+/**
+ * GNOME_VFS_URI_MAGIC_CHR:
+ *
+ * The character used to divide location from
+ * extra "arguments" passed to the method.
+ **/
+/**
+ * GNOME_VFS_URI_MAGIC_STR:
+ *
+ * The character used to divide location from
+ * extra "arguments" passed to the method.
+ **/
+#define GNOME_VFS_URI_MAGIC_CHR	'#'
+#define GNOME_VFS_URI_MAGIC_STR "#"
+
+/**
+ * GNOME_VFS_URI_PATH_CHR:
+ *
+ * Defines the path seperator character.
+ **/
+/**
+ * GNOME_VFS_URI_PATH_STR:
+ *
+ * Defines the path seperator string.
+ **/
+#define GNOME_VFS_URI_PATH_CHR '/'
+#define GNOME_VFS_URI_PATH_STR "/"
+
+void na_gnome_vfs_uri_parse( NAGnomeVFSURI *vfs, const gchar *uri );
+
+void na_gnome_vfs_uri_free( NAGnomeVFSURI *vfs );
+
+G_END_DECLS
+
+#endif /* __NA_GNOME_VFS_URI_H__ */
diff --git a/src/common/na-xml-names.h b/src/common/na-xml-names.h
index 659e400..36ebe72 100644
--- a/src/common/na-xml-names.h
+++ b/src/common/na-xml-names.h
@@ -109,7 +109,7 @@ enum {
 #define ACTION_PATH_DESC_SHORT		_("The path of the command")
 #define ACTION_PATH_DESC_LONG		_("The path of the command to start when the user select the menu item in the Nautilus popup menu")
 #define ACTION_PARAMETERS_DESC_SHORT _("The parameters of the command")
-#define ACTION_PARAMETERS_DESC_LONG	_("The parameters of the command to start when the user selects the menu item in the Nautilus popup menu.\n\nThe parameters can contain some special tokens which are replaced by Nautilus information before starting the command:\n\n%d: base folder of the selected file(s)\n%f: the name of the selected file or the first one if many are selected\n%m: space-separated list of the basenames of the selected file(s)/folder(s)\n%M: space-separated list of the selected file(s)/folder(s), with their full paths\n%u: GVFS URI\n%s: scheme of the GVFS URI\n%h: hostname of the GVFS URI\n%U: username of the GVFS URI\n%%: a percent sign")
+#define ACTION_PARAMETERS_DESC_LONG	_("The parameters of the command to start when the user selects the menu item in the Nautilus popup menu.\n\nThe parameters can contain some special tokens which are replaced by Nautilus information before starting the command:\n\n%d: base folder of the selected file(s)\n%f: the name of the selected file or the first one if many are selected\n%h: hostname of the URI\n%m: space-separated list of the basenames of the selected file(s)/folder(s)\n%M: space-separated list of the selected file(s)/folder(s), with their full paths\n%s: scheme of the URI\n%u: URI\n%U: username of the URI\n%%: a percent sign")
 #define ACTION_BASENAMES_DESC_SHORT	_("The list of pattern to match the selected file(s)/folder(s)")
 #define ACTION_BASENAMES_DESC_LONG	_("A list of strings with joker '*' or '?' to match the name of the selected file(s)/folder(s). Each selected items must match at least one of the filename patterns for the action to appear")
 #define ACTION_MATCHCASE_DESC_SHORT _("'true' if the filename patterns have to be case sensitive, 'false' otherwise")
@@ -122,8 +122,8 @@ enum {
 #define ACTION_ISDIR_DESC_LONG		_("This setting is tied in with the 'isfile' setting. The valid combinations are:\n\nisfile=TRUE and isdir=FALSE: the selection may hold only files\nisfile=FALSE and isdir=TRUE: the selection may hold only folders\nisfile=TRUE and isdir=TRUE: the selection may hold both files and folders\nisfile=FALSE and isdir=FALSE: this is an invalid combination (your configuration will never appear)")
 #define ACTION_MULTIPLE_DESC_SHORT	_("'true' if the selection can have several items, 'false' otherwise")
 #define ACTION_MULTIPLE_DESC_LONG	_("If you need one or more files or folders to be selected, set this key to 'true'. If you want just one file or folder, set 'false'")
-#define ACTION_SCHEMES_DESC_SHORT	_("The list of GVFS schemes where the selected files should be located")
-#define ACTION_SCHEMES_DESC_LONG	_("Defines the list of valid GVFS schemes to be matched against the selected items. The GVFS scheme is the protocol used to access the files. The keyword to use is the one used in the GVFS URI.\n\nExamples of GVFS URI include: \nfile:///tmp/foo.txt\nsftp:///root test example net/tmp/foo.txt\n\nThe most common schemes are:\n\n'file': local files\n'sftp': files accessed via SSH\n'ftp': files accessed via FTP\n'smb': files accessed via Samba (Windows share)\n'dav': files accessed via WebDav\n\nAll GVFS schemes used by Nautilus can be used here.")
+#define ACTION_SCHEMES_DESC_SHORT	_("The list of schemes where the selected files should be located")
+#define ACTION_SCHEMES_DESC_LONG	_("Defines the list of valid schemes to be matched against the selected items. The scheme is the protocol used to access the files. The keyword to use is the one used in the URI.\n\nExamples of URI include: \nfile:///tmp/foo.txt\nsftp:///root test example net/tmp/foo.txt\n\nThe most common schemes are:\n\n'file': local files\n'sftp': files accessed via SSH\n'ftp': files accessed via FTP\n'smb': files accessed via Samba (Windows share)\n'dav': files accessed via WebDAV\n\nAll schemes used by Nautilus can be used here.")
 #define ACTION_VERSION_DESC_SHORT	_("The version of the configuration format")
 #define ACTION_VERSION_DESC_LONG	_("The version of the configuration format that will be used to manage backward compatibility")
 
diff --git a/src/nact/nautilus-actions-config-tool.ui b/src/nact/nautilus-actions-config-tool.ui
index 8325888..6155dd8 100644
--- a/src/nact/nautilus-actions-config-tool.ui
+++ b/src/nact/nautilus-actions-config-tool.ui
@@ -884,8 +884,8 @@
       <object class="GtkFileChooserWidget" id="filechooserwidget1">
         <property name="visible">True</property>
         <property name="orientation">vertical</property>
-        <property name="select_multiple">True</property>
         <property name="local_only">False</property>
+        <property name="select_multiple">True</property>
         <property name="use_preview_label">False</property>
         <property name="preview_widget_active">False</property>
       </object>
@@ -970,10 +970,10 @@ to extend a selection.</property>
           <object class="GtkFileChooserWidget" id="ExportFolderChooser">
             <property name="visible">True</property>
             <property name="orientation">vertical</property>
-            <property name="action">select-folder</property>
             <property name="local_only">False</property>
             <property name="use_preview_label">False</property>
             <property name="preview_widget_active">False</property>
+            <property name="action">select-folder</property>
           </object>
           <packing>
             <property name="position">0</property>
@@ -1289,7 +1289,7 @@ The exported file may later be imported via :
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
-                <property name="label" translatable="yes">&lt;b&gt;%h&lt;/b&gt;: hostname of the GVFS URI</property>
+                <property name="label" translatable="yes">&lt;b&gt;%h&lt;/b&gt;: hostname of the URI</property>
                 <property name="use_markup">True</property>
                 <property name="wrap">True</property>
               </object>
@@ -1335,7 +1335,7 @@ file(s)/folder(s)</property>
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
-                <property name="label" translatable="yes">&lt;b&gt;%s&lt;/b&gt;: scheme of the GVFS URI</property>
+                <property name="label" translatable="yes">&lt;b&gt;%s&lt;/b&gt;: scheme of the URI</property>
                 <property name="use_markup">True</property>
                 <property name="wrap">True</property>
               </object>
@@ -1350,7 +1350,7 @@ file(s)/folder(s)</property>
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
-                <property name="label" translatable="yes">&lt;b&gt;%u&lt;/b&gt;: GVFS URI</property>
+                <property name="label" translatable="yes">&lt;b&gt;%u&lt;/b&gt;: URI</property>
                 <property name="use_markup">True</property>
                 <property name="wrap">True</property>
               </object>
@@ -1365,7 +1365,7 @@ file(s)/folder(s)</property>
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
-                <property name="label" translatable="yes">&lt;b&gt;%U&lt;/b&gt;: username of the GVFS URI</property>
+                <property name="label" translatable="yes">&lt;b&gt;%U&lt;/b&gt;: username of the URI</property>
                 <property name="use_markup">True</property>
                 <property name="wrap">True</property>
               </object>
@@ -1400,16 +1400,16 @@ file(s)/folder(s)</property>
   </object>
   <object class="GtkSizeGroup" id="CommandLabelSizeGroup">
     <widgets>
-      <widget name="CommandExamplePreLabel"/>
-      <widget name="CommandParametersLabel"/>
-      <widget name="CommandPathLabel"/>
       <widget name="ProfileLabelLabel"/>
+      <widget name="CommandPathLabel"/>
+      <widget name="CommandParametersLabel"/>
+      <widget name="CommandExamplePreLabel"/>
     </widgets>
   </object>
   <object class="GtkSizeGroup" id="CommandButtonSizeGroup">
     <widgets>
-      <widget name="CommandLegendButton"/>
       <widget name="CommandPathButton"/>
+      <widget name="CommandLegendButton"/>
     </widgets>
   </object>
 </interface>
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
new file mode 100644
index 0000000..58666f0
--- /dev/null
+++ b/src/test/Makefile.am
@@ -0,0 +1,47 @@
+# Nautilus Actions
+# A Nautilus extension which offers configurable context menu actions.
+#
+# Copyright (C) 2005 The GNOME Foundation
+# Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+# Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
+#
+# This Program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This Program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this Library; see the file COPYING.  If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place,
+# Suite 330, Boston, MA 02111-1307, USA.
+#
+# Authors:
+#   Frederic Ruaudel <grumz grumz net>
+#   Rodrigo Moya <rodrigo gnome-db org>
+#   Pierre Wieser <pwieser trychlos org>
+#   ... and many others (see AUTHORS)
+
+noinst_PROGRAMS = \
+	test-parse-uris									\
+	$(NULL)
+
+AM_CPPFLAGS += \
+	-I $(top_srcdir)/src							\
+	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"		\
+	$(NAUTILUS_ACTIONS_CFLAGS)						\
+	-DG_LOG_DOMAIN=\"${NA_LOGDOMAIN_TEST}\"			\
+	$(NULL)
+
+test_parse_uris_SOURCES = \
+	test-parse-uris.c								\
+	$(NULL)
+
+test_parse_uris_LDADD = \
+	$(top_builddir)/src/common/libnact.la			\
+	$(NAUTILUS_ACTIONS_LIBS)						\
+	$(NULL)
diff --git a/src/test/test-parse-uris b/src/test/test-parse-uris
new file mode 100755
index 0000000..87c0c22
Binary files /dev/null and b/src/test/test-parse-uris differ
diff --git a/src/test/test-parse-uris.c b/src/test/test-parse-uris.c
new file mode 100644
index 0000000..6a4b5d2
--- /dev/null
+++ b/src/test/test-parse-uris.c
@@ -0,0 +1,71 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib-object.h>
+#include <glib/gprintf.h>
+#include <glib/gi18n.h>
+#include <stdlib.h>
+
+#include <common/na-gnome-vfs-uri.h>
+
+static const gchar *uris[] = {
+		"http://robert:azerty01 mon domain com/path/to/a/document?query#anchor",
+		"ssh://pwi.dyndns.biz:2207",
+		"sftp://kde.org:1234/pub/kde";,
+		"/usr/bin/nautilus-actions-config-tool",
+		NULL
+};
+
+int
+main( int argc, char** argv )
+{
+	g_type_init();
+	g_printf( _( "URIs parsing test.\n\n" ));
+
+	int i;
+	for( i = 0 ; uris[i] ; ++i ){
+		NAGnomeVFSURI *vfs = g_new0( NAGnomeVFSURI, 1 );
+		na_gnome_vfs_uri_parse( vfs, uris[i] );
+		g_printf( "original  uri=%s\n", uris[i] );
+		g_printf( "vfs       uri=%s\n", vfs->uri );
+		g_printf( "vfs    scheme=%s\n", vfs->scheme );
+		g_printf( "vfs host_name=%s\n", vfs->host_name );
+		g_printf( "vfs host_port=%d\n", vfs->host_port );
+		g_printf( "vfs user_name=%s\n", vfs->user_name );
+		g_printf( "vfs  password=%s\n", vfs->password );
+		g_printf( "\n" );
+	}
+
+	return( EXIT_SUCCESS );
+}
diff --git a/src/utils/nautilus-actions-new.c b/src/utils/nautilus-actions-new.c
index e43ac21..921adc3 100644
--- a/src/utils/nautilus-actions-new.c
+++ b/src/utils/nautilus-actions-new.c
@@ -90,7 +90,7 @@ static void            exit_with_usage( void );
 int
 main( int argc, char** argv )
 {
-	g_type_init ();
+	g_type_init();
 
 	int status = EXIT_SUCCESS;
 
diff --git a/src/utils/nautilus-actions-schema.c b/src/utils/nautilus-actions-schema.c
index 9dca5b1..0f862dd 100644
--- a/src/utils/nautilus-actions-schema.c
+++ b/src/utils/nautilus-actions-schema.c
@@ -62,7 +62,7 @@ static void            exit_with_usage( void );
 int
 main( int argc, char** argv )
 {
-	g_type_init ();
+	g_type_init();
 
 	int status = EXIT_SUCCESS;
 



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