GMutex (linux): detect and report some errors
[platform/upstream/glib.git] / glib / gshell.c
index 205519e..a1c7e79 100644 (file)
 #include "gstring.h"
 #include "gtestutils.h"
 #include "glibintl.h"
+#include "gthread.h"
 
 /**
  * SECTION:shell
  * @title: Shell-related Utilities
  * @short_description: shell-like commandline handling
- **/
+ *
+ * GLib provides the functions g_shell_quote() and g_shell_unquote()
+ * to handle shell-like quoting in strings. The function g_shell_parse_argv()
+ * parses a string similar to the way a POSIX shell (/bin/sh) would.
+ *
+ * Note that string handling in shells has many obscure and historical
+ * corner-cases which these functions do not necessarily reproduce. They
+ * are good enough in practice, though.
+ */
 
 /**
  * G_SHELL_ERROR:
  *
  * Error codes returned by shell functions.
  **/
-GQuark
-g_shell_error_quark (void)
-{
-  return g_quark_from_static_string ("g-shell-error-quark");
-}
+G_DEFINE_QUARK (g-shell-error-quark, g_shell_error)
 
 /* Single quotes preserve the literal string exactly. escape
  * sequences are not allowed; not even \' - if you want a '
@@ -194,7 +199,7 @@ unquote_string_inplace (gchar* str, gchar** end, GError** err)
  * quoting style used is undefined (single or double quotes may be
  * used).
  * 
- * Return value: quoted string
+ * Returns: quoted string
  **/
 gchar*
 g_shell_quote (const gchar *unquoted_string)
@@ -260,7 +265,7 @@ g_shell_quote (const gchar *unquoted_string)
  * be escaped with backslash. Otherwise double quotes preserve things
  * literally.
  *
- * Return value: an unquoted string
+ * Returns: an unquoted string
  **/
 gchar*
 g_shell_unquote (const gchar *quoted_string,
@@ -521,12 +526,30 @@ tokenize_command_line (const gchar *command_line,
               g_string_append_c (current_token, *p);
 
               /* FALL THRU */
-              
-            case '#':
             case '\\':
               current_quote = *p;
               break;
 
+            case '#':
+              if (p == command_line)
+               { /* '#' was the first char */
+                  current_quote = *p;
+                  break;
+                }
+              switch(*(p-1))
+                {
+                  case ' ':
+                  case '\n':
+                  case '\0':
+                    current_quote = *p;
+                    break;
+                  default:
+                    ensure_token (&current_token);
+                    g_string_append_c (current_token, *p);
+                   break;
+                }
+              break;
+
             default:
               /* Combines rules 4) and 6) - if we have a token, append to it,
                * otherwise create a new token.
@@ -596,9 +619,10 @@ tokenize_command_line (const gchar *command_line,
 /**
  * g_shell_parse_argv:
  * @command_line: command line to parse
- * @argcp: (out): return location for number of args
- * @argvp: (out) (array length=argcp zero-terminated=1): return location for array of args
- * @error: return location for error
+ * @argcp: (out) (optional): return location for number of args, or %NULL
+ * @argvp: (out) (optional) (array length=argcp zero-terminated=1): return
+ *   location for array of args, or %NULL
+ * @error: (optional): return location for error, or %NULL
  * 
  * Parses a command line into an argument vector, in much the same way
  * the shell would, but without many of the expansions the shell would
@@ -610,7 +634,7 @@ tokenize_command_line (const gchar *command_line,
  * literally. Possible errors are those from the #G_SHELL_ERROR
  * domain. Free the returned vector with g_strfreev().
  * 
- * Return value: %TRUE on success, %FALSE if error set
+ * Returns: %TRUE on success, %FALSE if error set
  **/
 gboolean
 g_shell_parse_argv (const gchar *command_line,