]> git.draconx.ca Git - cdecl99.git/log
cdecl99.git
8 months agoAvoid warnings about unused scanner functions.
Nick Bowler [Sun, 23 Jul 2023 15:48:33 +0000 (11:48 -0400)]
Avoid warnings about unused scanner functions.

We don't use input or unput in the scanner, so we can define some
macros to disable them which avoids some compiler warnings.

8 months agoSolve Bison conflicts using precedence declarations.
Nick Bowler [Sun, 23 Jul 2023 14:55:40 +0000 (10:55 -0400)]
Solve Bison conflicts using precedence declarations.

We can use a precedence declaration to directly inform Bison of how
to resolve the specific conflict at hand, rather than just saying
"it is ok to have N conflicts."

There is no significant change to the generated output but this way
keeps things more straightforward when modifying the parser.

8 months agotests: Add sanity test for variable-length arrays.
Nick Bowler [Fri, 21 Jul 2023 03:55:46 +0000 (23:55 -0400)]
tests: Add sanity test for variable-length arrays.

The random crossparse test generates these quite frequently but
it's nice to have the basics covered by simpler inputs.

9 months agolibcdecl: Remove magic T_ENGLISH token.
Nick Bowler [Fri, 21 Jul 2023 03:23:00 +0000 (23:23 -0400)]
libcdecl: Remove magic T_ENGLISH token.

This token is pointless, all english syntax is already sufficiently
distinguished by the T_DECLARE and T_TYPE tokens, which are only
returned by the scanner in english mode.

9 months agolibcdecl: Simplify Bison error message reporting.
Nick Bowler [Thu, 20 Jul 2023 02:22:10 +0000 (22:22 -0400)]
libcdecl: Simplify Bison error message reporting.

Bison emits a bunch of code to pretty print token names for error
messages, doing things like removing quotes and backslashes.

But this is all totally pointless: all of the relevant strings are
already correctly formatted (in part because fix-yytname.awk does
some of this at compile time), and the process will not alter them.
They simply need to be copied as-is.

Fortunately, Bison provides a simple mechanism to replace this with
our own function, and wouldn't you know it we already have a suitable
copying function in the library, so let's use that.

9 months agolibcdecl: Sidestep some possible snprintf issues.
Nick Bowler [Thu, 20 Jul 2023 02:12:24 +0000 (22:12 -0400)]
libcdecl: Sidestep some possible snprintf issues.

Adjust cdecl__emit to avoid some known problems with snprintf
implementations:

 * some implementations (e.g., newlib 1.8.2) write to the destination
   when the size is zero.
 * some implementations (e.g., HP-UX 11) return -1 when the string is
   truncated.
 * some implementations (e.g., the replacement provided by gnulib!)
   allocate memory even for trivial conversions and return -1 on malloc
   failure.

Since we currently use gnulib, only the last one is presently a concern,
but the plan is to eventually remove the library dependency on gnulib
snprintf since in reality we barely need any snprintf functionality.

Adjust the cdecl__emit implementation to simply avoid tripping over these
sorts of problems.  Other snprintf calls in the library remain as before.

9 months agolibcdecl: Combine tag/typedef identifier rules.
Nick Bowler [Thu, 20 Jul 2023 01:25:09 +0000 (21:25 -0400)]
libcdecl: Combine tag/typedef identifier rules.

There are actually no conflicts to add an empty production alongside
the rule for "struct", "union" and "enum", which allows the subsequent
reductions for "tag identifier" and "[nothing] identifier" to be done
with just one rule.

This replaces a relatively large action from the eliminated rule with
a very simple one.

9 months agolibcdecl: Avoid using strcpy w/ empty strings.
Nick Bowler [Thu, 20 Jul 2023 01:15:14 +0000 (21:15 -0400)]
libcdecl: Avoid using strcpy w/ empty strings.

The parser is currently using strcpy to copy constant empty strings; it
is just as easy to explicitly assign the single zero byte instead.

Since these are the only use of strcpy in the library, and for whatever
reason GCC is not optimizing out these strcpy calls, on ELF hosts this
saves a PLT entry in the shared library and everything associated with
that too.

9 months agolibcdecl: Combine array length parser rules.
Nick Bowler [Thu, 20 Jul 2023 01:08:03 +0000 (21:08 -0400)]
libcdecl: Combine array length parser rules.

Some of the parser rules to handle incomplete array types versus arrays
with explicit length (not VLAs) are duplicated between the regular and
english parsers.

As this is the same in both cases we can use a new symbol and drop some
duplicate actions to simplify things a bit.

9 months agolibcdecl: Parse function parameters in order.
Nick Bowler [Thu, 20 Jul 2023 00:52:21 +0000 (20:52 -0400)]
libcdecl: Parse function parameters in order.

Currently the parser collects function parameters in reverse order,
then reverses them at the end.

There is no reason to do this.  It is only a slight restructuring of
the rules to collect parameters in the right order from the get go,
which means we can delete the duplicated list reversal code.

The grammar itself is also simpler this way, using two less nonterminals.

9 months agolibcdecl: Factor out open-coded identifier patchup.
Nick Bowler [Thu, 20 Jul 2023 00:40:32 +0000 (20:40 -0400)]
libcdecl: Factor out open-coded identifier patchup.

There are two parser rules which handle english declarations of the
form "identifier as type", these have to traverse the type name
to replace the "null" declarator with the identifier.

Instead of duplicating the code for this traversal, let's use a
helper function to do it.

9 months agolibcdecl: Factor out open-coded list concatenation.
Nick Bowler [Thu, 20 Jul 2023 00:28:59 +0000 (20:28 -0400)]
libcdecl: Factor out open-coded list concatenation.

The parser has two rules which join two lists.  Let's add a helper
to do that instead of duplicating the code for list concatenation.
Furthermore, in both cases one of the lists is known to be nonempty;
the implementation can be slightly simplified with that assumption.

9 months agolibcdecl: Fix crash when bootstrapped w/ old Bison.
Nick Bowler [Thu, 20 Jul 2023 00:22:32 +0000 (20:22 -0400)]
libcdecl: Fix crash when bootstrapped w/ old Bison.

We are comparing the packed token value to check whether this is an
identifier or a keyword against the true value.  This happens to work
on new Bison (when using api.token.raw) as these values are the same,
but on old Bison the result is never true.

Thus, the scanner fails to assign the "strval" for identifier tokens
and the result fails very badly.  Easy enough to fix.

9 months agolibcdecl: Avoid redundant string literal in yyerror.
Nick Bowler [Tue, 18 Jul 2023 02:33:03 +0000 (22:33 -0400)]
libcdecl: Avoid redundant string literal in yyerror.

The T_LEX_ERROR string literal in yyerror won't be merged with the
now-duplicate string in the token name table; use the appropriate
indirection to shave off some bytes.

9 months agolibcdecl: Don't propagate specifier lists more than once.
Nick Bowler [Tue, 18 Jul 2023 02:20:07 +0000 (22:20 -0400)]
libcdecl: Don't propagate specifier lists more than once.

The very first thing the library does with the parse tree is normalize
the top-level specifiers, and then propagate the resulting list across
all top-level declarators.

So it is completely redundant for the parser itself to propagate the
un-normalized specifier list.

9 months agoAdd an explanation for declaration specifier rules.
Nick Bowler [Tue, 18 Jul 2023 01:55:28 +0000 (21:55 -0400)]
Add an explanation for declaration specifier rules.

It took me a while to wrap my head around WTF the declaration specifier
parser rules were trying to accomplish.  Let's add a big explanation so
hopefully, if I try to read them again after another decade or so, they
will make sense more easily.

9 months agolibcdecl: Move specifier type determination into scanner.
Nick Bowler [Fri, 14 Jul 2023 01:25:04 +0000 (21:25 -0400)]
libcdecl: Move specifier type determination into scanner.

Instead of having a parser action for every keyword which sets the
appropriate specifier type, the scanner can just directly assign
the semantic value for the returned specifier tokens.

This reduces the size of the generated parser quite a bit, without
needing any change to the tokens.

9 months agolibcdecl: Use macros for packing tokens into bytes.
Nick Bowler [Fri, 14 Jul 2023 01:20:26 +0000 (21:20 -0400)]
libcdecl: Use macros for packing tokens into bytes.

Instead of coding the same structures everywhere, move the logic to
drop/restore the upper bits of tokens into helper macros.

Should be no functional change.

9 months agoUpdate .gitmodules URI for Gnulib.
Nick Bowler [Fri, 14 Jul 2023 00:42:37 +0000 (20:42 -0400)]
Update .gitmodules URI for Gnulib.

Apparently the https://git.savannah.gnu.org/r/gnulib.git location
doesn't support the smart protocol over HTTP, but /git/gnulib.git
does.  Weird.

9 months agolibcdecl: Avoid duplicating keyword strings w/ gperf.
Nick Bowler [Tue, 11 Jul 2023 04:57:04 +0000 (00:57 -0400)]
libcdecl: Avoid duplicating keyword strings w/ gperf.

The string table generated by gperf is quite redundant: since we already
resolved to the parser token, we can easily get the string from the
parser's token name table.

Unfortunately gperf provides no options to customize the string table
generation to the extent needed, so let's continue our theme of post-
processing everything in awk.

9 months agolibcdecl: Combine scanner rules for punctuation.
Nick Bowler [Sun, 9 Jul 2023 20:51:29 +0000 (16:51 -0400)]
libcdecl: Combine scanner rules for punctuation.

Use a single rule to match all punctuation, with a lookup table to
return the correct token.  This gives a small size reduction for
the scanner.

9 months agolibcdecl: Use gperf to identify keywords during scanning.
Nick Bowler [Sun, 9 Jul 2023 18:43:43 +0000 (14:43 -0400)]
libcdecl: Use gperf to identify keywords during scanning.

Instead of having a flex rule for each keyword, we can use a catch-all
rule for identifiers and then use gperf to distinguish keywords from
ordinary identifiers.

This reduces the size of the scanner much more than the addition of
gperf-generated code increases it.

9 months agotests: Fix interactive test without libreadline.
Nick Bowler [Sat, 8 Jul 2023 17:33:29 +0000 (13:33 -0400)]
tests: Fix interactive test without libreadline.

When using actual readline, the user's input is echoed internally, so
the test case sees the actual input commands in the captured standard
output.  But in the getline-based fallback, the input is not reflected
to the output.  This is expected behaviour, but confuses the test case.

Rewrite the check to accept either form.

9 months agolibcdecl: Use Bison's api.token.raw feature.
Nick Bowler [Sat, 8 Jul 2023 14:04:31 +0000 (10:04 -0400)]
libcdecl: Use Bison's api.token.raw feature.

By default, Bison numbers user-defined tokens starting from 257.
If the scanner never returns plain characters (which is the case
for libcdecl), this is inefficient.

Recent versions of Bison provide the api.token.raw option to improve
things.  Let's turn it on, if configure detects that it is supported.

This requires a very minor tweak to spec_string in order for the
encoding of tokens into single-byte values to work regardless of
which mode Bison is run in.

9 months agolibcdecl: Re-use strings from parser in spec_string.
Nick Bowler [Fri, 7 Jul 2023 03:56:29 +0000 (23:56 -0400)]
libcdecl: Re-use strings from parser in spec_string.

With the fixups applied by fix-yytname, we now have two distinct string
tables containing the same strings.  To avoid this duplication, add a
new internal function to allow spec_string to access the parser's token
name table.

9 months agolibcdecl: Replace yytname array in the Bison parser.
Nick Bowler [Fri, 7 Jul 2023 02:46:20 +0000 (22:46 -0400)]
libcdecl: Replace yytname array in the Bison parser.

Bison generates a list of symbol names as a static array of char pointers
initialized with string literals, which is simply horrible.  These pointers
are two to four times larger than necessary, but with position-independent
code this also forces them into an unshareable, writeable segment since
they are not compile-time constants and must be initialized by the dynamic
loader at runtime.

Furthermore, the names of nonterminal symbols are always included but they
are not always needed; they should only be output by tracing code which
is disabled by default at compile time.

Fix this by adding a new build script which postprocesses the output,
replacing the yytname array with a function implementing the same lookup
with truly constant tables.  Inclusion of nonterminals is now conditional
on YYDEBUG.

This is a big win, reducing the overall library size about 5 to 10 percent
(64-bit hosts see the most improvement).

9 months agotests: Ensure that English keywords can be parsed.
Nick Bowler [Fri, 7 Jul 2023 01:02:25 +0000 (21:02 -0400)]
tests: Ensure that English keywords can be parsed.

We don't want to reject words like "declare" in identifiers, at least
when parsing C code, so add test cases to make sure that works.

9 months agotests: Don't pull output routines into normalize testcase.
Nick Bowler [Fri, 7 Jul 2023 00:57:41 +0000 (20:57 -0400)]
tests: Don't pull output routines into normalize testcase.

This program isn't about testing the output routines, and it's simple
enough to just have the test program do its own printing, so linking
in the output routines to this testcase is just causing more trouble
than it's worth.

9 months agolibcdecl: Combine error and i18n init.
Nick Bowler [Fri, 7 Jul 2023 00:50:22 +0000 (20:50 -0400)]
libcdecl: Combine error and i18n init.

We can just do the gettext initialization at the same time as error
initialization, which lets us use a single "glthread_once" invocation
for everything.

9 months agolibcdecl: Fix regression in function parsing.
Nick Bowler [Thu, 6 Jul 2023 06:15:35 +0000 (02:15 -0400)]
libcdecl: Fix regression in function parsing.

Merging the reduce_parentheses and simplify_functions step missed a case
where the function simplification could pull a fake function declarator
up to the current tree position.  Continuing the tree traversal will miss
this, leaving the fake parameter in the tree (which is then rejected as
a syntax error later).

The fix is easy enough, just repeat the whole reduction step until no
changes are needed at the current position before continuing traversal.

Add a new test case that targets this behaviour.

9 months agolibcdecl: Remove "too many parentheses" error check.
Nick Bowler [Thu, 6 Jul 2023 05:59:43 +0000 (01:59 -0400)]
libcdecl: Remove "too many parentheses" error check.

It is simply not the case that "int ((int))" is invalid.

Since "int (x(int))" declares x as a function returning int, it follows
that "int ((int))" is simply a type name for function returning int.
Likewise, "int (((int)))" is equivalent, etc.

Rejecting these type names is longstanding broken behaviour.  I think
the entire error check can simply be deleted outright, along with its
associated error message.  The bogus negative test cases are replaced
with new positive tests.

Furthermore, rewrite the big comment that suggests this was reasonable
behaviour, replacing it with a (hopefully) better explanation that
covers how this particular case should be interpreted.

9 months agocdecl99: Simplify main loops a bit.
Nick Bowler [Wed, 5 Jul 2023 05:48:11 +0000 (01:48 -0400)]
cdecl99: Simplify main loops a bit.

Convert the calls to repl/repl_execute to tail calls from main.

9 months agocdecl99: Reverse sense of "interactive" global variable.
Nick Bowler [Wed, 5 Jul 2023 01:39:55 +0000 (21:39 -0400)]
cdecl99: Reverse sense of "interactive" global variable.

Instead of a default-true "interactive" global variable, we can use
a default-false "batch" global variable, reversing the sense of all
the tests.

This moves the variable from the initialized data segment into bss,
which is more efficient.

9 months agocdecl99: Don't check blank lines if no history support.
Nick Bowler [Wed, 5 Jul 2023 01:27:47 +0000 (21:27 -0400)]
cdecl99: Don't check blank lines if no history support.

Move the whole "if not blank, then add history" logic under the #ifdef,
so it can be eliminated completely if add_history is not available at
compile time.

This probably makes no major difference on GNU/Linux, since GCC knows
that strspn has no side effects and can drop the call as dead code, but
this may help with less sophisticated toolchains.

9 months agocdecl99: Fall back to getline, instead of Gnulib's readline.
Nick Bowler [Wed, 5 Jul 2023 01:15:39 +0000 (21:15 -0400)]
cdecl99: Fall back to getline, instead of Gnulib's readline.

When building without readline, instead of using Gnulib's readline
replacement, use getline directly.  We can combine most of the batch
and interactive mode processing loops which saves a bunch of pointless
extra code in the readline-disabled case.

To actually do this, we prepare a Gnulib "local dir" to implement
a cut-down readline module that includes the configure tests only.

9 months agoAdd test for interactive mode.
Nick Bowler [Wed, 5 Jul 2023 00:57:06 +0000 (20:57 -0400)]
Add test for interactive mode.

We currently don't have any tests which actually run cdecl99 in the
interactive mode.  Let's fix that, shall we?

9 months agolibcdecl: Simplify mixed type name error condition.
Nick Bowler [Sat, 1 Jul 2023 03:03:09 +0000 (23:03 -0400)]
libcdecl: Simplify mixed type name error condition.

"List item X is either not the first or not the last item" is just a
very complicated way to say "the list has more than one item".

9 months agotests: Add more coverage for parenthesis handling.
Nick Bowler [Sat, 1 Jul 2023 02:09:33 +0000 (22:09 -0400)]
tests: Add more coverage for parenthesis handling.

Add a couple extra test cases which cover some special behaviours
that are apparently missed by the existing tests.

9 months agolibcdecl: Simplify reduce_parentheses implementation.
Nick Bowler [Fri, 30 Jun 2023 05:24:12 +0000 (01:24 -0400)]
libcdecl: Simplify reduce_parentheses implementation.

Simplify the reduce_parentheses implementation so it operates in a
much more straightforward way.  We can also just call simplify_functions
directly during the same tree traversal, instead of trying to predict
what simplify_functions will do to a node on a later traversal.

9 months agolibcdecl: Combine several postprocessing steps into one.
Nick Bowler [Fri, 30 Jun 2023 01:22:44 +0000 (21:22 -0400)]
libcdecl: Combine several postprocessing steps into one.

We currently have 5 postprocessing steps common to both parse variants,
four of which don't do any modification at all (just syntax checks).
This is overkill.  We can easily combine all five of these operations
into one function which does everything in a single tree traversal.

9 months agolibcdecl: Simplify declarator traversal logic.
Nick Bowler [Wed, 28 Jun 2023 05:07:59 +0000 (01:07 -0400)]
libcdecl: Simplify declarator traversal logic.

It seems unnecessary to handle the case where the traversal function
modifies the subtree differently from the case where the function does
not modify the subtree.

So we only have to deal with two cases for the traversal function's
return value, which allows us to simplify a bit.

9 months agolibcdecl: Merge both parser function implementations.
Nick Bowler [Wed, 28 Jun 2023 02:48:11 +0000 (22:48 -0400)]
libcdecl: Merge both parser function implementations.

The only remaining meaningful difference between the cdecl_parse_decl
and cdecl_parse_english implementations is the function-simplification
passes are only done for cdecl_parse_decl.

We can easily just make those conditional in a common parser function,
to reduce code duplication.

9 months agolibcdecl: Simplify sorting in cdecl__normalize_specs.
Nick Bowler [Tue, 27 Jun 2023 02:08:01 +0000 (22:08 -0400)]
libcdecl: Simplify sorting in cdecl__normalize_specs.

Rewrite the merge sort helper in a simpler way, which not only
simplifies the source code but also helps reduce the library size.

9 months agoFix TEST_NEED_PROGRAM to work on old Solaris /bin/sh.
Nick Bowler [Sat, 1 Jul 2023 21:26:08 +0000 (17:26 -0400)]
Fix TEST_NEED_PROGRAM to work on old Solaris /bin/sh.

Solaris /bin/sh does not support ${x##y} expansions.  For this macro
we can almost as easily use a case statement instead.

9 months agoPull in Solaris /bin/sh testsuite fixes from dxcommon.
Nick Bowler [Sat, 1 Jul 2023 21:24:54 +0000 (17:24 -0400)]
Pull in Solaris /bin/sh testsuite fixes from dxcommon.

9 months agoWork around Solaris 8 nawk issue in the test suite.
Nick Bowler [Sat, 1 Jul 2023 19:28:15 +0000 (15:28 -0400)]
Work around Solaris 8 nawk issue in the test suite.

Apparently "nawk" on Solaris 8 does not understand -f- to mean "read
program from standard input", we must spell it as two arguments: -f -

9 months agoAdd missing errmsg.str source file.
Nick Bowler [Sat, 1 Jul 2023 14:27:17 +0000 (10:27 -0400)]
Add missing errmsg.str source file.

Oops, forgot to commit this file.

9 months agolibcdecl: Avoid vsnprintf for error reporting.
Nick Bowler [Fri, 23 Jun 2023 05:11:15 +0000 (01:11 -0400)]
libcdecl: Avoid vsnprintf for error reporting.

Using vsnprintf is overkill here.  We only need to handle a single %s
conversion, which can be done by direct call to snprintf.

As this is the only caller of vsnprintf, dropping it means we can drop
the vsnprintf gnulib module.  Also, at least with gcc, using va_start
and such is fairly expensive.  The direct-snprintf version is quite
a bit more compact.

9 months agolibcdecl: Make cdecl__emit_specs return value usable directly.
Nick Bowler [Fri, 23 Jun 2023 04:39:45 +0000 (00:39 -0400)]
libcdecl: Make cdecl__emit_specs return value usable directly.

Since there is now only one caller of cdecl__emit_specs that cares
about its return value, let's adjust this function to return exactly
what that caller wants, so it doesn't have to do any extra calculation.

9 months agolibcdecl: Accumulate output length in structure.
Nick Bowler [Fri, 23 Jun 2023 04:05:41 +0000 (00:05 -0400)]
libcdecl: Accumulate output length in structure.

Instead of cascading the lengths back via function return values, since
we now have a state structure we can just track the total length in one
place.  This is quite a lot conceptually simpler and cuts out a good
chunk of code.

9 months agolibcdecl: Simplify cdecl__advance.
Nick Bowler [Fri, 23 Jun 2023 03:37:54 +0000 (23:37 -0400)]
libcdecl: Simplify cdecl__advance.

It seems unnecessary to set the dst pointer to null here, nothing
cares if this pointer is null or not null, only the length matters.

9 months agolibcdecl: Use a structure for dst/dstlen in output routines.
Nick Bowler [Fri, 23 Jun 2023 03:25:50 +0000 (23:25 -0400)]
libcdecl: Use a structure for dst/dstlen in output routines.

Since pretty much all the output functions now just directly pass the
dst and dstlen pointers around without touching them in any other way,
it is more efficient to use a structure so there is only one pointer.

9 months agolibcdecl: Rework specifier output logic.
Nick Bowler [Fri, 23 Jun 2023 02:00:34 +0000 (22:00 -0400)]
libcdecl: Rework specifier output logic.

With both the explain and declare code paths using cdecl__emit, we
can give the same treatment to cdecl__explain_specs (now called
cdecl__emit_specs) to simplify things a bit.

This removes the last caller of cdecl__advance, so we can remove
that function (and use this better name for cdecl__advance_).

9 months agolibcdecl: Rework cdecl_declare output logic.
Nick Bowler [Fri, 23 Jun 2023 01:24:19 +0000 (21:24 -0400)]
libcdecl: Rework cdecl_declare output logic.

Instead of adjusting the output pointer/length values after each
internal call, tweak all the functions in declare.c to take an extra
level of indirection so they can just directly adjust the destination
as they go.

9 months agolibcdecl: Rework cdecl_explain output logic.
Nick Bowler [Fri, 23 Jun 2023 01:21:46 +0000 (21:21 -0400)]
libcdecl: Rework cdecl_explain output logic.

Instead of adjusting the output pointer/length values after each
internal call, tweak all the functions in explain.c to take an
extra level of indirection so they can just directly adjust the
destination as they go.

A new helper, cdecl__emit, is provided to simplify the common pattern
of "print a single C string" followed by "advance pointer/length."

9 months agotests: Add canned test case for incomplete arrays.
Nick Bowler [Fri, 23 Jun 2023 01:12:47 +0000 (21:12 -0400)]
tests: Add canned test case for incomplete arrays.

I messed up the whitespace for this while experimenting with the output
routines, and none of the existing test cases noticed.

9 months agolibcdecl: Simplify cdecl__explain_specs.
Nick Bowler [Thu, 22 Jun 2023 05:20:12 +0000 (01:20 -0400)]
libcdecl: Simplify cdecl__explain_specs.

A bunch of conditions in the specifier printing loop are meaningless,
since all valid specifier types take idenical execution paths through
this function.  So much of this can just be deleted.

9 months agolibcdecl: Improve specifier to string conversions.
Nick Bowler [Thu, 22 Jun 2023 05:01:46 +0000 (01:01 -0400)]
libcdecl: Improve specifier to string conversions.

Instead of a big switch statement, we can generate some compact lookup
tables to convert specifiers to strings, which appears to produce much
better results with gcc at least.

9 months agotests: Adjust positive tests to verify both parse directions.
Nick Bowler [Thu, 22 Jun 2023 02:11:07 +0000 (22:11 -0400)]
tests: Adjust positive tests to verify both parse directions.

We don't actually have any canned tests of the "declare" or "type"
commands to produce C syntax from pseudo-English.  While the randomized
crossparse test does provide some coverage of this, failures here
are difficult to understand compared to more simple, standalone test
cases.

So to start, let's just expand the existing "positive" tests to check
in both directions.

9 months agolibcdecl: Simplify explain_decl -> explain_prologue.
Nick Bowler [Thu, 22 Jun 2023 00:46:53 +0000 (20:46 -0400)]
libcdecl: Simplify explain_decl -> explain_prologue.

Rather than threading a flag through this function just to print
"declare" or "type" at the toplevel, we can just directly print
that in the one place where it is needed, which simplifies the
implementation a bit.

9 months agolibcdecl: Simplify internal specifier printing functions.
Nick Bowler [Thu, 22 Jun 2023 00:35:58 +0000 (20:35 -0400)]
libcdecl: Simplify internal specifier printing functions.

Since reworking how specifiers are printed, the "pre"/"post" specifier
printing functions are pretty much pointless, and can (mostly) be
deleted, which reduces the library size somewhat.

10 months agocdecl99: Avoid passing uninitialized value to help_print_option.
Nick Bowler [Fri, 16 Jun 2023 04:34:41 +0000 (00:34 -0400)]
cdecl99: Avoid passing uninitialized value to help_print_option.

For options that do not take arguments, the "arg" member of the help
structure is not assigned by lopt_get_help.  Since the structure
is not otherwise initialized, it is technically undefined to even
evaluate this member in order to pass it to the help_print_option
function.

In this case, the argument is not actually used, and I'm not aware
of any actual failures as a result, but it easy enough to avoid.

10 months agotests: Eliminate random floating-point generation.
Nick Bowler [Fri, 16 Jun 2023 04:12:42 +0000 (00:12 -0400)]
tests: Eliminate random floating-point generation.

The only use of test_rng_uniform in the test suite is to do 50/50 coin
toss type checks, add a simple helper based on test_rng_uniform_int to
do this, instead of bringing in all this floating-point machinery for
no real reason.

10 months agolibcdecl: Avoid stray semicolon after gl_once_define.
Nick Bowler [Fri, 16 Jun 2023 04:01:07 +0000 (00:01 -0400)]
libcdecl: Avoid stray semicolon after gl_once_define.

For some weird reason the gnulib gl_once_define function-like macro
expansion includes the semicolon.  Thus, the extra semicolon after
the macro invocation is technically a syntax error, although most
compilers seem to not care too much.

10 months agolibcdecl: Tweak invalid character error from scanner.
Nick Bowler [Thu, 15 Jun 2023 00:34:56 +0000 (20:34 -0400)]
libcdecl: Tweak invalid character error from scanner.

By adjusting how we format the error message, the format string is
changed to be completely identical to a format string used by the
parser error reporting, which avoids some wasted code space in
the library.

Furthermore, make some tweaks to the invalid character pretty-printing
which seems to let GCC generate a bit more compact code.

10 months agolibcdecl: Consolidate most error messages.
Nick Bowler [Fri, 9 Jun 2023 14:43:36 +0000 (10:43 -0400)]
libcdecl: Consolidate most error messages.

Almost every error message returned by the library is a fixed
string describing some particular syntax problem.  Keep this
list of strings in one place, and add a new internal helper
to report one of these errors.

Furthermore, reduce the amount of distinct error codes returned
to the user to (once again) just two, as the current plethora of
codes seems completely pointless.

10 months agoUse gnulib's vsnprintf module.
Nick Bowler [Tue, 13 Jun 2023 06:14:44 +0000 (02:14 -0400)]
Use gnulib's vsnprintf module.

The snprintf module provides only snprintf, not vsnprintf.  As we
currently depend on both functions in the library, it is necessary
to use both modules.

This fixes failures in the new cdeclerr test on HP-UX 11, which has
vsnprintf but it is not entirely C99-like (wrong return value).

10 months agoFix library error state allocation.
Nick Bowler [Tue, 13 Jun 2023 05:31:06 +0000 (01:31 -0400)]
Fix library error state allocation.

The assignment to the thread-local state is missing both from the
failed-allocation and the resize paths of the library error reporting.

Fix that up, and add a new test case which provides coverage of at
least the realloc path.

10 months agoRename "test" directory to "t".
Nick Bowler [Tue, 13 Jun 2023 04:18:24 +0000 (00:18 -0400)]
Rename "test" directory to "t".

It's been bugging me to be using "test" in this project but "t" in
others.  So let's try to standardise on "t".

10 months agoAdd more type specifier tests.
Nick Bowler [Thu, 1 Jun 2023 04:53:26 +0000 (00:53 -0400)]
Add more type specifier tests.

Add some more coverage of invalid type specifier combinations to
support possible future changes in this area.

10 months agoFactor out common parser invocation.
Nick Bowler [Thu, 1 Jun 2023 00:29:41 +0000 (20:29 -0400)]
Factor out common parser invocation.

The two main parsing functions have nearly identical parser invocation
sequences, with the only difference being the flag passed to the scanner
init.  Split that off into a separate function, to simplify the code.

Additionally, if the code is compiled with YYDEBUG, enable parser
debugging.

10 months agoRestore gperf-related definitions to makefile.
Nick Bowler [Tue, 30 May 2023 02:10:54 +0000 (22:10 -0400)]
Restore gperf-related definitions to makefile.

Previously, gnulib was providing definitions for GPERF and other
variables in the makefile indirectly via the striconv module.  But
since we removed that module, the definitions disappeared, leading
to build failures after maintainer-clean.

Easy enough to just do the same thing explicitly.  In the future
we might want to use configure to locate gperf but for now this
will do.

10 months agocdecl99: Use packed option format from gen-options.awk.
Nick Bowler [Mon, 29 May 2023 02:05:17 +0000 (22:05 -0400)]
cdecl99: Use packed option format from gen-options.awk.

This feature uses a compact, fully constant array to generate the
real struct option array at runtime.  This allows the full-sized array
to be dropped after command-line processing is finished, and with
position-independent executables, reduces the amount of relocation
processing needed.

10 months agoEnsure all headers are distributed.
Nick Bowler [Mon, 29 May 2023 00:43:52 +0000 (20:43 -0400)]
Ensure all headers are distributed.

The copysym.h and xtra.h files need to be listed as a source file
somewhere otherwise the distribution will not include them.  Fix
that up.

10 months agoReplace Gnulib striconv with copyright_symbol from dxcommon.
Nick Bowler [Sat, 27 May 2023 01:25:04 +0000 (21:25 -0400)]
Replace Gnulib striconv with copyright_symbol from dxcommon.

The only use of the striconv module is to produce the copyright symbol
for --version output and at the start of an interactive session.  Using
the new, single-purpose function reduces code size quite a bit.

10 months agoStop using gnulib's flexmember module.
Nick Bowler [Sat, 27 May 2023 00:38:11 +0000 (20:38 -0400)]
Stop using gnulib's flexmember module.

The only thing we're actually using from this module is provided
directly by Autoconf, via AC_C_FLEXIBLE_ARRAY_MEMBER, so we can
just use that macro instead.

10 months agocdecl99: Fix some improper error message formatting.
Nick Bowler [Thu, 25 May 2023 23:38:59 +0000 (19:38 -0400)]
cdecl99: Fix some improper error message formatting.

Errors opening the file specified by a --file option are printed with
two newlines, and errors generated by actual commands are not properly
prefixed with the program name.

Add test cases to catch these specific problems and fix them.

14 months agoAvoid POSIX character classes in the test suite.
Nick Bowler [Tue, 24 Jan 2023 07:37:00 +0000 (02:37 -0500)]
Avoid POSIX character classes in the test suite.

Instead of [[:alnum:]] and friends, expand to an explicit list of
characters, which is a bit more portable usage (and also avoids
unneeded locale dependency).  We can use macros to make this
just as convenient to write.

14 months agoFix configuration on Solaris 8.
Nick Bowler [Tue, 24 Jan 2023 07:14:53 +0000 (02:14 -0500)]
Fix configuration on Solaris 8.

There is an quoting error in Gnulib's threadlib.m4 which causes
incorrect configuration settings on old Solaris.  We can repeat
the simple check with correct quoting to workaround the problem.

Additionally, pull in DX_LINGUAS fixes from dxcommon to avoid
tripping on Solaris' pre-POSIX /bin/awk.

14 months agocdecl99: Drop locale-sensitive isblank usage.
Nick Bowler [Tue, 24 Jan 2023 04:58:55 +0000 (23:58 -0500)]
cdecl99: Drop locale-sensitive isblank usage.

The intention of this function is to avoid recording no-op command lines
in the history.  This is exactly the set of commands containing just
regular tabs and spaces.

It is inappropriate to use the locale-sensitive isblank for this, as
this may be a little bit different.  In practice there is probably no
meaningful difference, but as isblank is a C99 feature losing this call
also helps when building against older C libraries that lack it.

14 months agoProvide strtoumax fallback in the scanner.
Nick Bowler [Tue, 24 Jan 2023 04:47:18 +0000 (23:47 -0500)]
Provide strtoumax fallback in the scanner.

We already do something similar in the test suite.  We don't really care
about the full range of uintmax_t, we just prefer the widest type that
is available to us.  It is no real problem to fall back to a narrower
conversion function.

15 months agoDon't parse command-line options more than once.
Nick Bowler [Tue, 10 Jan 2023 01:20:19 +0000 (20:20 -0500)]
Don't parse command-line options more than once.

Instead of parsing the options a second time to collect the --execute
option arguments, we can easily permute the argv array on the first
pass through, which simplifies the subsequent evaluation.

17 months agoAvoid Gnulib std-gnu11 module.
Nick Bowler [Fri, 18 Nov 2022 03:45:07 +0000 (22:45 -0500)]
Avoid Gnulib std-gnu11 module.

It has come to my attention that this module rewrites AC_PROG_CC in
a way that actually breaks Automake's AM_PROG_CC_C_O functionality.
This results in the "compile" script not being included or used in
packages bootstrapped with Autoconf 2.69.

With later versions of Autoconf things work because this module
doesn't touch things and thus disables itself.

I don't care about building with C11 one way or the other.  Let's
just skip the module.

23 months agoDefine GNULIB_MBRTOWC_SINGLE_THREAD.
Nick Bowler [Fri, 22 Apr 2022 04:25:59 +0000 (00:25 -0400)]
Define GNULIB_MBRTOWC_SINGLE_THREAD.

As the mbrtowc replacement module is not used by the library,
there is no need for multithreaded mbrtowc (all programs are
single threaded).

This fixes a build failure on DJGPP when NLS is enabled.

23 months agoBump dxcommon to improve builds with DJGPP.
Nick Bowler [Fri, 22 Apr 2022 02:43:40 +0000 (22:43 -0400)]
Bump dxcommon to improve builds with DJGPP.

23 months agoExplicitly require gnulib getline module.
Nick Bowler [Fri, 22 Apr 2022 02:01:57 +0000 (22:01 -0400)]
Explicitly require gnulib getline module.

Currently, the gnulib getline module is only pulled in indirectly via
the readline module.  As a result, when configuring for a system that
has GNU readline installed (and readline is enabled), the readline
replacement is not used and therefore the getline replacement is
never included.

But on systems that lack getline in the C library, without the gnulib
replacement the build will fail.  Simply listing getline as a needed
module suffices to allow such configurations to build successfully.

2 years agoRelease 1.2. v1.2
Nick Bowler [Sun, 3 Apr 2022 19:13:42 +0000 (15:13 -0400)]
Release 1.2.

2 years agotests: Correct RNG implementation.
Nick Bowler [Sun, 3 Apr 2022 01:56:22 +0000 (21:56 -0400)]
tests: Correct RNG implementation.

Due to a mistake in the adaptation, the output of the generator was
not done correctly.  Correct that, and add a little test program that
would have caught this mistake by directly comparing against the
reference implementation.

2 years agoBump dxcommon to fix builds using --disable-dependency-tracking.
Nick Bowler [Sat, 26 Mar 2022 04:00:56 +0000 (00:00 -0400)]
Bump dxcommon to fix builds using --disable-dependency-tracking.

Some build rules were inadvertently depending on directory creation that
happens as a side effect of depfiles generation.  This does not happen
when configuring with --disable-dependency-tracking, leading to issues
with both VPATH builds and the gnulib symfiles machinery.

Failures are easily observed with a command like

  make DISTCHECK_CONFIGURE_FLAGS=--disable-dependency-tracking distcheck

Using parallel make can hide problems since it seems Automake also
generates make rules that incidentally create these directories.

2 years agoFix regressions caused by symbol renaming changes.
Nick Bowler [Sat, 19 Feb 2022 23:07:59 +0000 (18:07 -0500)]
Fix regressions caused by symbol renaming changes.

A bug in dxcommon was causing VPATH builds to continue to apply symbol
renaming to all gnulib sources.  Fixing this revealed that dependency
tracking was broken for the non-renamed objects (distcheck noticed that
the dependency products were not being cleaned).

To fix dependency tracking Automake needs to be aware of all the source
files going into the statically-linked version of the library.

Unfortunately, Automake complains if we just add the same sources to a
non-libtool library, even though there is no real conflict since only
one will actually be built.  The issue can be worked around by using
Automake's object renaming facilities, which complicates things slightly
but is straightforward enough to implement.

2 years agoFix gen-typegen.awk incompatibility with busybox awk.
Nick Bowler [Fri, 18 Feb 2022 22:15:34 +0000 (17:15 -0500)]
Fix gen-typegen.awk incompatibility with busybox awk.

It seems that busybox awk does not support * in printf conversions.
There is only one use of this feature in the scripts and we can use
the substr function instead.

2 years agoImprove gnulib build times.
Nick Bowler [Fri, 18 Feb 2022 04:08:19 +0000 (23:08 -0500)]
Improve gnulib build times.

Use the new dxcommon features in an attempt to avoid the expensive
symbol renaming and PIC build steps for the portions of gnulib that
are not actually needed by the libcdecl library.

2 years agoPlug memory leak in declgen.
Nick Bowler [Thu, 10 Feb 2022 01:37:50 +0000 (20:37 -0500)]
Plug memory leak in declgen.

When a void typespec is generated in a context where it is invalid,
gen_typespecs just rolls the dice again.  Unfortunately, the typespec
is not freed in this case, leaking memory.  Easily fixed.

2 years agoPortability improvements for new random number generator.
Nick Bowler [Wed, 9 Feb 2022 08:06:02 +0000 (03:06 -0500)]
Portability improvements for new random number generator.

On HP-UX 11, the ldexp function requires linking against libm.
Moreover, instead of strtoull declared in <stdlib.h> we have
__strtoull declared in <inttypes.h>.  Add configure tests to
find these.

2 years agoClean up declgen a bit.
Nick Bowler [Wed, 9 Feb 2022 04:37:53 +0000 (23:37 -0500)]
Clean up declgen a bit.

Use wrapper functions to perform the "allocate a structure and
initialize its members" sequence which is a common sequence here,
and avoid the use of compound literals for this which improves
portability to older compilers.

2 years agoSimplify and improve randomdecl sanity test.
Nick Bowler [Wed, 9 Feb 2022 04:34:17 +0000 (23:34 -0500)]
Simplify and improve randomdecl sanity test.

We don't need to do any weird shell variable stuff here, we can just
directly compute the expected output and verify against that.  As a
bonus, when the test fails this gives a much better description of
which expected forms are missing in the testsuite log.

2 years agoRemove randomdecl test dependency on GSL.
Nick Bowler [Wed, 9 Feb 2022 03:30:48 +0000 (22:30 -0500)]
Remove randomdecl test dependency on GSL.

It's a bit silly for a test application to depend on this huge library
just for random number generation.  We can just directly incorporate
a simple RNG implementation which should be plenty good enough for
this purpose.

2 years agoUse common help formatting in test cases.
Nick Bowler [Fri, 4 Feb 2022 04:50:38 +0000 (23:50 -0500)]
Use common help formatting in test cases.

There apparently was a copy of the help formatter hidden in the
test suite, let's port that over to the shared code too.

2 years agoBump dxcommon to improve portability to systems without "join"
Nick Bowler [Sun, 30 Jan 2022 03:50:24 +0000 (22:50 -0500)]
Bump dxcommon to improve portability to systems without "join"

2 years agocdecl99: Remove unused printf argument.
Nick Bowler [Wed, 24 Nov 2021 02:08:02 +0000 (21:08 -0500)]
cdecl99: Remove unused printf argument.

This harmless extra argument was presumably left over from some code
shuffle, we can just remove it.