Merge remote branch 'gvdb/master'
[platform/upstream/glib.git] / glib / gshell.c
index 08318fd..d3b76f4 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
-#include <config.h>
+#include "config.h"
 
-#include "glib.h"
 #include <string.h>
 
+#include "glib.h"
+
 #ifdef _
 #warning "FIXME remove gettext hack"
 #endif
 
 #include "glibintl.h"
+#include "galias.h"
+
+/**
+ * SECTION: shell
+ * @title: Shell-related Utilities
+ * @short_description: shell-like commandline handling
+ **/
+
+/**
+ * G_SHELL_ERROR:
+ *
+ * Error domain for shell functions. Errors in this domain will be from
+ * the #GShellError enumeration. See #GError for information on error
+ * domains.
+ **/
 
+/**
+ * GShellError:
+ * @G_SHELL_ERROR_BAD_QUOTING: Mismatched or otherwise mangled quoting.
+ * @G_SHELL_ERROR_EMPTY_STRING: String to be parsed was empty.
+ * @G_SHELL_ERROR_FAILED: Some other error.
+ *
+ * Error codes returned by shell functions.
+ **/
 GQuark
 g_shell_error_quark (void)
 {
-  static GQuark quark = 0;
-  if (quark == 0)
-    quark = g_quark_from_static_string ("g-shell-error-quark");
-  return quark;
+  return g_quark_from_static_string ("g-shell-error-quark");
 }
 
 /* Single quotes preserve the literal string exactly. escape
@@ -65,8 +86,8 @@ unquote_string_inplace (gchar* str, gchar** end, GError** err)
   
   if (!(*s == '"' || *s == '\''))
     {
-      if (err)
-        *err = g_error_new(G_SHELL_ERROR,
+      g_set_error_literal (err,
+                           G_SHELL_ERROR,
                            G_SHELL_ERROR_BAD_QUOTING,
                            _("Quoted text doesn't begin with a quotation mark"));
       *end = str;
@@ -155,8 +176,8 @@ unquote_string_inplace (gchar* str, gchar** end, GError** err)
 
   *dest = '\0';
   
-  if (err)
-    *err = g_error_new(G_SHELL_ERROR,
+  g_set_error_literal (err,
+                       G_SHELL_ERROR,
                        G_SHELL_ERROR_BAD_QUOTING,
                        _("Unmatched quotation mark in command line or other shell-quoted text"));
   *end = s;
@@ -257,7 +278,7 @@ g_shell_unquote (const gchar *quoted_string,
 
   start = unquoted;
   end = unquoted;
-  retval = g_string_new ("");
+  retval = g_string_new (NULL);
 
   /* The loop allows cases such as
    * "foo"blah blah'bar'woo foo"baz"la la la\'\''foo'
@@ -389,7 +410,7 @@ static inline void
 ensure_token (GString **token)
 {
   if (*token == NULL)
-    *token = g_string_new ("");
+    *token = g_string_new (NULL);
 }
 
 static void
@@ -412,10 +433,12 @@ tokenize_command_line (const gchar *command_line,
   const gchar *p;
   GString *current_token = NULL;
   GSList *retval = NULL;
-  
+  gboolean quoted;;
+
   current_quote = '\0';
+  quoted = FALSE;
   p = command_line;
-
   while (*p)
     {
       if (current_quote == '\\')
@@ -451,7 +474,7 @@ tokenize_command_line (const gchar *command_line,
         {
           if (*p == current_quote &&
               /* check that it isn't an escaped double quote */
-              !(current_quote == '"' && p != command_line && *(p - 1) == '\\'))
+              !(current_quote == '"' && quoted))
             {
               /* close the quote */
               current_quote = '\0';
@@ -515,6 +538,14 @@ tokenize_command_line (const gchar *command_line,
             }
         }
 
+      /* We need to count consecutive backslashes mod 2, 
+       * to detect escaped doublequotes.
+       */
+      if (*p != '\\')
+       quoted = FALSE;
+      else
+       quoted = !quoted;
+
       ++p;
     }
 
@@ -542,10 +573,10 @@ tokenize_command_line (const gchar *command_line,
 
   if (retval == NULL)
     {
-      g_set_error (error,
-                   G_SHELL_ERROR,
-                   G_SHELL_ERROR_EMPTY_STRING,
-                   _("Text was empty (or contained only whitespace)"));
+      g_set_error_literal (error,
+                           G_SHELL_ERROR,
+                           G_SHELL_ERROR_EMPTY_STRING,
+                           _("Text was empty (or contained only whitespace)"));
 
       goto error;
     }
@@ -659,3 +690,6 @@ g_shell_parse_argv (const gchar *command_line,
   
   return FALSE;
 }
+
+#define __G_SHELL_C__
+#include "galiasdef.c"