Skip to content

Commit

Permalink
zcbor.py: Add dummy calls to function pointers
Browse files Browse the repository at this point in the history
To verify that the args are the right type.

Signed-off-by: Øyvind Rønningstad <[email protected]>
  • Loading branch information
oyvindronningstad committed Aug 21, 2024
1 parent bb962b9 commit bed3782
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
8 changes: 7 additions & 1 deletion samples/pet/src/pet_decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,19 @@ static bool decode_Pet(
{
zcbor_log("%s\r\n", __func__);

bool res = (((zcbor_list_start_decode(state) && ((((zcbor_list_start_decode(state) && ((zcbor_multi_decode(1, 3, &(*result).names_count, (zcbor_decoder_t *)zcbor_tstr_decode, state, (&(*result).names), sizeof(struct zcbor_string))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state)))
bool res = (((zcbor_list_start_decode(state) && ((((zcbor_list_start_decode(state) && ((zcbor_multi_decode(1, 3, &(*result).names_count, (zcbor_decoder_t *)zcbor_tstr_decode, state, (*&(*result).names), sizeof(struct zcbor_string))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state)))
&& ((zcbor_bstr_decode(state, (&(*result).birthday)))
&& ((((((*result).birthday.len == 8)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)))
&& ((((zcbor_uint_decode(state, &(*result).species_choice, sizeof((*result).species_choice)))) && ((((((*result).species_choice == Pet_species_cat_c) && ((1)))
|| (((*result).species_choice == Pet_species_dog_c) && ((1)))
|| (((*result).species_choice == Pet_species_other_c) && ((1)))) || (zcbor_error(state, ZCBOR_ERR_WRONG_VALUE), false)))))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state))));

if (false) {
/* For testing that the types of the arguments are correct.
A compiler error here means a bug in zcbor. */
zcbor_tstr_decode(state, (*&(*result).names));
}

log_result(state, res, __func__);
return res;
}
Expand Down
2 changes: 1 addition & 1 deletion samples/pet/src/pet_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static bool encode_Pet(
{
zcbor_log("%s\r\n", __func__);

bool res = (((zcbor_list_start_encode(state, 3) && ((((zcbor_list_start_encode(state, 3) && ((zcbor_multi_encode_minmax(1, 3, &(*input).names_count, (zcbor_encoder_t *)zcbor_tstr_encode, state, (&(*input).names), sizeof(struct zcbor_string))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_list_end_encode(state, 3)))
bool res = (((zcbor_list_start_encode(state, 3) && ((((zcbor_list_start_encode(state, 3) && ((zcbor_multi_encode_minmax(1, 3, &(*input).names_count, (zcbor_encoder_t *)zcbor_tstr_encode, state, (*&(*input).names), sizeof(struct zcbor_string))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_list_end_encode(state, 3)))
&& (((((((*input).birthday.len == 8)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))
&& (zcbor_bstr_encode(state, (&(*input).birthday))))
&& ((((*input).species_choice == Pet_species_cat_c) ? ((zcbor_uint32_put(state, (1))))
Expand Down
35 changes: 31 additions & 4 deletions zcbor/zcbor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from argparse import ArgumentParser, ArgumentTypeError, RawDescriptionHelpFormatter, FileType
from datetime import datetime
from copy import copy
from itertools import tee
from itertools import tee, chain
from cbor2 import (loads, dumps, CBORTag, load, CBORDecodeValueError, CBORDecodeEOF, undefined,
CBORSimpleValue)
from yaml import safe_load as yaml_load, dump as yaml_dump
Expand Down Expand Up @@ -2599,7 +2599,8 @@ def full_xcode(self, union_int=None):
f"zcbor_present_decode(&(%s), (zcbor_decoder_t *)%s, %s)" %
(self.present_var_access(), func, xcode_args(*arguments),))
elif self.count_var_condition():
func, *arguments = self.repeated_single_func(ptr_result=True)
func, arg = self.repeated_single_func(ptr_result=True)

minmax = "_minmax" if self.mode == "encode" else ""
mode = self.mode
return (
Expand All @@ -2608,7 +2609,7 @@ def full_xcode(self, union_int=None):
self.max_qty,
self.count_var_access(),
func,
xcode_args(*arguments),
xcode_args("*" + arg if arg != "NULL" and self.result_len() != "0" else arg),
self.result_len()))
else:
return self.repeated_xcode(union_int)
Expand Down Expand Up @@ -2755,6 +2756,32 @@ def render_forward_declaration(self, xcoder, mode):

def render_function(self, xcoder, mode):
body = xcoder.body

# Define the subroutine "paren" that matches parenthesised expressions.
paren_re = r'(?(DEFINE)(?P<paren>\(((?>[^\(\)]+|(?&paren))*)\)))'
# This uses "paren" to match a single argument to a function.
arg_re = rf'([^,\(\)]|(?&paren))+'
# Match a function pointer argument to a function.
func_re = rf'\(zcbor_(en|de)coder_t \*\)(?P<func>{arg_re})'
# Match a triplet of function pointer, state arg, and result arg.
call_re = rf'{func_re}, (?P<state>{arg_re}), (?P<arg>{arg_re})'
multi_re = rf'{paren_re}zcbor_multi_(en|de)code\(({arg_re},){{3}} {call_re}'
present_re = rf'{paren_re}zcbor_present_(en|de)code\({arg_re}, {call_re}\)'
map_re = rf'{paren_re}zcbor_unordered_map_search\({call_re}\)'
all_funcs = chain(getrp(multi_re).finditer(body),
getrp(present_re).finditer(body),
getrp(map_re).finditer(body))
arg_test = ""
calls = ("\n ".join(
(f"{m.group('func')}({m.group('state')}, {m.group('arg')});" for m in (all_funcs))))
if calls != "":
arg_test = f"""
if (false) {{
/* For testing that the types of the arguments are correct.
A compiler error here means a bug in zcbor. */
{calls}
}}
"""
return f"""
static bool {xcoder.func_name}(
zcbor_state_t *state, {"" if mode == "decode" else "const "}{
Expand All @@ -2766,7 +2793,7 @@ def render_function(self, xcoder, mode):
{"bool int_res;" if "int_res" in body else ""}
bool res = ({body});
{arg_test}
log_result(state, res, __func__);
return res;
}}""".replace(" \n", "") # call replace() to remove empty lines.
Expand Down

0 comments on commit bed3782

Please sign in to comment.