(new c lib) dynamic printf and scanf introduced

New features and project activity between releases
Post Reply
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

(new c lib) dynamic printf and scanf introduced

Post by alvin »

The new c lib allows the user to decide which printf and scanf converters are activated when a target's library is built by customizing the target's clib_cfg.asm file. An excerpt from such a file contains defined constants __CLIB_OPT_PRINTF, __CLIB_OPT_PRINTF_2, __CLIB_OPT_SCANF, __CLIB_OPT_SCANF_2 with individual bits indicating which converters should be active.

Code: Select all

; -------------------------------------------------------------
; -- printf converter selection -------------------------------
; -------------------------------------------------------------

; You can select which printf converters are included in
; the library.  Omitting unused ones can reduce code size.
; Note the bit assignments are the same as for scanf.

defc __CLIB_OPT_PRINTF = $002ff6ff

; bit 0 =  $      01 = enable %d
; bit 1 =  $      02 = enable %u
; bit 2 =  $      04 = enable %x
; bit 3 =  $      08 = enable %X
; bit 4 =  $      10 = enable %o
; bit 5 =  $      20 = enable %n
; bit 6 =  $      40 = enable %i
; bit 7 =  $      80 = enable %p
; bit 8 =  $     100 = enable %B
; bit 9 =  $     200 = enable %s
; bit 10 = $     400 = enable %c
; bit 11 = $     800 = enable %I
; bit 12 = $    1000 = enable %ld
; bit 13 = $    2000 = enable %lu
; bit 14 = $    4000 = enable %lx
; bit 15 = $    8000 = enable %lX
; bit 16 = $   10000 = enable %lo
; bit 17 = $   20000 = enable %ln
; bit 18 = $   40000 = enable %li
; bit 19 = $   80000 = enable %lp
; bit 20 = $  100000 = enable %lB
; bit 21 = $  200000 = ignored
; bit 22 = $  400000 = enable %a
; bit 23 = $  800000 = enable %A
; bit 24 = $ 1000000 = enable %e
; bit 25 = $ 2000000 = enable %E
; bit 26 = $ 4000000 = enable %f
; bit 27 = $ 8000000 = enable %F
; bit 28 = $10000000 = enable %g
; bit 29 = $20000000 = enable %G

defc __CLIB_OPT_PRINTF_2 = $0
;;defc __CLIB_OPT_PRINTF_2 = $ffffffff

; bit 0 =  $      01 = enable %lld
; bit 1 =  $      02 = enable %llu
; bit 2 =  $      04 = enable %llx
; bit 3 =  $      08 = enable %llX
; bit 4 =  $      10 = enable %llo
; bit 5 =  $      20 = ignored
; bit 6 =  $      40 = enable %lli

; Setting all flag bits to zero will remove the % logic
; from printf entirely, meaning printf can only be used
; to output format text to the stream.


; -------------------------------------------------------------
; -- scanf converter selection --------------------------------
; -------------------------------------------------------------

; You can select which scanf converters are included in
; the library.  Omitting unused ones can reduce code size.
; Note the bit assignments are the same as for printf.

defc __CLIB_OPT_SCANF = $002ff6ff

; bit 0 =  $    01 = enable %d
; bit 1 =  $    02 = enable %u
; bit 2 =  $    04 = enable %x
; bit 3 =  $    08 = enable %x (duplicate)
; bit 4 =  $    10 = enable %o
; bit 5 =  $    20 = enable %n
; bit 6 =  $    40 = enable %i
; bit 7 =  $    80 = enable %p
; bit 8 =  $   100 = enable %B
; bit 9 =  $   200 = enable %s
; bit 10 = $   400 = enable %c
; bit 11 = $   800 = enable %I
; bit 12 = $  1000 = enable %ld
; bit 13 = $  2000 = enable %lu
; bit 14 = $  4000 = enable %lx
; bit 15 = $  8000 = enable %lx (duplicate)
; bit 16 = $ 10000 = enable %lo
; bit 17 = $ 20000 = enable %ln
; bit 18 = $ 40000 = enable %li
; bit 19 = $ 80000 = enable %lp
; bit 20 = $100000 = enable %lB
; bit 21 = $200000 = enable %[

defc __CLIB_OPT_SCANF_2 = $0

; bit 0 =  $      01 = enable %lld
; bit 1 =  $      02 = enable %llu
; bit 2 =  $      04 = enable %llx
; bit 3 =  $      08 = enable %llX
; bit 4 =  $      10 = enable %llo
; bit 5 =  $      20 = ignored
; bit 6 =  $      40 = enable %lli

; Setting all flag bits to zero will remove the % logic
; from scanf entirely, meaning scanf can only be used to
; match format text against the stream.
By deactivating unused converters, the user can reduce program size when printf or scanf is used in programs.

Because the set of active converters are baked into the target's library, making changes can be time consuming, involving editing the clib_cfg.asm file, re-building the target library (~5 mins) and then recompiling the program.

Effective with the July 4 build, the set of active printf and scanf converters can be determined at compile time without recompiling the target library.

This is done by defining one or more of the following constants either in the compile line or in the c source with pragmas:

CLIB_OPT_STDIO (0 is the default, 1 indicates stdio should check validity of FILE* before use)
CLIB_OPT_PRINTF (bit flags as described in text above)
CLIB_OPT_PRINTF_2 (bit flags as described in text above)
CLIB_OPT_SCANF (bit flags as described in text above)
CLIB_OPT_SCANF_2 (bit flags as described in text above)

If only one of the PRINTF constants is defined, the other will default to 0. Likewise if only one of the SCANF constants is defined, the other will default to 0.

Here are a couple of example compiles:

zcc +zx -vn -O3 -clib=new test.c -o test -create-app
printf and scanf will use the library defaults

zcc +zx -vn -O3 -clib=new test.c -o test -create-app -pragma-define:CLIB_OPT_PRINTF=0x201
printf will have %s and %d enabled only, scanf will use the library default

Code: Select all

#pragma output CLIB_OPT_PRINTF = 0

#include <stdio.h>

void main(void)
{
   printf("Hello World!\n");
}
zcc +zx -vn -startup=32 -clib=sdcc_iy --max-allocs-per-node200000 hw.c -o hw -create-app
if2 cartridge image is output, all printf converters deactivated, scanf uses library default


Note: When either CLIB_OPT_PRINTF or CLIB_OPT_PRINTF_2 is defined for the compile, printf will always be attached to the output binary whether printf is used by the program or not. Similarly when either CLIB_OPT_SCANF or CLIB_OPT_SCANF_2 is defined for the compile, scanf will always be attached to the output binary whether scanf is used by the program or not. When these constants are not defined, as per a "normal" compile, the linker will only attach the printf or scanf code to the output if printf or scanf are actually used.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

Bugs affecting -clib=sdcc_iy compiles and occasional symbol conflicts fixed in July 5 build.
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

This is a really neat idea and I've copied the concept for the classic scanf library.

As an added bonus (for classic), sccz80 will work out the value for CLIB_OPT_SCANF and automatically pull in the required formatters for the project.

This will be available in the 7th July build.
Post Reply