changeset 1248:4d96c17d0c49

.
author Jim Meyering <jim@meyering.net>
date Mon, 23 Feb 1998 10:16:53 +0000
parents d48d2e0fa40f
children 260ad4ecb45a
files lib/quotearg.c lib/quotearg.h
diffstat 2 files changed, 443 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/lib/quotearg.c
@@ -0,0 +1,346 @@
+/* quotearg.c - quote arguments for output
+   Copyright (C) 1998 Free Software Foundation, Inc.
+
+   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, 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 program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Written by Paul Eggert <eggert@twinsun.com> */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <quotearg.h>
+#include <xalloc.h>
+
+#include <ctype.h>
+#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
+# define ISASCII(c) 1
+#else
+# define ISASCII(c) isascii (c)
+#endif
+#ifdef isgraph
+# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
+#else
+# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
+#endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+#ifndef CHAR_BIT
+# define CHAR_BIT 8
+#endif
+#ifndef UCHAR_MAX
+# define UCHAR_MAX ((unsigned char) -1)
+#endif
+
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#define INT_BITS (sizeof (int) * CHAR_BIT)
+
+struct quoting_options
+{
+  /* Basic quoting style.  */
+  enum quoting_style style;
+
+  /* Quote the chararacters indicated by this bit vector even if the
+     quoting style would not normally require them to be quoted.  */
+  int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
+		       + ((UCHAR_MAX + 1) % INT_BITS != 0))];
+};
+
+/* Names of quoting styles.  */
+char const *const quoting_style_args[] =
+{
+  "literal", "shell", "shell-always", "c", "escape", 0
+};
+
+/* Allocate a new set of quoting options, with contents initially identical
+   to O if O is not null, or to a default value if O is null.
+   It is the caller's responsibility to free the result.  */
+struct quoting_options *
+clone_quoting_options (struct quoting_options *o)
+{
+  struct quoting_options *p
+    = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
+  if (o)
+    *p = *o;
+  else
+    memset (p, 0, sizeof *p);
+  return p;
+}
+
+/* Get the value of O's quoting style.  */
+enum quoting_style
+get_quoting_style (struct quoting_options *o)
+{
+  return o->style;
+}
+
+/* In O, set the value of the quoting style to S.  */
+void
+set_quoting_style (struct quoting_options *o, enum quoting_style s)
+{
+  o->style = s;
+}
+
+/* In O, set the value of the quoting options for character C to I.
+   Return the old value.  Currently, the only values defined for I are
+   0 (the default) and 1 (which means to quote the character even if
+   it would not otherwise be quoted).  */
+int
+set_char_quoting (struct quoting_options *o, char c, int i)
+{
+  unsigned char uc = c;
+  int *p = o->quote_these_too + uc / INT_BITS;
+  int shift = uc % INT_BITS;
+  int r = (*p >> shift) & 1;
+  *p ^= ((i & 1) ^ r) << shift;
+  return r;
+}
+
+/* Place into buffer BUF (of size BUFSIZE) a quoted version of
+   argument ARG (of size ARGSIZE), using O to control quoting.
+   Terminate the output with a null character, and return the written
+   size of the output, not counting the terminating null.
+   If BUFSIZE is too small to store the output string, return the
+   value that would have been returned had BUFSIZE been large enough.
+   If ARGSIZE is -1, use the string length of the argument for ARGSIZE.  */
+size_t
+quotearg_buffer (char *buf, size_t bufsize,
+		 char const *arg, size_t argsize,
+		 struct quoting_options const *o)
+{
+  unsigned char c;
+  size_t i;
+  size_t len;
+  int quote_mark;
+  enum quoting_style quoting_style = o->style;
+#define STORE(c) do { if (len < bufsize) buf[len] = (c); len++; } while (0)
+
+  switch (quoting_style)
+    {
+    case shell_quoting_style:
+      if (! (argsize == -1 ? arg[0] == '\0' : argsize == 0))
+	{
+	  switch (arg[0])
+	    {
+	    case '#': case '~':
+	      break;
+
+	    default:
+	      len = 0;
+	      for (i = 0; ; i++)
+		{
+		  if (argsize == -1 ? arg[i] == '\0' : i == argsize)
+		    goto done;
+
+		  c = arg[i];
+
+		  switch (c)
+		    {
+		    case '\t': case '\n': case ' ':
+		    case '!': /* special in csh */
+		    case '"': case '$': case '&': case '\'':
+		    case '(': case ')': case '*': case ';':
+		    case '<': case '>': case '?': case '[': case '\\':
+		    case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
+		    case '`': case '|':
+		      goto needs_quoting;
+		    }
+
+		  if (o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
+		    goto needs_quoting;
+
+		  STORE (c);
+		}
+
+	    needs_quoting:;
+	      break;
+	    }
+	}
+      /* Fall through.  */
+
+    case shell_always_quoting_style:
+      quote_mark = '\'';
+      break;
+
+    case c_quoting_style:
+      quote_mark = '"';
+      break;
+
+    default:
+      quote_mark = 0;
+      break;
+    }
+
+  len = 0;
+
+  if (quote_mark)
+    STORE (quote_mark);
+
+  for (i = 0;  ! (argsize == -1 ? arg[i] == '\0' : i == argsize);  i++)
+    {
+      c = arg[i];
+
+      switch (quoting_style)
+	{
+	case literal_quoting_style:
+	  break;
+
+	case shell_quoting_style:
+	case shell_always_quoting_style:
+	  if (c == '\'')
+	    {
+	      STORE ('\'');
+	      STORE ('\\');
+	      STORE ('\'');
+	    }
+	  break;
+
+	case c_quoting_style:
+	case escape_quoting_style:
+	  switch (c)
+	    {
+	    case '?': /* Do not generate trigraphs.  */
+	    case '\\': goto store_escape;
+	      /* Not all C compilers know what \a means.  */
+	    case   7 : c = 'a'; goto store_escape;
+	    case '\b': c = 'b'; goto store_escape;
+	    case '\f': c = 'f'; goto store_escape;
+	    case '\n': c = 'n'; goto store_escape;
+	    case '\r': c = 'r'; goto store_escape;
+	    case '\t': c = 't'; goto store_escape;
+	    case '\v': c = 'v'; goto store_escape;
+
+	    case ' ':
+	      if (quoting_style == escape_quoting_style)
+		goto store_escape;
+	      break;
+
+	    case '"':
+	      if (quoting_style == c_quoting_style)
+		goto store_escape;
+	      break;
+
+	    default:
+	      if (!ISGRAPH (c))
+		{
+		  STORE ('\\');
+		  STORE ('0' + (c >> 6));
+		  STORE ('0' + ((c >> 3) & 3));
+		  c = '0' + (c & 3);
+		  goto store_c;
+		}
+	      break;
+	    }
+
+	  if (! (o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
+	    goto store_c;
+
+	store_escape:
+	  STORE ('\\');
+	}
+
+    store_c:
+      STORE (c);
+    }
+
+  if (quote_mark)
+    STORE (quote_mark);
+
+ done:
+  if (len < bufsize)
+    buf[len] = '\0';
+  return len;
+}
+
+/* Use storage slot N to return a quoted version of the string ARG.
+   OPTIONS specifies the quoting options.
+   The returned value points to static storage that can be
+   reused by the next call to this function with the same value of N.
+   N must be nonnegative.  */
+static char *
+quotearg_n_options (int n, char const *arg, struct quoting_options *options)
+{
+  static unsigned nslots;
+  static struct slotvec
+    {
+      size_t size;
+      char *val;
+    } *slotvec;
+
+  if (nslots <= n)
+    {
+      int n1 = n + 1;
+      size_t s = n1 * sizeof (struct slotvec);
+      if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
+	abort ();
+      slotvec = (struct slotvec *) xrealloc (slotvec, s);
+      memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
+      nslots = n;
+    }
+
+  {
+    size_t size = slotvec[n].size;
+    char *val = slotvec[n].val;
+    size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
+
+    if (size <= qsize)
+      {
+	slotvec[n].size = size = qsize + 1;
+	slotvec[n].val = val = xrealloc (val, size);
+	quotearg_buffer (val, size, arg, (size_t) -1, options);
+      }
+
+    return val;
+  }
+}
+
+struct quoting_options quotearg_quoting_options;
+
+char *
+quotearg_n (int n, char const *arg)
+{
+  return quotearg_n_options (n, arg, &quotearg_quoting_options);
+}
+
+char *
+quotearg (char const *arg)
+{
+  return quotearg_n (0, arg);
+}
+
+char *
+quotearg_char (char const *arg, char ch)
+{
+  struct quoting_options options;
+  options = quotearg_quoting_options;
+  set_char_quoting (&options, ch, 1);
+  return quotearg_n_options (0, arg, &options);
+}
+
+char *
+quotearg_colon (char const *arg)
+{
+  return quotearg_char (arg, ':');
+}
new file mode 100644
--- /dev/null
+++ b/lib/quotearg.h
@@ -0,0 +1,97 @@
+/* quotearg.h - quote arguments for output
+   Copyright (C) 1998 Free Software Foundation, Inc.
+
+   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, 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 program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Written by Paul Eggert <eggert@twinsun.com> */
+
+/* Basic quoting styles.  */
+enum quoting_style
+  {
+    literal_quoting_style,	/* --quoting-style=literal */
+    shell_quoting_style,	/* --quoting-style=shell */
+    shell_always_quoting_style,	/* --quoting-style=shell-always */
+    c_quoting_style,		/* --quoting-style=c */
+    escape_quoting_style	/* --quoting-style=escape */
+  };
+
+/* For now, --quoting-style=literal is the default, but
+   this is planned to change to --quoting-style=shell in the future.  */
+#ifndef DEFAULT_QUOTING_STYLE
+# define DEFAULT_QUOTING_STYLE literal_quoting_style
+#endif
+
+/* Names of quoting styles.  */
+extern char const *const quoting_style_args[];
+
+struct quoting_options;
+
+#ifndef PARAMS
+# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
+#  define PARAMS(Args) Args
+# else
+#  define PARAMS(Args) ()
+# endif
+#endif
+
+/* Allocate a new set of quoting options, with contents initially identical
+   to O if O is not null, or to a default value if O is null.
+   It is the caller's responsibility to free the result.  */
+struct quoting_options *clone_quoting_options
+   PARAMS ((struct quoting_options *o));
+
+/* Get the value of O's quoting style.  */
+enum quoting_style get_quoting_style PARAMS ((struct quoting_options *o));
+
+/* In O, set the value of the quoting style to S.  */
+void set_quoting_style PARAMS ((struct quoting_options *o,
+				enum quoting_style s));
+
+/* In O, set the value of the quoting options for character C to I.
+   Return the old value.  Currently, the only values defined for I are
+   0 (the default) and 1 (which means to quote the character even if
+   it would not otherwise be quoted).  */
+int set_char_quoting PARAMS ((struct quoting_options *o, char c, int i));
+
+/* Place into buffer BUF (of size BUFSIZE) a quoted version of
+   argument ARG (of size ARGSIZE), using O to control quoting.
+   Terminate the output with a null character, and return the written
+   size of the output, not counting the terminating null.
+   If BUFSIZE is too small to store the output string, return the
+   value that would have been returned had BUFSIZE been large enough.
+   If ARGSIZE is -1, use the string length of the argument for ARGSIZE.  */
+size_t quotearg_buffer PARAMS ((char *buf, size_t bufsize,
+				char const *arg, size_t argsize,
+				struct quoting_options const *o));
+
+/* The quoting options used by the convenience functions listed below.  */
+
+extern struct quoting_options quotearg_quoting_options;
+
+/* Use storage slot N to return a quoted version of the string ARG.
+   The variable quotearg_quoting_options specifies the quoting options.
+   The returned value points to static storage that can be
+   reused by the next call to this function with the same value of N.
+   N must be nonnegative.  */
+char *quotearg_n PARAMS ((int n, char const *arg));
+
+/* Equivalent to quotearg_n (ARG, 0).  */
+char *quotearg PARAMS ((char const *arg));
+
+/* Like quotearg (ARG), except also quote any instances of CH.  */
+char *quotearg_char PARAMS ((char const *arg, char ch));
+
+/* Equivalent to quotearg_char (ARG, ':').  */
+char *quotearg_colon PARAMS ((char const *arg));