In yyerror(), prefix the line reporting the error with the program
name. This makes the output consistent with the output of errx()
which reports memory allocation errors.
Note that this uses a GNU-only feature; if that's not desirable it's
easy to do this more portably.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-18-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Create a new macro that allocates and zeroes a block of memory,
which guarantees that the allocation will succeed. Use this in two
spots where calloc() is already assumed not to fail, and use it in
other places where memory is dynamically allocated.
If the malloc() call in the macro fails, memalloc() will call errx()
to print an error message to stderr and exit with status 1.
In addition, check for a null pointer returned by strdup() in
yylex(), and report a similar error if that occurs.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-17-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Send error text output by yyerror() to stderr instead of stdout.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-16-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
If parse_package() finds anything other than an identifier as the
next token, it calls yyerror(). This is exactly what token_expect()
does, so use that instead.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-15-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Rather than maintaining an input buffer and details about its
current state--as well as a lookahead character--just let the
standard I/O library take care of those details. A single character
of "lookahead" is guaranteed by the library, so this will be no
worse than the hand-done buffering, and will certainly be more
robust.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-14-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The scratch_buf[] array is used to hold characters supplied to
unput().
The only time unput() is called is in yylex(), when a character
returned by input() isn't in the character set appropriate for the
symbol being parsed. And in that case unput() is called only once.
We will not call unput() again until input() has been called at
least once, and that will consume the only character in the scratch
buffer.
Therefore, for our purposes, only one character is required for the
lookahead buffer.
We never accept a NUL byte on input, so it will never be used as a
lookahead character. So we can use 0 as a special lookahead value
that indicates "no lookahead present."
So replace the scratch_buf[] and scratch_pos with a single character
lookahead, which is considered invalid if its value is 0.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-13-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The first token id is given the value 256. This ensures it is
outside the range of any valid character.
But we don't allow non-ASCII characters on input, so we can use 128
as the first non-character token id value. Represent this as
(CHAR_MAX + 1), to make explicit the reason this value is chosen.
Give the enumerated type representing token ids a name.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-12-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Define an explicit end-of-file token, TOK_EOF. When EOF is reached,
input() returns 0. Use a symbolic TOK_EOF value rather than 0 to
represent that condition.
Note that also implies '\0' is not a valid input character; add an
explicit check to disallow a NUL byte on input.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-11-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Report an error if any input byte is not an ASCII character.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-10-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Now that read errors are dealt with immediately, input() will never
return anything but a character. Change its return type to char,
and change the type of the variable in yylex() that holds its return
value to char as well.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-9-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
In qmi_parse(), the main loop accepts tokens until it sees one with
id 0. If an unrecognized (or unexpected) token is encountered, it
reports an error and exits using yyerror().
Normally, input() returns the next character to be processed while
parsing. If the read() call in input() encounters an error, input()
will return -1 instead (which happens to be EOF).
The only caller of input() is yylex(). It recognizes tokens
comprised of alphanumeric characters and '_'. If input() returns
any other value, it uses that value as the token identifier. And in
particular, if input() returns -1, that will be the value stored in
the id field of the token structure yylex() returns.
So, back to the top, qmi_parse() will not consider -1 a valid token
id, and will report the read error as an "unexpected symbol".
Instead, report a read error immediately when it occurs and exit.
Move the definition of yyerror() earlier in the source file so it
can be called from yylex() (and all other functions) without needing
a declaration.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-8-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
In qmi_parse(), when a message token is recognized its token
structure will contain a dynamically-allocated string continaing the
message name. We only use the message identifier (number) though,
and as a result the message name gets leaked. Fix this by freeing
the type token string if no-null.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-7-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
In qmi_message_parse(), the type token for each field parsed will
contain a dynamically-allocated string continaing the field type.
We only use the type identifier (number) though, and as a result
the type name gets leaked. Fix this by freeing the type token
string if non-null.
Essentially the same thing occurs in qmi_struct_parse() while
parsing the fields of a message. Fix the problem there as well.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-6-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
If token_accept() is provided a null token pointer argument, the
previous "current" token is discarded. If the token matched is a
symbol type, the token string (which will have been dynamically
allocated in yylex()) will be leaked.
Fix this by freeing the current token string if token pointer passed
is null.
The compiler warns when we attempt to free a pointer to constant
data, so change the type of the string pointer in the symbol
structure to be pointer to non-constant.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-5-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Just print the message passed to yyerror(); don't bother putting it
into a buffer first.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-4-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
We have no use for negative array indexes, so change the types of
the static variables scratch_pos, input_pos, and input_len to be
unsigned.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-3-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
A loop at the top of yylex() traverses the symbols list without
doing anything. It serves no purpose, so get rid of it.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-2-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This helps with cross compilation where toolchains specify
certain flags via environment e.g. CFLAGS/LDFLAGS
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Statically sized arrays should not have a len property and should be
marked as STATIC_ARRAY in the elem_info list.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Use the list implementation from other projects instead of rolling
custom list operations throughout the codebase.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The yyerror() doesn't return, so let the compiler know this, in order to
silence warnings about potentially uninitialized variables.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
GNU coding standards notably specifies:
* install files with the $(DESTDIR) to the target system image
* install files with the $(prefix), not $(PREFIX)
* the default value of $(prefix) should be /usr/local
as per https://www.gnu.org/prep/standards/html_node/Directory-Variables.html.
Signed-off-by: Nicolas Dechesne <nicolas.dechesne@linaro.org>
Structs can contain strings, we still don't encode and decode these but
this change makes the generated header file compilable.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The accessor function generator for strings in qmi messages output code
that is incorrect, fix this.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Allow specifying message type for the tlv support functions to verify
and create the right type of qmi header.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This initial implementation is capable of generating encoder and decoder
accessors for messages with basic integers, strings, arrays and structs.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>