On 9/19/26 15:13, Andrew L. Moore wrote:
--- shell-quote.c begins here ---
...> --- shell-quote.c ends here ---
It turns out that comparing size_t against long double only only works
with extended-precision floating point (i.e., a 64-bit significand), which
ARM64 platforms don't support (e.g., macOS). So for the sake of
completeness, here's a portable version of shell-quote:
--- shell-quote.c begins here
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
/* Assert: 256 <= BUFSIZ <= 512KB and that 2 ^ BUFSIZ_LOG2 == BUFSIZ */
#define BUFSIZ_LOG2 \
((BUFSIZ & 0x100) ? 8 : \
(BUFSIZ & 0x200) ? 9 : \
(BUFSIZ & 0x400) ? 10 : \
(BUFSIZ & 0x800) ? 11 : \
(BUFSIZ & 0x1000) ? 12 : \
(BUFSIZ & 0x2000) ? 13 : \
(BUFSIZ & 0x4000) ? 14 : \
(BUFSIZ & 0x8000) ? 15 : \
(BUFSIZ & 0x10000) ? 16 : \
(BUFSIZ & 0x20000) ? 17 : \
(BUFSIZ & 0x40000) ? 18 : \
(BUFSIZ & 0x80000) ? 19 : -1)
#ifdef HAVE___BUILTIN_UADDL_OVERFLOW
/*
* REALLOC_ADD_THROW: Assure minimum size `i + j' for buffer `b' with size `n'.
*/
# define REALLOC_ADD_THROW(_b, _n, _i, _j, _err) \
do \
{ \
size_t _k = 0; \
if (__builtin_uaddl_overflow ((_i), (_j), &_k)) \
return (_err); \
else if (!realloc_buffer ((void **)&(_b), &(_n), _k)) \
return (_err); \
} \
while (0)
#else
# define REALLOC_ADD_THROW(_b, _n, _i, _j, _err) \
do \
{ \
if ((size_t)(_i) > SIZE_MAX - (_j)) \
return (_err); \
else if (!realloc_buffer ((void **)&(_b), &(_n), (_i) + (_j))) \
return (_err); \
} \
while (0)
#endif /* !HAVE___BUILTIN_UADDL_OVERFLOW */
static char *shell_quote(const char *fn);
static void *realloc_buffer(void **b, size_t *n, size_t i);
int
main(int argc, char *argv[])
{
char *s = argv[1];
printf("Original: %s\nQuoted: %s\n", s, shell_quote(s));
return 0;
}
/* shell_quote: Return pointer shell-quoted fn: 'lo y'all' => \''lo y'\''all'\'
*/
static char *
shell_quote (const char *fn)
{
static char *quoted = NULL;
static size_t quoted_size = 0;
size_t len = strlen (fn);
REALLOC_ADD_THROW (quoted, quoted_size, len, 3, NULL);
size_t quoted_len = len + 2; /* 'fn' */
size_t idx = 0;
if (!len)
{
quoted[idx++] = '\'';
quoted[idx++] = '\'';
quoted[idx] = '\0';
return quoted;
}
while (*fn == '\'')
{
REALLOC_ADD_THROW (quoted, quoted_size, quoted_len, 2, NULL);
quoted_len += 1;
quoted[idx++] = '\\';
quoted[idx++] = '\'';
++fn;
}
if (*fn)
quoted[idx++] = '\'';
for (; *fn; ++fn)
{
if (*fn == '\'')
{
if (*(fn + 1))
{
REALLOC_ADD_THROW (quoted, quoted_size, quoted_len, 4, NULL);
quoted_len += 3;
quoted[idx++] = '\'';
quoted[idx++] = '\\';
quoted[idx++] = '\'';
quoted[idx++] = '\'';
}
else
{
REALLOC_ADD_THROW (quoted, quoted_size, quoted_len, 3, NULL);
quoted_len += 2;
quoted[idx++] = '\'';
quoted[idx++] = '\\';
quoted[idx++] = '\'';
}
}
else
{
if (*(fn + 1))
{
quoted[idx++] = *fn;
}
else
{
quoted[idx++] = *fn;
quoted[idx++] = '\'';
}
}
}
quoted[idx] = '\0';
return quoted;
}
/* realloc_buffer: Increase size, *n, of buffer, *b, to at least i. */
static void *
realloc_buffer (void **b, size_t *n, size_t i)
{
char *ts;
size_t ti;
/*
* Assert: 0 <= i && i <= SIZE_MAX.
* NB: Allocate memory if i == *n == 0.
*/
if (i < *n)
return *b;
if (i < BUFSIZ)
ti = BUFSIZ;
else if (i >> BUFSIZ_LOG2 <= SIZE_MAX >> (BUFSIZ_LOG2 + 1))
ti = (size_t) (i >> BUFSIZ_LOG2 << (BUFSIZ_LOG2 + 1));
else
ti = i;
if (!(ts = (char *) realloc (*b, ti)))
{
fprintf (stderr, "%s\n", strerror (errno));
return NULL;
}
*n = ti;
*b = ts;
return *b;
}
--- shell-quote.c ends here ---