nanoprintf는 완전히 활성화되면 C11 표준 준수를 목표로 하는 임베디드 시스템을 위한 snprintf 및 vsnprintf의 방해 없는 구현입니다. 주요 예외는 부동 소수점, 과학적 표기법( %e
, %g
, %a
) 및 wcrtomb
있어야 하는 변환입니다. C23 이진 정수 출력은 N2630에 따라 선택적으로 지원됩니다. 버퍼 오버플로 이벤트에서 잘린 문자열이나 완전히 비어 있는 문자열을 반환하도록 snprintf 및 vsnprintf에 대한 안전 확장을 선택적으로 구성할 수 있습니다.
또한 nanoprintf를 사용하면 실제 텍스트 서식을 지정하지 않고도 printf 스타일 형식 문자열을 구문 분석하여 다양한 매개변수와 변환 지정자를 추출할 수 있습니다.
nanoprintf는 메모리를 할당하지 않으며 100바이트 미만의 스택을 사용합니다. 구성에 따라 Cortex-M0 아키텍처에서 ~740-2640바이트의 개체 코드 로 컴파일됩니다.
모든 코드는 최대한의 컴파일러 호환성을 위해 최소한의 C99 방언으로 작성되었으며, clang + gcc + msvc에서 가장 높은 경고 수준에서 깔끔하게 컴파일되고, UBsan 또는 Asan에서 문제가 발생하지 않으며, 32비트 및 64비트 아키텍처에서 철저하게 테스트되었습니다. . nanoprintf에는 C 표준 헤더가 포함되어 있지만 C99 유형 및 인수 목록에만 사용됩니다. 컴파일러가 내보낼 수 있는 내부의 큰 정수 연산 호출을 제외하고는 stdlib/libc에 대한 호출이 이루어지지 않습니다. 평소와 같이 msvc용으로 기본적으로 컴파일하는 경우 일부 Windows 관련 헤더가 필요합니다.
nanoprintf는 stb 라이브러리 스타일의 단일 헤더 파일입니다. 저장소의 나머지 부분은 테스트 및 스캐폴딩이며 사용에 필요하지 않습니다.
nanoprintf는 정적으로 구성 가능하므로 사용자는 크기, 컴파일러 요구 사항 및 기능 세트 간의 균형을 찾을 수 있습니다. 부동 소수점 변환, "대형" 길이 수정자 및 크기 쓰기 저장은 모두 구성 가능하며 명시적으로 요청한 경우에만 컴파일됩니다. 자세한 내용은 구성을 참조하세요.
nanoprintf 구현을 컴파일하려면 소스 파일 중 하나에 다음 코드를 추가하세요.
// define your nanoprintf configuration macros here (see "Configuration" below) #define NANOPRINTF_IMPLEMENTATION #include "path/to/nanoprintf.h"
그런 다음 nanoprintf를 사용하려는 파일에서 헤더를 포함하고 npf_ 함수를 호출하면 됩니다.
#include "nanoprintf.h" void print_to_uart(void) { npf_pprintf(&my_uart_putc, NULL, "Hello %s%c %d %u %fn", "worl", 'd', 1, 2, 3.f); } void print_to_buf(void *buf, unsigned len) { npf_snprintf(buf, len, "Hello %s", "world"); }
자세한 내용은 "nanoprintf 직접 사용" 및 "nanoprintf 래핑" 예제를 참조하세요.
나는 최소 구성(부트로더 등)에서 1KB 미만, 부동 소수점 벨과 휘파람 기능이 활성화된 3KB 미만의 단일 파일 공개 도메인 드롭인 printf를 원했습니다.
펌웨어 작업에서는 일반적으로 syscall이나 파일 설명자 계층 요구 사항 없이 stdio의 문자열 형식을 원합니다. 작은 버퍼에 로그인하거나 버스로 직접 내보내려는 작은 시스템에서는 거의 필요하지 않습니다. 또한 많은 임베디드 stdio 구현은 필요한 것보다 크거나 느립니다. 이는 부트로더 작업에 중요합니다. syscall이나 stdio 벨 + 휘파람이 필요하지 않은 경우 nanoprintf 및 nosys.specs
사용하여 빌드를 줄일 수 있습니다.
이 코드는 가독성이나 구조가 아닌 크기에 최적화되어 있습니다. 불행하게도 모듈화와 "청결성"(이것이 무엇을 의미하든)은 이 작은 규모에 오버헤드를 추가하므로 대부분의 기능과 논리가 npf_vpprintf
에 함께 푸시됩니다. 이는 일반적인 임베디드 시스템 코드의 모습이 아닙니다. #ifdef
수프이고 이해하기 어렵습니다. 구현 중에 몰래 훔쳐보아야 한다면 사과드립니다. 다양한 테스트가 당신이 해킹한다면 가이드 레일 역할을 할 수 있기를 바랍니다.
아니면 아마도 당신은 나보다 훨씬 더 나은 프로그래머일 수도 있습니다! 그런 경우에는 공간을 더 크게 만들지 않고 이 코드를 더 작고 깔끔하게 만들거나 올바른 방향으로 나를 밀어줄 수 있도록 도와주세요. :)
nanoprintf에는 4가지 주요 기능이 있습니다.
npf_snprintf
: snprintf와 비슷하게 사용합니다.
npf_vsnprintf
: vsnprintf( va_list
지원)와 같이 사용합니다.
npf_pprintf
: 문자별 쓰기 콜백(세미호스팅, UART 등)과 함께 printf처럼 사용합니다.
npf_vpprintf
: npf_pprintf
와 유사하게 사용하지만 va_list
를 사용합니다.
pprintf
변형은 인쇄할 문자와 사용자가 제공한 컨텍스트 포인터를 받는 콜백을 사용합니다.
아무것도 쓰지 않으려면 npf_[v]snprintf
에 NULL
또는 nullptr
전달하고 형식이 지정된 문자열의 길이만 반환합니다.
nanoprintf는 printf
나 putchar
자체를 제공하지 않습니다 . 이는 시스템 수준 서비스로 간주되며 nanoprintf는 유틸리티 라이브러리입니다. 하지만 nanoprintf는 자신만의 printf
롤링하기 위한 좋은 구성 요소가 되기를 바랍니다.
nanoprintf 함수는 모두 동일한 값을 반환합니다. 즉, 콜백(npf_pprintf의 경우)으로 전송된 문자 수 또는 충분한 공간이 제공된 버퍼에 기록된 문자 수입니다. 널 종결자 0바이트는 카운트에 포함되지 않습니다.
C 표준에서는 문자열 또는 문자 인코딩을 수행할 수 없거나 출력 스트림이 EOF를 만나는 경우 printf 함수가 음수 값을 반환하도록 허용합니다. nanoprintf는 파일과 같은 OS 리소스를 인식하지 못하고 wchar_t
지원을 위한 l
길이 수정자를 지원하지 않으므로 모든 런타임 오류는 내부 버그(보고해 주세요!)이거나 잘못된 사용입니다. 이 때문에 nanoprintf는 형식화된 문자열에 포함된 바이트 수(역시 null 종결자 바이트 제외)를 나타내는 음수가 아닌 값만 반환합니다.
nanoprintf에는 다음과 같은 정적 구성 플래그가 있습니다.
NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS
: 0
또는 1
로 설정합니다. 필드 너비 지정자를 활성화합니다.
NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS
: 0
또는 1
로 설정합니다. 정밀도 지정자를 활성화합니다.
NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS
: 0
또는 1
로 설정합니다. 부동 소수점 지정자를 활성화합니다.
NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS
: 0
또는 1
로 설정합니다. 대형 수정자를 활성화합니다.
NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS
: 0
또는 1
로 설정합니다. 바이너리 지정자를 활성화합니다.
NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS
: 0
또는 1
로 설정합니다. 후기입을 위해 %n
활성화합니다.
NANOPRINTF_VISIBILITY_STATIC
: 선택적으로 정의합니다. 프로토타입을 샌드박스 nanoprintf에 대해 static
으로 표시합니다.
구성 플래그가 지정되지 않으면 nanoprintf는 도움이 되도록 "합리적인" 내장 값을 기본값으로 설정합니다. 부동 소수점은 활성화되지만 쓰기 저장, 바이너리 및 대형 포맷터는 비활성화됩니다. 구성 플래그가 명시적으로 지정된 경우 nanoprintf에서는 모든 플래그를 명시적으로 지정해야 합니다.
비활성화된 형식 지정자 기능을 사용하면 변환이 발생하지 않고 대신 형식 지정자 문자열만 인쇄됩니다.
nanoprintf에는 다음과 같은 부동 소수점 특정 구성 정의가 있습니다.
NANOPRINTF_CONVERSION_BUFFER_SIZE
: 선택 사항, 기본값은 23
입니다. 변환된 값을 저장하는 데 사용되는 문자 버퍼의 크기를 설정합니다. 더 많은 문자로 부동 소수점 숫자를 인쇄하려면 더 큰 숫자로 설정하십시오. 버퍼 크기에는 정수 부분, 분수 부분 및 소수 구분 기호가 포함되지만 부호 및 패딩 문자는 포함되지 않습니다. 숫자가 버퍼에 맞지 않으면 err
가 인쇄됩니다. 변환 버퍼는 스택 메모리에 할당되므로 큰 크기에 주의하세요.
NANOPRINTF_CONVERSION_FLOAT_TYPE
: 선택사항, 기본값은 unsigned int
입니다. 변환 정확도를 결정하는 부동 소수점 변환 알고리즘에 사용되는 정수 유형을 설정합니다. 예를 들어 uint64_t
또는 uint8_t
와 같이 부호 없는 정수 유형으로 설정할 수 있습니다.
기본적으로 npf_snprintf 및 npf_vsnprintf는 C 표준에 따라 동작합니다. 제공된 버퍼는 채워지지만 오버런되지는 않습니다. 문자열이 버퍼를 오버런하게 되면 null 종결자 바이트가 버퍼의 마지막 바이트에 기록됩니다. 버퍼가 null
이거나 크기가 0이면 바이트가 기록되지 않습니다.
NANOPRINTF_SNPRINTF_SAFE_EMPTY_STRING_ON_OVERFLOW
정의하고 문자열이 버퍼보다 큰 경우 버퍼의 첫 번째 바이트가 null 종결자 바이트로 덮어쓰여집니다. 이는 Microsoft의 snprintf_s와 유사합니다.
모든 경우에 nanoprintf는 충분한 공간이 있었다면 버퍼에 기록되었을 바이트 수를 반환합니다. 이 값은 C 표준에 따라 널 종료자 바이트를 고려하지 않습니다.
nanoprintf는 스택 메모리만 사용하고 동시성 기본 요소는 사용하지 않으므로 내부적으로 실행 환경을 인식하지 못합니다. 이렇게 하면 여러 실행 컨텍스트에서 동시에 호출하거나 다른 npf_
호출(예: ISR 등)로 npf_
호출을 중단하는 것이 안전해집니다. 동일한 npf_putc
대상과 npf_pprintf
동시에 사용하는 경우 콜백 내부의 정확성을 보장하는 것은 사용자의 몫입니다. 여러 스레드에서 동일한 버퍼로 npf_snprintf
수행하면 명백한 데이터 경쟁이 발생합니다.
printf
와 마찬가지로 nanoprintf
다음 형식의 변환 사양 문자열을 기대합니다.
[flags][field width][.precision][length modifier][conversion specifier]
플래그
다음 중 하나 이상:
0
: 필드를 앞에 0 문자로 채웁니다.
-
: 해당 필드에 변환 결과를 왼쪽 정렬합니다.
+
: 서명된 변환은 항상 +
또는 -
문자로 시작됩니다.
: (공백) 변환된 첫 번째 문자가 기호가 아닌 경우 공백 문자가 삽입됩니다.
#
: 추가 문자를 씁니다(16진수의 경우 0x
, 빈 부동 소수점의 경우 .
, 빈 8진수의 경우 '0' 등).
필드 너비 (활성화된 경우)
변환을 위한 전체 필드 너비를 지정하는 숫자로 패딩이 추가됩니다. 필드 너비가 *
이면 다음 가변 인수에서 필드 너비를 읽습니다.
정밀도 (활성화된 경우)
.
, 숫자 또는 문자열의 정밀도를 지정하는 숫자입니다. 정밀도가 *
이면 다음 가변 인수에서 정밀도를 읽습니다.
길이 수정자
다음 중 하나 이상:
h
: 적분 및 후기입 가변 인수 너비에는 short
사용합니다.
L
: float vararg 너비에 long double
사용합니다(참고: 그런 다음 double
로 캐스팅됩니다).
l
: long
, double
또는 wide vararg 너비를 사용합니다.
hh
: 정수 및 쓰기 저장 가변 인수 너비에 char
사용합니다.
ll
: (대형 지정자) 정수 및 쓰기 저장 가변 인수 너비에는 long long
사용합니다.
j
: (대형 지정자) 정수 및 쓰기 저장 가변 인수 너비에는 [u]intmax_t
유형을 사용합니다.
z
: (대형 지정자) 정수 및 쓰기 저장 가변 인수 너비에 size_t
유형을 사용합니다.
t
: (대형 지정자) 정수 및 쓰기 저장 가변 인수 너비에 대해 ptrdiff_t
유형을 사용합니다.
변환 지정자
정확히 다음 중 하나입니다.
%
: 백분율 기호 리터럴
c
: 캐릭터
s
: Null로 끝나는 문자열
i
/ d
: 부호 있는 정수
u
: 부호 없는 정수
o
: 부호 없는 8진 정수
x
/ X
: 부호 없는 16진수 정수
p
: 포인터
n
: 포인터 vararg에 쓰여진 바이트 수를 씁니다.
f
/ F
: 부동소수점 십진수
e
/ E
: 부동 소수점 과학(구현되지 않음, 부동 소수점 인쇄)
g
/ G
: 가장 짧은 부동 소수점 (구현되지 않음, 부동 소수점 인쇄)
a
/ A
: 부동 소수점 16진수(구현되지 않음, 부동 소수점 인쇄)
b
/ B
: 이진 정수
부동 소수점 변환은 숫자의 정수 부분과 분수 부분을 두 개의 개별 정수 변수로 추출하여 수행됩니다. 각 부분에 대해 지수는 가수에 2와 5를 적절하게 반복적으로 곱하고 나누어서 2진수에서 10진수로 크기가 조정됩니다. 스케일링 작업의 순서는 가수의 가장 중요한 비트를 최대한 많이 유지하기 위해 값에 따라 동적으로 선택됩니다. 값이 소수 구분 기호에서 멀어질수록 스케일링 시 더 많은 오류가 누적됩니다. 평균적으로 N
비트의 변환 정수 유형 너비를 사용하면 알고리즘은 N - log2(5)
또는 N - 2.322
비트의 정확도를 유지합니다. 또한 최대 2 ^^ N - 1
의 정수 부분과 소수 구분 기호 뒤 최대 N - 2.322
비트의 분수 부분도 비트 손실 없이 완벽하게 변환됩니다.
부동 소수점 -> 고정 코드는 원시 부동 소수점 값 비트에서 작동하므로 부동 소수점 연산이 수행되지 않습니다. 이를 통해 nanoprintf는 Cortex-M0과 같은 소프트 플로트 아키텍처에서 플로트 형식을 효율적으로 지정하고 "빠른 수학"과 같은 최적화 유무에 관계없이 동일하게 작동하며 코드 공간을 최소화할 수 있습니다.
%e
/ %E
, %a
/ %A
및 %g
/ %G
지정자는 구문 분석되지만 형식은 지정되지 않습니다. 사용하는 경우 출력은 %f
/ %F
사용한 경우와 동일합니다. 풀 요청을 환영합니다! :)
와이드 문자 지원은 없습니다. %lc
및 %ls
필드에서는 wcrtomb를 호출하는 것처럼 인수를 char 배열로 변환해야 합니다. 로캘 및 문자 집합 변환이 관련되면 "nano"라는 이름을 유지하기가 어렵습니다. 따라서 %lc
및 %ls
각각 %c
및 %s
처럼 동작합니다.
현재 지원되는 유일한 부동 소수점 변환은 소수 형식인 %f
및 %F
입니다. 풀 요청을 환영합니다!
CI 빌드는 gcc 및 nm을 사용하여 모든 끌어오기 요청의 컴파일된 크기를 측정하도록 설정됩니다. 최근 실행에 대한 사전 제출 확인 "크기 보고서" 작업 출력을 참조하세요.
Cortex-M0 빌드에 대해 다음 크기 측정이 수행됩니다.
Configuration "Minimal": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 00000270 00000016 T npf_pprintf 000002cc 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 00000286 00000046 T npf_vsnprintf 00000058 00000218 T npf_vpprintf Total size: 0x2e2 (738) bytes Configuration "Binary": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 000002a8 00000016 T npf_pprintf 00000304 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 000002be 00000046 T npf_vsnprintf 00000058 00000250 T npf_vpprintf Total size: 0x31a (794) bytes Configuration "Field Width + Precision": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 000004fe 00000016 T npf_pprintf 0000055c 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 00000514 00000048 T npf_vsnprintf 00000058 000004a6 T npf_vpprintf Total size: 0x572 (1394) bytes Configuration "Field Width + Precision + Binary": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 00000560 00000016 T npf_pprintf 000005bc 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 00000576 00000046 T npf_vsnprintf 00000058 00000508 T npf_vpprintf Total size: 0x5d2 (1490) bytes Configuration "Float": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 00000618 00000016 T npf_pprintf 00000674 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 0000062e 00000046 T npf_vsnprintf 00000058 000005c0 T npf_vpprintf Total size: 0x68a (1674) bytes Configuration "Everything": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=1 - arm-none-eabi-nm --print-size --size-sort npf.o 0000005a 00000002 t npf_bufputc_nop 0000005c 00000010 t npf_putc_cnt 00000046 00000014 t npf_bufputc 000009da 00000016 T npf_pprintf 00000a38 00000016 T npf_snprintf 00000000 00000046 t npf_utoa_rev 000009f0 00000048 T npf_vsnprintf 0000006c 0000096e T npf_vpprintf Total size: 0xa4e (2638) bytes
환경을 확보하고 테스트를 실행하려면 다음 안내를 따르세요.
이 저장소를 복제하거나 포크하세요.
루트에서 ./b
실행(또는 Windows 사용자의 경우 루트에서 py -3 build.py
)
그러면 호스트 환경에 대한 모든 단위, 적합성 및 컴파일 테스트가 구축됩니다. 모든 테스트 실패는 0이 아닌 종료 코드를 반환합니다.
nanoprintf 개발 환경은 cmake와 ninja를 사용합니다. 경로에 이러한 항목이 있으면 ./b
이를 사용합니다. 그렇지 않은 경우 ./b
이를 다운로드하여 path/to/your/nanoprintf/external
에 배포합니다.
nanoprintf는 모든 지속적인 통합 빌드에 GitHub Actions를 사용합니다. GitHub Linux 빌드는 내 Docker 저장소의 이 Docker 이미지를 사용합니다.
매트릭스는 32비트 clang Mac 구성을 제외하고 [Debug, Release] x [32비트, 64비트] x [Mac, Windows, Linux] x [gcc, clang, msvc]를 빌드합니다.
하나의 테스트 스위트는 MIT 라이센스가 있는 printf 테스트 스위트의 포크입니다. 라이센스 목적을 위한 하위 모듈로 존재합니다. nanoprintf는 공개 도메인이므로 이 특정 테스트 스위트는 선택 사항이며 기본적으로 제외됩니다. 이를 빌드하려면 하위 모듈을 업데이트하여 검색하고 ./b
호출에 --paland
플래그를 추가하세요. nanoprintf를 사용할 필요는 전혀 없습니다.
float-to-int 변환의 기본 아이디어는 Wojciech Muła의 float -> 64:64 고정 알고리즘에서 영감을 얻었으며 Oskars Rubenis의 동적 스케일링 및 구성 가능한 정수 너비를 추가하여 더욱 확장되었습니다.
printf 테스트 스위트를 nanoprintf로 포팅했습니다. 원래는 mpaland printf 프로젝트 코드베이스에서 왔지만 Eyal Rozenberg 및 다른 사람들이 채택하고 개선했습니다. (Nanoprintf에는 자체 테스트가 많이 있지만 이 테스트도 매우 철저하고 훌륭합니다!)
바이너리 구현은 Jörg Wunsch의 N2630 제안에 지정된 요구 사항을 기반으로 하며 C23에 채택되기를 바랍니다!