Skip to content

Commit c86c64f

Browse files
committed
tinystdio: Finish switchover to _PICOLIBC_PRINTF and _PICOLIBC_SCANF
These two values replace the list of per-variant PICOLIBC_*_PRINTF_SCANF variables. They provide a simpler mechanism for the compiler driver to pass along the right value and select the right linker aliases. Switch the code to use the new values instead of the old ones, providing backward-compatibility hooks in stdio.h so that existing external code continues to work. Signed-off-by: Keith Packard <[email protected]>
1 parent ec588e8 commit c86c64f

29 files changed

+316
-540
lines changed

CMakeLists.txt

+2-29
Original file line numberDiff line numberDiff line change
@@ -235,35 +235,8 @@ if(NOT DEFINED __IO_WCHAR)
235235
option(__IO_WCHAR "Support %ls/%lc formats in printf even without multi-byte" OFF)
236236
endif()
237237

238-
if(NOT DEFINED __IO_DEFAULT_MINIMAL)
239-
set(__IO_DEFAULT_MINIMAL ${IO_MINIMAL})
240-
endif()
241-
242-
if(__IO_DEFAULT_MINIMAL)
243-
set(__IO_DEFAULT_DOUBLE OFF)
244-
set(__IO_DEFAULT_FLOAT OFF)
245-
set(__IO_DEFAULT_INTEGER OFF)
246-
set(__IO_DEFAULT_LONG_LONG OFF)
247-
endif()
248-
249-
if(NOT DEFINED __IO_DEFAULT_DOUBLE)
250-
set(__IO_DEFAULT_DOUBLE ${__IO_FLOAT})
251-
endif()
252-
253-
if(NOT DEFINED __IO_DEFAULT_FLOAT)
254-
set(__IO_DEFAULT_FLOAT OFF)
255-
endif()
256-
257-
if(NOT DEFINED __IO_DEFAULT_LONG_LONG)
258-
set(__IO_DEFAULT_LONG_LONG OFF)
259-
endif()
260-
261-
if(NOT DEFINED __IO_DEFAULT_INTEGER)
262-
if (__IO_FLOAT)
263-
set(__IO_DEFAULT_INTEGER OFF)
264-
else()
265-
set(__IO_DEFAULT_INTEGER ON)
266-
endif()
238+
if(NOT DEFINED __IO_DEFAULT)
239+
set(__IO_DEFAULT d)
267240
endif()
268241

269242
# math library sets errno

meson.build

+50-155
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,14 @@ stack_symbol = meson.get_cross_property('stack_symbol', '__stack')
290290
posix_console = tinystdio and get_option('posix-console')
291291
io_float_exact = not tinystdio or get_option('io-float-exact')
292292
atomic_ungetc = tinystdio and get_option('atomic-ungetc')
293-
format_default = get_option('format-default')
293+
_line = get_option('format-default')
294+
# Pick off just the leading character
295+
if meson.version().version_compare('>=0.56')
296+
format_default = _line.substring(0, 1)
297+
else
298+
format_default = run_command(['expr', 'substr', _line, '1', '1'], check : false).stdout().split('\n')[0]
299+
endif
300+
294301
printf_aliases = get_option('printf-aliases')
295302
io_percent_b = tinystdio and get_option('io-percent-b')
296303
printf_small_ultoa = tinystdio and get_option('printf-small-ultoa')
@@ -299,139 +306,38 @@ minimal_io_long_long = tinystdio and get_option('minimal-io-long-long')
299306
fast_bufio = tinystdio and get_option('fast-bufio')
300307
io_wchar = tinystdio and get_option('io-wchar')
301308

309+
foreach format : ['d', 'f', 'l', 'i', 'm']
302310

303-
if printf_aliases
304-
double_printf_compile_args=['-DPICOLIBC_DOUBLE_PRINTF_SCANF']
305-
float_printf_compile_args=['-DPICOLIBC_FLOAT_PRINTF_SCANF']
306-
llong_printf_compile_args=['-DPICOLIBC_LONG_LONG_PRINTF_SCANF']
307-
int_printf_compile_args=['-DPICOLIBC_INTEGER_PRINTF_SCANF']
308-
min_printf_compile_args=['-DPICOLIBC_MINIMAL_PRINTF_SCANF']
309-
else
310-
double_printf_compile_args=[]
311-
float_printf_compile_args=[]
312-
llong_printf_compile_args=[]
313-
int_printf_compile_args=[]
314-
min_printf_compile_args=[]
315-
endif
316-
double_printf_link_args=double_printf_compile_args
317-
float_printf_link_args=float_printf_compile_args
318-
llong_printf_link_args=llong_printf_compile_args
319-
int_printf_link_args=int_printf_compile_args
320-
min_printf_link_args=min_printf_compile_args
321-
322-
if tinystdio and printf_aliases
323-
vfprintf_symbol = global_prefix + 'vfprintf'
324-
__d_vfprintf_symbol = global_prefix + '__d_vfprintf'
325-
__f_vfprintf_symbol = global_prefix + '__f_vfprintf'
326-
__l_vfprintf_symbol = global_prefix + '__l_vfprintf'
327-
__i_vfprintf_symbol = global_prefix + '__i_vfprintf'
328-
__m_vfprintf_symbol = global_prefix + '__m_vfprintf'
329-
vfscanf_symbol = global_prefix + 'vfscanf'
330-
__d_vfscanf_symbol = global_prefix + '__d_vfscanf'
331-
__f_vfscanf_symbol = global_prefix + '__f_vfscanf'
332-
__l_vfscanf_symbol = global_prefix + '__l_vfscanf'
333-
__i_vfscanf_symbol = global_prefix + '__i_vfscanf'
334-
__m_vfscanf_symbol = global_prefix + '__m_vfscanf'
335-
336-
if has_link_defsym
337-
if format_default != 'double'
338-
double_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __d_vfprintf_symbol
339-
double_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __d_vfscanf_symbol
340-
endif
341-
if format_default != 'float'
342-
float_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __f_vfprintf_symbol
343-
float_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __f_vfscanf_symbol
344-
endif
345-
if format_default != 'long-long'
346-
llong_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __l_vfprintf_symbol
347-
llong_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __l_vfscanf_symbol
348-
endif
349-
if format_default != 'integer'
350-
int_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __i_vfprintf_symbol
351-
int_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __i_vfscanf_symbol
352-
endif
353-
if format_default != 'minimal'
354-
min_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __m_vfprintf_symbol
355-
min_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __m_vfscanf_symbol
356-
endif
357-
elif has_link_alias
358-
if format_default == 'double'
359-
float_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __d_vfprintf_symbol
360-
float_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __d_vfscanf_symbol
361-
llong_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __d_vfprintf_symbol
362-
llong_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __d_vfscanf_symbol
363-
int_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __d_vfprintf_symbol
364-
int_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __d_vfscanf_symbol
365-
min_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __d_vfprintf_symbol
366-
min_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __d_vfscanf_symbol
367-
endif
368-
if format_default == 'float'
369-
double_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __f_vfprintf_symbol
370-
double_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __f_vfscanf_symbol
371-
llong_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __f_vfprintf_symbol
372-
llong_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __f_vfscanf_symbol
373-
int_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __f_vfprintf_symbol
374-
int_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __f_vfscanf_symbol
375-
min_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __f_vfprintf_symbol
376-
min_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __f_vfscanf_symbol
377-
endif
378-
if format_default == 'long-long'
379-
double_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __l_vfprintf_symbol
380-
double_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __l_vfscanf_symbol
381-
float_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __l_vfprintf_symbol
382-
float_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __l_vfscanf_symbol
383-
int_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __l_vfprintf_symbol
384-
int_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __l_vfscanf_symbol
385-
min_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __l_vfprintf_symbol
386-
min_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __l_vfscanf_symbol
387-
endif
388-
if format_default == 'integer'
389-
double_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __i_vfprintf_symbol
390-
double_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __i_vfscanf_symbol
391-
float_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __i_vfprintf_symbol
392-
float_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __i_vfscanf_symbol
393-
llong_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __i_vfprintf_symbol
394-
llong_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __i_vfscanf_symbol
395-
min_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __i_vfprintf_symbol
396-
min_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __i_vfscanf_symbol
397-
endif
398-
if format_default == 'minimal'
399-
double_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __m_vfprintf_symbol
400-
double_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __m_vfscanf_symbol
401-
float_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __m_vfprintf_symbol
402-
float_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __m_vfscanf_symbol
403-
llong_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __m_vfprintf_symbol
404-
llong_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __m_vfscanf_symbol
405-
int_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __m_vfprintf_symbol
406-
int_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __m_vfscanf_symbol
407-
endif
408-
if format_default != 'double'
409-
double_printf_link_args += '-Wl,-alias,' + __d_vfprintf_symbol + ',' + vfprintf_symbol
410-
double_printf_link_args += '-Wl,-alias,' + __d_vfscanf_symbol + ',' + vfscanf_symbol
411-
endif
412-
if format_default != 'float'
413-
float_printf_link_args += '-Wl,-alias,' + __f_vfprintf_symbol + ',' + vfprintf_symbol
414-
float_printf_link_args += '-Wl,-alias,' + __f_vfscanf_symbol + ',' + vfscanf_symbol
415-
endif
416-
if format_default != 'long-long'
417-
llong_printf_link_args += '-Wl,-alias,' + __l_vfprintf_symbol + ',' + vfprintf_symbol
418-
llong_printf_link_args += '-Wl,-alias,' + __l_vfscanf_symbol + ',' + vfscanf_symbol
419-
endif
420-
if format_default != 'integer'
421-
int_printf_link_args += '-Wl,-alias,' + __i_vfprintf_symbol + ',' + vfprintf_symbol
422-
int_printf_link_args += '-Wl,-alias,' + __i_vfscanf_symbol + ',' + vfscanf_symbol
423-
endif
424-
if format_default != 'minimal'
425-
min_printf_link_args += '-Wl,-alias,' + __m_vfprintf_symbol + ',' + vfprintf_symbol
426-
min_printf_link_args += '-Wl,-alias,' + __m_vfscanf_symbol + ',' + vfscanf_symbol
427-
endif
311+
compile_variable = 'printf_compile_args_@0@'.format(format)
312+
if tinystdio and printf_aliases
313+
compile_value = ['-D_PICOLIBC_PRINTF=\'@0@\''.format(format),
314+
'-D_PICOLIBC_SCANF=\'@0@\''.format(format)]
428315
else
429-
if enable_tests
430-
# If the alias flag is not supported and we are building tests, emit an
431-
# error here to avoid surprising test failures.
432-
error('Symbol alias linker flag not supported - printf tests will fail!')
316+
compile_value = []
317+
endif
318+
set_variable(compile_variable, compile_value)
319+
320+
link_variable = 'printf_link_args_@0@'.format(format)
321+
link_value = compile_value
322+
if tinystdio and printf_aliases
323+
if format_default != format
324+
if has_link_defsym
325+
link_value += '-Wl,--defsym=@0@vfprintf=@0@__@1@_vfprintf'.format(global_prefix, format)
326+
link_value += '-Wl,--defsym=@0@vfscanf=@0@__@1@_vfscanf'.format(global_prefix, format)
327+
else
328+
link_value += '-Wl,-alias,@0@__@1@_vfprintf,@0@vfprintf'.format(global_prefix, format)
329+
link_value += '-Wl,-alias,@0@__@1@_vfscanf,@0@vfscanf'.format(global_prefix, format)
330+
endif
433331
endif
434332
endif
333+
set_variable(link_variable, link_value)
334+
335+
endforeach
336+
337+
if tinystdio and enable_tests and not (has_link_defsym or has_link_alias)
338+
# If the alias flag is not supported and we are building tests, emit an
339+
# error here to avoid surprising test failures.
340+
error('Symbol alias linker flag not supported - printf tests will fail!')
435341
endif
436342

437343
# A bunch of newlib-stdio only options
@@ -583,18 +489,20 @@ if specs_extra_list != []
583489
specs_extra = '\n' + '\n'.join(specs_extra_list)
584490
endif
585491

492+
# Handle old-style printf/scanf selection mechanism in the specs file
493+
586494
specs_printf = ''
587495
if tinystdio and printf_aliases
588-
specs_printf=('%{DPICOLIBC_DOUBLE_PRINTF_SCANF:--defsym=vfprintf=' + __d_vfprintf_symbol + '}' +
589-
' %{DPICOLIBC_DOUBLE_PRINTF_SCANF:--defsym=vfscanf=' + __d_vfscanf_symbol + '}' +
590-
' %{DPICOLIBC_FLOAT_PRINTF_SCANF:--defsym=vfprintf=' + __f_vfprintf_symbol + '}' +
591-
' %{DPICOLIBC_FLOAT_PRINTF_SCANF:--defsym=vfscanf=' + __f_vfscanf_symbol + '}' +
592-
' %{DPICOLIBC_LONG_LONG_PRINTF_SCANF:--defsym=vfprintf=' + __l_vfprintf_symbol + '}' +
593-
' %{DPICOLIBC_LONG_LONG_PRINTF_SCANF:--defsym=vfscanf=' + __l_vfscanf_symbol + '}' +
594-
' %{DPICOLIBC_INTEGER_PRINTF_SCANF:--defsym=vfprintf=' + __i_vfprintf_symbol + '}' +
595-
' %{DPICOLIBC_INTEGER_PRINTF_SCANF:--defsym=vfscanf=' + __i_vfscanf_symbol + '}' +
596-
' %{DPICOLIBC_MINIMAL_PRINTF_SCANF:--defsym=vfprintf=' + __m_vfprintf_symbol + '}' +
597-
' %{DPICOLIBC_MINIMAL_PRINTF_SCANF:--defsym=vfscanf=' + __m_vfscanf_symbol + '}')
496+
specs_printf=('%{DPICOLIBC_DOUBLE_PRINTF_SCANF:--defsym=vfprintf=@0@__d_vfprintf}' +
497+
' %{DPICOLIBC_DOUBLE_PRINTF_SCANF:--defsym=vfscanf=@0@__d_vfscanf}' +
498+
' %{DPICOLIBC_FLOAT_PRINTF_SCANF:--defsym=vfprintf=@0@__f_vfprintf}' +
499+
' %{DPICOLIBC_FLOAT_PRINTF_SCANF:--defsym=vfscanf=@0@__f_vfscanf}' +
500+
' %{DPICOLIBC_LONG_LONG_PRINTF_SCANF:--defsym=vfprintf=@0@__l_vfprintf}' +
501+
' %{DPICOLIBC_LONG_LONG_PRINTF_SCANF:--defsym=vfscanf=@0@__l_vfscanf}' +
502+
' %{DPICOLIBC_INTEGER_PRINTF_SCANF:--defsym=vfprintf=@0@__i_vfprintf}' +
503+
' %{DPICOLIBC_INTEGER_PRINTF_SCANF:--defsym=vfscanf=@0@__i_vfscanf}' +
504+
' %{DPICOLIBC_MINIMAL_PRINTF_SCANF:--defsym=vfprintf=@0@__m_vfprintf}' +
505+
' %{DPICOLIBC_MINIMAL_PRINTF_SCANF:--defsym=vfscanf=@0@__m_vfscanf}').format(global_prefix)
598506
endif
599507

600508
crt0_expr = '%{-crt0=*:crt0-%*%O%s; :crt0%O%s}'
@@ -1389,21 +1297,8 @@ endif
13891297

13901298
conf_data.set('__TINY_STDIO', tinystdio, description: 'Use tiny stdio from gcc avr')
13911299
if tinystdio
1392-
conf_data.set('__IO_DEFAULT_DOUBLE',
1393-
format_default == 'double',
1394-
description: 'The default printf functions is the double variant')
1395-
conf_data.set('__IO_DEFAULT_FLOAT',
1396-
format_default == 'float',
1397-
description: 'The default printf functions is the float variant')
1398-
conf_data.set('__IO_DEFAULT_LONG_LONG',
1399-
format_default == 'long-long',
1400-
description: 'The default printf functions is the long-long variant')
1401-
conf_data.set('__IO_DEFAULT_INTEGER',
1402-
format_default == 'integer',
1403-
description: 'The default printf functions is the integer variant')
1404-
conf_data.set('__IO_DEFAULT_MINIMAL',
1405-
format_default == 'minimal',
1406-
description: 'The default printf functions is the minimal variant')
1300+
conf_data.set('__IO_DEFAULT', '\'@0@\''.format(format_default),
1301+
description: 'The default printf and scanf variants')
14071302
conf_data.set('__IO_SMALL_ULTOA',
14081303
printf_small_ultoa,
14091304
description: 'avoid software division in decimal conversion')

meson_options.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ option('atomic-ungetc', type: 'boolean', value: true,
135135
description: 'use atomics in fgetc/ungetc to make them re-entrant')
136136
option('posix-console', type: 'boolean', value: false,
137137
description: 'Use POSIX I/O for stdin/stdout/stderr')
138-
option('format-default', type: 'combo', choices: ['double', 'float', 'long-long', 'integer', 'minimal'], value: 'double',
138+
option('format-default', type: 'combo', choices: ['double', 'float', 'long-long', 'integer', 'minimal', 'd', 'f', 'l', 'i', 'm'], value: 'd',
139139
description: 'which printf/scanf versions should be the default')
140140
option('printf-aliases', type: 'boolean', value: true,
141141
description: 'Allow link-time printf aliases')
@@ -212,7 +212,7 @@ option('crt-runtime-size', type: 'boolean', value: false,
212212
description: 'compute crt memory space sizes at runtime')
213213

214214
#
215-
# Non-picoexit startup/shutdown options
215+
# Legacy (non-picoexit) startup/shutdown options
216216
#
217217

218218
option('newlib-atexit-dynamic-alloc', type: 'boolean', value: false,

newlib/libc/tinystdio/conv_flt.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ static const char pstr_nfinity[] = "nfinity";
3434
static const char pstr_an[] = "an";
3535

3636
#if defined(STRTOD) || defined(STRTOF) || defined(STRTOLD)
37+
3738
# define CHECK_WIDTH() 1
3839
# define CHECK_RANGE(flt) do { \
3940
int __class = fpclassify(flt); \
@@ -43,21 +44,28 @@ static const char pstr_an[] = "an";
4344
# ifdef __IO_C99_FORMATS
4445
# define _NEED_IO_C99_FORMATS
4546
# endif
47+
4648
# if defined(STRTOD)
49+
4750
# define _NEED_IO_DOUBLE
48-
# define SCANF_LEVEL SCANF_DBL
51+
# define SCANF_VARIANT __IO_VARIANT_DOUBLE
4952
# define CHECK_LONG() 1
5053
# define CHECK_LONG_LONG() 0
54+
5155
# elif defined(STRTOLD)
56+
5257
# define _NEED_IO_LONG_DOUBLE
53-
# define SCANF_LEVEL SCANF_DBL
58+
# define SCANF_VARIANT __IO_VARIANT_DOUBLE
5459
# define CHECK_LONG() 0
5560
# define CHECK_LONG_LONG() 1
61+
5662
# elif defined(STRTOF)
63+
5764
# define _NEED_IO_FLOAT
58-
# define SCANF_LEVEL SCANF_FLT
65+
# define SCANF_VARIANT __IO_VARIANT_FLOAT
5966
# define CHECK_LONG() 0
6067
# define CHECK_LONG_LONG() 0
68+
6169
# endif
6270

6371
#define FLT_STREAM const char

0 commit comments

Comments
 (0)