198038Sache/* quotearg.c - quote arguments for output 298038Sache 3133543Stjr Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software 4133543Stjr Foundation, Inc. 5133543Stjr 698038Sache This program is free software; you can redistribute it and/or modify 798038Sache it under the terms of the GNU General Public License as published by 898038Sache the Free Software Foundation; either version 2, or (at your option) 998038Sache any later version. 1098038Sache 1198038Sache This program is distributed in the hope that it will be useful, 1298038Sache but WITHOUT ANY WARRANTY; without even the implied warranty of 1398038Sache MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1498038Sache GNU General Public License for more details. 1598038Sache 1698038Sache You should have received a copy of the GNU General Public License 1798038Sache along with this program; if not, write to the Free Software Foundation, 1898038Sache Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 1998038Sache 2098038Sache/* Written by Paul Eggert <eggert@twinsun.com> */ 2198038Sache 2298038Sache#if HAVE_CONFIG_H 2398038Sache# include <config.h> 2498038Sache#endif 2598038Sache 26131447Stjr#include "quotearg.h" 2798038Sache 28131447Stjr#include "xalloc.h" 29131447Stjr 3098038Sache#include <ctype.h> 31131447Stjr#include <errno.h> 32131447Stjr#include <limits.h> 33133543Stjr#include <stdbool.h> 34131447Stjr#include <stdlib.h> 35131447Stjr#include <string.h> 3698038Sache 37131447Stjr#include "gettext.h" 38131447Stjr#define _(msgid) gettext (msgid) 39131447Stjr#define N_(msgid) msgid 4098038Sache 4198038Sache#if HAVE_WCHAR_H 4298038Sache 4398038Sache/* BSD/OS 4.1 wchar.h requires FILE and struct tm to be declared. */ 4498038Sache# include <stdio.h> 4598038Sache# include <time.h> 4698038Sache 4798038Sache# include <wchar.h> 4898038Sache#endif 4998038Sache 5098038Sache#if !HAVE_MBRTOWC 5198038Sache/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the 5298038Sache other macros are defined only for documentation and to satisfy C 5398038Sache syntax. */ 5498038Sache# undef MB_CUR_MAX 5598038Sache# define MB_CUR_MAX 1 5698038Sache# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0) 57131447Stjr# define iswprint(wc) isprint ((unsigned char) (wc)) 58131447Stjr# undef HAVE_MBSINIT 59131447Stjr#endif 60131447Stjr 61131447Stjr#if !defined mbsinit && !HAVE_MBSINIT 6298038Sache# define mbsinit(ps) 1 6398038Sache#endif 6498038Sache 6598038Sache#ifndef iswprint 6698038Sache# if HAVE_WCTYPE_H 6798038Sache# include <wctype.h> 6898038Sache# endif 6998038Sache# if !defined iswprint && !HAVE_ISWPRINT 7098038Sache# define iswprint(wc) 1 7198038Sache# endif 7298038Sache#endif 7398038Sache 74131447Stjr#ifndef SIZE_MAX 75131447Stjr# define SIZE_MAX ((size_t) -1) 7698038Sache#endif 7798038Sache 78131447Stjr#define INT_BITS (sizeof (int) * CHAR_BIT) 7998038Sache 8098038Sachestruct quoting_options 8198038Sache{ 8298038Sache /* Basic quoting style. */ 8398038Sache enum quoting_style style; 8498038Sache 8598038Sache /* Quote the characters indicated by this bit vector even if the 8698038Sache quoting style would not normally require them to be quoted. */ 8798038Sache int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; 8898038Sache}; 8998038Sache 9098038Sache/* Names of quoting styles. */ 9198038Sachechar const *const quoting_style_args[] = 9298038Sache{ 9398038Sache "literal", 9498038Sache "shell", 9598038Sache "shell-always", 9698038Sache "c", 9798038Sache "escape", 9898038Sache "locale", 9998038Sache "clocale", 10098038Sache 0 10198038Sache}; 10298038Sache 10398038Sache/* Correspondences to quoting style names. */ 10498038Sacheenum quoting_style const quoting_style_vals[] = 10598038Sache{ 10698038Sache literal_quoting_style, 10798038Sache shell_quoting_style, 10898038Sache shell_always_quoting_style, 10998038Sache c_quoting_style, 11098038Sache escape_quoting_style, 11198038Sache locale_quoting_style, 11298038Sache clocale_quoting_style 11398038Sache}; 11498038Sache 11598038Sache/* The default quoting options. */ 11698038Sachestatic struct quoting_options default_quoting_options; 11798038Sache 11898038Sache/* Allocate a new set of quoting options, with contents initially identical 11998038Sache to O if O is not null, or to the default if O is null. 12098038Sache It is the caller's responsibility to free the result. */ 12198038Sachestruct quoting_options * 12298038Sacheclone_quoting_options (struct quoting_options *o) 12398038Sache{ 124131447Stjr int e = errno; 125131447Stjr struct quoting_options *p = xmalloc (sizeof *p); 12698038Sache *p = *(o ? o : &default_quoting_options); 127131447Stjr errno = e; 12898038Sache return p; 12998038Sache} 13098038Sache 13198038Sache/* Get the value of O's quoting style. If O is null, use the default. */ 13298038Sacheenum quoting_style 13398038Sacheget_quoting_style (struct quoting_options *o) 13498038Sache{ 13598038Sache return (o ? o : &default_quoting_options)->style; 13698038Sache} 13798038Sache 13898038Sache/* In O (or in the default if O is null), 13998038Sache set the value of the quoting style to S. */ 14098038Sachevoid 14198038Sacheset_quoting_style (struct quoting_options *o, enum quoting_style s) 14298038Sache{ 14398038Sache (o ? o : &default_quoting_options)->style = s; 14498038Sache} 14598038Sache 14698038Sache/* In O (or in the default if O is null), 14798038Sache set the value of the quoting options for character C to I. 14898038Sache Return the old value. Currently, the only values defined for I are 14998038Sache 0 (the default) and 1 (which means to quote the character even if 15098038Sache it would not otherwise be quoted). */ 15198038Sacheint 15298038Sacheset_char_quoting (struct quoting_options *o, char c, int i) 15398038Sache{ 15498038Sache unsigned char uc = c; 15598038Sache int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; 15698038Sache int shift = uc % INT_BITS; 15798038Sache int r = (*p >> shift) & 1; 15898038Sache *p ^= ((i & 1) ^ r) << shift; 15998038Sache return r; 16098038Sache} 16198038Sache 16298038Sache/* MSGID approximates a quotation mark. Return its translation if it 16398038Sache has one; otherwise, return either it or "\"", depending on S. */ 16498038Sachestatic char const * 16598038Sachegettext_quote (char const *msgid, enum quoting_style s) 16698038Sache{ 16798038Sache char const *translation = _(msgid); 16898038Sache if (translation == msgid && s == clocale_quoting_style) 16998038Sache translation = "\""; 17098038Sache return translation; 17198038Sache} 17298038Sache 17398038Sache/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of 17498038Sache argument ARG (of size ARGSIZE), using QUOTING_STYLE and the 17598038Sache non-quoting-style part of O to control quoting. 17698038Sache Terminate the output with a null character, and return the written 17798038Sache size of the output, not counting the terminating null. 17898038Sache If BUFFERSIZE is too small to store the output string, return the 17998038Sache value that would have been returned had BUFFERSIZE been large enough. 180133543Stjr If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE. 18198038Sache 18298038Sache This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG, 18398038Sache ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting 18498038Sache style specified by O, and O may not be null. */ 18598038Sache 18698038Sachestatic size_t 18798038Sachequotearg_buffer_restyled (char *buffer, size_t buffersize, 18898038Sache char const *arg, size_t argsize, 18998038Sache enum quoting_style quoting_style, 19098038Sache struct quoting_options const *o) 19198038Sache{ 19298038Sache size_t i; 19398038Sache size_t len = 0; 19498038Sache char const *quote_string = 0; 19598038Sache size_t quote_string_len = 0; 196133543Stjr bool backslash_escapes = false; 197133543Stjr bool unibyte_locale = MB_CUR_MAX == 1; 19898038Sache 19998038Sache#define STORE(c) \ 20098038Sache do \ 20198038Sache { \ 20298038Sache if (len < buffersize) \ 20398038Sache buffer[len] = (c); \ 20498038Sache len++; \ 20598038Sache } \ 20698038Sache while (0) 20798038Sache 20898038Sache switch (quoting_style) 20998038Sache { 21098038Sache case c_quoting_style: 21198038Sache STORE ('"'); 212133543Stjr backslash_escapes = true; 21398038Sache quote_string = "\""; 21498038Sache quote_string_len = 1; 21598038Sache break; 21698038Sache 21798038Sache case escape_quoting_style: 218133543Stjr backslash_escapes = true; 21998038Sache break; 22098038Sache 22198038Sache case locale_quoting_style: 22298038Sache case clocale_quoting_style: 22398038Sache { 22498038Sache /* Get translations for open and closing quotation marks. 22598038Sache 22698038Sache The message catalog should translate "`" to a left 22798038Sache quotation mark suitable for the locale, and similarly for 22898038Sache "'". If the catalog has no translation, 22998038Sache locale_quoting_style quotes `like this', and 23098038Sache clocale_quoting_style quotes "like this". 23198038Sache 23298038Sache For example, an American English Unicode locale should 23398038Sache translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and 23498038Sache should translate "'" to U+201D (RIGHT DOUBLE QUOTATION 23598038Sache MARK). A British English Unicode locale should instead 23698038Sache translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and 23798038Sache U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. */ 23898038Sache 23998038Sache char const *left = gettext_quote (N_("`"), quoting_style); 24098038Sache char const *right = gettext_quote (N_("'"), quoting_style); 24198038Sache for (quote_string = left; *quote_string; quote_string++) 24298038Sache STORE (*quote_string); 243133543Stjr backslash_escapes = true; 24498038Sache quote_string = right; 24598038Sache quote_string_len = strlen (quote_string); 24698038Sache } 24798038Sache break; 24898038Sache 24998038Sache case shell_always_quoting_style: 25098038Sache STORE ('\''); 25198038Sache quote_string = "'"; 25298038Sache quote_string_len = 1; 25398038Sache break; 25498038Sache 25598038Sache default: 25698038Sache break; 25798038Sache } 25898038Sache 259131447Stjr for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++) 26098038Sache { 26198038Sache unsigned char c; 26298038Sache unsigned char esc; 26398038Sache 26498038Sache if (backslash_escapes 26598038Sache && quote_string_len 26698038Sache && i + quote_string_len <= argsize 26798038Sache && memcmp (arg + i, quote_string, quote_string_len) == 0) 26898038Sache STORE ('\\'); 26998038Sache 27098038Sache c = arg[i]; 27198038Sache switch (c) 27298038Sache { 27398038Sache case '\0': 27498038Sache if (backslash_escapes) 27598038Sache { 27698038Sache STORE ('\\'); 27798038Sache STORE ('0'); 27898038Sache STORE ('0'); 27998038Sache c = '0'; 28098038Sache } 28198038Sache break; 28298038Sache 28398038Sache case '?': 28498038Sache switch (quoting_style) 28598038Sache { 28698038Sache case shell_quoting_style: 28798038Sache goto use_shell_always_quoting_style; 28898038Sache 28998038Sache case c_quoting_style: 29098038Sache if (i + 2 < argsize && arg[i + 1] == '?') 29198038Sache switch (arg[i + 2]) 29298038Sache { 29398038Sache case '!': case '\'': 29498038Sache case '(': case ')': case '-': case '/': 29598038Sache case '<': case '=': case '>': 29698038Sache /* Escape the second '?' in what would otherwise be 29798038Sache a trigraph. */ 298131447Stjr c = arg[i + 2]; 29998038Sache i += 2; 30098038Sache STORE ('?'); 30198038Sache STORE ('\\'); 30298038Sache STORE ('?'); 30398038Sache break; 30498038Sache } 30598038Sache break; 30698038Sache 30798038Sache default: 30898038Sache break; 30998038Sache } 31098038Sache break; 31198038Sache 312131447Stjr case '\a': esc = 'a'; goto c_escape; 31398038Sache case '\b': esc = 'b'; goto c_escape; 31498038Sache case '\f': esc = 'f'; goto c_escape; 31598038Sache case '\n': esc = 'n'; goto c_and_shell_escape; 31698038Sache case '\r': esc = 'r'; goto c_and_shell_escape; 31798038Sache case '\t': esc = 't'; goto c_and_shell_escape; 31898038Sache case '\v': esc = 'v'; goto c_escape; 31998038Sache case '\\': esc = c; goto c_and_shell_escape; 32098038Sache 32198038Sache c_and_shell_escape: 32298038Sache if (quoting_style == shell_quoting_style) 32398038Sache goto use_shell_always_quoting_style; 32498038Sache c_escape: 32598038Sache if (backslash_escapes) 32698038Sache { 32798038Sache c = esc; 32898038Sache goto store_escape; 32998038Sache } 33098038Sache break; 33198038Sache 332133543Stjr case '{': case '}': /* sometimes special if isolated */ 333133543Stjr if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1)) 334133543Stjr break; 335133543Stjr /* Fall through. */ 33698038Sache case '#': case '~': 33798038Sache if (i != 0) 33898038Sache break; 33998038Sache /* Fall through. */ 34098038Sache case ' ': 34198038Sache case '!': /* special in bash */ 34298038Sache case '"': case '$': case '&': 34398038Sache case '(': case ')': case '*': case ';': 344133543Stjr case '<': 345133543Stjr case '=': /* sometimes special in 0th or (with "set -k") later args */ 346133543Stjr case '>': case '[': 34798038Sache case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */ 34898038Sache case '`': case '|': 34998038Sache /* A shell special character. In theory, '$' and '`' could 35098038Sache be the first bytes of multibyte characters, which means 35198038Sache we should check them with mbrtowc, but in practice this 35298038Sache doesn't happen so it's not worth worrying about. */ 35398038Sache if (quoting_style == shell_quoting_style) 35498038Sache goto use_shell_always_quoting_style; 35598038Sache break; 35698038Sache 35798038Sache case '\'': 35898038Sache switch (quoting_style) 35998038Sache { 36098038Sache case shell_quoting_style: 36198038Sache goto use_shell_always_quoting_style; 36298038Sache 36398038Sache case shell_always_quoting_style: 36498038Sache STORE ('\''); 36598038Sache STORE ('\\'); 36698038Sache STORE ('\''); 36798038Sache break; 36898038Sache 36998038Sache default: 37098038Sache break; 37198038Sache } 37298038Sache break; 37398038Sache 37498038Sache case '%': case '+': case ',': case '-': case '.': case '/': 37598038Sache case '0': case '1': case '2': case '3': case '4': case '5': 376133543Stjr case '6': case '7': case '8': case '9': case ':': 37798038Sache case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 37898038Sache case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': 37998038Sache case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 38098038Sache case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 38198038Sache case 'Y': case 'Z': case ']': case '_': case 'a': case 'b': 38298038Sache case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': 38398038Sache case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 38498038Sache case 'o': case 'p': case 'q': case 'r': case 's': case 't': 38598038Sache case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': 38698038Sache /* These characters don't cause problems, no matter what the 38798038Sache quoting style is. They cannot start multibyte sequences. */ 38898038Sache break; 38998038Sache 39098038Sache default: 39198038Sache /* If we have a multibyte sequence, copy it until we reach 39298038Sache its end, find an error, or come back to the initial shift 39398038Sache state. For C-like styles, if the sequence has 39498038Sache unprintable characters, escape the whole sequence, since 39598038Sache we can't easily escape single characters within it. */ 39698038Sache { 39798038Sache /* Length of multibyte sequence found so far. */ 39898038Sache size_t m; 39998038Sache 400133543Stjr bool printable; 40198038Sache 40298038Sache if (unibyte_locale) 40398038Sache { 40498038Sache m = 1; 405133543Stjr printable = isprint (c) != 0; 40698038Sache } 40798038Sache else 40898038Sache { 40998038Sache mbstate_t mbstate; 41098038Sache memset (&mbstate, 0, sizeof mbstate); 41198038Sache 41298038Sache m = 0; 413133543Stjr printable = true; 414131447Stjr if (argsize == SIZE_MAX) 41598038Sache argsize = strlen (arg); 41698038Sache 41798038Sache do 41898038Sache { 41998038Sache wchar_t w; 42098038Sache size_t bytes = mbrtowc (&w, &arg[i + m], 42198038Sache argsize - (i + m), &mbstate); 42298038Sache if (bytes == 0) 42398038Sache break; 42498038Sache else if (bytes == (size_t) -1) 42598038Sache { 426133543Stjr printable = false; 42798038Sache break; 42898038Sache } 42998038Sache else if (bytes == (size_t) -2) 43098038Sache { 431133543Stjr printable = false; 43298038Sache while (i + m < argsize && arg[i + m]) 43398038Sache m++; 43498038Sache break; 43598038Sache } 43698038Sache else 43798038Sache { 438133543Stjr /* Work around a bug with older shells that "see" a '\' 439133543Stjr that is really the 2nd byte of a multibyte character. 440133543Stjr In practice the problem is limited to ASCII 441133543Stjr chars >= '@' that are shell special chars. */ 442133543Stjr if ('[' == 0x5b && quoting_style == shell_quoting_style) 443133543Stjr { 444133543Stjr size_t j; 445133543Stjr for (j = 1; j < bytes; j++) 446133543Stjr switch (arg[i + m + j]) 447133543Stjr { 448133543Stjr case '[': case '\\': case '^': 449133543Stjr case '`': case '|': 450133543Stjr goto use_shell_always_quoting_style; 451133543Stjr } 452133543Stjr } 453133543Stjr 45498038Sache if (! iswprint (w)) 455133543Stjr printable = false; 45698038Sache m += bytes; 45798038Sache } 45898038Sache } 45998038Sache while (! mbsinit (&mbstate)); 46098038Sache } 46198038Sache 46298038Sache if (1 < m || (backslash_escapes && ! printable)) 46398038Sache { 46498038Sache /* Output a multibyte sequence, or an escaped 46598038Sache unprintable unibyte character. */ 46698038Sache size_t ilim = i + m; 46798038Sache 46898038Sache for (;;) 46998038Sache { 47098038Sache if (backslash_escapes && ! printable) 47198038Sache { 47298038Sache STORE ('\\'); 47398038Sache STORE ('0' + (c >> 6)); 47498038Sache STORE ('0' + ((c >> 3) & 7)); 47598038Sache c = '0' + (c & 7); 47698038Sache } 47798038Sache if (ilim <= i + 1) 47898038Sache break; 47998038Sache STORE (c); 48098038Sache c = arg[++i]; 48198038Sache } 48298038Sache 48398038Sache goto store_c; 48498038Sache } 48598038Sache } 48698038Sache } 48798038Sache 48898038Sache if (! (backslash_escapes 48998038Sache && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))) 49098038Sache goto store_c; 49198038Sache 49298038Sache store_escape: 49398038Sache STORE ('\\'); 49498038Sache 49598038Sache store_c: 49698038Sache STORE (c); 49798038Sache } 49898038Sache 499133543Stjr if (i == 0 && quoting_style == shell_quoting_style) 500133543Stjr goto use_shell_always_quoting_style; 501133543Stjr 50298038Sache if (quote_string) 50398038Sache for (; *quote_string; quote_string++) 50498038Sache STORE (*quote_string); 50598038Sache 50698038Sache if (len < buffersize) 50798038Sache buffer[len] = '\0'; 50898038Sache return len; 50998038Sache 51098038Sache use_shell_always_quoting_style: 51198038Sache return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, 51298038Sache shell_always_quoting_style, o); 51398038Sache} 51498038Sache 51598038Sache/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of 51698038Sache argument ARG (of size ARGSIZE), using O to control quoting. 51798038Sache If O is null, use the default. 51898038Sache Terminate the output with a null character, and return the written 51998038Sache size of the output, not counting the terminating null. 52098038Sache If BUFFERSIZE is too small to store the output string, return the 52198038Sache value that would have been returned had BUFFERSIZE been large enough. 522133543Stjr If ARGSIZE is SIZE_MAX, use the string length of the argument for 523133543Stjr ARGSIZE. */ 52498038Sachesize_t 52598038Sachequotearg_buffer (char *buffer, size_t buffersize, 52698038Sache char const *arg, size_t argsize, 52798038Sache struct quoting_options const *o) 52898038Sache{ 52998038Sache struct quoting_options const *p = o ? o : &default_quoting_options; 530131447Stjr int e = errno; 531131447Stjr size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize, 532131447Stjr p->style, p); 533131447Stjr errno = e; 534131447Stjr return r; 53598038Sache} 53698038Sache 537133543Stjr/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly 538133543Stjr allocated storage containing the quoted string. */ 539133543Stjrchar * 540133543Stjrquotearg_alloc (char const *arg, size_t argsize, 541133543Stjr struct quoting_options const *o) 542133543Stjr{ 543133543Stjr int e = errno; 544133543Stjr size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1; 545133543Stjr char *buf = xmalloc (bufsize); 546133543Stjr quotearg_buffer (buf, bufsize, arg, argsize, o); 547133543Stjr errno = e; 548133543Stjr return buf; 549133543Stjr} 550133543Stjr 55198038Sache/* Use storage slot N to return a quoted version of argument ARG. 552133543Stjr ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a 553133543Stjr null-terminated string. 55498038Sache OPTIONS specifies the quoting options. 55598038Sache The returned value points to static storage that can be 55698038Sache reused by the next call to this function with the same value of N. 55798038Sache N must be nonnegative. N is deliberately declared with type "int" 55898038Sache to allow for future extensions (using negative values). */ 55998038Sachestatic char * 56098038Sachequotearg_n_options (int n, char const *arg, size_t argsize, 56198038Sache struct quoting_options const *options) 56298038Sache{ 563131447Stjr int e = errno; 564131447Stjr 56598038Sache /* Preallocate a slot 0 buffer, so that the caller can always quote 56698038Sache one small component of a "memory exhausted" message in slot 0. */ 56798038Sache static char slot0[256]; 56898038Sache static unsigned int nslots = 1; 56998038Sache unsigned int n0 = n; 57098038Sache struct slotvec 57198038Sache { 57298038Sache size_t size; 57398038Sache char *val; 57498038Sache }; 57598038Sache static struct slotvec slotvec0 = {sizeof slot0, slot0}; 57698038Sache static struct slotvec *slotvec = &slotvec0; 57798038Sache 57898038Sache if (n < 0) 57998038Sache abort (); 58098038Sache 58198038Sache if (nslots <= n0) 58298038Sache { 58398038Sache unsigned int n1 = n0 + 1; 58498038Sache 585131447Stjr if (xalloc_oversized (n1, sizeof *slotvec)) 58698038Sache xalloc_die (); 58798038Sache 58898038Sache if (slotvec == &slotvec0) 58998038Sache { 590131447Stjr slotvec = xmalloc (sizeof *slotvec); 59198038Sache *slotvec = slotvec0; 59298038Sache } 593131447Stjr slotvec = xrealloc (slotvec, n1 * sizeof *slotvec); 59498038Sache memset (slotvec + nslots, 0, (n1 - nslots) * sizeof *slotvec); 59598038Sache nslots = n1; 59698038Sache } 59798038Sache 59898038Sache { 59998038Sache size_t size = slotvec[n].size; 60098038Sache char *val = slotvec[n].val; 60198038Sache size_t qsize = quotearg_buffer (val, size, arg, argsize, options); 60298038Sache 60398038Sache if (size <= qsize) 60498038Sache { 60598038Sache slotvec[n].size = size = qsize + 1; 606131447Stjr if (val != slot0) 607131447Stjr free (val); 608131447Stjr slotvec[n].val = val = xmalloc (size); 60998038Sache quotearg_buffer (val, size, arg, argsize, options); 61098038Sache } 61198038Sache 612131447Stjr errno = e; 61398038Sache return val; 61498038Sache } 61598038Sache} 61698038Sache 61798038Sachechar * 61898038Sachequotearg_n (int n, char const *arg) 61998038Sache{ 620131447Stjr return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options); 62198038Sache} 62298038Sache 62398038Sachechar * 62498038Sachequotearg (char const *arg) 62598038Sache{ 62698038Sache return quotearg_n (0, arg); 62798038Sache} 62898038Sache 62998038Sache/* Return quoting options for STYLE, with no extra quoting. */ 63098038Sachestatic struct quoting_options 63198038Sachequoting_options_from_style (enum quoting_style style) 63298038Sache{ 63398038Sache struct quoting_options o; 63498038Sache o.style = style; 63598038Sache memset (o.quote_these_too, 0, sizeof o.quote_these_too); 63698038Sache return o; 63798038Sache} 63898038Sache 63998038Sachechar * 64098038Sachequotearg_n_style (int n, enum quoting_style s, char const *arg) 64198038Sache{ 64298038Sache struct quoting_options const o = quoting_options_from_style (s); 643131447Stjr return quotearg_n_options (n, arg, SIZE_MAX, &o); 64498038Sache} 64598038Sache 64698038Sachechar * 64798038Sachequotearg_n_style_mem (int n, enum quoting_style s, 64898038Sache char const *arg, size_t argsize) 64998038Sache{ 65098038Sache struct quoting_options const o = quoting_options_from_style (s); 65198038Sache return quotearg_n_options (n, arg, argsize, &o); 65298038Sache} 65398038Sache 65498038Sachechar * 65598038Sachequotearg_style (enum quoting_style s, char const *arg) 65698038Sache{ 65798038Sache return quotearg_n_style (0, s, arg); 65898038Sache} 65998038Sache 66098038Sachechar * 66198038Sachequotearg_char (char const *arg, char ch) 66298038Sache{ 66398038Sache struct quoting_options options; 66498038Sache options = default_quoting_options; 66598038Sache set_char_quoting (&options, ch, 1); 666131447Stjr return quotearg_n_options (0, arg, SIZE_MAX, &options); 66798038Sache} 66898038Sache 66998038Sachechar * 67098038Sachequotearg_colon (char const *arg) 67198038Sache{ 67298038Sache return quotearg_char (arg, ':'); 67398038Sache} 674