From ba626bf366a1a2247b5fde74e7c5bc451af5caae Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 14 Jan 2024 22:03:25 +0100 Subject: [PATCH] stdio: scanf tests --- CMakeLists.txt | 1 + include/ft/all-tests.h | 2 + src/main.c | 4 +- src/stdio/scanf.c | 677 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 683 insertions(+), 1 deletion(-) create mode 100644 src/stdio/scanf.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a6dd44..fdd9632 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ set(SOURCES # stdio src/stdio/files.c src/stdio/printf.c + src/stdio/scanf.c # stdlib src/stdlib/arith.c src/stdlib/exit.c diff --git a/include/ft/all-tests.h b/include/ft/all-tests.h index fada5cf..4de071b 100644 --- a/include/ft/all-tests.h +++ b/include/ft/all-tests.h @@ -38,6 +38,8 @@ extern ft_test ft_stdio_write_chars; extern ft_test ft_stdio_read_chars; extern ft_test ft_stdio_stdstreams; extern ft_test ft_stdio_getdelim; +extern ft_test ft_stdio_sscanf; +extern ft_test ft_stdio_fscanf; /* stdlib */ extern ft_test ft_stdlib_arith; diff --git a/src/main.c b/src/main.c index c0a4c38..4eb4f41 100644 --- a/src/main.c +++ b/src/main.c @@ -56,7 +56,9 @@ ft_list headers_libc[] = { &ft_stdio_write_chars, &ft_stdio_read_chars, &ft_stdio_stdstreams, - &ft_stdio_getdelim, + &ft_stdio_getdelim, + &ft_stdio_sscanf, + &ft_stdio_fscanf, NULL, }}, { _("stdlib.h", ""), (ft_test*[]){ diff --git a/src/stdio/scanf.c b/src/stdio/scanf.c new file mode 100644 index 0000000..7c4c736 --- /dev/null +++ b/src/stdio/scanf.c @@ -0,0 +1,677 @@ +#include +#include +#include +#include +#include +#include +#include + +#define ASSERTFP(X, TARGET, EPS) \ + ((X) >= (TARGET)-(EPS) && (X) <= (TARGET)+(EPS)) + +/* Return value of *scanf() and total number of bytes read */ +static int ret = -20; +static int n = -20; + +/* Various strings... */ +static char c[10] = "........."; +static char str[25] = "........................"; +static char str2[25] = "........................"; +/* unsigned integers... */ +static unsigned long long ulli = 0; +static unsigned long uli = 0; +static unsigned int ui = 0; +static unsigned short usi = 0; +static unsigned char ussi = 0; +/* integers... */ +static long long slli = 0; +static long sli = 0; +static int si = 0; +static short ssi = 0; +static char sssi = 0; +/* and floating-point numbers to test the formats. */ +static float f1 = 0; +static float f2 = 0; +static double d1 = 0; +static double d2 = 0; +static long double ld1 = 0; +static long double ld2 = 0; + +_Static_assert(sizeof(long long int) == 8); +_Static_assert(sizeof(long int) == 4); +_Static_assert(sizeof(int) == 4); +_Static_assert(sizeof(short) == 2); +_Static_assert(sizeof(char) == 1); + +#define PRINT(FMT, ...) \ + ft_log(t, FMT, ##__VA_ARGS__) + +static void _ft_stdio_fscanf_switch(ft_test *t) +{ + FILE *fp = fopen("input.txt", "w"); + if(!ft_assert(t, fp != NULL)) + return; + + char const *data = + "123\n" + "3.14\n" + "Hello\n" + "A\n" + "10 3.14 20\n" + "This is a sentence with spaces.\n" + "1 2 3 4 5\n" + "Invalid Input Test\n"; + + fwrite(data, strlen(data), 1, fp); + fclose(fp); + + fp = fopen("input.txt", "r"); + if(!ft_assert(t, fp != NULL)) + return; + + // Test 1: Read an integer + int i; + fscanf(fp, "%d", &i); + PRINT("Test 1: Read integer: %d\n", i); + ft_assert(t, i == 123); + + // Test 2: Read a floating-point number + float f; + fscanf(fp, "%f", &f); + PRINT("Test 2: Read floating-point number: %f\n", f); + ft_assert(t, ASSERTFP(f, 3.14, 1E-6)); + + // Test 3: Read a string with spaces + char s[20]; + fscanf(fp, "%s", s); + PRINT("Test 3: Read string: '%s'\n", s); + ft_assert(t, !strcmp(s, "Hello")); + + // Test 4: Read a character + char cc; + fscanf(fp, "%*c%c", &cc); + PRINT("Test 4: Read character: %c\n", cc); + ft_assert(t, cc == 'A'); + + // Test 5: Read multiple values + int a, b; + float c1; + fscanf(fp, "%d%f%d", &a, &c1, &b); + PRINT("Test 5: Read multiple values: %d, %f, %d\n", a, c1, b); + ft_assert(t, a == 10 && ASSERTFP(c1, 3.14, 1E-6) && b == 20); + + // Test 6: Read a string with spaces using %[^\n] + char s1[50]; + fscanf(fp, " %[^\n]", s1); + PRINT("Test 6: Read string with spaces: '%s'\n", s1); + ft_assert(t, !strcmp(s1, "This is a sentence with spaces.")); + + // Test 7: Read until EOF + int num, count = 0; + while (fscanf(fp, "%d", &num) == 1) { + count++; + ft_assert(t, num == count); + PRINT("Test 7: Read number: %d\n", num); + } + PRINT("Test 7: Total numbers read: %d\n", count); + ft_assert(t, count == 5); + + // Test 8: Error handling - invalid input + int x; + int ret = fscanf(fp, "%d", &x); + if(ret == EOF) + PRINT("Test 8: End of file reached\n"); + else if(ret == 0) + PRINT("Test 8: Invalid input\n"); + else + PRINT("Test 8: Read number: %d\n", x); + ft_assert(t, ret == 0); + + // Test 9: Error handling - end of file + fscanf(fp, "%*[^\n]"); + + int y = -1; + ret = fscanf(fp, "%d", &y); + if (ret == EOF) + PRINT("Test 9: End of file reached\n"); + else + PRINT("Test 9: Read number: %d\n", y); + ft_assert(t, ret == EOF); + + // TODO: Check EOF behavior a lot more thoroughly + + fclose(fp); +} + +static void _ft_stdio_fscanf(ft_test *t) +{ + gint_world_switch(GINT_CALL(_ft_stdio_fscanf_switch, (void *)t)); +} + +ft_test ft_stdio_fscanf = { + .name = "scanf: File buffering", + .function = _ft_stdio_fscanf, +}; + +static void clear(void) +{ + ret = -20; + n = -20; + + strcpy(c, "........."); + strcpy(str, "........................"); + strcpy(str2, "........................"); + + ulli = 0; + uli = 0; + ui = 0; + usi = 0; + ussi = 0; + + slli = 0; + sli = 0; + si = 0; + ssi = 0; + sssi = 0; + + f1 = 0; + f2 = 0; + + d1 = 0; + d2 = 0; + + ld1 = 0; + ld2 = 0; +} + +static void _ft_stdio_sscanf(ft_test *t) +{ + /******************************/ + /* TESTS ON CHARS AND STRINGS */ + /******************************/ + + clear(); + ret = sscanf("abcdefghij", "%c%n", &c[0], &n); + PRINT("#1 : rd 1c : [%c] cn=%d rt=%d\n", c[0], n, ret); + ft_assert(t, ret==1 && c[0]=='a' && n==1); + + clear(); + ret = sscanf("abcdefghij", "%c%*c%c%n", &c[0], &c[2], &n); + PRINT("#2 : rd 1c + skp 1c + rd 1c : [%c][%c][%c] cn=%d rt=%d\n", + c[0], c[1], c[2], n, ret); + ft_assert(t, ret==2 && c[0]=='a' && c[1]=='.' && c[2]=='c' && n==3); + + clear(); + ret = sscanf("abcdefghij", "%3c%n", c, &n); + PRINT("#3 : rd 3c (w 3c) : [%c][%c][%c] cn=%d rt=%d\n", + c[0], c[1], c[2], n, ret); + ft_assert(t, ret==1 && c[0]=='a' && c[1]=='b' && c[2]=='c' + && c[3] == '.' && n==3); + + clear(); + ret = sscanf("abcdefghij", "%*5c%n", &n); + PRINT("#4a : skp 5c : cn=%d rt=%d\n", n, ret); + ft_assert(t, ret==0 && n==5); + + clear(); + ret = sscanf("abcdefghij", "%*5c%c%n", &c[0], &n); + PRINT("#4b : skp 5c : [%c] cn=%d rt=%d\n", c[0], n, ret); + ft_assert(t, ret==1 && n==6 && c[0]=='f' && c[1]=='.'); + + clear(); + ret = sscanf("abcdefghij", "%*5c%1c%n", &c[0], &n); + PRINT("#4c : skp 5c : [%c][%c] cn=%d rt=%d\n", c[0], c[1], n, ret); + ft_assert(t, ret==1 && n==6 && c[0]=='f' && c[1]=='.'); + + clear(); + ret = sscanf("abcdefghij", "%*5c%2c%n", c, &n); + PRINT("#4d : skp 5c : [%c][%c][%c] cn=%d rt=%d\n", + c[0], c[1], c[2], n, ret); + ft_assert(t, ret==1 && n==7 && c[0]=='f' && c[1]=='g' && c[2]=='.'); + + clear(); + ret = sscanf("abcdefghij", "%*5c%3c%n", c, &n); + PRINT("#4 : skp 5c + rd 3c (w 3c) : [%c][%c][%c] cn=%d rt=%d\n", + c[0], c[1], c[2], n, ret); + ft_assert(t, ret==1 && c[0]=='f' && c[1]=='g' && c[2]=='h' && n==8); + + clear(); + ret = sscanf("abcdefghij", "%n", &n); + PRINT("#5 : no char : cn=%d rt=%d\n", n, ret); + ft_assert(t, ret==0 && n==0); + + clear(); + ret = sscanf("abcdefghij", "%s%n", str, &n); + PRINT("#6 : rd 1s : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "abcdefghij")==0 && n==10); + + clear(); + ret = sscanf("abcde ghij", "%s%n", str, &n); + PRINT("#7 : rd 1s with space : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "abcde")==0 && n==5); + + clear(); + ret = sscanf("abcdefghij", "%*5c%s%n", str, &n); + PRINT("#8 : skp 5c + rd 1str : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "fghij")==0 && n==10); + + clear(); + ret = sscanf("", "%*5c%s%n", str, &n); + PRINT("#9 : empty str tst1 : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==-1 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("", "%c%s%n", &c[0], str, &n); + PRINT("#10 : empty str tst2 : [%c][%s] cn=%d rt=%d\n", + c[0], str, n, ret); + ft_assert(t, ret==-1 && c[0]=='.' && + strcmp(str, "........................" )==0 && n==-20); + + clear(); + ret = sscanf("abcdef ghijkl", "%s%s%n", str, str2, &n); + PRINT("#11 : rd 1s + 1s : [%s][%s] cn=%d rt=%d\n", str, str2, n, ret); + ft_assert(t, ret==2 && strcmp( str, "abcdef")==0 && + strcmp(str2, "ghijkl" )==0 && n==13); + + clear(); + ret = sscanf("abcdef ghijkl", "%s%c%s%n", str, &c[0], str2, &n); + PRINT("#12 : rd 1s + 1c + 1s : [%s][%c][%s] cn=%d rt=%d\n", + str, c[0], str2, n, ret); + ft_assert(t, ret==3 && strcmp( str, "abcdef")==0 && c[0]==' ' && + strcmp(str2, "ghijkl" )==0 && n==13); + + /******************************/ + /* TESTS ON INTEGER NUMBERS */ + /******************************/ + + clear(); + ret = sscanf("1234567890", "%d%n", &si, &n); + PRINT("#13 : rd 1d : [%d] cn=%d rt=%d\n", si, n, ret); + ft_assert(t, ret==1 && si==1234567890 && n==10); + + clear(); + ret = sscanf("1234567890", "%d%n", &ui, &n); + PRINT("#14 : rd 1d : [%d] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==1234567890 && n==10); + + clear(); + ret = sscanf("-1234567890", "%d%n", &si, &n); + PRINT("#15 : rd 1d : [%d] cn=%d rt=%d\n", si, n, ret); + ft_assert(t, ret==1 && si==-1234567890 && n==11); + + clear(); + ret = sscanf("-1234567890", "%d%n", &ui, &n); + PRINT("#16 : rd 1d : [%d] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==(uint32_t)-1234567890 && n==11); + + clear(); + ret = sscanf("1234567890", "%hd%n", &ssi, &n); + PRINT("#17 : rd 1hd : [%hd] cn=%d rt=%d\n", ssi, n, ret); + ft_assert(t, ret==1 && ssi==722 && n==10); + + clear(); + ret = sscanf("1234567890", "%hhd%n", &sssi, &n); + PRINT("#18 : rd 1hhd : [%hhd] cn=%d rt=%d\n", sssi, n, ret); + ft_assert(t, ret==1 && sssi==-46 && n==10); + + clear(); + ret = sscanf("1234567890", "%ld%n", &sli, &n); + PRINT("#19 : rd 1ld : [%ld] cn=%d rt=%d\n", sli, n, ret); + ft_assert(t, ret==1 && sli==1234567890 && n==10); + + clear(); + ret = sscanf("1234567890", "%lld%n", &slli, &n); + PRINT("#20 : rd 1lld : [%lld] cn=%d rt=%d\n", slli, n, ret); + ft_assert(t, ret==1 && slli==1234567890 && n==10); + + clear(); + ret = sscanf("-1234567890", "%hd%n", &ssi, &n); + PRINT("#21 : rd 1hd : [%hd] cn=%d rt=%d\n", ssi, n, ret); + ft_assert(t, ret==1 && ssi==-722 && n==11); + + clear(); + ret = sscanf("-1234567890", "%hhd%n", &sssi, &n); + PRINT("#22 : rd 1hhd : [%hhd] cn=%d rt=%d\n", sssi, n, ret); + ft_assert(t, ret==1 && sssi==46 && n==11); + + clear(); + ret = sscanf("-1234567890", "%ld%n", &sli, &n); + PRINT("#23 : rd 1ld : [%ld] cn=%d rt=%d\n", sli, n, ret); + ft_assert(t, ret==1 && sli==-1234567890 && n==11); + + clear(); + ret = sscanf("-1234567890", "%lld%n", &slli, &n); + PRINT("#24 : rd 1lld : [%lld] cn=%d rt=%d\n", slli, n, ret); + ft_assert(t, ret==1 && slli==-1234567890 && n==11); + + clear(); + ret = sscanf("1234567890", "%u%n", &ui, &n); + PRINT("#25 : rd 1u : [%u] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==1234567890 && n==10); + + clear(); + ret = sscanf("1234567890", "%hhu%n", &ussi, &n); + PRINT("#26 : rd 1hhu : [%hhu] cn=%d rt=%d\n", ussi, n, ret); + ft_assert(t, ret==1 && ussi==210 && n==10); + + clear(); + ret = sscanf("-1234567890", "%lu%n", &uli, &n); + PRINT("#27 : rd 1lu : [%lu] cn=%d rt=%d\n", uli, n, ret); + ft_assert(t, ret==1 && uli==3060399406 && n==11); + + clear(); + ret = sscanf("-1234567890", "%llu%n", &ulli, &n); + PRINT("#28 : rd 1llu : [%llu] cn=%d rt=%d\n", ulli, n, ret); + ft_assert(t, ret==1 && ulli==18446744072474983726ull && n==11); + + clear(); + ret = sscanf("1234567890", "%3i%2c%4i%c%n", &ui, &c[0], &si, &c[3], &n); + PRINT("#29 : rd 1i+2c+4i+c : [%i][%c][%c][%i][%c] cn=%d rt=%d\n", + ui, c[0], c[1], si, c[3], n, ret); + ft_assert(t, ret==4 && ui==123 && c[0]=='4' && c[1]=='5' && si==6789 + && c[3]=='0' && n==10); + + clear(); + ret = sscanf("123", "%i%n", &ui, &n); + PRINT("#30 : rd 1i from decimal : [%i] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==123 && n==3); + + clear(); + ret = sscanf("0123", "%i%n", &ui, &n); + PRINT("#31 : rd 1i from octal : [%i] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==83 && n==4); + + clear(); + ret = sscanf("0x123", "%i%n", &ui, &n); + PRINT("#32 : rd 1i from hexadecimal : [%i] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==291 && n==5); + + /********************************************/ + /* TESTS ON HEXADECIMAL AND OCTAL NUMBERS */ + /********************************************/ + + clear(); + ret = sscanf("0123", "%o%n", &ui, &n); + PRINT("#33 : rd 1o from decimal : [%i] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==83 && n==4); + + clear(); + ret = sscanf("0x123", "%x%n", &ui, &n); + PRINT("#34 : rd 1x from hexadecimal : [%i] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==291 && n==5); + + clear(); + ret = sscanf("0X123", "%x%n", &ui, &n); + PRINT("#35 : rd 1x from hexadecimal : [%i] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==291 && n==5); + + clear(); + ret = sscanf("0x123", "%X%n", &ui, &n); + PRINT("#36 : rd 1X from hexadecimal : [%i] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==291 && n==5); + + clear(); + ret = sscanf("0X123", "%X%n", &ui, &n); + PRINT("#37 : rd 1X from hexadecimal : [%i] cn=%d rt=%d\n", ui, n, ret); + ft_assert(t, ret==1 && ui==291 && n==5); + + /*************************************/ + /* TESTS ON FLOATING POINT NUMBERS */ + /*************************************/ + + // read %a%e%f%g%A%E%F%G + + clear(); + ret = sscanf("0.123 -0.456", "%a%A%n", &f1, &f2, &n); + PRINT("#38 : rd 1a+1A: [%.3f][%.3f] cn=%d rt=%d\n", f1, f2, n, ret); + ft_assert(t, ret==2 && ASSERTFP(f1,0.123,1E-7) + && ASSERTFP(f2,-0.456,1E-7) && n==12); + + clear(); + ret = sscanf("0.0123E+1 -45.6E-2", "%f%F%n", &f1, &f2, &n); + PRINT("#39 : rd 1f+1F: [%.3f][%.3f] cn=%d rt=%d\n", f1, f2, n, ret); + ft_assert(t, ret==2 && ASSERTFP(f1,0.123,1E-7) + && ASSERTFP(f2,-0.456,1E-7) && n==18); + + clear(); + ret = sscanf("0.123 -0.456", "%g%G%n", &f1, &f2, &n); + PRINT("#40 : rd 1g+1G: [%.3f][%.3f] cn=%d rt=%d\n", f1, f2, n, ret); + ft_assert(t, ret==2 && ASSERTFP(f1,0.123,1E-7) + && ASSERTFP(f2,-0.456,1E-7) && n==12); + + clear(); + ret = sscanf("0.0123E+1 -45.6E-2", "%e%E%n", &f1, &f2, &n); + PRINT("#41 : rd 1e+1E: [%.3f][%.3f] cn=%d rt=%d\n", f1, f2, n, ret); + ft_assert(t, ret==2 && ASSERTFP(f1,0.123,1E-7) + && ASSERTFP(f2,-0.456,1E-7) && n==18); + + clear(); + ret = sscanf("0.123 -0.456", "%la%lA%n", &d1, &d2, &n); + PRINT("#42 : rd 1la+1lA: [%.3lf][%.3lf] cn=%d rt=%d\n", + d1, d2, n, ret); + ft_assert(t, ret==2 && ASSERTFP(d1,0.123,1E-7) + && ASSERTFP(d2,-0.456,1E-7) && n==12); + + clear(); + ret = sscanf("0.0123E+1 -45.6E-2", "%lf%lF%n", &d1, &d2, &n); + PRINT("#43 : rd 1lf+1lF: [%.3lf][%.3lf] cn=%d rt=%d\n", + d1, d2, n, ret); + ft_assert(t, ret==2 && ASSERTFP(d1,0.123,1E-7) + && ASSERTFP(d2,-0.456,1E-7) && n==18); + + clear(); + ret = sscanf("0.123 -0.456", "%La%LA%n", &ld1, &ld2, &n); + PRINT("#44 : rd 1La+1LA: [%.3Lf][%.3Lf] cn=%d rt=%d\n", + ld1, ld2, n, ret); + ft_assert(t, ret==2 && ASSERTFP(ld1,0.123,1E-7) + && ASSERTFP(ld2,-0.456,1E-7) && n==12); + + clear(); + ret = sscanf("0.0123E+1 -45.6E-2", "%Lf%LF%n", &ld1, &ld2, &n); + PRINT("#45 : rd 1Lf+1LF: [%.3Lf][%.3Lf] cn=%d rt=%d\n", + ld1, ld2, n, ret); + ft_assert(t, ret==2 && ASSERTFP(ld1,0.123,1E-7) + && ASSERTFP(ld2,-0.456,1E-7) && n==18); + + /***********************/ + /* TESTS ON POINTERS */ + /***********************/ + + int val; + char buf[30]; + sprintf(buf, "%p", &val); + void *ptr; + sscanf(buf, "%p", &ptr); + ft_assert(t, ptr == &val); + PRINT("#46 : rd 1p : [in:%p][out:%p]\n", &val, ptr); + + /**************************/ + /* TESTS ON SET OF CHAR */ + /**************************/ + + clear(); + ret = sscanf("abcdefghij", "%[abdr-v0-9A-F]%n", str, &n); + PRINT("#47 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "ab")==0 && n==2); + + clear(); + ret = sscanf("bcdefghij", "%[abdr-v0-9A-F]%n", str, &n); + PRINT("#48 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "b")==0 && n==1); + + clear(); + ret = sscanf("1abcdefghij", "%[abdr-v0-9A-F]%n", str, &n); + PRINT("#49 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "1ab")==0 && n==3); + + clear(); + ret = sscanf("Gabcdefghij", "%[abdr-v0-9A-F]%n", str, &n); + PRINT("#50 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("6abcdefghij", "%[abdr-v0-5A-F]%n", str, &n); + PRINT("#51 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("uabcdefghij", "%[abdr-v0-9A-F]%n", str, &n); + PRINT("#52 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "uab")==0 && n==3); + + clear(); + ret = sscanf("-abcdefghij", "%[abdr-v0-9A-F]%n", str, &n); + PRINT("#53 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("-abcdefghij", "%[abdr-v0-5A-F-]%n", str, &n); + PRINT("#54 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "-ab")==0 && n==3); + + clear(); + ret = sscanf("Gabcdefghij", "%[abdr-v0-9A-F-]%n", str, &n); + PRINT("#55 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("]abcdefghij", "%[abdr-v0-9A-F-]%n", str, &n); + PRINT("#56 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("]abcdefghij", "%3[]abdr-v0-9A-F-]%n", str, &n); + PRINT("#57 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "]ab")==0 && n==3); + + clear(); + ret = sscanf("Gabcdefghij", "%2[abdr-v0-9A-F-]%n", str, &n); + PRINT("#58 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("]abcdefghij", "%4[abdr-v0-9A-F-]%n", str, &n); + PRINT("#59 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("]abcdefghij", "%5[]a-z0-9A-Z-]%n", str, &n); + PRINT("#60 : rd 1[] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "]abcd")==0 && n==5); + + clear(); + ret = sscanf("abcdefghij", "%[^abdr-v0-9A-F]%n", str, &n); + PRINT("#61 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("bcdefghij", "%[^abdr-v0-9A-F]%n", str, &n); + PRINT("#62 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("1abcdefghij", "%[^abdr-v0-9A-F]%n", str, &n); + PRINT("#63 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("Gabcdefghij", "%[^abdr-v0-9A-F]%n", str, &n); + PRINT("#64 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "G")==0 && n==1); + + clear(); + ret = sscanf("6abcdefghij", "%[^abdr-v0-5A-F]%n", str, &n); + PRINT("#65 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "6")==0 && n==1); + + clear(); + ret = sscanf("uabcdefghij", "%[^abdr-v0-9A-F]%n", str, &n); + PRINT("#66 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("-abcdefghij", "%[^abdr-v0-9A-F]%n", str, &n); + PRINT("#67 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "-")==0 && n==1); + + clear(); + ret = sscanf("-abcdefghij", "%[^abdr-v0-5A-F-]%n", str, &n); + PRINT("#68 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("Gabcdefghij", "%[^abdr-v0-9A-F-]%n", str, &n); + PRINT("#69 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "G")==0 && n==1); + + clear(); + ret = sscanf("]GHIJabcdefghij", "%[^abdr-v0-9A-F-]%n", str, &n); + PRINT("#70 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "]GHIJ")==0 && n==5); + + clear(); + ret = sscanf("]abcdefghij", "%3[^]abdr-v0-9A-F-]%n", str, &n); + PRINT("#71 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + ret = sscanf("Gabcdefghij", "%2[^abdr-v0-9A-F-]%n", str, &n); + PRINT("#72 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "G")==0 && n==1); + + clear(); + ret = sscanf("]abcdefghij", "%4[^abdr-v0-9A-F-]%n", str, &n); + PRINT("#73 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==1 && strcmp(str, "]")==0 && n==1); + + clear(); + ret = sscanf("]abcdefghij", "%5[^]a-z0-9A-Z-]%n", str, &n); + PRINT("#74 : rd 1[^] : [%s] cn=%d rt=%d\n", str, n, ret); + ft_assert(t, ret==0 && strcmp(str, "........................")==0 + && n==-20); + + clear(); + char str3[50] = "................................................."; + ret = sscanf("Any combi: You can to use any combi.\n", + "%*[^:]%*2c%[^\n]%n", str3, &n); + PRINT("#75 : rd 1[^] : [%s] cn=%d rt=%d\n", str3, n, ret); + ft_assert(t, ret==1 && strcmp(str3, "You can to use any combi.")==0 + && n==36); + + clear(); + char str4[50] = "................................................."; + ret = sscanf(" This is a line with spaces.\n", + " %[^\n]%n", str4, &n); + PRINT("#76 : rd 1 [^] : [%s] cn=%d rt=%d\n", str4, n, ret); + ft_assert(t, ret==1 && strcmp(str4, "This is a line with spaces.")==0 + && n==33); + + /* Check that leading whitespace isn't counted in field width */ + clear(); + ret = sscanf(" 123456", "%4d%n", &si, &n); + PRINT("#77: \"%%4d%%n\": [%d] cn=%d rt=%d\n", si, n, ret); + ft_assert(t, ret==1 && si==1234 && n==6); + + /* Check that %d, %o, %x don't accept other bases */ + + /* Check that %f, etc. support size limits in the weirdest places */ +} + +ft_test ft_stdio_sscanf = { + .name = "scanf: All formats (string input)", + .function = _ft_stdio_sscanf, +};