tiny_printf - 小さいprintf()を作る

目的

組込み用途などで、footprintが小さいprintf関数が欲しい。
ライセンスを気にしなくて良いように、縛りがゆるいものが良い。

結果

printf()の仕様の勉強を兼ねて、自作した。パブリックドメインにするので、扱いはなんでも可。
サイズ縮小のために、一部機能を限定している(%p,%f,%gは非対応など)。
footprintは以下の通り:

命令セット サイズ(byte)
ARM 1426
Thumb-2 862

以下、詳細。

Cソースファイル

以下に置く:

tiny_printf.c
https://sssvn.jp/svn/spikelet/c/arm-tiny/tiny_printf.c

簡単な表示サンプルコード(__TEST__ を define すると有効になる)も付けてある。
ビルド方法は以下(テストコードを有効にして、実行ファイルを作る場合):

arm-none-linux-gnueabi-gcc -mthumb \
  -D__TEST__ \
  -Os -Wall -fno-unwind-tables -fno-unroll-loops -fomit-frame-pointer \
  -o tiny_printf tiny_printf.c

表示サンプル

__TEST__ マクロを定義してビルドして実行する:

printf(%c): 0 => <
printf(%c): '0' => 0<
printf(%c): 'A' => A<
printf(%c): '~' => ~<
printf(%s): "" => <
printf(%s): "-" => -<
printf(%s): "string" => string<
printf(%s): "too long long long long string, yet continue, too long, and exhaust allocated buffer, at that time is this function works correctly?" => too long long long long string, yet continue, too long, and exhaust allocated buffer, at that time is thi
printf(%s): long_string => too long long long long long long long string, long long long, enough long to exhaust buffer, still continue long, longl long....<

printf(%s=%s): => LD_PRELOAD=/usr/local/lib/lib0trace.so
printf(%s%d): => /dev/iosc/tsd1
printf(%d): 0 => 0<
printf(%d): 1 => 1<
printf(%d): 0x7fffffff => 2147483647<
printf(%d): 0x80000000 => -2147483648<
printf(%d): -1 => -1<
printf(%u): 0 => 0<
printf(%u): 1 => 1<
printf(%u): 0x7fffffff => 2147483647<
printf(%u): 0x80000000 => 2147483648<
printf(%u): -1 => 4294967295<
printf(%1d): 0 => 0<
printf(%2d): 0 =>  0<
printf(%3d): 0 =>   0<
printf(%10d): 12345678 =>   12345678<
printf(%11d): 12345678 =>    12345678<
printf(%12d): 12345678 =>     12345678<
printf(%13d): 12345678 =>      12345678<
printf(%14d): 12345678 =>       12345678<
printf(%15d): 12345678 =>        12345678<
printf(%16d): 12345678 =>         12345678<
printf(%17d): 12345678 =>          12345678<
printf(%18d): 12345678 =>           12345678<
printf(%19d): 12345678 =>            12345678<
printf(%010d): 12345678 => 0012345678<
printf(%011d): 12345678 => 00012345678<
printf(%012d): 12345678 => 000012345678<
printf(%013d): 12345678 => 0000012345678<
printf(%014d): 12345678 => 00000012345678<
printf(%015d): 12345678 => 000000012345678<
printf(%016d): 12345678 => 0000000012345678<
printf(%017d): 12345678 => 00000000012345678<
printf(%018d): 12345678 => 000000000012345678<
printf(%019d): 12345678 => 0000000000012345678<
printf(%10u): -1 => 4294967295<
printf(%11u): -1 =>  4294967295<
printf(%12u): -1 =>   4294967295<
printf(%13u): -1 =>    4294967295<
printf(%14u): -1 =>     4294967295<
printf(%15u): -1 =>      4294967295<
printf(%16u): -1 =>       4294967295<
printf(%17u): -1 =>        4294967295<
printf(%18u): -1 =>         4294967295<
printf(%19u): -1 =>          4294967295<
printf(%010u): -1 => 4294967295<
printf(%011u): -1 => 04294967295<
printf(%012u): -1 => 004294967295<
printf(%013u): -1 => 0004294967295<
printf(%014u): -1 => 00004294967295<
printf(%015u): -1 => 000004294967295<
printf(%016u): -1 => 0000004294967295<
printf(%017u): -1 => 00000004294967295<
printf(%018u): -1 => 000000004294967295<
printf(%019u): -1 => 0000000004294967295<
printf(%b): 0 => 0<
printf(%b): 1 => 1<
printf(%b): 0x7fffffff => 1111111111111111111111111111111<
printf(%b): 0x80000000 => 10000000000000000000000000000000<
printf(%b): -1 => 11111111111111111111111111111111<
printf(%16b): 0xa5a5 => 1010010110100101<
printf(%17b): 0xa5a5 =>  1010010110100101<
printf(%18b): 0xa5a5 =>   1010010110100101<
printf(%19b): 0xa5a5 =>    1010010110100101<
printf(%20b): 0xa5a5 =>     1010010110100101<
printf(%21b): 0xa5a5 =>      1010010110100101<
printf(%22b): 0xa5a5 =>       1010010110100101<
printf(%23b): 0xa5a5 =>        1010010110100101<
printf(%24b): 0xa5a5 =>         1010010110100101<
printf(%25b): 0xa5a5 =>          1010010110100101<
printf(%26b): 0xa5a5 =>           1010010110100101<
printf(%o): 0 => 0<
printf(%o): 1 => 1<
printf(%o): 0x7fffffff => 17777777777<
printf(%o): 0x80000000 => 20000000000<
printf(%o): -1 => 37777777777<
printf(%10o): 06661234 =>    6661234<
printf(%11o): 06661234 =>     6661234<
printf(%12o): 06661234 =>      6661234<
printf(%13o): 06661234 =>       6661234<
printf(%14o): 06661234 =>        6661234<
printf(%15o): 06661234 =>         6661234<
printf(%16o): 06661234 =>          6661234<
printf(%17o): 06661234 =>           6661234<
printf(%18o): 06661234 =>            6661234<
printf(%19o): 06661234 =>             6661234<
printf(%x): 0 => 0<
printf(%x): 1 => 1<
printf(%x): 0x7fffffff => 7fffffff<
printf(%x): 0x80000000 => 80000000<
printf(%x): -1 => ffffffff<
printf(%10x): 0xdeadbeef =>   deadbeef<
printf(%11x): 0xdeadbeef =>    deadbeef<
printf(%12x): 0xdeadbeef =>     deadbeef<
printf(%13x): 0xdeadbeef =>      deadbeef<
printf(%14x): 0xdeadbeef =>       deadbeef<
printf(%15x): 0xdeadbeef =>        deadbeef<
printf(%16x): 0xdeadbeef =>         deadbeef<
printf(%17x): 0xdeadbeef =>          deadbeef<
printf(%18x): 0xdeadbeef =>           deadbeef<
printf(%19x): 0xdeadbeef =>            deadbeef<
printf(%X): 0 => 0<
printf(%X): 1 => 1<
printf(%X): 0x7fffffff => 7FFFFFFF<
printf(%X): 0x80000000 => 80000000<
printf(%X): -1 => FFFFFFFF<
printf(%10X): 0xdeadbeef =>   DEADBEEF<
printf(%11X): 0xdeadbeef =>    DEADBEEF<
printf(%12X): 0xdeadbeef =>     DEADBEEF<
printf(%13X): 0xdeadbeef =>      DEADBEEF<
printf(%14X): 0xdeadbeef =>       DEADBEEF<
printf(%15X): 0xdeadbeef =>        DEADBEEF<
printf(%16X): 0xdeadbeef =>         DEADBEEF<
printf(%17X): 0xdeadbeef =>          DEADBEEF<
printf(%18X): 0xdeadbeef =>           DEADBEEF<
printf(%19X): 0xdeadbeef =>            DEADBEEF<

ざっと見た感じでは、うまくいってるかな。