nodist_include_HEADERS = src/config/cdecl.h
src/config/cdecl.h: config.h src/cdecl.h $(DX_BASEDIR)/scripts/bake-config.awk
- $(AM_V_at) $(AWK) -f $(DX_BASEDIR)/scripts/bake-config.awk \
+ $(AM_V_GEN) $(AWK) -f $(DX_BASEDIR)/scripts/bake-config.awk \
config.h $(srcdir)/src/cdecl.h >$@-t
$(AM_V_at) mv -f $@-t $@
EXTRA_DIST += $(DX_BASEDIR)/scripts/bake-config.awk
-Subproject commit aaaacebf1f04c364803f308c3b3e9670e216da09
+Subproject commit 2f638e51e602982648087e00c788a4751f1a4a8c
gl_EARLY
AC_HEADER_ASSERT
+AC_TYPE_UNSIGNED_LONG_LONG_INT
AC_C_FLEXIBLE_ARRAY_MEMBER
AC_C_INLINE
DX_C_FOR_DECLARATIONS
-.Dd December 3, 2023
+.Dd January 17, 2024
.Dt LIBCDECL \&3 "Cdecl99 Developer's Manual"
.Os cdecl99
.Sh NAME
manual page.
.Pp
.Nm
-is intended to be portable to any system with a working C implementation that
-at least makes an effort to support C99.
+is intended to be portable to any system with a standard C compiler.
The library is thread-safe when appropriate facilities exist and are enabled at
build time.
.Sh NAMESPACE
of type qualifiers.
.Ss Array Declarators
.Bd -literal -offset indent
+typedef unsigned long long cdecl_uintmax; /* depends on configuration */
struct cdecl_array {
char *vla;
- uintmax_t length;
+ cdecl_uintmax length;
};
.Ed
.Pp
.Va length
is positive, then this is an array declarator with the specified length.
Otherwise, this is an incomplete array declarator.
+.Pp
+If the library was configured using a compiler which does not support
+.Vt unsigned long long ,
+then the
+.Vt cdecl_uintmax
+type is defined as
+.Vt unsigned long
+instead.
+Prior versions of
+.Nm
+used
+.Vt uintmax_t
+directly.
.Ss Function Declarators
.Bd -literal -offset indent
typedef _Bool cdecl_bool; /* depends on configuration */
.Sh AUTHORS
Nick Bowler <nbowler@draconx.ca>
.Sh COPYRIGHT
-Copyright \(co 2011\(en2012, 2021, 2023 Nick Bowler
+Copyright \(co 2011\(en2012, 2021, 2023\(en2024 Nick Bowler
.Pp
Permission is granted to copy, distribute and/or modify this manual under the
terms of the GNU General Public License as published by the Free Software
size_t cdecl__advance(struct output_state *dst, size_t amount);
size_t cdecl__emit(struct output_state *dst, const char *src);
-size_t cdecl__emit_uint(struct output_state *dst, uintmax_t val);
+size_t cdecl__emit_uint(struct output_state *dst, cdecl_uintmax val);
size_t cdecl__strlcpy(char *dst, const char *src, size_t len);
const char *cdecl__emit_specs(struct output_state *dst,
/*
- * Copyright © 2011, 2021, 2023 Nick Bowler
+ * Copyright © 2011, 2021, 2023-2024 Nick Bowler
*
* 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
#ifndef CDECL_H_
#define CDECL_H_
-#include <stddef.h>
-#include <stdint.h>
+#include <stddef.h> /* for size_t */
#if __GNUC__
# define CDECL__INLINE __inline
typedef signed char cdecl_bool;
#endif
+#if HAVE_UNSIGNED_LONG_LONG_INT
+typedef unsigned long long cdecl_uintmax;
+#else
+typedef unsigned long cdecl_uintmax;
+#endif
+
/* Declaration specifier kinds. */
enum {
CDECL_SPEC_TYPE = 256,
} pointer;
struct cdecl_array {
char *vla;
- uintmax_t length;
+ cdecl_uintmax length;
} array;
struct cdecl_function {
struct cdecl *parameters;
#include <locale.h>
#include <assert.h>
#include <stdarg.h>
+#include <inttypes.h>
#include <getopt.h>
#include <gettext.h>
#include <config.h>
#include <stdio.h>
#include <stdbool.h>
-#include <inttypes.h>
#include <assert.h>
#include "cdecl.h"
retry:
rc = fmt_err(state, fmt, arg);
if (rc >= state->nstr) {
- assert(try++ == 0 && rc < SIZE_MAX / 4);
+ assert(try++ == 0 && rc < (size_t)-1 / 4);
state = alloc_err_state(state, (size_t)(rc+1u) * 3 / 2);
if (!state)
%{
/*
- * Copyright © 2021, 2023 Nick Bowler
+ * Copyright © 2021, 2023-2024 Nick Bowler
*
* 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
#include <config.h>
#include <stdio.h>
#include <string.h>
-#include <stdint.h>
+#include <inttypes.h>
#include <assert.h>
#include "cdecl99.h"
#!/bin/awk -f
#
-# Copyright © 2023 Nick Bowler
+# Copyright © 2023-2024 Nick Bowler
#
# Hackjob to improve the horrible yytname array generated by Bison.
#
# At the end of the yytname definition, output our replacement function.
in_table && $0 ~ /^};/ {
print "#if !defined(UINT_LEAST8_MAX) || !defined(UINT_LEAST16_MAX)";
- print "# include <stdint.h>";
+ print "# include <inttypes.h>";
print "#endif";
print "#ifndef assert";
print "# include <assert.h>";
/*
- * Copyright © 2023 Nick Bowler
+ * Copyright © 2023-2024 Nick Bowler
*
* 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
#include <string.h>
#include <stdbool.h>
-#include <inttypes.h>
enum { INTCONV_OCTAL = 8, INTCONV_DECIMAL = 10, INTCONV_HEXADECIMAL = 16 };
* Multiply *v by base, which must be one of the above enumeration constants,
* and add digit, updating *v with the result.
*
- * If the result does not fit in uintmax_t, then 0 is returned. Otherwise,
+ * If the result does not fit in cdecl_uintmax, then 0 is returned. Otherwise,
* a non-zero result is returned.
*/
-static inline bool intconv_shift(uintmax_t *v, unsigned base, unsigned digit)
+static inline bool intconv_shift(cdecl_uintmax *v, unsigned base, unsigned digit)
{
- uintmax_t old_v = *v;
+ cdecl_uintmax old_v = *v;
- if (old_v > (uintmax_t)-1 / base)
+ if (old_v > (cdecl_uintmax)-1 / base)
return false;
old_v *= base;
/*
* Helper functions for outputting text.
- * Copyright © 2011, 2021, 2023 Nick Bowler
+ * Copyright © 2011, 2021, 2023-2024 Nick Bowler
*
* 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
*/
#include <config.h>
#include <stdio.h>
+#include <limits.h>
#include <assert.h>
#include "cdecl.h"
return cdecl__advance(dst, rc);
}
-/*
- * 31 decimal digits is enough for values up to 2^102 - 1.
- * 63 decimal digits is enough for values up to 2^209 - 1.
- *
- * We can't portably write numbers this large in preprocessor conditionals,
- * but since the maximum values of unsigned integer types are always one
- * less than a power of two, we can use a sequence of small shifts to infer
- * the bounds.
- *
- * All known implementations have 64-bit uintmax_t. Leave some headroom
- * to support a possible future implementatons with 128-bit uintmax_t.
- */
enum {
-#if (UINTMAX_MAX >> 27 >> 27 >> 26 >> 26) == 0
- MAX_UINT_DIGITS = 31
-#elif (UINTMAX_MAX >> 27 >> 26 >> 26 >> 26 >> 26 >> 26 >> 26 >> 26) == 0
- MAX_UINT_DIGITS = 63
-#else
-# error UINTMAX_MAX is too large, please report a bug.
-#endif
+ /*
+ * upper bound on number of decimal digits required to convert
+ * cdecl_uintmax.
+ */
+ MAX_UINT_DIGITS = (CHAR_BIT * sizeof (cdecl_uintmax) + 2)/3
};
-size_t cdecl__emit_uint(struct output_state *dst, uintmax_t val)
+size_t cdecl__emit_uint(struct output_state *dst, cdecl_uintmax val)
{
char buf[MAX_UINT_DIGITS + 1], *p = &buf[sizeof buf];
#include <stdbool.h>
#include "scan.h"
-#include "cdecl.h"
#include "cdecl-internal.h"
#include "errmsg.h"
%code requires {
#include <inttypes.h>
#include <stdbool.h>
+#include "cdecl.h"
}
%code provides {
}
%union {
- uintmax_t uintval;
+ cdecl_uintmax uintval;
unsigned spectype;
bool boolval;
struct cdecl_declspec *declspec;
[1-9][0-9]* { intconv_base = INTCONV_DECIMAL; goto int_parse; }
0[Xx][[:xdigit:]]+ {
unsigned char d;
- uintmax_t v;
+ cdecl_uintmax v;
yytext += 2;
intconv_base = INTCONV_HEXADECIMAL;
/*
* Generate random C declarations for testing.
- * Copyright © 2012, 2021-2023 Nick Bowler
+ * Copyright © 2012, 2021-2024 Nick Bowler
*
* 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
return gen_randomize_specs(rng, s);
}
-static uintmax_t gen_uintmax(struct test_rng *rng)
+static cdecl_uintmax gen_uintmax(struct test_rng *rng)
{
+ cdecl_uintmax ret = 0;
unsigned char tmp;
- uintmax_t ret = 0;
size_t i;
for (i = 0; i < sizeof ret; i++) {
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <inttypes.h>
#include <errno.h>
#include <limits.h>
#if !TEST_RNG_NO_EXTERNAL_API
struct test_rng *test_rng_alloc(const char *seed_str)
{
+ test_uintmax limit, seed_val;
unsigned long long seed;
- uintmax_t limit, seed_val;
struct test_rng *rng;
- limit = (uintmax_t)0xffffffff;
+ limit = 0xffffffff;
limit |= (limit << 16 << 16);
if (!test_strtoumax(&seed_val, seed_str, limit)) {
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
+/*
+ * The test_uintmax typedef is interchangeable with cdecl_uintmax defined in
+ * <cdecl.h>, but we may want to avoid including that header for some tests.
+ */
+#if HAVE_UNSIGNED_LONG_LONG_INT
+typedef unsigned long long test_uintmax;
+#else
+typedef unsigned long test_uintmax;
+#endif
+
struct cdecl_declspec;
struct option;
struct cdecl;
void *malloc_nofail(size_t size);
void *realloc_nofail(void *ptr, size_t size);
-bool test_strtoumax(uintmax_t *out, const char *s, uintmax_t limit);
+bool test_strtoumax(test_uintmax *out, const char *s, test_uintmax limit);
static inline bool test_strtoul(unsigned long *val, const char *str)
{
- uintmax_t v;
+ test_uintmax v;
bool rc;
rc = test_strtoumax(&v, str, (unsigned long)-1);
return INTCONV_DECIMAL;
}
-bool test_strtoumax(uintmax_t *out, const char *s, uintmax_t limit)
+bool test_strtoumax(cdecl_uintmax *out, const char *s, cdecl_uintmax limit)
{
static const char idx[] = "0123456789abcdef0123456789ABCDEF";
unsigned base = intconv_base(&s);
- uintmax_t v;
+ cdecl_uintmax v;
char *c, d;
for (v = 0; (d = *s++);) {