Linux Netfilter development
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: "Jan Kończak" <jan.konczak@cs.put.poznan.pl>
Cc: netfilter-devel@vger.kernel.org
Subject: Re: [PATCH nft] parser_bison: on syntax errors, output expected tokens
Date: Fri, 16 Jan 2026 14:07:24 +0100	[thread overview]
Message-ID: <aWo4DAHLS5284upo@strlen.de> (raw)
In-Reply-To: <1950751.CQOukoFCf9@imladris>

Jan Kończak <jan.konczak@cs.put.poznan.pl> wrote:
> +static int
> +yyreport_syntax_error(const yypcontext_t *yyctx, struct nft_ctx *nft,
> +                      void *scanner, struct parser_state *state)
> +{
> +	struct location *loc = yypcontext_location(yyctx);
> +	const char *badTok = yysymbol_name(yypcontext_token(yyctx));
> +
> +	char * msg;
> +	int len = 1024;
> +	int pos;
> +	const char * const sep = ", ";
> +
> +	// get expected tokens
> +	int expTokCnt = yypcontext_expected_tokens(yyctx, NULL, 0);

No need for these comments, the function name below is verbose enough.

> +	yysymbol_kind_t *expTokArr = malloc(sizeof(yysymbol_kind_t) * expTokCnt);

You could use xmalloc_array() instead.

> +	if (!expTokArr) return YYENOMEM;
> +	yypcontext_expected_tokens(yyctx, expTokArr, expTokCnt);
> +
> +	// reserve space for the error message
> +	msg = malloc(len);

You can use xmalloc() here, like other parts in the parser already do.

> +	if (!msg) { free(expTokArr); return YYENOMEM; }

... and then this can be removed.

> +	// start building up the error message
> +	pos = snprintf(msg, len, "syntax error, unexpected %s\n"
> +	                         "expected any of: ", badTok);

I think it would be easier to switch this to fprintf, with
FILE *err = open_memstream(&msg,  ...).

> +	// append expected tokens to the error message
> +	for (int i = 0; i < expTokCnt; ++i) {
> +		yysymbol_kind_t expTokKind = expTokArr[i];
> +		const char * expTokName = yysymbol_name(expTokKind);
> +
> +		// tokens that name generic things shall be printed as <foo>; detect them
> +		int isNotAKeyword = 0;
> +		switch( expTokKind ){
> +			case YYSYMBOL_NUM:      case YYSYMBOL_QUOTED_STRING:
> +			case YYSYMBOL_STRING:   case YYSYMBOL_ASTERISK_STRING:
> +				isNotAKeyword = 1;
> +			default:
> +		}
> +
> +		if ((size_t)len-pos-1 < strlen(expTokName)+strlen(sep)+isNotAKeyword*2) {
> +			// need more space for the error message to fit all expected tokens
> +			char * newMsg;
> +			len += 1024;
> +			newMsg = realloc(msg, len);
> +			if (!newMsg) { free(msg); free(expTokArr); return YYENOMEM; }
> +			msg = newMsg;

... it would allow to remove these checks; libc would take care of
reallocting the memory buffer.

> +		pos += snprintf(msg+pos, len-pos, "%s%s%s%s",

and no more need to advance the target buffer and manual fiddling with
allowed length.

Other than these nits I think this is ready to get merged.

      parent reply	other threads:[~2026-01-16 13:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-04 21:54 [PATCH nft] parser_bison: on syntax errors, output expected tokens Jan Kończak
2025-12-04 22:37 ` Florian Westphal
2025-12-13 12:32   ` Jan Kończak
2026-01-16 13:07 ` Florian Westphal [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aWo4DAHLS5284upo@strlen.de \
    --to=fw@strlen.de \
    --cc=jan.konczak@cs.put.poznan.pl \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox