mirror of
https://github.com/tailix/libkernaux.git
synced 2026-08-15 11:00:07 -04:00
Main: generate tests for printf format parser
This commit is contained in:
parent
7a06114ab6
commit
7041066109
5 changed files with 451 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -118,6 +118,8 @@
|
||||||
/tests/test_ntoa
|
/tests/test_ntoa
|
||||||
/tests/test_pfa
|
/tests/test_pfa
|
||||||
/tests/test_pfa_assert
|
/tests/test_pfa_assert
|
||||||
|
/tests/test_printf_fmt_gen
|
||||||
|
/tests/test_printf_fmt_gen.c
|
||||||
/tests/test_printf_gen
|
/tests/test_printf_gen
|
||||||
/tests/test_printf_gen.c
|
/tests/test_printf_gen.c
|
||||||
/tests/test_units_human
|
/tests/test_units_human
|
||||||
|
|
|
||||||
15
Makefile.am
15
Makefile.am
|
|
@ -17,6 +17,7 @@ libkernaux_a_SOURCES = \
|
||||||
src/libc.c
|
src/libc.c
|
||||||
|
|
||||||
CLEANFILES = \
|
CLEANFILES = \
|
||||||
|
tests/test_printf_fmt_gen.c \
|
||||||
tests/test_printf_gen.c
|
tests/test_printf_gen.c
|
||||||
|
|
||||||
if ASM_I386
|
if ASM_I386
|
||||||
|
|
@ -143,6 +144,9 @@ libkernaux_a_SOURCES += src/printf_fmt.c
|
||||||
if ENABLE_TESTS
|
if ENABLE_TESTS
|
||||||
TESTS += examples/printf_fmt
|
TESTS += examples/printf_fmt
|
||||||
endif
|
endif
|
||||||
|
if ENABLE_TESTS_PYTHON
|
||||||
|
TESTS += tests/test_printf_fmt_gen
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if WITH_UNITS
|
if WITH_UNITS
|
||||||
|
|
@ -278,6 +282,14 @@ tests_test_pfa_assert_SOURCES = \
|
||||||
$(libkernaux_a_SOURCES) \
|
$(libkernaux_a_SOURCES) \
|
||||||
tests/test_pfa_assert.c
|
tests/test_pfa_assert.c
|
||||||
|
|
||||||
|
tests_test_printf_fmt_gen_SOURCES = \
|
||||||
|
$(libkernaux_a_SOURCES) \
|
||||||
|
tests/test_printf_fmt_gen.c \
|
||||||
|
tests/printf_fmt_gen.py \
|
||||||
|
tests/printf_fmt_gen.jinja \
|
||||||
|
common/printf.yml \
|
||||||
|
common/printf_orig.yml
|
||||||
|
|
||||||
tests_test_printf_gen_SOURCES = \
|
tests_test_printf_gen_SOURCES = \
|
||||||
$(libkernaux_a_SOURCES) \
|
$(libkernaux_a_SOURCES) \
|
||||||
tests/test_printf_gen.c \
|
tests/test_printf_gen.c \
|
||||||
|
|
@ -290,5 +302,8 @@ tests_test_units_human_SOURCES = \
|
||||||
$(libkernaux_a_SOURCES) \
|
$(libkernaux_a_SOURCES) \
|
||||||
tests/test_units_human.c
|
tests/test_units_human.c
|
||||||
|
|
||||||
|
tests/test_printf_fmt_gen.c: tests/printf_fmt_gen.py tests/printf_fmt_gen.jinja common/printf_fmt.yml
|
||||||
|
python3 tests/printf_fmt_gen.py
|
||||||
|
|
||||||
tests/test_printf_gen.c: tests/printf_gen.py tests/printf_gen.jinja common/printf.yml common/printf_orig.yml
|
tests/test_printf_gen.c: tests/printf_gen.py tests/printf_gen.jinja common/printf.yml common/printf_orig.yml
|
||||||
python3 tests/printf_gen.py
|
python3 tests/printf_gen.py
|
||||||
|
|
|
||||||
340
common/printf_fmt.yml
Normal file
340
common/printf_fmt.yml
Normal file
|
|
@ -0,0 +1,340 @@
|
||||||
|
- in:
|
||||||
|
format: 's'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '-s'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [left]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '+s'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [plus]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: ' s'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [space]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '#s'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [hash]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '0s'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [zeropad]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '123s'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 123
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '*s'
|
||||||
|
width: 123
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 123
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '.123s'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [precision]
|
||||||
|
width: 0
|
||||||
|
precision: 123
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '.*s'
|
||||||
|
width: null
|
||||||
|
precision: 123
|
||||||
|
out:
|
||||||
|
flags: [precision]
|
||||||
|
width: 0
|
||||||
|
precision: 123
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'ls'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [long]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'lls'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [long, long_long]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'hs'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [short]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'hhs'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [short, char]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'd'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: int
|
||||||
|
base: 10
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'i'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: int
|
||||||
|
base: 10
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'u'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: uint
|
||||||
|
base: 10
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'x'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: uint
|
||||||
|
base: 16
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'X'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [uppercase]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: uint
|
||||||
|
base: 16
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'o'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: uint
|
||||||
|
base: 8
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'b'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: uint
|
||||||
|
base: 2
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'f'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: float
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'F'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [uppercase]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: float
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'e'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: exp
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'E'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [uppercase]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: exp
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'g'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [adapt_exp]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: exp
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'G'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: [adapt_exp, uppercase]
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: exp
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 'c'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: char
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: 's'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: str
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '%'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: percent
|
||||||
|
base: 0
|
||||||
|
|
||||||
|
- in:
|
||||||
|
format: '_'
|
||||||
|
width: null
|
||||||
|
precision: null
|
||||||
|
out:
|
||||||
|
flags: []
|
||||||
|
width: 0
|
||||||
|
precision: 0
|
||||||
|
type: none
|
||||||
|
base: 0
|
||||||
35
tests/printf_fmt_gen.jinja
Normal file
35
tests/printf_fmt_gen.jinja
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <kernaux/printf_fmt.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{% for case in cases %}
|
||||||
|
{
|
||||||
|
const char *format = {{ escape_str(case.in.format) }};
|
||||||
|
|
||||||
|
struct KernAux_PrintfFmt_Spec spec = KernAux_PrintfFmt_Spec_create();
|
||||||
|
KernAux_PrintfFmt_Spec_eval_flags(&spec, &format);
|
||||||
|
if (KernAux_PrintfFmt_Spec_eval_width1(&spec, &format)) {
|
||||||
|
KernAux_PrintfFmt_Spec_eval_width2(&spec, {{ none_to_zero(case.in.width) }});
|
||||||
|
}
|
||||||
|
if (KernAux_PrintfFmt_Spec_eval_precision1(&spec, &format)) {
|
||||||
|
KernAux_PrintfFmt_Spec_eval_precision2(&spec, {{ none_to_zero(case.in.precision) }});
|
||||||
|
}
|
||||||
|
KernAux_PrintfFmt_Spec_eval_length(&spec, &format);
|
||||||
|
KernAux_PrintfFmt_Spec_eval_type(&spec, &format);
|
||||||
|
|
||||||
|
assert(spec.flags == {{ escape_flags(case.out.flags) }});
|
||||||
|
assert(spec.width == {{ case.out.width }});
|
||||||
|
assert(spec.precision == {{ case.out.precision }});
|
||||||
|
assert(spec.type == {{ escape_type(case.out.type) }});
|
||||||
|
assert(spec.base == {{ case.out.base }});
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
59
tests/printf_fmt_gen.py
Normal file
59
tests/printf_fmt_gen.py
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
from os import path
|
||||||
|
from yaml import SafeLoader, safe_load
|
||||||
|
|
||||||
|
CASES_FILENAME = 'printf_fmt.yml'
|
||||||
|
TEMPLATE_FILENAME = 'printf_fmt_gen.jinja'
|
||||||
|
TEST_FILENAME = 'test_printf_fmt_gen.c'
|
||||||
|
|
||||||
|
ROOT_DIRPATH = path.dirname(path.dirname(path.join(path.abspath(__file__))))
|
||||||
|
|
||||||
|
COMMON_DIRPATH = path.join(ROOT_DIRPATH, 'common')
|
||||||
|
TESTS_DIRPATH = path.join(ROOT_DIRPATH, 'tests')
|
||||||
|
|
||||||
|
CASES_FILEPATH = path.join(COMMON_DIRPATH, CASES_FILENAME)
|
||||||
|
TEST_FILEPATH = path.join(TESTS_DIRPATH, TEST_FILENAME)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
cases = safe_load(open(CASES_FILEPATH))
|
||||||
|
|
||||||
|
jinja_env = Environment(
|
||||||
|
keep_trailing_newline=True,
|
||||||
|
loader=FileSystemLoader(TESTS_DIRPATH),
|
||||||
|
)
|
||||||
|
jinja_template = jinja_env.get_template(TEMPLATE_FILENAME)
|
||||||
|
|
||||||
|
result = jinja_template.render(
|
||||||
|
cases=cases,
|
||||||
|
escape_flags=escape_flags,
|
||||||
|
escape_str=escape_str,
|
||||||
|
escape_type=escape_type,
|
||||||
|
none_to_zero=none_to_zero,
|
||||||
|
)
|
||||||
|
|
||||||
|
with open(TEST_FILEPATH, 'w') as f:
|
||||||
|
f.write(result)
|
||||||
|
|
||||||
|
def escape_flag(flag):
|
||||||
|
return 'KERNAUX_PRINTF_FMT_FLAGS_' + flag.upper()
|
||||||
|
|
||||||
|
def escape_flags(flags):
|
||||||
|
if len(flags) == 0:
|
||||||
|
return '0'
|
||||||
|
|
||||||
|
return '(' + ' | '.join(map(escape_flag, flags)) + ')'
|
||||||
|
|
||||||
|
def escape_str(s):
|
||||||
|
return '"' + s + '"'
|
||||||
|
|
||||||
|
def escape_type(type_):
|
||||||
|
return 'KERNAUX_PRINTF_FMT_TYPE_' + type_.upper()
|
||||||
|
|
||||||
|
def none_to_zero(num):
|
||||||
|
if num is None:
|
||||||
|
return '0'
|
||||||
|
else:
|
||||||
|
return str(num)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue