user: implement mlibc as the libc, finally.
It's finally done.. Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
int main(){
|
||||
assert(abs(-10) == 10);
|
||||
assert(abs(2021) == 2021);
|
||||
|
||||
assert(labs(-256) == 256);
|
||||
assert(labs(10034890) == 10034890);
|
||||
|
||||
assert(llabs(-0x2deadbeef) == 0x2deadbeef);
|
||||
assert(llabs(49238706947) == 49238706947);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main() {
|
||||
void *p;
|
||||
|
||||
p = aligned_alloc(sizeof(void *), sizeof(void *));
|
||||
assert(p != NULL && (uintptr_t)p % sizeof(void *) == 0);
|
||||
free(p);
|
||||
|
||||
p = aligned_alloc(256, 256);
|
||||
assert(p != NULL && (uintptr_t)p % 256 == 0);
|
||||
free(p);
|
||||
|
||||
// small alignments are okay
|
||||
p = aligned_alloc(1, 8);
|
||||
assert(p != NULL);
|
||||
free(p);
|
||||
p = aligned_alloc(1, 1);
|
||||
assert(p != NULL);
|
||||
free(p);
|
||||
|
||||
// It seems that glibc doesn't report error in these cases.
|
||||
#if !(defined(USE_HOST_LIBC) && defined(__GLIBC__))
|
||||
// size % align must be 0
|
||||
p = aligned_alloc(256, 1);
|
||||
assert(errno == EINVAL);
|
||||
assert(p == NULL);
|
||||
|
||||
// align must be a 'valid alignment supported by the implementation'
|
||||
p = aligned_alloc(3, 1);
|
||||
assert(errno == EINVAL);
|
||||
assert(p == NULL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main() {
|
||||
errno = 0;
|
||||
void *ptr = calloc((SIZE_MAX / 2) + 2, 2);
|
||||
assert(!ptr);
|
||||
assert(errno);
|
||||
|
||||
errno = 0;
|
||||
ptr = calloc(10, sizeof(size_t));
|
||||
assert(ptr);
|
||||
for(size_t i = 0; i < 10; i++) {
|
||||
size_t *p = ptr;
|
||||
assert(!p[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <complex.h>
|
||||
|
||||
// FIXME: We should create a proper floating point facility
|
||||
// in order for other functions to be tested properly
|
||||
|
||||
#define APPROXIMATELY_EQUAL(calculated, expected) fabs((calculated) - (expected)) <= 0.0000005
|
||||
#define APPROXIMATELY_EQUALF(calculated, expected) fabsf((calculated) - (expected)) <= 0.0000005f
|
||||
#define APPROXIMATELY_EQUALL(calculated, expected) fabsl((calculated) - (expected)) <= 0.0000005L
|
||||
|
||||
#define IS_COMPLEX_NUMBER(Z) \
|
||||
_Generic((Z), \
|
||||
double complex: 1, \
|
||||
float complex: 1, \
|
||||
long double complex: 1, \
|
||||
default: 0 \
|
||||
)
|
||||
|
||||
int main() {
|
||||
#if !(defined(USE_HOST_LIBC) && defined(__clang__))
|
||||
assert(IS_COMPLEX_NUMBER(CMPLX(5.2, 4.3)));
|
||||
double complex cz = CMPLX(5.2, 4.3);
|
||||
assert(APPROXIMATELY_EQUAL(creal(cz), 5.2));
|
||||
assert(APPROXIMATELY_EQUAL(cimag(cz), 4.3));
|
||||
|
||||
assert(IS_COMPLEX_NUMBER(CMPLXF(1.2f, 2.5f)));
|
||||
float complex czf = CMPLXF(1.2f, 2.5f);
|
||||
assert(APPROXIMATELY_EQUALF(crealf(czf), 1.2f));
|
||||
assert(APPROXIMATELY_EQUALF(cimagf(czf), 2.5f));
|
||||
|
||||
assert(IS_COMPLEX_NUMBER(CMPLXL(0.1L, 123.54L)));
|
||||
long double complex czl = CMPLXL(0.1L, 123.54L);
|
||||
assert(APPROXIMATELY_EQUALL(creall(czl), 0.1L));
|
||||
assert(APPROXIMATELY_EQUALL(cimagl(czl), 123.54L));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
/* qemu-m68k < version 9.1.0 cannot run the test due to missing FPU logic. */
|
||||
#ifdef __m68k__
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define NO_OPTIMIZE(x) asm volatile("" :: "r,m" (x) : "memory")
|
||||
|
||||
static void div_by_zero() {
|
||||
volatile float zero = 0.0f;
|
||||
NO_OPTIMIZE(69.0f / zero);
|
||||
}
|
||||
|
||||
static bool float_cmp(float a, float b) {
|
||||
return a == b || fabs(a - b) < (fabs(a) + fabs(b)) * FLT_EPSILON;
|
||||
}
|
||||
|
||||
static void test_rounding(float expectation1, float expectation2) {
|
||||
float x;
|
||||
volatile float f = 1.968750f;
|
||||
volatile float m = 0x1.0p23f;
|
||||
|
||||
NO_OPTIMIZE(x = f + m);
|
||||
assert(float_cmp(expectation1, x));
|
||||
NO_OPTIMIZE(x = x - m);
|
||||
assert(x == expectation2);
|
||||
}
|
||||
|
||||
void test0() {
|
||||
// test whether the divide-by-zero exception is raised
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
|
||||
div_by_zero();
|
||||
int raised = fetestexcept(FE_DIVBYZERO);
|
||||
assert((raised & FE_DIVBYZERO));
|
||||
}
|
||||
|
||||
void test1() {
|
||||
// test various rounding modes
|
||||
feclearexcept(FE_DIVBYZERO);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
|
||||
fesetround(FE_UPWARD);
|
||||
assert(fegetround() == FE_UPWARD);
|
||||
test_rounding(8388610.0f, 2.0f);
|
||||
|
||||
fesetround(FE_DOWNWARD);
|
||||
assert(fegetround() == FE_DOWNWARD);
|
||||
test_rounding(8388609.0f, 1.0f);
|
||||
|
||||
fesetround(FE_TONEAREST);
|
||||
assert(fegetround() == FE_TONEAREST);
|
||||
test_rounding(8388610.0f, 2.0f);
|
||||
|
||||
fesetround(FE_TOWARDZERO);
|
||||
assert(fegetround() == FE_TOWARDZERO);
|
||||
test_rounding(8388609.0f, 1.0f);
|
||||
}
|
||||
|
||||
void test2() {
|
||||
// test feraiseexcept
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
assert(feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW) == 0);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == (FE_DIVBYZERO | FE_OVERFLOW));
|
||||
}
|
||||
|
||||
void test3() {
|
||||
// test fe{get,set}env
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
assert(feraiseexcept(FE_OVERFLOW) == 0);
|
||||
|
||||
fenv_t state;
|
||||
assert(fegetenv(&state) == 0);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == FE_OVERFLOW);
|
||||
|
||||
div_by_zero();
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == (FE_DIVBYZERO | FE_OVERFLOW));
|
||||
|
||||
assert(fesetenv(&state) == 0);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == FE_OVERFLOW);
|
||||
}
|
||||
|
||||
int main() {
|
||||
test0();
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
(void) argc;
|
||||
|
||||
FILE *f = fopen(argv[0], "r");
|
||||
assert(f);
|
||||
|
||||
int ret = fseek(f, 0, SEEK_SET);
|
||||
assert(!ret);
|
||||
|
||||
fpos_t start_pos;
|
||||
ret = fgetpos(f, &start_pos);
|
||||
assert(!ret);
|
||||
|
||||
ret = fseek(f, 0, SEEK_END);
|
||||
assert(!ret);
|
||||
|
||||
long end_off = ftell(f);
|
||||
|
||||
fpos_t end_pos;
|
||||
ret = fgetpos(f, &end_pos);
|
||||
assert(!ret);
|
||||
|
||||
ret = fsetpos(f, &start_pos);
|
||||
assert(!ret);
|
||||
assert(ftell(f) == 0);
|
||||
|
||||
ret = fsetpos(f, &end_pos);
|
||||
assert(!ret);
|
||||
assert(ftell(f) == end_off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_HOST_LIBC
|
||||
#define TEST_FILE "fopen-host-libc.tmp"
|
||||
#else
|
||||
#define TEST_FILE "fopen.tmp"
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
FILE *file;
|
||||
char str[] = "mlibc fopen test";
|
||||
char str2[] = " mlibc appending";
|
||||
char completestr[] = "mlibc fopen test mlibc appending";
|
||||
char buffer[100];
|
||||
char buffer2[100];
|
||||
|
||||
// Clear all the buffers to zero.
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(buffer2, 0, sizeof(buffer2));
|
||||
|
||||
// Open the file for writing.
|
||||
file = fopen(TEST_FILE, "w");
|
||||
assert(file);
|
||||
|
||||
// Write string minus null terminator, flush and close.
|
||||
fwrite(str, 1, sizeof(str) - 1, file);
|
||||
fflush(file);
|
||||
fclose(file);
|
||||
|
||||
// Open the file for reading.
|
||||
file = fopen(TEST_FILE, "r");
|
||||
assert(file);
|
||||
|
||||
// Verify that we read back the written string and close the file.
|
||||
assert(fread(buffer, 1, sizeof(str) - 1, file));
|
||||
assert(!strcmp(buffer, str));
|
||||
fclose(file);
|
||||
|
||||
// Open the file in appending mode, append string 2 (minus the null terminator) to the file, flush and close.
|
||||
file = fopen(TEST_FILE, "a");
|
||||
fwrite(str2, 1, sizeof(str2) - 1, file);
|
||||
fflush(file);
|
||||
fclose(file);
|
||||
|
||||
// Open the file for reading again, verify the contents, close the file and return.
|
||||
file = fopen(TEST_FILE, "r");
|
||||
assert(fread(buffer2, 1, sizeof(completestr) - 1, file));
|
||||
assert(!strcmp(buffer2, completestr));
|
||||
fclose(file);
|
||||
|
||||
// Check that stdout, stdin and stderr can be closed by the application (issue #12).
|
||||
fclose(stdout);
|
||||
fclose(stdin);
|
||||
fclose(stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_HOST_LIBC
|
||||
#define TEST_FILE "fputs-host-libc.tmp"
|
||||
#else
|
||||
#define TEST_FILE "fputs.tmp"
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
FILE *file;
|
||||
char str[] = "mlibc fputs test";
|
||||
char buffer[100];
|
||||
|
||||
// Clear the buffer to zero.
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
// Open the file for writing.
|
||||
file = fopen(TEST_FILE, "w");
|
||||
assert(file);
|
||||
|
||||
// Verify that we can write an empty string.
|
||||
assert(fputs("", file) != EOF);
|
||||
|
||||
// Write string, flush and close.
|
||||
assert(fputs(str, file) != EOF);
|
||||
fflush(file);
|
||||
fclose(file);
|
||||
|
||||
// Open the file for reading.
|
||||
file = fopen(TEST_FILE, "r");
|
||||
assert(file);
|
||||
|
||||
// Verify that we read back the written string and close.
|
||||
assert(fread(buffer, 1, sizeof(str) - 1, file));
|
||||
assert(!strcmp(buffer, str));
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_HOST_LIBC
|
||||
#define TEST_FILE "freopen-host-libc.tmp"
|
||||
#else
|
||||
#define TEST_FILE "freopen.tmp"
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
FILE *file = fopen(TEST_FILE, "w");
|
||||
assert(file);
|
||||
|
||||
assert(freopen("/dev/null", "w", file));
|
||||
|
||||
char str[] = "mlibc freopen test";
|
||||
fwrite(str, 1, sizeof(str) - 1, file);
|
||||
fflush(file);
|
||||
fclose(file);
|
||||
|
||||
file = fopen(TEST_FILE, "r");
|
||||
assert(file);
|
||||
|
||||
char buf[sizeof(str)];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
int ret = fread(buf, 1, sizeof(buf) - 1, file);
|
||||
fprintf(stderr, "ret %d\n", ret);
|
||||
assert(ret == 0);
|
||||
fclose(file);
|
||||
|
||||
file = fopen("/dev/null", "w");
|
||||
assert(file);
|
||||
|
||||
assert(freopen(TEST_FILE, "w", file));
|
||||
fwrite(str, 1, sizeof(str) - 1, file);
|
||||
fflush(file);
|
||||
fclose(file);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
file = fopen(TEST_FILE, "r");
|
||||
assert(fread(buf, 1, sizeof(buf) - 1, file));
|
||||
|
||||
fprintf(stderr, "buffer content '%s'\n", buf);
|
||||
assert(!strcmp(buf, "mlibc freopen test"));
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_HOST_LIBC
|
||||
#define TEST_FILE "ftell-host-libc.tmp"
|
||||
#else
|
||||
#define TEST_FILE "ftell.tmp"
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
FILE *file;
|
||||
char str[] = "mlibc ftell test";
|
||||
size_t str_size = sizeof(str) - 1;
|
||||
char buffer[20];
|
||||
|
||||
// Clear buffer to zero
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
// Open the file for writing in binary mode, because ftell is unspecified
|
||||
// in text mode.
|
||||
file = fopen(TEST_FILE, "wb");
|
||||
assert(file);
|
||||
|
||||
// Write string minus null terminator, flush and close.
|
||||
assert(fwrite(str, 1, str_size, file) == str_size);
|
||||
fflush(file);
|
||||
fclose(file);
|
||||
|
||||
// Open the file for reading in binary mode.
|
||||
file = fopen(TEST_FILE, "rb");
|
||||
assert(file);
|
||||
|
||||
// Check position indicator at the start of the file.
|
||||
assert(ftell(file) == 0);
|
||||
|
||||
// Read 4 bytes and check fread and ftell.
|
||||
assert(fread(buffer, 1, 4, file) == 4);
|
||||
assert(ftell(file) == 4);
|
||||
|
||||
// Rewind and check position indicator at the start of the file.
|
||||
rewind(file);
|
||||
assert(ftell(file) == 0);
|
||||
|
||||
// Read the entire file and check fread and ftell.
|
||||
assert(fread(buffer, 1, str_size, file) == str_size);
|
||||
assert((size_t) ftell(file) == str_size);
|
||||
|
||||
// Rewind and check how ftell interacts with getc.
|
||||
rewind(file);
|
||||
assert(fgetc(file) == 'm');
|
||||
assert(ftell(file) == 1);
|
||||
assert(fgetc(file) == 'l');
|
||||
assert(ftell(file) == 2);
|
||||
assert(fgetc(file) == 'i');
|
||||
assert(ftell(file) == 3);
|
||||
|
||||
// Check whether ftell is decremented after ungetc
|
||||
assert(ungetc('X', file) == 'X');
|
||||
int ftell_after_ungetc = ftell(file);
|
||||
fprintf(stderr, "ftell_after_ungetc: %d\n", ftell_after_ungetc);
|
||||
assert(ftell_after_ungetc == 2);
|
||||
ungetc('Y', file);
|
||||
assert(ftell(file) == 1);
|
||||
|
||||
// Check if rewind undoes ungetc's effects on ftell
|
||||
rewind(file);
|
||||
assert(ftell(file) == 0);
|
||||
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
wchar_t c = 0xC9;
|
||||
unsigned char buf[MB_LEN_MAX] = { 0 };
|
||||
setlocale(LC_ALL, "");
|
||||
if (sprintf(buf, "%lc", c) < 0)
|
||||
return -1;
|
||||
|
||||
assert(buf[0] == 0xc3 && buf[1] == 0x89
|
||||
&& buf[2] == '\0' && buf[3] == '\0');
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdnoreturn.h>
|
||||
#include <assert.h>
|
||||
|
||||
jmp_buf buf;
|
||||
|
||||
noreturn void do_jump(int arg) {
|
||||
longjmp(buf, 2 * arg);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
volatile int times_called = 0;
|
||||
|
||||
if (setjmp(buf) != 8) {
|
||||
do_jump(++times_called);
|
||||
}
|
||||
|
||||
assert(times_called == 4);
|
||||
|
||||
times_called = 0;
|
||||
int ret = setjmp(buf);
|
||||
assert(ret == times_called);
|
||||
|
||||
if (!ret) {
|
||||
times_called = 1;
|
||||
longjmp(buf, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <assert.h>
|
||||
#include <locale.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <uchar.h>
|
||||
|
||||
struct {
|
||||
size_t ret;
|
||||
char32_t c32;
|
||||
uint8_t bytes[4];
|
||||
} expected_results[] = {
|
||||
{1, 0x7A, {0x7A, 0, 0, 0}},
|
||||
{2, 0xDF, {0xC3, 0x9F, 0, 0}},
|
||||
{3, 0x6C34, {0xE6, 0xB0, 0xB4, 0}},
|
||||
{4, 0x1F34C, {0xF0, 0x9F, 0x8D, 0x8C}},
|
||||
};
|
||||
|
||||
int main() {
|
||||
setlocale(LC_ALL, "en_US.utf8");
|
||||
|
||||
size_t ret = 0;
|
||||
|
||||
char *str = "z\u00df\u6c34\U0001F34C";
|
||||
|
||||
fprintf(stderr, "string: '%s'\n", str);
|
||||
|
||||
mbstate_t state = {};
|
||||
char32_t c32;
|
||||
size_t loop = 0;
|
||||
while((ret = mbrtoc32(&c32, str, strlen(str), &state))) {
|
||||
assert(ret != (size_t)-3);
|
||||
if(ret == (size_t)-1)
|
||||
break;
|
||||
if(ret == (size_t)-2)
|
||||
break;
|
||||
|
||||
fprintf(stderr, "Next UTF-32 char: 0x%x obtained from %zu bytes [", c32, ret);
|
||||
for(size_t n = 0; n < ret; ++n) {
|
||||
fprintf(stderr, " 0x%02x ", (uint8_t) str[n]);
|
||||
}
|
||||
fprintf(stderr, "]\n");
|
||||
|
||||
assert(ret == expected_results[loop].ret);
|
||||
assert(c32 == expected_results[loop].c32);
|
||||
for(size_t n = 0; n < ret; ++n) {
|
||||
assert((uint8_t) str[n] == expected_results[loop].bytes[n]);
|
||||
}
|
||||
|
||||
str += ret;
|
||||
loop++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
char *haystack = "abc123\0x45";
|
||||
|
||||
char *needle1 = "abc";
|
||||
void *rv = memmem(haystack, strlen(haystack), needle1, strlen(needle1));
|
||||
assert(rv == haystack);
|
||||
|
||||
char *needle2 = "123";
|
||||
rv = memmem(haystack, strlen(haystack), needle2, strlen(needle2));
|
||||
assert(rv == haystack + 3);
|
||||
|
||||
char *needle3 = "1234";
|
||||
rv = memmem(haystack, strlen(haystack), needle3, strlen(needle3));
|
||||
assert(rv == NULL);
|
||||
|
||||
char *needle4 = "23\0x45";
|
||||
rv = memmem(haystack, 10, needle4, 6);
|
||||
assert(rv == haystack + 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *arr[] = { "xyz", "abc", "ghi", "def" };
|
||||
|
||||
static const size_t magic = 0xDEADBEEF;
|
||||
|
||||
static int cmpstringp(const void *p1, const void *p2, void *ctx) {
|
||||
/* The actual arguments to this function are "pointers to
|
||||
* pointers to char", but strcmp(3) arguments are "pointers
|
||||
* to char", hence the following cast plus dereference. */
|
||||
assert(*(size_t *) ctx == magic);
|
||||
return strcmp(*(const char **) p1, *(const char **) p2);
|
||||
}
|
||||
|
||||
int main() {
|
||||
qsort_r(&arr[0], sizeof(arr) / sizeof(*arr), sizeof(char *), cmpstringp, (void *) &magic);
|
||||
|
||||
assert(!strcmp(arr[0], "abc"));
|
||||
assert(!strcmp(arr[1], "def"));
|
||||
assert(!strcmp(arr[2], "ghi"));
|
||||
assert(!strcmp(arr[3], "xyz"));
|
||||
|
||||
for(size_t i = 0; i < sizeof(arr) / sizeof(*arr); i++) {
|
||||
fprintf(stderr, "%s\n", arr[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <wctype.h>
|
||||
|
||||
int main() {
|
||||
char buffer[10];
|
||||
int ret = snprintf(buffer, 10, "%d", 123456789);
|
||||
assert(strncmp("123456789", buffer, 10) == 0);
|
||||
assert(ret == 9);
|
||||
|
||||
// We deliberately induce a warning here.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-truncation"
|
||||
ret = snprintf(buffer, 10, "%d", 1234567890);
|
||||
assert(strncmp("123456789", buffer, 10) == 0);
|
||||
assert(ret == 10);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// mlibc issue #118.
|
||||
ret = snprintf(NULL, 0, "%d", 123456789);
|
||||
assert(ret == 9);
|
||||
|
||||
char buf[128];
|
||||
assert(snprintf(buf, 2, "a") == 1);
|
||||
assert(strcmp(buf, "a") == 0);
|
||||
assert(snprintf(buf, 3, "abc") == 3);
|
||||
assert(strcmp(buf, "ab") == 0);
|
||||
assert(snprintf(buf, 128, "%%") == 1);
|
||||
assert(strcmp(buf, "%") == 0);
|
||||
assert(snprintf(buf, 128, "a%cc%c", 'b', 'd') == 4);
|
||||
assert(strcmp(buf, "abcd") == 0);
|
||||
assert(snprintf(buf, 128, "a%lcc%lc", (wint_t)L'b', (wint_t)L'd') == 4);
|
||||
assert(strcmp(buf, "abcd") == 0);
|
||||
assert(snprintf(buf, 128, "%s", "hello") == 5);
|
||||
assert(strcmp(buf, "hello") == 0);
|
||||
assert(snprintf(buf, 128, "%ls", L"hello") == 5);
|
||||
assert(strcmp(buf, "hello") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%d", 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%d", 0) == 1);
|
||||
assert(strcmp(buf, "0") == 0);
|
||||
assert(snprintf(buf, 128, "%d", -1234) == 5);
|
||||
assert(strcmp(buf, "-1234") == 0);
|
||||
assert(snprintf(buf, 128, "%hhd", 123) == 3);
|
||||
assert(strcmp(buf, "123") == 0);
|
||||
assert(snprintf(buf, 128, "%hd", 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%ld", 1234L) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%lld", 1234LL) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%jd", (intmax_t) 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%zd", (ssize_t) 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%td", (ptrdiff_t) 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%i", 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%i", 0) == 1);
|
||||
assert(strcmp(buf, "0") == 0);
|
||||
assert(snprintf(buf, 128, "%i", -1234) == 5);
|
||||
assert(strcmp(buf, "-1234") == 0);
|
||||
assert(snprintf(buf, 128, "%hhi", 123) == 3);
|
||||
assert(strcmp(buf, "123") == 0);
|
||||
assert(snprintf(buf, 128, "%hi", 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%li", 1234L) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%lli", 1234LL) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%ji", (intmax_t) 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%zi", (ssize_t) 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%ti", (ptrdiff_t) 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%b", 0b1011) == 4);
|
||||
assert(strcmp(buf, "1011") == 0);
|
||||
assert(snprintf(buf, 128, "%b", 0) == 1);
|
||||
assert(strcmp(buf, "0") == 0);
|
||||
assert(snprintf(buf, 128, "%hhb", 0b1011) == 4);
|
||||
assert(strcmp(buf, "1011") == 0);
|
||||
assert(snprintf(buf, 128, "%hb", 0b1011) == 4);
|
||||
assert(strcmp(buf, "1011") == 0);
|
||||
assert(snprintf(buf, 128, "%lb", 0b1011UL) == 4);
|
||||
assert(strcmp(buf, "1011") == 0);
|
||||
assert(snprintf(buf, 128, "%llb", 0b1011ULL) == 4);
|
||||
assert(strcmp(buf, "1011") == 0);
|
||||
assert(snprintf(buf, 128, "%jb", (uintmax_t) 0b1011) == 4);
|
||||
assert(strcmp(buf, "1011") == 0);
|
||||
assert(snprintf(buf, 128, "%zb", (size_t) 0b1011) == 4);
|
||||
assert(strcmp(buf, "1011") == 0);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
assert(snprintf(buf, 128, "%tb", 0b1011UL) == 4);
|
||||
assert(strcmp(buf, "1011") == 0);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
assert(snprintf(buf, 128, "%o", 01234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%o", 0) == 1);
|
||||
assert(strcmp(buf, "0") == 0);
|
||||
assert(snprintf(buf, 128, "%o", -01234) == 11);
|
||||
assert(strcmp(buf, "37777776544") == 0);
|
||||
assert(snprintf(buf, 128, "%hho", 012) == 2);
|
||||
assert(strcmp(buf, "12") == 0);
|
||||
assert(snprintf(buf, 128, "%ho", 01234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%lo", 01234UL) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%llo", 01234ULL) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%jo", (uintmax_t) 01234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%zo", (size_t) 01234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
assert(snprintf(buf, 128, "%to", 01234UL) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
assert(snprintf(buf, 128, "%x", 0x1234AB) == 6);
|
||||
assert(strcmp(buf, "1234ab") == 0);
|
||||
assert(snprintf(buf, 128, "%x", 0) == 1);
|
||||
assert(strcmp(buf, "0") == 0);
|
||||
assert(snprintf(buf, 128, "%x", -0x1234AB) == 8);
|
||||
assert(strcmp(buf, "ffedcb55") == 0);
|
||||
assert(snprintf(buf, 128, "%X", 0x1234AB) == 6);
|
||||
assert(strcmp(buf, "1234AB") == 0);
|
||||
assert(snprintf(buf, 128, "%hhx", 0xAB) == 2);
|
||||
assert(strcmp(buf, "ab") == 0);
|
||||
assert(snprintf(buf, 128, "%hx", 0x12AB) == 4);
|
||||
assert(strcmp(buf, "12ab") == 0);
|
||||
assert(snprintf(buf, 128, "%lx", 0x1234ABUL) == 6);
|
||||
assert(strcmp(buf, "1234ab") == 0);
|
||||
assert(snprintf(buf, 128, "%llx", 0x1234ABULL) == 6);
|
||||
assert(strcmp(buf, "1234ab") == 0);
|
||||
assert(snprintf(buf, 128, "%jx", (uintmax_t) 0x1234AB) == 6);
|
||||
assert(strcmp(buf, "1234ab") == 0);
|
||||
assert(snprintf(buf, 128, "%zx", (size_t) 0x1234AB) == 6);
|
||||
assert(strcmp(buf, "1234ab") == 0);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
assert(snprintf(buf, 128, "%tx", 0x1234ABUL) == 6);
|
||||
assert(strcmp(buf, "1234ab") == 0);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
assert(snprintf(buf, 128, "%u", 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%u", 0) == 1);
|
||||
assert(strcmp(buf, "0") == 0);
|
||||
assert(snprintf(buf, 128, "%u", -1234) == 10);
|
||||
assert(strcmp(buf, "4294966062") == 0);
|
||||
assert(snprintf(buf, 128, "%hhu", 123) == 3);
|
||||
assert(strcmp(buf, "123") == 0);
|
||||
assert(snprintf(buf, 128, "%hu", 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%lu", 1234UL) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%llu", 1234ULL) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%ju", (uintmax_t) 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
assert(snprintf(buf, 128, "%zu", (size_t) 1234) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
assert(snprintf(buf, 128, "%tu", 1234UL) == 4);
|
||||
assert(strcmp(buf, "1234") == 0);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
assert(snprintf(buf, 128, "%f", 1234.1234567) == 11);
|
||||
assert(strcmp(buf, "1234.123457") == 0);
|
||||
assert(snprintf(buf, 128, "%f", 0.0) == 8);
|
||||
assert(strcmp(buf, "0.000000") == 0);
|
||||
assert(snprintf(buf, 128, "%f", -1234.123456) == 12);
|
||||
assert(strcmp(buf, "-1234.123456") == 0);
|
||||
assert(snprintf(buf, 128, "%f", INFINITY) == 3);
|
||||
assert(strcmp(buf, "inf") == 0);
|
||||
assert(snprintf(buf, 128, "%04f", INFINITY) == 4);
|
||||
assert(strcmp(buf, " inf") == 0);
|
||||
assert(snprintf(buf, 128, "%-4f", INFINITY) == 4);
|
||||
assert(strcmp(buf, "inf ") == 0);
|
||||
assert(snprintf(buf, 128, "%f", NAN) == 3);
|
||||
assert(strcmp(buf, "nan") == 0);
|
||||
assert(snprintf(buf, 128, "%lf", 1234.123456) == 11);
|
||||
assert(strcmp(buf, "1234.123456") == 0);
|
||||
assert(snprintf(buf, 128, "%Lf", 1234.123456L) == 11);
|
||||
assert(strcmp(buf, "1234.123456") == 0);
|
||||
assert(snprintf(buf, 128, "%F", 1234.123456) == 11);
|
||||
assert(strcmp(buf, "1234.123456") == 0);
|
||||
assert(snprintf(buf, 128, "%F", INFINITY) == 3);
|
||||
assert(strcmp(buf, "INF") == 0);
|
||||
assert(snprintf(buf, 128, "%F", NAN) == 3);
|
||||
assert(strcmp(buf, "NAN") == 0);
|
||||
assert(snprintf(buf, 128, "%lF", 1234.123456) == 11);
|
||||
assert(strcmp(buf, "1234.123456") == 0);
|
||||
assert(snprintf(buf, 128, "%LF", 1234.123456L) == 11);
|
||||
assert(strcmp(buf, "1234.123456") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%e", 1.123456) == 12);
|
||||
assert(strcmp(buf, "1.123456e+00") == 0);
|
||||
assert(snprintf(buf, 128, "%e", 0.0) == 12);
|
||||
assert(strcmp(buf, "0.000000e+00") == 0);
|
||||
assert(snprintf(buf, 128, "%e", -1.123456) == 13);
|
||||
assert(strcmp(buf, "-1.123456e+00") == 0);
|
||||
assert(snprintf(buf, 128, "%e", 1.123456e12) == 12);
|
||||
assert(strcmp(buf, "1.123456e+12") == 0);
|
||||
assert(snprintf(buf, 128, "%e", -1.123456e12) == 13);
|
||||
assert(strcmp(buf, "-1.123456e+12") == 0);
|
||||
assert(snprintf(buf, 128, "%e", -1.123456e-12) == 13);
|
||||
assert(strcmp(buf, "-1.123456e-12") == 0);
|
||||
assert(snprintf(buf, 128, "%e", INFINITY) == 3);
|
||||
assert(strcmp(buf, "inf") == 0);
|
||||
assert(snprintf(buf, 128, "%e", NAN) == 3);
|
||||
assert(strcmp(buf, "nan") == 0);
|
||||
assert(snprintf(buf, 128, "%le", 1.123456e12) == 12);
|
||||
assert(strcmp(buf, "1.123456e+12") == 0);
|
||||
assert(snprintf(buf, 128, "%Le", 1.123456e12L) == 12);
|
||||
assert(strcmp(buf, "1.123456e+12") == 0);
|
||||
assert(snprintf(buf, 128, "%E", 1.123456e12) == 12);
|
||||
assert(strcmp(buf, "1.123456E+12") == 0);
|
||||
assert(snprintf(buf, 128, "%E", INFINITY) == 3);
|
||||
assert(strcmp(buf, "INF") == 0);
|
||||
assert(snprintf(buf, 128, "%E", NAN) == 3);
|
||||
assert(strcmp(buf, "NAN") == 0);
|
||||
assert(snprintf(buf, 128, "%lE", 1.123456e12) == 12);
|
||||
assert(strcmp(buf, "1.123456E+12") == 0);
|
||||
assert(snprintf(buf, 128, "%LE", 1.123456e12L) == 12);
|
||||
assert(strcmp(buf, "1.123456E+12") == 0);
|
||||
|
||||
/*assert(snprintf(buf, 128, "%a", 0x1.123456p0) == 13);
|
||||
assert(strcmp(buf, "0x1.123456p+0") == 0);
|
||||
assert(snprintf(buf, 128, "%a", 0.0) == 6);
|
||||
assert(strcmp(buf, "0x0p+0") == 0);
|
||||
assert(snprintf(buf, 128, "%a", 0x1.123456p12) == 14);
|
||||
assert(strcmp(buf, "0x1.123456p+12") == 0);
|
||||
assert(snprintf(buf, 128, "%a", -0x1.123456p-12) == 15);
|
||||
assert(strcmp(buf, "-0x1.123456p-12") == 0);
|
||||
assert(snprintf(buf, 128, "%a", INFINITY) == 3);
|
||||
assert(strcmp(buf, "inf") == 0);
|
||||
assert(snprintf(buf, 128, "%a", NAN) == 3);
|
||||
assert(strcmp(buf, "nan") == 0);
|
||||
assert(snprintf(buf, 128, "%la", 0x1.123456p12) == 14);
|
||||
assert(strcmp(buf, "0x1.123456p+12") == 0);
|
||||
assert(snprintf(buf, 128, "%La", 0x1.123456p12L) == 12);
|
||||
assert(strcmp(buf, "0x8.91a2bp+9") == 0);
|
||||
assert(snprintf(buf, 128, "%A", 0x1.123456p12) == 14);
|
||||
assert(strcmp(buf, "0X1.123456P+12") == 0);
|
||||
assert(snprintf(buf, 128, "%A", INFINITY) == 3);
|
||||
assert(strcmp(buf, "INF") == 0);
|
||||
assert(snprintf(buf, 128, "%A", NAN) == 3);
|
||||
assert(strcmp(buf, "NAN") == 0);
|
||||
assert(snprintf(buf, 128, "%lA", 0x1.123456p12) == 14);
|
||||
assert(strcmp(buf, "0X1.123456P+12") == 0);
|
||||
assert(snprintf(buf, 128, "%LA", 0x1.123456p12L) == 12);
|
||||
assert(strcmp(buf, "0X8.91A2BP+9") == 0);*/
|
||||
|
||||
assert(snprintf(buf, 128, "%g", 1.1234) == 6);
|
||||
assert(strcmp(buf, "1.1234") == 0);
|
||||
assert(snprintf(buf, 128, "%g", 0.0) == 1);
|
||||
assert(strcmp(buf, "0") == 0);
|
||||
assert(snprintf(buf, 128, "%g", -1.1234) == 7);
|
||||
assert(strcmp(buf, "-1.1234") == 0);
|
||||
assert(snprintf(buf, 128, "%g", 1.1234e12) == 10);
|
||||
assert(strcmp(buf, "1.1234e+12") == 0);
|
||||
assert(snprintf(buf, 128, "%g", -1.1234e-12) == 11);
|
||||
assert(strcmp(buf, "-1.1234e-12") == 0);
|
||||
assert(snprintf(buf, 128, "%g", INFINITY) == 3);
|
||||
assert(strcmp(buf, "inf") == 0);
|
||||
assert(snprintf(buf, 128, "%g", NAN) == 3);
|
||||
assert(strcmp(buf, "nan") == 0);
|
||||
assert(snprintf(buf, 128, "%lg", 1.1234e12) == 10);
|
||||
assert(strcmp(buf, "1.1234e+12") == 0);
|
||||
assert(snprintf(buf, 128, "%Lg", 1.1234e12L) == 10);
|
||||
assert(strcmp(buf, "1.1234e+12") == 0);
|
||||
assert(snprintf(buf, 128, "%G", 1.1234) == 6);
|
||||
assert(strcmp(buf, "1.1234") == 0);
|
||||
assert(snprintf(buf, 128, "%G", 1.1234e12) == 10);
|
||||
assert(strcmp(buf, "1.1234E+12") == 0);
|
||||
assert(snprintf(buf, 128, "%G", INFINITY) == 3);
|
||||
assert(strcmp(buf, "INF") == 0);
|
||||
assert(snprintf(buf, 128, "%G", NAN) == 3);
|
||||
assert(strcmp(buf, "NAN") == 0);
|
||||
assert(snprintf(buf, 128, "%lG", 1.1234e12) == 10);
|
||||
assert(strcmp(buf, "1.1234E+12") == 0);
|
||||
assert(snprintf(buf, 128, "%LG", 1.1234e12L) == 10);
|
||||
assert(strcmp(buf, "1.1234E+12") == 0);
|
||||
|
||||
signed char char_value = 0;
|
||||
assert(snprintf(buf, 128, "ab%hhnc", &char_value) == 3);
|
||||
assert(strcmp(buf, "abc") == 0);
|
||||
assert(char_value == 2);
|
||||
short short_value = 0;
|
||||
assert(snprintf(buf, 128, "ab%hnc", &short_value) == 3);
|
||||
assert(strcmp(buf, "abc") == 0);
|
||||
assert(short_value == 2);
|
||||
int int_value = 0;
|
||||
assert(snprintf(buf, 128, "ab%nc", &int_value) == 3);
|
||||
assert(strcmp(buf, "abc") == 0);
|
||||
assert(int_value == 2);
|
||||
long long_value = 0;
|
||||
assert(snprintf(buf, 128, "ab%lnc", &long_value) == 3);
|
||||
assert(strcmp(buf, "abc") == 0);
|
||||
assert(long_value == 2);
|
||||
long long long_long_value = 0;
|
||||
assert(snprintf(buf, 128, "ab%llnc", &long_long_value) == 3);
|
||||
assert(strcmp(buf, "abc") == 0);
|
||||
assert(long_long_value == 2);
|
||||
intmax_t intmax_value = 0;
|
||||
assert(snprintf(buf, 128, "ab%jnc", &intmax_value) == 3);
|
||||
assert(strcmp(buf, "abc") == 0);
|
||||
assert(intmax_value == 2);
|
||||
ssize_t size_value = 0;
|
||||
assert(snprintf(buf, 128, "ab%znc", &size_value) == 3);
|
||||
assert(strcmp(buf, "abc") == 0);
|
||||
assert(size_value == 2);
|
||||
ptrdiff_t ptrdiff_value = 0;
|
||||
assert(snprintf(buf, 128, "ab%tnc", &ptrdiff_value) == 3);
|
||||
assert(strcmp(buf, "abc") == 0);
|
||||
assert(ptrdiff_value == 2);
|
||||
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
uintptr_t ptr_value = 0xFFFFFFFFFFFFFFFF;
|
||||
assert(snprintf(buf, 128, "%p", (void *)ptr_value) == 18);
|
||||
assert(strcmp(buf, "0xffffffffffffffff") == 0);
|
||||
#else
|
||||
uintptr_t ptr_value = 0xFFFFFFFF;
|
||||
assert(snprintf(buf, 128, "%p", (void*)ptr_value) == 10);
|
||||
assert(strcmp(buf, "0xffffffff") == 0);
|
||||
#endif
|
||||
|
||||
ptr_value = 0xFFFF;
|
||||
assert(snprintf(buf, 128, "%p", (void*)ptr_value) == 6);
|
||||
assert(strcmp(buf, "0xffff") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%-4dhello", 12) == 9);
|
||||
assert(strcmp(buf, "12 hello") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%-4dhello", -12) == 9);
|
||||
assert(strcmp(buf, "-12 hello") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%#-4xhello", 0x12) == 9);
|
||||
assert(strcmp(buf, "0x12hello") == 0);
|
||||
assert(snprintf(buf, 128, "%#-4Xhello", 0x12) == 9);
|
||||
assert(strcmp(buf, "0X12hello") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%#b", 0b1011) == 6);
|
||||
assert(strcmp(buf, "0b1011") == 0);
|
||||
assert(snprintf(buf, 128, "%#B", 0b1011) == 6);
|
||||
assert(strcmp(buf, "0B1011") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%+d", 1234) == 5);
|
||||
assert(strcmp(buf, "+1234") == 0);
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
assert(snprintf(buf, 128, "%+ d", 1234) == 5);
|
||||
assert(strcmp(buf, "+1234") == 0);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
assert(snprintf(buf, 128, "% d", 1234) == 5);
|
||||
assert(strcmp(buf, " 1234") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%4dhello", 12) == 9);
|
||||
assert(strcmp(buf, " 12hello") == 0);
|
||||
assert(snprintf(buf, 128, "%2dhello", 1234) == 9);
|
||||
assert(strcmp(buf, "1234hello") == 0);
|
||||
int width = 4;
|
||||
assert(snprintf(buf, 128, "%*dhello", width, 12) == 9);
|
||||
assert(strcmp(buf, " 12hello") == 0);
|
||||
width = -4;
|
||||
assert(snprintf(buf, 128, "%*dhello", width, 12) == 9);
|
||||
assert(strcmp(buf, "12 hello") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%04dhello", 12) == 9);
|
||||
assert(strcmp(buf, "0012hello") == 0);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
assert(snprintf(buf, 128, "%-04dhello", 12) == 9);
|
||||
assert(strcmp(buf, "12 hello") == 0);
|
||||
assert(snprintf(buf, 128, "%04.2dhello", 1) == 9);
|
||||
assert(strcmp(buf, " 01hello") == 0);
|
||||
#pragma GCC diagnostic pop
|
||||
assert(snprintf(buf, 128, "%.d", 0) == 0);
|
||||
assert(strcmp(buf, "") == 0);
|
||||
assert(snprintf(buf, 128, "%.0d", 0) == 0);
|
||||
assert(strcmp(buf, "") == 0);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
assert(snprintf(buf, 128, "%04.d", 0) == 4);
|
||||
assert(strcmp(buf, " ") == 0);
|
||||
assert(snprintf(buf, 128, "%#04.x", 0) == 4);
|
||||
assert(strcmp(buf, " ") == 0);
|
||||
assert(snprintf(buf, 128, "%+04.d", 0) == 4);
|
||||
assert(strcmp(buf, " +") == 0);
|
||||
assert(snprintf(buf, 128, "%+0.d", 0) == 1);
|
||||
assert(strcmp(buf, "+") == 0);
|
||||
#pragma GCC diagnostic pop
|
||||
int precision = 0;
|
||||
assert(snprintf(buf, 128, "%.*d", precision, 0) == 0);
|
||||
assert(strcmp(buf, "") == 0);
|
||||
precision = -1;
|
||||
assert(snprintf(buf, 128, "%.*d", precision, 0) == 1);
|
||||
assert(strcmp(buf, "0") == 0);
|
||||
assert(snprintf(buf, 128, "%.6d", 1234) == 6);
|
||||
assert(strcmp(buf, "001234") == 0);
|
||||
|
||||
assert(snprintf(buf, 128, "%.o", 0) == 0);
|
||||
assert(strcmp(buf, "") == 0);
|
||||
assert(snprintf(buf, 128, "%.0o", 0) == 0);
|
||||
assert(strcmp(buf, "") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
#include <fenv.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
int main() {
|
||||
char buf[64] = { 0 };
|
||||
sprintf(buf, "%d", 12);
|
||||
assert(!strcmp(buf, "12"));
|
||||
|
||||
sprintf(buf, "%f", 3.14);
|
||||
assert(!strcmp(buf, "3.140000"));
|
||||
sprintf(buf, "%.1f", 0.0);
|
||||
assert(!strcmp(buf, "0.0"));
|
||||
|
||||
// Test %g
|
||||
sprintf(buf, "%g", 0.0);
|
||||
assert(!strcmp(buf, "0"));
|
||||
sprintf(buf, "%.2g", 0.01234);
|
||||
assert(!strcmp(buf, "0.012"));
|
||||
sprintf(buf, "%.3g", 1.1);
|
||||
assert(!strcmp(buf, "1.1"));
|
||||
sprintf(buf, "%#.5g", 1.1);
|
||||
assert(!strcmp(buf, "1.1000"));
|
||||
sprintf(buf, "%g", 0.0000123);
|
||||
assert(!strcmp(buf, "1.23e-05"));
|
||||
|
||||
// Test %e
|
||||
sprintf(buf, "%4.3e", 0.0);
|
||||
assert(!strcmp(buf, "0.000e+00"));
|
||||
sprintf(buf, "%.3e", 6.9e27);
|
||||
assert(!strcmp(buf, "6.900e+27"));
|
||||
|
||||
// Test %c right padding.
|
||||
sprintf(buf, "%-2c", 'a');
|
||||
assert(!strcmp(buf, "a "));
|
||||
|
||||
// Test %c left padding.
|
||||
sprintf(buf, "%2c", 'a');
|
||||
assert(!strcmp(buf, " a"));
|
||||
|
||||
// Test %d right padding - mlibc issue #58.
|
||||
sprintf(buf, "%-2d", 1);
|
||||
assert(!strcmp(buf, "1 "));
|
||||
sprintf(buf, "%-2.2d", 1);
|
||||
assert(!strcmp(buf, "01"));
|
||||
sprintf(buf, "%-3.2d", 1);
|
||||
assert(!strcmp(buf, "01 "));
|
||||
sprintf(buf, "%-3.2d", 12);
|
||||
assert(!strcmp(buf, "12 "));
|
||||
sprintf(buf, "%-3.2d", 123);
|
||||
assert(!strcmp(buf, "123"));
|
||||
sprintf(buf, "%-3.2u", 12);
|
||||
assert(!strcmp(buf, "12 "));
|
||||
|
||||
// Test %d left padding.
|
||||
sprintf(buf, "%2d", 1);
|
||||
assert(!strcmp(buf, " 1"));
|
||||
sprintf(buf, "%3.2d", 1);
|
||||
assert(!strcmp(buf, " 01"));
|
||||
sprintf(buf, "%3.2d", 12);
|
||||
assert(!strcmp(buf, " 12"));
|
||||
sprintf(buf, "%3.2d", 123);
|
||||
assert(!strcmp(buf, "123"));
|
||||
sprintf(buf, "%3.2u", 12);
|
||||
assert(!strcmp(buf, " 12"));
|
||||
// Disable -Wformat here since we deliberately induce some warnings.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
sprintf(buf, "%04.3u", 12);
|
||||
assert(!strcmp(buf, " 012"));
|
||||
#pragma GCC diagnostic pop
|
||||
sprintf(buf, "%+04d", 0);
|
||||
assert(!strcmp(buf, "+000"));
|
||||
|
||||
// Test %f padding.
|
||||
// TODO: Test printing of huge numbers (larger than 2^64)
|
||||
sprintf(buf, "%2.f", 1.2);
|
||||
assert(!strcmp(buf, " 1"));
|
||||
sprintf(buf, "%2.f", 12.3);
|
||||
assert(!strcmp(buf, "12"));
|
||||
sprintf(buf, "%5.2f", 1.0);
|
||||
assert(!strcmp(buf, " 1.00"));
|
||||
sprintf(buf, "%.1f", -4.0);
|
||||
assert(!strcmp(buf, "-4.0"));
|
||||
sprintf(buf, "%-3.f", 8.0);
|
||||
assert(!strcmp(buf, "8 "));
|
||||
sprintf(buf, "%4f", INFINITY);
|
||||
assert(!strcmp(buf, " inf") || !strcmp(buf, "infinity"));
|
||||
sprintf(buf, "%4f", NAN);
|
||||
assert(!strcmp(buf, " nan"));
|
||||
sprintf(buf, "%4F", INFINITY);
|
||||
assert(!strcmp(buf, " INF") || !strcmp(buf, "INFINITY"));
|
||||
sprintf(buf, "%4F", NAN);
|
||||
assert(!strcmp(buf, " NAN"));
|
||||
sprintf(buf, "%05.2f", 1.0);
|
||||
assert(!strcmp(buf, "01.00"));
|
||||
sprintf(buf, "%09f", INFINITY); // 0 ignored when padding infs
|
||||
assert(!strcmp(buf, " inf") || !strcmp(buf, " infinity"));
|
||||
|
||||
// Test %f rounding
|
||||
sprintf(buf, "%5.2f", 1.2);
|
||||
assert(!strcmp(buf, " 1.20"));
|
||||
sprintf(buf, "%5.2f", 1.23);
|
||||
assert(!strcmp(buf, " 1.23"));
|
||||
sprintf(buf, "%5.2f", 1.234);
|
||||
assert(!strcmp(buf, " 1.23"));
|
||||
sprintf(buf, "%5.2f", 12.345);
|
||||
assert(!strcmp(buf, "12.35"));
|
||||
sprintf(buf, "%-5.2f", 1.2);
|
||||
assert(!strcmp(buf, "1.20 "));
|
||||
|
||||
// Test '+' and ' ' flags - mlibc issue #229.
|
||||
// Disable -Wformat here since we deliberately induce some warnings.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
sprintf(buf, "%+d", 12);
|
||||
assert(!strcmp(buf, "+12"));
|
||||
sprintf(buf, "% d", 12);
|
||||
assert(!strcmp(buf, " 12"));
|
||||
sprintf(buf, "% +d", 12);
|
||||
assert(!strcmp(buf, "+12"));
|
||||
sprintf(buf, "%+ d", 12);
|
||||
assert(!strcmp(buf, "+12"));
|
||||
sprintf(buf, "%+d", -12);
|
||||
assert(!strcmp(buf, "-12"));
|
||||
sprintf(buf, "% d", -12);
|
||||
assert(!strcmp(buf, "-12"));
|
||||
sprintf(buf, "% +d", -12);
|
||||
assert(!strcmp(buf, "-12"));
|
||||
sprintf(buf, "%+ d", -12);
|
||||
assert(!strcmp(buf, "-12"));
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// Test '#' flag.
|
||||
// TODO: Test with a, A, e, E, f, F, g, G conversions.
|
||||
sprintf(buf, "%#x", 12);
|
||||
assert(!strcmp(buf, "0xc"));
|
||||
sprintf(buf, "%#X", 12);
|
||||
assert(!strcmp(buf, "0XC"));
|
||||
sprintf(buf, "%#o", 12);
|
||||
assert(!strcmp(buf, "014"));
|
||||
|
||||
sprintf(buf, "%#x", 0);
|
||||
assert(!strcmp(buf, "0"));
|
||||
sprintf(buf, "%#X", 0);
|
||||
assert(!strcmp(buf, "0"));
|
||||
sprintf(buf, "%#o", 0);
|
||||
assert(!strcmp(buf, "0"));
|
||||
|
||||
// Disable -Wformat here because the compiler might not know about the b specifier.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
sprintf(buf, "%#b", 12);
|
||||
assert(!strcmp(buf, "0b1100"));
|
||||
sprintf(buf, "%#B", 12);
|
||||
assert(!strcmp(buf, "0B1100"));
|
||||
sprintf(buf, "%#b", 0);
|
||||
assert(!strcmp(buf, "0"));
|
||||
sprintf(buf, "%#B", 0);
|
||||
assert(!strcmp(buf, "0"));
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// Test 'd' with different size mods to see
|
||||
// if they work
|
||||
sprintf(buf, "%d", 12);
|
||||
assert(!strcmp(buf, "12"));
|
||||
sprintf(buf, "%ld", 12L);
|
||||
assert(!strcmp(buf, "12"));
|
||||
sprintf(buf, "%lld", 12LL);
|
||||
assert(!strcmp(buf, "12"));
|
||||
sprintf(buf, "%zd", (size_t)12);
|
||||
assert(!strcmp(buf, "12"));
|
||||
sprintf(buf, "%hd", (short) 12);
|
||||
assert(!strcmp(buf, "12"));
|
||||
sprintf(buf, "%hhd", (char) 12);
|
||||
assert(!strcmp(buf, "12"));
|
||||
|
||||
// Test 'x' with different size mods to see
|
||||
// if they work
|
||||
sprintf(buf, "%x", 12);
|
||||
assert(!strcmp(buf, "c"));
|
||||
sprintf(buf, "%lx", 12L);
|
||||
assert(!strcmp(buf, "c"));
|
||||
sprintf(buf, "%llx", 12LL);
|
||||
assert(!strcmp(buf, "c"));
|
||||
sprintf(buf, "%zx", (size_t)12);
|
||||
assert(!strcmp(buf, "c"));
|
||||
sprintf(buf, "%hx", (unsigned short) 12);
|
||||
assert(!strcmp(buf, "c"));
|
||||
sprintf(buf, "%hhx", (unsigned char) 12);
|
||||
assert(!strcmp(buf, "c"));
|
||||
|
||||
// Test 'X' with different size mods to see
|
||||
// if they work
|
||||
sprintf(buf, "%X", 12);
|
||||
assert(!strcmp(buf, "C"));
|
||||
sprintf(buf, "%lX", 12L);
|
||||
assert(!strcmp(buf, "C"));
|
||||
sprintf(buf, "%llX", 12LL);
|
||||
assert(!strcmp(buf, "C"));
|
||||
sprintf(buf, "%zX", (size_t)12);
|
||||
assert(!strcmp(buf, "C"));
|
||||
sprintf(buf, "%hX", (unsigned short) 12);
|
||||
assert(!strcmp(buf, "C"));
|
||||
sprintf(buf, "%hhX", (unsigned char) 12);
|
||||
assert(!strcmp(buf, "C"));
|
||||
|
||||
// Test 'o' with different size mods to see
|
||||
// if they work
|
||||
sprintf(buf, "%o", 12);
|
||||
assert(!strcmp(buf, "14"));
|
||||
sprintf(buf, "%lo", 12L);
|
||||
assert(!strcmp(buf, "14"));
|
||||
sprintf(buf, "%llo", 12LL);
|
||||
assert(!strcmp(buf, "14"));
|
||||
sprintf(buf, "%zo", (size_t)12);
|
||||
assert(!strcmp(buf, "14"));
|
||||
sprintf(buf, "%ho", (unsigned short) 12);
|
||||
assert(!strcmp(buf, "14"));
|
||||
sprintf(buf, "%hho", (unsigned char) 12);
|
||||
assert(!strcmp(buf, "14"));
|
||||
|
||||
// Disable -Wformat here because the compiler might not know about the b specifier.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
// Test 'b' with different size mods to see
|
||||
// if they work
|
||||
sprintf(buf, "%b", 12);
|
||||
assert(!strcmp(buf, "1100"));
|
||||
sprintf(buf, "%lb", 12L);
|
||||
assert(!strcmp(buf, "1100"));
|
||||
sprintf(buf, "%llb", 12LL);
|
||||
assert(!strcmp(buf, "1100"));
|
||||
sprintf(buf, "%zb", (size_t)12);
|
||||
assert(!strcmp(buf, "1100"));
|
||||
sprintf(buf, "%hb", (unsigned short) 12);
|
||||
assert(!strcmp(buf, "1100"));
|
||||
sprintf(buf, "%hhb", (unsigned char) 12);
|
||||
assert(!strcmp(buf, "1100"));
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// Test %n$ syntax.
|
||||
sprintf(buf, "%1$d", 12);
|
||||
assert(!strcmp(buf, "12"));
|
||||
sprintf(buf, "%1$d %1$d", 12);
|
||||
assert(!strcmp(buf, "12 12"));
|
||||
sprintf(buf, "%1$d %2$d %1$d", 12, 14);
|
||||
assert(!strcmp(buf, "12 14 12"));
|
||||
sprintf(buf, "%1$d %2$s %2$s", 12, "foo");
|
||||
assert(!strcmp(buf, "12 foo foo"));
|
||||
|
||||
sprintf(buf, "%1$s%5$s%6$s%3$s%4$s%2$s", "a", "b", "u", "n", "h", "N");
|
||||
assert(!strcmp(buf, "ahNunb"));
|
||||
|
||||
// test negative precision
|
||||
sprintf(buf, "%.*g", -2, 15.1234567);
|
||||
assert(!strcmp(buf, "15.1235"));
|
||||
sprintf(buf, "%*g", -5, 15.1);
|
||||
assert(!strcmp(buf, "15.1 "));
|
||||
// Disable -Wformat as the compiler rightfully warns that the '0' flag is ignored
|
||||
// when the '0' flag is used
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
sprintf(buf, "%0-6g", 69.2);
|
||||
assert(!strcmp(buf, "69.2 "));
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// More extensive floating point tests.
|
||||
// Test zero and negative zero
|
||||
sprintf(buf, "%f", 0.0);
|
||||
assert(!strcmp(buf, "0.000000"));
|
||||
sprintf(buf, "%f", -0.0);
|
||||
assert(!strcmp(buf, "-0.000000"));
|
||||
sprintf(buf, "%e", 0.0);
|
||||
assert(!strcmp(buf, "0.000000e+00"));
|
||||
sprintf(buf, "%e", -0.0);
|
||||
assert(!strcmp(buf, "-0.000000e+00"));
|
||||
sprintf(buf, "%g", 0.0);
|
||||
assert(!strcmp(buf, "0"));
|
||||
sprintf(buf, "%g", -0.0);
|
||||
assert(!strcmp(buf, "-0"));
|
||||
|
||||
// Test rounding
|
||||
sprintf(buf, "%.2f", 1.235);
|
||||
assert(!strcmp(buf, "1.24"));
|
||||
sprintf(buf, "%.2f", -1.235);
|
||||
assert(!strcmp(buf, "-1.24"));
|
||||
// 1.2349999999999998 is a double literal that is slightly less than 1.235
|
||||
sprintf(buf, "%.2f", 1.2349999999999998);
|
||||
assert(!strcmp(buf, "1.23"));
|
||||
sprintf(buf, "%.0f", 0.49);
|
||||
assert(!strcmp(buf, "0"));
|
||||
sprintf(buf, "%.0f", -0.49);
|
||||
assert(!strcmp(buf, "-0"));
|
||||
|
||||
// Test round-to-even behavior
|
||||
fesetround(FE_TONEAREST);
|
||||
|
||||
sprintf(buf, "%.0f", 0.5);
|
||||
assert(!strcmp(buf, "0"));
|
||||
sprintf(buf, "%.0f", -0.5);
|
||||
assert(!strcmp(buf, "-0"));
|
||||
sprintf(buf, "%.0f", 0.51);
|
||||
assert(!strcmp(buf, "1"));
|
||||
sprintf(buf, "%.0f", -0.51);
|
||||
assert(!strcmp(buf, "-1"));
|
||||
sprintf(buf, "%.0f", 2.5);
|
||||
assert(!strcmp(buf, "2"));
|
||||
sprintf(buf, "%.0f", -2.5);
|
||||
assert(!strcmp(buf, "-2"));
|
||||
sprintf(buf, "%.0f", 2.51);
|
||||
assert(!strcmp(buf, "3"));
|
||||
sprintf(buf, "%.0f", -2.51);
|
||||
assert(!strcmp(buf, "-3"));
|
||||
|
||||
// Test %e/%E
|
||||
sprintf(buf, "%.3e", 12345.0);
|
||||
assert(!strcmp(buf, "1.234e+04"));
|
||||
sprintf(buf, "%.3E", 12345.0);
|
||||
assert(!strcmp(buf, "1.234E+04"));
|
||||
sprintf(buf, "%.3e", 0.00012345);
|
||||
assert(!strcmp(buf, "1.234e-04"));
|
||||
sprintf(buf, "%.3E", -0.00012345);
|
||||
assert(!strcmp(buf, "-1.234E-04"));
|
||||
|
||||
// Test %g/%G behavior
|
||||
sprintf(buf, "%g", 123456.0); // Should not use e-notation
|
||||
assert(!strcmp(buf, "123456"));
|
||||
sprintf(buf, "%g", 1234567.0); // Should use e-notation
|
||||
assert(!strcmp(buf, "1.23457e+06"));
|
||||
sprintf(buf, "%g", 12345.0);
|
||||
assert(!strcmp(buf, "12345"));
|
||||
sprintf(buf, "%g", 1.2345);
|
||||
assert(!strcmp(buf, "1.2345"));
|
||||
sprintf(buf, "%g", 0.00012345); // Should not use e-notation
|
||||
assert(!strcmp(buf, "0.00012345"));
|
||||
sprintf(buf, "%g", 0.000012345); // Should use e-notation
|
||||
assert(!strcmp(buf, "1.2345e-05"));
|
||||
|
||||
// %g precision
|
||||
sprintf(buf, "%.3g", 12345.0);
|
||||
assert(!strcmp(buf, "1.23e+04"));
|
||||
sprintf(buf, "%.3G", 12345.0);
|
||||
assert(!strcmp(buf, "1.23E+04"));
|
||||
sprintf(buf, "%.3g", 1.234);
|
||||
assert(!strcmp(buf, "1.23"));
|
||||
sprintf(buf, "%.3g", 0.001234);
|
||||
assert(!strcmp(buf, "0.00123"));
|
||||
sprintf(buf, "%.3g", 0.0001234); // Should not use e-notation
|
||||
assert(!strcmp(buf, "0.000123"));
|
||||
sprintf(buf, "%.3g", 0.00001234); // Should use e-notation
|
||||
assert(!strcmp(buf, "1.23e-05"));
|
||||
sprintf(buf, "%08.1g", 69.2);
|
||||
assert(!strcmp(buf, "0007e+01"));
|
||||
sprintf(buf, "%#08.4g", 69.29854);
|
||||
assert(!strcmp(buf, "00069.30"));
|
||||
|
||||
// %g trailing zeros
|
||||
sprintf(buf, "%g", 1.200);
|
||||
assert(!strcmp(buf, "1.2"));
|
||||
sprintf(buf, "%#g", 1.200);
|
||||
assert(!strcmp(buf, "1.20000"));
|
||||
sprintf(buf, "%g", 1200.0);
|
||||
assert(!strcmp(buf, "1200"));
|
||||
sprintf(buf, "%#g", 1200.0);
|
||||
assert(!strcmp(buf, "1200.00"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <wchar.h>
|
||||
|
||||
struct format_test_cases {
|
||||
const char *format;
|
||||
const char *data;
|
||||
int expected_int;
|
||||
enum {
|
||||
T_INT,
|
||||
T_UINT,
|
||||
T_CHAR,
|
||||
T_NONE,
|
||||
} type;
|
||||
int ret;
|
||||
} formats[] = {
|
||||
{"%i", "0x420", 0x420, T_INT, 1},
|
||||
{"%i", "0420", 0420, T_INT, 1},
|
||||
{"%i", "420", 420, T_INT, 1},
|
||||
{"%i", "-420", -420, T_INT, 1},
|
||||
{"%d", "-12345", -12345, T_INT, 1},
|
||||
{"%u", "69", 69, T_UINT, 1},
|
||||
{"%u", "0420", 420, T_UINT, 1},
|
||||
{"%o", "0420", 0420, T_UINT, 1},
|
||||
{"%x", "0xCB7", 0xCB7, T_UINT, 1},
|
||||
#ifndef USE_HOST_LIBC
|
||||
{"%b", "0b1011", 0b1011, T_UINT, 1},
|
||||
{"%b", "0B1011", 0b1011, T_UINT, 1},
|
||||
#endif
|
||||
{"%%", "%", 0, T_NONE, 0},
|
||||
{"%c", " I am not a fan of this solution.", ' ', T_CHAR, 1},
|
||||
{" %c", " CBT (capybara therapy)", 'C', T_CHAR, 1},
|
||||
{"%d %d %d", " 111111 I<3Managarm 1234", 111111, T_UINT, 1},
|
||||
{"%c %d", "C", 'C', T_CHAR, 1}
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||
|
||||
static void test_matrix() {
|
||||
for(size_t i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) {
|
||||
struct format_test_cases *f = &formats[i];
|
||||
int ret = -1;
|
||||
int data_int;
|
||||
unsigned int data_uint;
|
||||
char data_char;
|
||||
|
||||
switch(f->type) {
|
||||
case T_INT: {
|
||||
ret = sscanf(f->data, f->format, &data_int);
|
||||
assert(data_int == f->expected_int);
|
||||
break;
|
||||
}
|
||||
case T_UINT: {
|
||||
ret = sscanf(f->data, f->format, &data_uint);
|
||||
assert(data_uint == (unsigned int) f->expected_int);
|
||||
break;
|
||||
}
|
||||
case T_CHAR: {
|
||||
ret = sscanf(f->data, f->format, &data_char);
|
||||
assert(data_char == (unsigned char) f->expected_int);
|
||||
break;
|
||||
}
|
||||
case T_NONE: {
|
||||
ret = sscanf(f->data, f->format);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
assert(ret == f->ret);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
{
|
||||
int x = 0;
|
||||
char buf[] = "12345";
|
||||
sscanf(buf, "%d", &x);
|
||||
assert(x == 12345);
|
||||
}
|
||||
|
||||
{
|
||||
char c;
|
||||
int n1;
|
||||
int n2;
|
||||
char buf[] = "z$ 7 5 440";;
|
||||
int count = sscanf(buf, "%*c%c %d %*d %d", &c, &n1, &n2);
|
||||
assert(count == 3);
|
||||
assert(c == '$');
|
||||
assert(n1 == 7);
|
||||
assert(n2 == 440);
|
||||
}
|
||||
|
||||
{
|
||||
// From dsda-doom
|
||||
char buf[] = "process_priority 0\n";
|
||||
char def[80], strparm[128];
|
||||
memset(def, '!', 80);
|
||||
memset(strparm, '!', 128);
|
||||
sscanf(buf, "%s %[^\n]\n", def, strparm);
|
||||
assert(!strcmp(def, "process_priority"));
|
||||
assert(!strcmp(strparm, "0"));
|
||||
}
|
||||
|
||||
{
|
||||
char buf[] = "fffff100";
|
||||
unsigned long y = 0;
|
||||
sscanf(buf, "%lx", &y);
|
||||
assert(y == 0xfffff100);
|
||||
}
|
||||
|
||||
#if !defined(__i386__) && !defined(__m68k__)
|
||||
{
|
||||
char buf[] = "fffffffff100";
|
||||
unsigned long y = 0;
|
||||
sscanf(buf, "%lx", &y);
|
||||
assert(y == 0xfffffffff100);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
char buf[] = "410dc000";
|
||||
unsigned long y = 0;
|
||||
sscanf(buf, "%lx", &y);
|
||||
assert(y == 0x410dc000);
|
||||
}
|
||||
|
||||
{
|
||||
// From webkitgtk
|
||||
char buf[] = "MemTotal: 16299664 kB\n";
|
||||
char token[51] = {0};
|
||||
size_t amount = 0;
|
||||
int ret = sscanf(buf, "%50s%zukB", token, &amount);
|
||||
assert(ret == 2);
|
||||
assert(!strcmp(token, "MemTotal:"));
|
||||
assert(amount == 16299664);
|
||||
}
|
||||
|
||||
{
|
||||
char buf[] = "SIGINT";
|
||||
int sig;
|
||||
int ret = sscanf(buf, "%d", &sig);
|
||||
assert(!ret);
|
||||
}
|
||||
|
||||
{
|
||||
char buf[50];
|
||||
int ret = sscanf("", "%s", buf);
|
||||
assert(ret == EOF);
|
||||
}
|
||||
|
||||
{
|
||||
char *str = NULL;
|
||||
int ret = sscanf("Managarm", "%ms", &str);
|
||||
assert(ret == 1);
|
||||
assert(str != NULL);
|
||||
assert(!strcmp(str, "Managarm"));
|
||||
free(str);
|
||||
}
|
||||
|
||||
test_matrix();
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-zero-length"
|
||||
assert(sscanf("", "") == 0);
|
||||
#pragma GCC diagnostic pop
|
||||
assert(sscanf("", "a") == EOF);
|
||||
assert(sscanf(" \t\na", " a") == 0);
|
||||
assert(sscanf("a%", "a%%") == 0);
|
||||
assert(sscanf("ab", "abcd") == EOF);
|
||||
assert(sscanf("abab", "abcd") == 0);
|
||||
|
||||
char char_value[8];
|
||||
wchar_t wchar_value[8];
|
||||
|
||||
assert(sscanf("a", "%c", char_value) == 1);
|
||||
assert(char_value[0] == 'a');
|
||||
assert(sscanf("a", "%lc", wchar_value) == 1);
|
||||
assert(wchar_value[0] == L'a');
|
||||
assert(sscanf("hello", "%s", char_value) == 1);
|
||||
assert(strcmp(char_value, "hello") == 0);
|
||||
assert(sscanf("", "%s", char_value) == EOF);
|
||||
assert(sscanf(" ", "%s", char_value) == EOF);
|
||||
assert(sscanf(" a", "%sb", char_value) == 1);
|
||||
assert(sscanf("hello", "%ls", wchar_value) == 1);
|
||||
assert(wcscmp(wchar_value, L"hello") == 0);
|
||||
assert(sscanf("abcd", "%[ac]bcd", char_value) == 1);
|
||||
assert(strcmp(char_value, "a") == 0);
|
||||
assert(sscanf("abcd", "%l[ac]bcd", wchar_value) == 1);
|
||||
assert(wcscmp(wchar_value, L"a") == 0);
|
||||
assert(sscanf("aacd", "%[ac]bcd", char_value) == 1);
|
||||
assert(strcmp(char_value, "aac") == 0);
|
||||
assert(sscanf("aacd", "%[ac]bcd", char_value) == 1);
|
||||
assert(strcmp(char_value, "aac") == 0);
|
||||
assert(sscanf("]", "%[]]", char_value) == 1);
|
||||
assert(strcmp(char_value, "]") == 0);
|
||||
assert(sscanf("]", "%[^]]", char_value) == 0);
|
||||
assert(sscanf("abcd", "%[^ac]bcd", char_value) == 0);
|
||||
assert(sscanf("aacd", "%[^ac]bcd", char_value) == 0);
|
||||
assert(sscanf("aacd", "%[^ac]bcd", char_value) == 0);
|
||||
assert(sscanf("ddd", "%[^ac]bcd", char_value) == 1);
|
||||
assert(strcmp(char_value, "ddd") == 0);
|
||||
assert(sscanf("abcd", "%[0-9]", char_value) == 0);
|
||||
assert(sscanf("2a", "%[0-9]", char_value) == 1);
|
||||
assert(strcmp(char_value, "2") == 0);
|
||||
|
||||
unsigned char uchar_value;
|
||||
signed char schar_value;
|
||||
unsigned short ushort_value;
|
||||
short short_value;
|
||||
unsigned int uint_value;
|
||||
int int_value;
|
||||
unsigned long ulong_value;
|
||||
long long_value;
|
||||
unsigned long long ulonglong_value;
|
||||
long long longlong_value;
|
||||
uintmax_t uintmax_value;
|
||||
intmax_t intmax_value;
|
||||
size_t size_value;
|
||||
ptrdiff_t ptrdiff_value;
|
||||
|
||||
assert(sscanf("1234abc", "%d", &int_value) == 1);
|
||||
assert(int_value == 1234);
|
||||
assert(sscanf("123", "%hhd", &schar_value) == 1);
|
||||
assert(schar_value == 123);
|
||||
assert(sscanf("1234", "%hd", &short_value) == 1);
|
||||
assert(short_value == 1234);
|
||||
assert(sscanf("1234", "%ld", &long_value) == 1);
|
||||
assert(long_value == 1234);
|
||||
assert(sscanf("1234", "%lld", &longlong_value) == 1);
|
||||
assert(longlong_value == 1234);
|
||||
assert(sscanf("1234", "%jd", &intmax_value) == 1);
|
||||
assert(intmax_value == 1234);
|
||||
assert(sscanf("1234", "%zd", &size_value) == 1);
|
||||
assert(size_value == 1234);
|
||||
assert(sscanf("1234", "%td", &ptrdiff_value) == 1);
|
||||
assert(ptrdiff_value == 1234);
|
||||
assert(sscanf(" 1235abc", "%d", &int_value) == 1);
|
||||
assert(int_value == 1235);
|
||||
assert(sscanf("+1234abc", "%d", &int_value) == 1);
|
||||
assert(int_value == 1234);
|
||||
assert(sscanf("-1234abc", "%d", &int_value) == 1);
|
||||
assert(int_value == -1234);
|
||||
assert(sscanf("-abc", "%d", &int_value) == 0);
|
||||
assert(sscanf("-", "%d", &int_value) == 0);
|
||||
|
||||
assert(sscanf("1234abc", "%i", &int_value) == 1);
|
||||
assert(int_value == 1234);
|
||||
assert(sscanf("123", "%hhi", &schar_value) == 1);
|
||||
assert(schar_value == 123);
|
||||
assert(sscanf("1234", "%hi", &short_value) == 1);
|
||||
assert(short_value == 1234);
|
||||
assert(sscanf("1234", "%li", &long_value) == 1);
|
||||
assert(long_value == 1234);
|
||||
assert(sscanf("1234", "%lli", &longlong_value) == 1);
|
||||
assert(longlong_value == 1234);
|
||||
assert(sscanf("1234", "%ji", &intmax_value) == 1);
|
||||
assert(intmax_value == 1234);
|
||||
assert(sscanf("1234", "%zi", &size_value) == 1);
|
||||
assert(size_value == 1234);
|
||||
assert(sscanf("1234", "%ti", &ptrdiff_value) == 1);
|
||||
assert(ptrdiff_value == 1234);
|
||||
assert(sscanf(" 1235abc", "%i", &int_value) == 1);
|
||||
assert(int_value == 1235);
|
||||
assert(sscanf("+1234abc", "%i", &int_value) == 1);
|
||||
assert(int_value == 1234);
|
||||
assert(sscanf("-1234abc", "%i", &int_value) == 1);
|
||||
assert(int_value == -1234);
|
||||
assert(sscanf("-abc", "%i", &int_value) == 0);
|
||||
|
||||
assert(sscanf(" 0b1011", "%i", &int_value) == 1);
|
||||
assert(int_value == 0b1011);
|
||||
assert(sscanf(" 0B1010", "%i", &int_value) == 1);
|
||||
assert(int_value == 0b1010);
|
||||
assert(sscanf(" +0b1011", "%i", &int_value) == 1);
|
||||
assert(int_value == 0b1011);
|
||||
assert(sscanf(" -0b1111", "%i", &int_value) == 1);
|
||||
assert(int_value == -0b1111);
|
||||
|
||||
assert(sscanf(" 01234", "%i", &int_value) == 1);
|
||||
assert(int_value == 01234);
|
||||
assert(sscanf(" +01234", "%i", &int_value) == 1);
|
||||
assert(int_value == 01234);
|
||||
assert(sscanf(" -01234", "%i", &int_value) == 1);
|
||||
assert(int_value == -01234);
|
||||
|
||||
assert(sscanf(" 0xab12", "%i", &int_value) == 1);
|
||||
assert(int_value == 0xAB12);
|
||||
assert(sscanf(" 0xAB12", "%i", &int_value) == 1);
|
||||
assert(int_value == 0xAB12);
|
||||
assert(sscanf(" 0Xab12", "%i", &int_value) == 1);
|
||||
assert(int_value == 0xAB12);
|
||||
assert(sscanf(" +0xab12", "%i", &int_value) == 1);
|
||||
assert(int_value == 0xAB12);
|
||||
assert(sscanf(" -0xab12", "%i", &int_value) == 1);
|
||||
assert(int_value == -0xAB12);
|
||||
|
||||
assert(sscanf("1234abc", "%u", &uint_value) == 1);
|
||||
assert(uint_value == 1234);
|
||||
assert(sscanf("123", "%hhu", &uchar_value) == 1);
|
||||
assert(uchar_value == 123);
|
||||
assert(sscanf("1234", "%hu", &ushort_value) == 1);
|
||||
assert(ushort_value == 1234);
|
||||
assert(sscanf("1234", "%lu", &ulong_value) == 1);
|
||||
assert(ulong_value == 1234);
|
||||
assert(sscanf("1234", "%llu", &ulonglong_value) == 1);
|
||||
assert(ulonglong_value == 1234);
|
||||
assert(sscanf("1234", "%ju", &uintmax_value) == 1);
|
||||
assert(uintmax_value == 1234);
|
||||
assert(sscanf("1234", "%zu", &size_value) == 1);
|
||||
assert(size_value == 1234);
|
||||
assert(sscanf("1234", "%tu", &ptrdiff_value) == 1);
|
||||
assert(ptrdiff_value == 1234);
|
||||
assert(sscanf(" 1235abc", "%u", &int_value) == 1);
|
||||
assert(int_value == 1235);
|
||||
assert(sscanf("+1234abc", "%u", &int_value) == 1);
|
||||
assert(int_value == 1234);
|
||||
assert(sscanf("-1234abc", "%u", &int_value) == 1);
|
||||
assert(int_value == -1234);
|
||||
assert(sscanf("-abc", "%d", &int_value) == 0);
|
||||
|
||||
assert(sscanf(" 12345", "%o", &int_value) == 1);
|
||||
assert(int_value == 012345);
|
||||
assert(sscanf("12", "%hho", &uchar_value) == 1);
|
||||
assert(uchar_value == 012);
|
||||
assert(sscanf("1234", "%ho", &ushort_value) == 1);
|
||||
assert(ushort_value == 01234);
|
||||
assert(sscanf("1234", "%lo", &ulong_value) == 1);
|
||||
assert(ulong_value == 01234);
|
||||
assert(sscanf("1234", "%llo", &ulonglong_value) == 1);
|
||||
assert(ulonglong_value == 01234);
|
||||
assert(sscanf("1234", "%jo", &uintmax_value) == 1);
|
||||
assert(uintmax_value == 01234);
|
||||
assert(sscanf("1234", "%zo", &size_value) == 1);
|
||||
assert(size_value == 01234);
|
||||
assert(sscanf("1234", "%to", &ptrdiff_value) == 1);
|
||||
assert(ptrdiff_value == 01234);
|
||||
assert(sscanf(" 01234", "%o", &int_value) == 1);
|
||||
assert(int_value == 01234);
|
||||
assert(sscanf(" +01234", "%o", &int_value) == 1);
|
||||
assert(int_value == 01234);
|
||||
assert(sscanf(" -01234", "%o", &int_value) == 1);
|
||||
assert(int_value == -01234);
|
||||
|
||||
assert(sscanf(" 1234ab", "%x", &int_value) == 1);
|
||||
assert(int_value == 0x1234AB);
|
||||
assert(sscanf("12", "%hhx", &uchar_value) == 1);
|
||||
assert(uchar_value == 0x12);
|
||||
assert(sscanf("1234", "%hx", &ushort_value) == 1);
|
||||
assert(ushort_value == 0x1234);
|
||||
assert(sscanf("1234", "%lx", &ulong_value) == 1);
|
||||
assert(ulong_value == 0x1234);
|
||||
assert(sscanf("1234", "%llx", &ulonglong_value) == 1);
|
||||
assert(ulonglong_value == 0x1234);
|
||||
assert(sscanf("1234", "%jx", &uintmax_value) == 1);
|
||||
assert(uintmax_value == 0x1234);
|
||||
assert(sscanf("1234", "%zx", &size_value) == 1);
|
||||
assert(size_value == 0x1234);
|
||||
assert(sscanf("1234", "%tx", &ptrdiff_value) == 1);
|
||||
assert(ptrdiff_value == 0x1234);
|
||||
assert(sscanf(" 1234ABC", "%x", &int_value) == 1);
|
||||
assert(int_value == 0x1234ABC);
|
||||
assert(sscanf(" 1234ab", "%X", &int_value) == 1);
|
||||
assert(int_value == 0x1234AB);
|
||||
assert(sscanf(" 0x1234", "%x", &int_value) == 1);
|
||||
assert(int_value == 0x1234);
|
||||
assert(sscanf(" 0x1234A", "%x", &int_value) == 1);
|
||||
assert(int_value == 0x1234A);
|
||||
assert(sscanf(" 0X1234AB", "%x", &int_value) == 1);
|
||||
assert(int_value == 0x1234AB);
|
||||
assert(sscanf(" +0x1234", "%x", &int_value) == 1);
|
||||
assert(int_value == 0x1234);
|
||||
assert(sscanf(" -0x1234", "%x", &int_value) == 1);
|
||||
assert(int_value == -0x1234);
|
||||
|
||||
assert(sscanf("abc", "abc%n", &int_value) == 0);
|
||||
assert(int_value == 3);
|
||||
assert(sscanf("1234", "1234%hhn", &uchar_value) == 0);
|
||||
assert(uchar_value == 4);
|
||||
assert(sscanf("1234", "1234%hn", &ushort_value) == 0);
|
||||
assert(ushort_value == 4);
|
||||
assert(sscanf("1234", "1234%ln", &ulong_value) == 0);
|
||||
assert(ulong_value == 4);
|
||||
assert(sscanf("1234", "1234%lln", &ulonglong_value) == 0);
|
||||
assert(ulonglong_value == 4);
|
||||
assert(sscanf("1234", "1234%jn", &uintmax_value) == 0);
|
||||
assert(uintmax_value == 4);
|
||||
assert(sscanf("1234", "1234%zn", &size_value) == 0);
|
||||
assert(size_value == 4);
|
||||
assert(sscanf("1234", "1234%tn", &ptrdiff_value) == 0);
|
||||
assert(ptrdiff_value == 4);
|
||||
assert(sscanf("abcd", "ab%nc%c", &int_value, char_value) == 1);
|
||||
assert(int_value == 2);
|
||||
assert(char_value[0] == 'd');
|
||||
|
||||
float float_value;
|
||||
double double_value;
|
||||
long double long_double_value;
|
||||
(void)float_value;
|
||||
(void)double_value;
|
||||
(void)long_double_value;
|
||||
/*assert(sscanf("1.123", "%a", &float_value) == 1);
|
||||
assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01);
|
||||
assert(sscanf("1.123", "%la", &double_value) == 1);
|
||||
assert(double_value >= 1.123 - 0.01 && double_value <= 1.123 + 0.01);
|
||||
assert(sscanf("1.123", "%La", &long_double_value) == 1);
|
||||
assert(long_double_value >= 1.123L - 0.01 && long_double_value <= 1.123L + 0.01);
|
||||
assert(sscanf("1.1234", "%A", &float_value) == 1);
|
||||
assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01);
|
||||
assert(sscanf("1.123", "%e", &float_value) == 1);
|
||||
assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01);
|
||||
assert(sscanf("1.123", "%le", &double_value) == 1);
|
||||
assert(double_value >= 1.123 - 0.01 && double_value <= 1.123 + 0.01);
|
||||
assert(sscanf("1.123", "%Le", &long_double_value) == 1);
|
||||
assert(long_double_value >= 1.123L - 0.01 && long_double_value <= 1.123L + 0.01);
|
||||
assert(sscanf("1.1234", "%E", &float_value) == 1);
|
||||
assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01);
|
||||
assert(sscanf("1.123", "%f", &float_value) == 1);
|
||||
assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01);
|
||||
assert(sscanf("1.123", "%lf", &double_value) == 1);
|
||||
assert(double_value >= 1.123 - 0.01 && double_value <= 1.123 + 0.01);
|
||||
assert(sscanf("1.123", "%Lf", &long_double_value) == 1);
|
||||
assert(long_double_value >= 1.123L - 0.01 && long_double_value <= 1.123L + 0.01);
|
||||
assert(sscanf("1.1234", "%F", &float_value) == 1);
|
||||
assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01);
|
||||
assert(sscanf("1.123", "%g", &float_value) == 1);
|
||||
assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01);
|
||||
assert(sscanf("1.123", "%lg", &double_value) == 1);
|
||||
assert(double_value >= 1.123 - 0.01 && double_value <= 1.123 + 0.01);
|
||||
assert(sscanf("1.123", "%Lg", &long_double_value) == 1);
|
||||
assert(long_double_value >= 1.123L - 0.01 && long_double_value <= 1.123L + 0.01);
|
||||
assert(sscanf("1.1234", "%G", &float_value) == 1);
|
||||
assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01);
|
||||
assert(sscanf("+1.1234", "%f", &float_value) == 1);
|
||||
assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01);
|
||||
assert(sscanf("-1.1234", "%f", &float_value) == 1);
|
||||
assert(float_value >= -1.1234f - 0.01 && float_value <= -1.1234f + 0.01);
|
||||
assert(sscanf("1.1234e3", "%f", &float_value) == 1);
|
||||
assert(float_value >= 1.1234E3f - 0.01 && float_value <= 1.1234E3f + 0.01);
|
||||
assert(sscanf("1.1234E3", "%f", &float_value) == 1);
|
||||
assert(float_value >= 1.1234E3f - 0.01 && float_value <= 1.1234E3f + 0.01);
|
||||
assert(sscanf("0x1234", "%f", &float_value) == 1);
|
||||
assert(float_value >= 0x1234P0f - 0.01 && float_value <= 0x1234P0f + 0.01);
|
||||
assert(sscanf("0X1234", "%f", &float_value) == 1);
|
||||
assert(float_value >= 0x1234P0f - 0.01 && float_value <= 0x1234P0f + 0.01);
|
||||
assert(sscanf("0x1.1234", "%f", &float_value) == 1);
|
||||
assert(float_value >= 0x1.1234P0 - 0.01 && float_value <= 0x1.1234P0 + 0.01);
|
||||
assert(sscanf("0x1.abcdP3", "%f", &float_value) == 1);
|
||||
assert(float_value >= 0x1.ABCDP3 - 0.01 && float_value <= 0x1.ABCDP3 + 0.01);
|
||||
assert(sscanf("0x1.abcdP+3", "%f", &float_value) == 1);
|
||||
assert(float_value >= 0x1.ABCDP3 - 0.01 && float_value <= 0x1.ABCDP3 + 0.01);
|
||||
assert(sscanf("0x1.abcdP-3", "%f", &float_value) == 1);
|
||||
assert(float_value >= 0x1.ABCDP-3 - 0.01 && float_value <= 0x1.ABCDP-3 + 0.01);
|
||||
assert(sscanf("0x1.AbCdP-3", "%f", &float_value) == 1);
|
||||
assert(float_value >= 0x1.ABCDP-3 - 0.01 && float_value <= 0x1.ABCDP-3 + 0.01);
|
||||
assert(sscanf("inf", "%f", &float_value) == 1);
|
||||
assert(isinf(float_value));
|
||||
assert(sscanf("InF", "%f", &float_value) == 1);
|
||||
assert(isinf(float_value));
|
||||
assert(sscanf("+inf", "%f", &float_value) == 1);
|
||||
assert(isinf(float_value));
|
||||
assert(sscanf("-inf", "%f", &float_value) == 1);
|
||||
assert(isinf(float_value));
|
||||
assert(sscanf("INF", "%f", &float_value) == 1);
|
||||
assert(isinf(float_value));
|
||||
assert(sscanf("infinity", "%f", &float_value) == 1);
|
||||
assert(isinf(float_value));
|
||||
assert(sscanf("INFINITY", "%f", &float_value) == 1);
|
||||
assert(isinf(float_value));
|
||||
assert(sscanf("nan", "%f", &float_value) == 1);
|
||||
assert(isnan(float_value));
|
||||
assert(sscanf("NaN", "%f", &float_value) == 1);
|
||||
assert(isnan(float_value));
|
||||
assert(sscanf("+nan", "%f", &float_value) == 1);
|
||||
assert(isnan(float_value));
|
||||
assert(sscanf("-nan", "%f", &float_value) == 1);
|
||||
assert(isnan(float_value));
|
||||
assert(sscanf("0xhello", "%f", &float_value) == 0);
|
||||
assert(sscanf("0x1hello", "%f", &float_value) == 1);
|
||||
assert(float_value >= 0x1P0f - 0.01 && float_value <= 0x1P0f + 0.01);
|
||||
assert(sscanf("ab1.1234", "%f", &float_value) == 0);
|
||||
assert(sscanf(" 1.123", "%f", &float_value) == 1);
|
||||
assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01);*/
|
||||
|
||||
void* ptr;
|
||||
assert(sscanf("hello", "%p", &ptr) == 0);
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
assert(sscanf("0xabcdef12abcdef12", "%p", &ptr) == 1);
|
||||
assert(ptr == (void*)0xabcdef12abcdef12);
|
||||
#else
|
||||
assert(sscanf("0xabcdef12", "%p", &ptr) == 1);
|
||||
assert(ptr == (void*)0xabcdef12);
|
||||
#endif
|
||||
|
||||
assert(sscanf("a", "%*c") == 0);
|
||||
char_value[2] = 'q';
|
||||
assert(sscanf("abcd", "%2c", char_value) == 1);
|
||||
assert(char_value[2] == 'q');
|
||||
char_value[2] = 0;
|
||||
assert(strcmp(char_value, "ab") == 0);
|
||||
|
||||
assert(sscanf("cdef", "%2s", char_value) == 1);
|
||||
assert(strcmp(char_value, "cd") == 0);
|
||||
assert(sscanf("c def", "%2s", char_value) == 1);
|
||||
assert(strcmp(char_value, "c") == 0);
|
||||
|
||||
assert(sscanf("aacd", "%2[ac]", char_value) == 1);
|
||||
assert(strcmp(char_value, "aa") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int main() {
|
||||
char str[] = "This is a sample string";
|
||||
char *pch;
|
||||
// The character 's' is at position 4, 7, 11 and 18
|
||||
pch = strchr(str, 's');
|
||||
assert(pch - str + 1 == 4);
|
||||
pch = strchr(pch + 1, 's');
|
||||
assert(pch - str + 1 == 7);
|
||||
pch = strchr(pch + 1, 's');
|
||||
assert(pch - str + 1 == 11);
|
||||
pch = strchr(pch + 1, 's');
|
||||
assert(pch - str + 1 == 18);
|
||||
pch = strchr(pch + 1, 's');
|
||||
assert(pch == NULL);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
// Date representation depends on locale, here only C is tested.
|
||||
// Maybe consider testing more locales?
|
||||
if (setlocale (LC_ALL, "C") == NULL) {
|
||||
fputs("strftime testcase could not set locale, errors may be expected!", stderr);
|
||||
}
|
||||
|
||||
char timebuf[32];
|
||||
char result[32] = " 8";
|
||||
struct tm tm;
|
||||
tm.tm_sec = 0;
|
||||
tm.tm_min = 17;
|
||||
tm.tm_hour = 17;
|
||||
tm.tm_mday = 8;
|
||||
tm.tm_mon = 2;
|
||||
tm.tm_year = 121;
|
||||
tm.tm_wday = 2;
|
||||
tm.tm_yday = 39;
|
||||
tm.tm_gmtoff = 3600;
|
||||
strftime(timebuf, sizeof(timebuf), "%e", &tm);
|
||||
assert(!strcmp(timebuf, result));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%x", &tm);
|
||||
assert(!strcmp(timebuf, "03/08/21"));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%X", &tm);
|
||||
assert(!strcmp(timebuf, "17:17:00"));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%D", &tm);
|
||||
assert(!strcmp(timebuf, "03/08/21"));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%OB %Ob", &tm);
|
||||
assert(!strcmp(timebuf, "March Mar"));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%c", &tm);
|
||||
memset(result, 0, sizeof(result));
|
||||
strftime(result, sizeof(result), "%a %b %e %H:%M:%S %Y", &tm);
|
||||
assert(!strcmp(timebuf, result));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%k %p %P%n", &tm);
|
||||
assert(!strcmp(timebuf, "17 PM pm\n"));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%a %A", &tm);
|
||||
assert(!strcmp(timebuf, "Tue Tuesday"));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%b %B %h", &tm);
|
||||
assert(!strcmp(timebuf, "Mar March Mar"));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
assert(!strftime(timebuf, sizeof(timebuf), "%a %A %a %A %b %B %h", &tm));
|
||||
|
||||
memset(timebuf, 0, sizeof(timebuf));
|
||||
strftime(timebuf, sizeof(timebuf), "%z", &tm);
|
||||
assert(!strcmp(timebuf, "+0100"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
char str[] = "This is a sample string";
|
||||
char *pch;
|
||||
pch = strrchr(str, 's');
|
||||
// The last occurence of 's' is at position 18
|
||||
assert(pch - str + 1 == 18);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define FLT_RANGE 0.000001f
|
||||
#define DBL_RANGE 0.000001
|
||||
#define LDBL_RANGE 0.000001
|
||||
|
||||
#define DO_TEST(str, value, off, func, range) ({ \
|
||||
char s[] = (str); \
|
||||
char *pEnd = NULL; \
|
||||
__typeof(func(s, &pEnd)) result = func(s, &pEnd); \
|
||||
assert(result >= (value) - (range)); \
|
||||
assert(result <= (value) + (range)); \
|
||||
assert(pEnd == (off == -1 ? s + strlen(s) : s + off)); })
|
||||
|
||||
#define DO_TEST_SUCCESS_FUNC(str, success_func, off, func) ({ \
|
||||
char s[] = (str); \
|
||||
char *pEnd = NULL; \
|
||||
assert(success_func(func(s, &pEnd))); \
|
||||
assert(pEnd == (off == -1 ? s + strlen(s) : s + off)); })
|
||||
|
||||
int main () {
|
||||
DO_TEST("0", 0.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("0.12", 0.12f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("12", 12.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("12.13", 12.13f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("10.0e1", 100.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("10.0e10", 100000000000.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("100.0e-1", 10.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("0x0", 0.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("0x0.12", 0.0703125f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("0x12", 18.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("0x12.13", 18.07421875f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("0x10.0p1", 32.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("0x10.0p10", 16384.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST("0x100.0p-1", 128.0f, -1, strtof, FLT_RANGE);
|
||||
DO_TEST_SUCCESS_FUNC("NAN", isnan, -1, strtof);
|
||||
DO_TEST_SUCCESS_FUNC("nan", isnan, -1, strtof);
|
||||
DO_TEST_SUCCESS_FUNC("INF", isinf, -1, strtof);
|
||||
DO_TEST_SUCCESS_FUNC("INFINITY", isinf, -1, strtof);
|
||||
|
||||
DO_TEST("0", 0.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("0.12", 0.12, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("12", 12.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("12.13", 12.13, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("10.0e1", 100.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("10.0e10", 100000000000.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("100.0e-1", 10.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("0x0", 0.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("0x0.12", 0.0703125, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("0x12", 18.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("0x12.13", 18.07421875, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("0x10.0p1", 32.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("0x10.0p10", 16384.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST("0x100.0p-1", 128.0, -1, strtod, DBL_RANGE);
|
||||
DO_TEST_SUCCESS_FUNC("NAN", isnan, -1, strtod);
|
||||
DO_TEST_SUCCESS_FUNC("nan", isnan, -1, strtod);
|
||||
DO_TEST_SUCCESS_FUNC("INF", isinf, -1, strtod);
|
||||
DO_TEST_SUCCESS_FUNC("INFINITY", isinf, -1, strtod);
|
||||
|
||||
DO_TEST("0", 0.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("0.12", 0.12, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("12", 12.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("12.13", 12.13, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("10.0e1", 100.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("10.0e10", 100000000000.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("100.0e-1", 10.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("0x0", 0.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("0x0.12", 0.0703125, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("0x12", 18.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("0x12.13", 18.07421875, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("0x10.0p1", 32.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("0x10.0p10", 16384.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST("0x100.0p-1", 128.0, -1, strtold, LDBL_RANGE);
|
||||
DO_TEST_SUCCESS_FUNC("NAN", isnan, -1, strtold);
|
||||
DO_TEST_SUCCESS_FUNC("nan", isnan, -1, strtold);
|
||||
DO_TEST_SUCCESS_FUNC("INF", isinf, -1, strtold);
|
||||
DO_TEST_SUCCESS_FUNC("INFINITY", isinf, -1, strtold);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#define DO_TEST(str, value, off, func, base) ({ \
|
||||
char s[] = (str); \
|
||||
char *pEnd = NULL; \
|
||||
errno = 0; \
|
||||
assert(func(s, &pEnd, base) == (value)); \
|
||||
assert(errno == 0); \
|
||||
assert(pEnd == (off == -1 ? s + strlen(s) : s + off)); })
|
||||
|
||||
#define DO_ERR_TEST(str, value, err, func, base) ({ \
|
||||
char s[] = (str); \
|
||||
char *pEnd = NULL; \
|
||||
errno = 0; \
|
||||
assert(func(s, &pEnd, base) == (value)); \
|
||||
assert(errno == err); \
|
||||
assert(pEnd == (err == ERANGE ? s + strlen(s) : s)); })
|
||||
|
||||
#define DO_TESTL(str, value, off, func, base) ({ \
|
||||
wchar_t s[] = (str); \
|
||||
wchar_t *pEnd = NULL; \
|
||||
errno = 0; \
|
||||
assert(func(s, &pEnd, base) == (value)); \
|
||||
assert(errno == 0); \
|
||||
assert(pEnd == (off == -1 ? s + wcslen(s) : s + off)); })
|
||||
|
||||
#define DO_ERR_TESTL(str, value, err, func, base) ({ \
|
||||
wchar_t s[] = (str); \
|
||||
wchar_t *pEnd = NULL; \
|
||||
errno = 0; \
|
||||
assert(func(s, &pEnd, base) == (value)); \
|
||||
assert(errno == err); \
|
||||
assert(pEnd == (err == ERANGE ? s + wcslen(s) : s)); })
|
||||
|
||||
int main () {
|
||||
// A few generic checks.
|
||||
DO_TEST("0", 0, -1, strtol, 0);
|
||||
DO_TEST("0", 0, -1, strtol, 10);
|
||||
DO_TEST("2001", 2001, -1, strtol, 10);
|
||||
DO_TEST("+2001", 2001, -1, strtol, 10);
|
||||
DO_TEST("60c0c0", 0x60c0c0, -1, strtol, 16);
|
||||
DO_TEST("-1101110100110100100000", -3624224, -1, strtol, 2);
|
||||
DO_TEST("0x6fffff", 0x6fffff, -1, strtol, 0);
|
||||
DO_TEST("0666", 0666, -1, strtol, 0);
|
||||
#ifndef USE_HOST_LIBC
|
||||
DO_TEST("1100", 0b1100, -1, strtol, 2);
|
||||
DO_TEST("0b1100", 0b1100, -1, strtol, 0);
|
||||
DO_TEST("0B1100", 0b1100, -1, strtol, 0);
|
||||
DO_TEST("0b1zzz", 1, 3, strtol, 0);
|
||||
#endif
|
||||
DO_TEST("0xzzz", 0, 1, strtol, 0);
|
||||
DO_TEST("0yzzz", 0, 1, strtol, 0);
|
||||
DO_TEST("00xzz", 0, 2, strtol, 0);
|
||||
DO_ERR_TEST("", 0, 0, strtol, 10);
|
||||
DO_ERR_TEST("asd", 0, 0, strtol, 10);
|
||||
DO_ERR_TEST("999999999999999999999999999", LONG_MAX, ERANGE, strtol, 10);
|
||||
DO_ERR_TEST("-999999999999999999999999999", LONG_MIN, ERANGE, strtol, 10);
|
||||
|
||||
// strtol
|
||||
#if defined(__i386__) || defined(__m68k__)
|
||||
DO_TEST("-2147483648", LONG_MIN, -1, strtol, 10);
|
||||
DO_TEST("2147483647", LONG_MAX, -1, strtol, 10);
|
||||
DO_ERR_TEST("-2147483649", LONG_MIN, ERANGE, strtol, 10);
|
||||
DO_ERR_TEST("2147483648", LONG_MAX, ERANGE, strtol, 10);
|
||||
#else
|
||||
DO_TEST("-9223372036854775808", LONG_MIN, -1, strtol, 10);
|
||||
DO_TEST("9223372036854775807", LONG_MAX, -1, strtol, 10);
|
||||
DO_ERR_TEST("9223372036854775808", LONG_MAX, ERANGE, strtol, 10);
|
||||
DO_ERR_TEST("-9223372036854775809", LONG_MIN, ERANGE, strtol, 10);
|
||||
#endif
|
||||
|
||||
// wcstol
|
||||
#if defined(__i386__) || defined(__m68k__)
|
||||
DO_TESTL(L"-2147483648", LONG_MIN, -1, wcstol, 10);
|
||||
DO_TESTL(L"2147483647", LONG_MAX, -1, wcstol, 10);
|
||||
DO_ERR_TESTL(L"2147483648", LONG_MAX, ERANGE, wcstol, 10);
|
||||
DO_ERR_TESTL(L"-2147483649", LONG_MIN, ERANGE, wcstol, 10);
|
||||
#else
|
||||
DO_TESTL(L"-9223372036854775808", LONG_MIN, -1, wcstol, 10);
|
||||
DO_TESTL(L"9223372036854775807", LONG_MAX, -1, wcstol, 10);
|
||||
DO_ERR_TESTL(L"9223372036854775808", LONG_MAX, ERANGE, wcstol, 10);
|
||||
DO_ERR_TESTL(L"-9223372036854775809", LONG_MIN, ERANGE, wcstol, 10);
|
||||
#endif
|
||||
|
||||
// strtoll
|
||||
DO_TEST("-9223372036854775808", LLONG_MIN, -1, strtoll, 10);
|
||||
DO_TEST("9223372036854775807", LLONG_MAX, -1, strtoll, 10);
|
||||
DO_ERR_TEST("9223372036854775808", LLONG_MAX, ERANGE, strtoll, 10);
|
||||
DO_ERR_TEST("-9223372036854775809", LLONG_MIN, ERANGE, strtoll, 10);
|
||||
// wcstoll
|
||||
DO_TESTL(L"-9223372036854775808", LLONG_MIN, -1, wcstoll, 10);
|
||||
DO_TESTL(L"9223372036854775807", LLONG_MAX, -1, wcstoll, 10);
|
||||
DO_ERR_TESTL(L"9223372036854775808", LLONG_MAX, ERANGE, wcstoll, 10);
|
||||
DO_ERR_TESTL(L"-9223372036854775809", LLONG_MIN, ERANGE, wcstoll, 10);
|
||||
|
||||
// strtoul
|
||||
#if defined(__i386__) || defined(__m68k__)
|
||||
DO_TEST("-1", -(1UL), -1, strtoul, 10);
|
||||
DO_TEST("2147483647", LONG_MAX, -1, strtoul, 10);
|
||||
DO_TEST("4294967295", ULONG_MAX, -1, strtoul, 10);
|
||||
DO_TEST("-4294967295", 1UL, -1, strtoul, 10);
|
||||
DO_ERR_TEST("4294967296", ULONG_MAX, ERANGE, strtoul, 10);
|
||||
#else
|
||||
DO_TEST("-1", -(1UL), -1, strtoul, 10);
|
||||
DO_TEST("9223372036854775807", LONG_MAX, -1, strtoul, 10);
|
||||
DO_TEST("18446744073709551615", ULONG_MAX, -1, strtoul, 10);
|
||||
DO_TEST("-18446744073709551615", 1UL, -1, strtoul, 10);
|
||||
DO_ERR_TEST("18446744073709551616", ULONG_MAX, ERANGE, strtoul, 10);
|
||||
#endif
|
||||
|
||||
// wcstoul
|
||||
#if defined(__i386__) || defined(__m68k__)
|
||||
DO_TESTL(L"-1", -(1UL), -1, wcstoul, 10);
|
||||
DO_TESTL(L"2147483647", LONG_MAX, -1, wcstoul, 10);
|
||||
DO_TESTL(L"4294967295", ULONG_MAX, -1, wcstoul, 10);
|
||||
DO_TESTL(L"-4294967295", 1UL, -1, wcstoul, 10);
|
||||
DO_ERR_TESTL(L"4294967296", ULONG_MAX, ERANGE, wcstoul, 10);
|
||||
#else
|
||||
DO_TESTL(L"-1", -(1UL), -1, wcstoul, 10);
|
||||
DO_TESTL(L"9223372036854775807", LONG_MAX, -1, wcstoul, 10);
|
||||
DO_TESTL(L"18446744073709551615", ULONG_MAX, -1, wcstoul, 10);
|
||||
DO_TESTL(L"-18446744073709551615", 1UL, -1, wcstoul, 10);
|
||||
DO_ERR_TESTL(L"18446744073709551616", ULONG_MAX, ERANGE, wcstoul, 10);
|
||||
#endif
|
||||
|
||||
// strtoull
|
||||
DO_TEST("-1", -(1ULL), -1, strtoull, 10);
|
||||
DO_TEST("9223372036854775807", LLONG_MAX, -1, strtoull, 10);
|
||||
DO_TEST("18446744073709551615", ULLONG_MAX, -1, strtoull, 10);
|
||||
DO_TEST("-18446744073709551615", 1ULL, -1, strtoull, 10);
|
||||
DO_ERR_TEST("18446744073709551616", ULLONG_MAX, ERANGE, strtoull, 10);
|
||||
// wcstoull
|
||||
DO_TESTL(L"-1", -(1ULL), -1, wcstoull, 10);
|
||||
DO_TESTL(L"9223372036854775807", LLONG_MAX, -1, wcstoull, 10);
|
||||
DO_TESTL(L"18446744073709551615", ULLONG_MAX, -1, wcstoull, 10);
|
||||
DO_TESTL(L"-18446744073709551615", 1ULL, -1, wcstoull, 10);
|
||||
DO_ERR_TESTL(L"18446744073709551616", ULLONG_MAX, ERANGE, wcstoull, 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
int res;
|
||||
|
||||
res = strverscmp("jan1", "jan10");
|
||||
assert(res < 0);
|
||||
|
||||
res = strverscmp("jan11", "jan10");
|
||||
assert(res > 0);
|
||||
|
||||
res = strverscmp("jan1", "jan1");
|
||||
assert(res == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <assert.h>
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
|
||||
int main() {
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
const char *buf = "cbtteststring";
|
||||
char dest[14];
|
||||
size_t ret = strxfrm(dest, buf, strlen(buf) + 1);
|
||||
assert(ret == 13);
|
||||
int cmp = strncmp(dest, buf, 13);
|
||||
assert(!cmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
struct tm soon = {};
|
||||
soon.tm_sec = 0;
|
||||
soon.tm_min = 0;
|
||||
soon.tm_hour = 0;
|
||||
soon.tm_mday = 1;
|
||||
soon.tm_mon = 0;
|
||||
soon.tm_year = 70;
|
||||
time_t result;
|
||||
time_t expected_result = 0;
|
||||
// This should be epoch.
|
||||
result = timegm(&soon);
|
||||
printf("epoch: %ld\n", result);
|
||||
assert(result == expected_result);
|
||||
|
||||
soon.tm_sec = 12;
|
||||
soon.tm_min = 8;
|
||||
soon.tm_hour = 16;
|
||||
soon.tm_mday = 17;
|
||||
soon.tm_mon = 4;
|
||||
soon.tm_year = 122;
|
||||
expected_result = 1652803692;
|
||||
result = timegm(&soon);
|
||||
// On my host, this returned 1652803692, verify this.
|
||||
printf("epoch: %ld\n", result);
|
||||
assert(result == expected_result);
|
||||
|
||||
soon.tm_sec = 45;
|
||||
soon.tm_min = 42;
|
||||
soon.tm_hour = 17;
|
||||
soon.tm_mday = 16;
|
||||
soon.tm_mon = 8;
|
||||
soon.tm_year = 69;
|
||||
expected_result = -9181035;
|
||||
result = timegm(&soon);
|
||||
// On my host, this returned -9181035, verify this.
|
||||
printf("epoch: %ld\n", result);
|
||||
assert(result == expected_result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
extern int daylight;
|
||||
extern long timezone;
|
||||
extern char *tzname[2];
|
||||
|
||||
int main() {
|
||||
tzset();
|
||||
printf("%s %s %ld %d\n", tzname[0], tzname[1], timezone, daylight);
|
||||
|
||||
time_t sometime_in_summer_in_the_north = 1752019200;
|
||||
struct tm *local = localtime(&sometime_in_summer_in_the_north);
|
||||
|
||||
// Print the current timezone offset from UTC in seconds, considering DST
|
||||
if (local) {
|
||||
long offset = local->tm_gmtoff;
|
||||
int hours = offset / 3600;
|
||||
int minutes = (offset % 3600) / 60;
|
||||
printf("UTC offset: %0d:%02d\n", hours, abs(minutes));
|
||||
} else {
|
||||
printf("localtime returned NULL\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
from pyexpect import expect
|
||||
|
||||
exe_wrapper = os.environ.get("MESON_EXE_WRAPPER")
|
||||
wrapper = exe_wrapper.split(" ") if exe_wrapper else []
|
||||
|
||||
def check_tz(tz, expected):
|
||||
environ = os.environ.copy()
|
||||
environ["TZ"] = tz
|
||||
|
||||
output = subprocess.check_output(
|
||||
wrapper + sys.argv[1:],
|
||||
stderr=subprocess.STDOUT,
|
||||
env=environ,
|
||||
)
|
||||
|
||||
expect(expected).to_equal(output)
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python3 tz.py <path to test program>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
check_tz("UTC0", b"UTC UTC 0 0\nUTC offset: 0:00\n")
|
||||
check_tz("GMT0", b"GMT GMT 0 0\nUTC offset: 0:00\n")
|
||||
check_tz(":UTC0", b"UTC UTC 0 0\nUTC offset: 0:00\n")
|
||||
check_tz("EST+5", b"EST EST 18000 0\nUTC offset: -5:00\n")
|
||||
check_tz("EET-2", b"EET EET -7200 0\nUTC offset: 2:00\n")
|
||||
check_tz("<+03>-03", b"+03 +03 -10800 0\nUTC offset: 3:00\n")
|
||||
check_tz("NPT-05:45", b"NPT NPT -20700 0\nUTC offset: 5:45\n")
|
||||
check_tz("NST+03:30NDT", b"NST NDT 12600 1\nUTC offset: -2:30\n")
|
||||
check_tz("NZST-12NZDT-13,M9.5.0,M4.1.0/3", b"NZST NZDT -43200 1\nUTC offset: 12:00\n")
|
||||
check_tz("<PST-8>+8<PDT-7>+7", b"PST-8 PDT-7 28800 1\nUTC offset: -7:00\n")
|
||||
check_tz("<PST-8>+8<PDT-7>+7,M3.2.0,M11.1.0", b"PST-8 PDT-7 28800 1\nUTC offset: -7:00\n")
|
||||
|
||||
# These depend on tzdata, which may or may not exist.
|
||||
# Useful to check every now and then, but these also present subtle differences
|
||||
# between the host libc and mlibc, so we can't expect these to always hold up.
|
||||
# E.g. glibc will set `tzname` from the TZ environment variable even if it
|
||||
# cannot find the tzinfo file, however mlibc will use the name of the timezone
|
||||
# as read from the tzinfo file or the timezone that it defaults to (UTC).
|
||||
|
||||
# Would be b"Universal 0 0\n" on glibc.
|
||||
# check_tz("", b"UTC UTC 0 0\n")
|
||||
|
||||
# Would be b"UTC 0 0\n" on glibc.
|
||||
# check_tz("UTC", b"UTC UTC 0 0\n")
|
||||
# check_tz(":UTC", b"UTC UTC 0 0\n")
|
||||
|
||||
# Would be b"Universal 0 0\n" on glibc.
|
||||
# check_tz("Universal", b"UTC UTC 0 0\n")
|
||||
# check_tz(":Universal", b"UTC UTC 0 0\n")
|
||||
|
||||
# Would be b"ATimeZoneThatShouldHopefullyNeverBeInTzdata 0 0\n" on glibc.
|
||||
# check_tz("ATimeZoneThatShouldHopefullyNeverBeInTzdata", b"UTC UTC 0 0\n")
|
||||
# check_tz(":ATimeZoneThatShouldHopefullyNeverBeInTzdata", b"UTC UTC 0 0\n")
|
||||
@@ -0,0 +1,76 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef USE_HOST_LIBC
|
||||
#define TEST_FILE "ungetc-host-libc.tmp"
|
||||
#else
|
||||
#define TEST_FILE "ungetc.tmp"
|
||||
#endif
|
||||
|
||||
void test(int buffering) {
|
||||
FILE *f = fopen(TEST_FILE, "w");
|
||||
for(int c = '0'; c <= '9'; c++) {
|
||||
fputc(c, f);
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
f = fopen(TEST_FILE, "r");
|
||||
if (!buffering) {
|
||||
setbuf(f, NULL);
|
||||
}
|
||||
|
||||
assert(ungetc('x', f) == 'x');
|
||||
assert(fgetc(f) == 'x');
|
||||
|
||||
// Test pushing back the same character
|
||||
for (int c = '0'; c <= '9'; c++) {
|
||||
assert(fgetc(f) == c);
|
||||
assert(ungetc(c, f) == c);
|
||||
assert(fgetc(f) == c);
|
||||
}
|
||||
assert(fgetc(f) == EOF);
|
||||
assert(ungetc(EOF, f) == EOF);
|
||||
|
||||
// Even though the spec does not guarantee it, we should be able to
|
||||
// ungetc more than one character.
|
||||
assert(ungetc('x', f) == 'x');
|
||||
assert(ungetc('y', f) == 'y');
|
||||
assert(fgetc(f) == 'y');
|
||||
assert(fgetc(f) == 'x');
|
||||
|
||||
// Seeking should discard the effects of ungetc.
|
||||
assert(ungetc('x', f) == 'x');
|
||||
rewind(f);
|
||||
|
||||
// Test pushing back a different character
|
||||
for (int c = '0'; c <= '9'; c++) {
|
||||
assert(fgetc(f) == c);
|
||||
assert(ungetc(c - '0' + 'a', f) == c - '0' + 'a');
|
||||
assert(fgetc(f) == c - '0' + 'a');
|
||||
}
|
||||
|
||||
#ifndef USE_HOST_LIBC
|
||||
// Too many ungetcs should fail.
|
||||
int eof = 0;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
if (ungetc('x', f) == EOF) {
|
||||
eof = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(eof);
|
||||
#endif
|
||||
|
||||
fclose(f);
|
||||
|
||||
// TODO: Test with other operations, like fread.
|
||||
}
|
||||
|
||||
int main() {
|
||||
fprintf(stderr, "with buffering...\n");
|
||||
test(1);
|
||||
fprintf(stderr, "without buffering...\n");
|
||||
test(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <locale.h>
|
||||
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
#define WCHAR_SPEC ""
|
||||
#else
|
||||
#define WCHAR_SPEC "l"
|
||||
#endif
|
||||
|
||||
#define EXPECT(func) ({ \
|
||||
if(res != expected_ret) { \
|
||||
printf(#func " decoded %d bytes (expected %d bytes), at %s:%d\n", \
|
||||
res, expected_ret, __FILE__, line); \
|
||||
fflush(stdout); \
|
||||
abort(); \
|
||||
} \
|
||||
if(wc != expected) { \
|
||||
printf(#func " output cp %" WCHAR_SPEC "x (expected cp %" WCHAR_SPEC "x), at %s:%d\n", wc, \
|
||||
expected, __FILE__, line); \
|
||||
fflush(stdout); \
|
||||
abort(); \
|
||||
} \
|
||||
})
|
||||
|
||||
void verify_decode(const char *input, wchar_t expected, int line) {
|
||||
wchar_t wc;
|
||||
int bytes = *input ? strlen(input) : 1;
|
||||
int expected_ret = *input ? strlen(input) : 0;
|
||||
|
||||
// Check mbrtowc().
|
||||
mbstate_t state;
|
||||
memset(&state, 0, sizeof(state));
|
||||
assert(mbrtowc(NULL, NULL, -1, &state) == 0);
|
||||
int res = mbrtowc(&wc, input, bytes, &state);
|
||||
EXPECT("mbrtowc");
|
||||
res = mbrtowc(NULL, input, bytes, &state);
|
||||
EXPECT("mbrtowc (pwc == NULL)");
|
||||
|
||||
// Check mbtowc().
|
||||
assert(mbtowc(NULL, NULL, -1) == 0);
|
||||
res = mbtowc(&wc, input, bytes);
|
||||
EXPECT("mbtowc");
|
||||
res = mbtowc(NULL, input, bytes);
|
||||
EXPECT("mbtowc (pwc == NULL)");
|
||||
}
|
||||
|
||||
int main() {
|
||||
setlocale(LC_ALL, "C.UTF-8");
|
||||
|
||||
#define verify_decode(in, out) verify_decode(in, out, __LINE__)
|
||||
verify_decode("\x24", 0x24);
|
||||
verify_decode("\xC2\xA2", 0xA2);
|
||||
verify_decode("\xE0\xA4\xB9", 0x939);
|
||||
verify_decode("\xE2\x82\xAC", 0x20AC);
|
||||
verify_decode("\xED\x95\x9C", 0xD55C);
|
||||
verify_decode("\xF0\x90\x8D\x88", 0x10348);
|
||||
verify_decode("", L'\0');
|
||||
|
||||
// Check wcrtomb.
|
||||
char representation[MB_CUR_MAX];
|
||||
representation[0] = '\0';
|
||||
mbstate_t state;
|
||||
memset(&state, 0, sizeof(state));
|
||||
assert(wcrtomb(representation, L'1', &state) == 1);
|
||||
assert(wcrtomb(representation, L'ß', &state) == 2);
|
||||
assert(!strncmp(representation, "\xC3\x9F", 2));
|
||||
assert(wcrtomb(representation, L'ࠑ', &state) == 3);
|
||||
assert(!strncmp(representation, "\xE0\xA0\x91", 3));
|
||||
assert(wcrtomb(representation, L'𒂲', &state) == 4);
|
||||
assert(!strncmp(representation, "\xF0\x92\x82\xB2", 4));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
int main() {
|
||||
wchar_t *wide_string = L"test string\n";
|
||||
wchar_t *dup_string = wcsdup(wide_string);
|
||||
assert(!memcmp(wide_string, dup_string, (wcslen(wide_string) + 1) * sizeof(wchar_t)));
|
||||
free(dup_string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <assert.h>
|
||||
#include <wchar.h>
|
||||
|
||||
int main() {
|
||||
assert(!wcsncasecmp(L"foo", L"foo", 3));
|
||||
assert(!wcsncasecmp(L"foo", L"FOO", 3));
|
||||
assert(!wcsncasecmp(L"fooa", L"FOOB", 3));
|
||||
assert(wcsncasecmp(L"foo", L"bar", 3));
|
||||
assert(!wcsncasecmp(L"fooa", L"FOOA", 4));
|
||||
assert(!wcsncasecmp(L"123abc", L"123AbC", 6));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
int main() {
|
||||
const wchar_t str[] = L"wcsrtombs";
|
||||
const wchar_t *p = str;
|
||||
int ret = wcsrtombs(NULL, &p, 343245234, NULL);
|
||||
assert(ret == 9);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <assert.h>
|
||||
#include <wchar.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void){
|
||||
wchar_t *ws1 = calloc(10, sizeof(wchar_t));
|
||||
wchar_t *ws2 = calloc(10, sizeof(wchar_t));
|
||||
|
||||
mbstowcs(ws1, "Test 1", 10);
|
||||
mbstowcs(ws2, "Tester 2", 10);
|
||||
|
||||
assert(wmemcmp(ws1, ws2, 10) < 0);
|
||||
assert(wmemcmp(ws2, ws1, 10) > 0);
|
||||
assert(wmemcmp(ws2, ws2, 10) == 0);
|
||||
|
||||
free(ws1);
|
||||
free(ws2);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user