Remove procedural code that did the scanning, which was faulty and didn't
support complex constants such as 0x1p-61. Replace it with a finite state
machine expressed as a transition table. The table was rewritten by hand
from lx's output, given parts of grammar expressed as regular expressions.
lx is Katherine Flavel's lexer generator, currently available at
https://github.com/katef/libfsm and the parts of grammar were taken from
http://quut.com/c/ANSI-C-grammar-l-2011.html and extended to support binary
integer constants which are a popular GCC extension.
Reported by: bde
The trick is to copy everything from the start of the line into the buffer
that stores newlines and comments until indent finds a brace or an else.
pr_comment() will use that information to calculate the original indentation
of the boxed comment.
This requires storing two pieces of information: the real start of the
buffer (sc_buf) and the start of the comment (save_com).
"while (...)" and "else" or "{"
* Don't flush newlines - there can be multiple of them and they can happen
before a token that isn't else or {. Instead, always store them in save_com.
* Don't dump the buffer's contents on newline assuming that there is only
one comment before else or {.
* Avoid producing surplus newlines, especially before else when -ce is on.
* When -bl is on, don't treat { as a comment (was implemented by falling
through "case lbrace:" to "case comment:").
This commit fixes the above, but exposes another bug and thus breaks several
other tests. Another commit will make them pass again.
My previous indent(1) commit accidentally broke the -pcs option (which adds
space between function name and opening parenthesis in function calls) by
copying all but one of a few conditions in an if clause. Reinstate the
condition.
Add a regression test to lower the chances of breaking it again.
Correct a comment with description of what the option does.
If the current token is an opening parenthesis, it's either a function call
(or sizeof or offsetof) or a declaration. The former doesn't need a space
before the parenthesis.
This was done by Romain Tartière for PR123553. I initially thought that it would break code like this:
#define b00101010 -1
if (0 b00101010)
...
by joining 0 and b00101010 together. However, the real problem with that patch was that once it saw a 0, it assumed that the number was base 2, 8 or 16, ignoring base 10 floating point numbers. I fixed that.
I didn't copy the diagnostic part of the original patch as it seems out of scope of implementing binary integer literals formatting.
PR: 123553
Submitted by: romain (original version)
Approved by: pfg (mentor)
test suite
This change does the following:
- Introduces symmetry in the test inputs/outputs by adding the exit
code to the files. This simplified the test driver notably by
requiring less filename/test name manipulation.
- Adds a test driver for the testcases added in r313544, patterned
after bin/sh/tests/functional_test.sh . The driver calls indent as
noted in r313544, with an exception: The $FreeBSD$ RCS keyword's
expansion is reindented with indent, which means that the output
differs from the expected output. Thus, all lines with $FreeBSD$
in them are deleted on the fly, both in the input file and the
output file.
The test inputs/outputs are copied to the kyua sandbox before the
test is run as the pathing in some of the files relies on pathing
normalized to the current directory (copying the files is the
easiest way to resolve the issue).
Approved by: pstef (maintainer)
Reviewed by: pstef
X-MFC with: r313544
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D9682
These examples show expected behavior of indent(1). They are meant to be used
together with a regression test mechanism, either Kyua, a Makefile or perhaps
something else. The mechanism should in essence do this:
indent -P${test}.pro < ${test}.0 > ${test}.0.run
and compare ${test}.0.stdout to ${test}.0.run. If the files differ or the exit
status isn't 0, the test failed.
* ${test}.pro is an indent(1) profile: a list of options passed through a file.
The program doesn't complain if the file doesn't exist.
* ${test}.0 is a C source file which acts as input for indent(1). It doesn't
have to have any particular formatting, since it's the output that matters.
* ${test}.0.stdout contains expected output. It doesn't have to be formatted in
Kernel Normal Form as the point of the tests is to check for regressions in
the program and not to check that it always produces KNF.
Reviewed by: ngie
Approved by: pfg (mentor)
Differential Revision: https://reviews.freebsd.org/D9007