Loading...
#include <darwintest.h>
#include <darwintest_utils.h>

#include "libc_hooks_helper.h"
#include <xlocale.h>

T_DECL(libc_hooks_sscanf_l, "Test libc_hooks for sscanf_l")
{
    // Setup
    T_SETUPBEGIN;
    locale_t loc = duplocale(NULL);
    T_SETUPEND;

    // Signed integers (All lengths)
    int             d;
    signed char   hhd;
    short int      hd;
    long int       ld;
    long long int lld;
    intmax_t       jd;
    size_t         zd;
    ptrdiff_t      td;

    // Test
    char data_d[] = "42, 42, 42, 42, 42, 42, 42, 42";
    char fmt_d[] = "%d, %hhd, %hd, %ld, %lld, %jd, %zd, %td";
    libc_hooks_log_start();
    sscanf_l(data_d, loc, fmt_d, &d, &hhd, &hd, &ld, &lld, &jd, &zd, &td);
    libc_hooks_log_stop(11);

    // Check
    T_LOG("sscanf(\"%s\", loc, \"%s\", &d, &hhd, &hd, &ld, &lld, &jd, &zd, &td) - %s", data_d, fmt_d);
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, data_d, strlen(data_d) + 1), "checking data_d");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, loc, SIZE_LOCALE_T), "checking loc");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_d, strlen(fmt_d) + 1), "checking fmt_d");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &d, sizeof(d)), "checking d");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &hhd, sizeof(hhd)), "checking hhd");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &hd, sizeof(hd)), "checking hd");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &ld, sizeof(ld)), "checking ld");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &lld, sizeof(lld)), "checking lld");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &jd, sizeof(jd)), "checking jd");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &zd, sizeof(zd)), "checking zd");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &td, sizeof(td)), "checking td");

    // Unsigned integers (All lengths)
    int             u;
    signed char   hhu;
    short int      hu;
    long int       lu;
    long long int llu;
    intmax_t       ju;
    size_t         zu;
    ptrdiff_t      tu;

    // Test
    char data_u[] = "42, 42, 42, 42, 42, 42, 42, 42";
    char fmt_u[] = "%u, %hhu, %hu, %lu, %llu, %ju, %zu, %tu";
    libc_hooks_log_start();
    sscanf_l(data_u, loc, fmt_u, &u, &hhu, &hu, &lu, &llu, &ju, &zu, &tu);
    libc_hooks_log_stop(11);

    // Check
    T_LOG("sscanf_l(\"%s\", loc, \"%s\", &u, &hhu, &hu, &lu, &llu, &ju, &zu, &tu)", data_u, fmt_u);
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, data_u, strlen(data_u) + 1), "checking data_u");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, loc, SIZE_LOCALE_T), "checking loc");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_u, strlen(fmt_u) + 1), "checking fmt_u");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &u, sizeof(u)), "checking u");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &hhu, sizeof(hhu)), "checking hhu");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &hu, sizeof(hu)), "checking hu");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &lu, sizeof(lu)), "checking lu");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &llu, sizeof(llu)), "checking llu");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &ju, sizeof(ju)), "checking ju");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &zu, sizeof(zu)), "checking zu");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &tu, sizeof(tu)), "checking tu");

    // Floats (all lengths)
    float f;
    double lf;
    long double Lf;

    // Test
    char data_f[] = "42.0, 42.0, 42.0";
    char fmt_f[] = "%f, %lf, %Lf";
    libc_hooks_log_start();
    sscanf_l(data_f, loc, fmt_f, &f, &lf, &Lf);
    libc_hooks_log_stop(6);

    // Check
    T_LOG("sscanf_l(\"%s\", loc, \"%s\", &f, &lf, &Lf)", data_f, fmt_f);
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, data_f, strlen(data_f) + 1), "checking data_f");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, loc, SIZE_LOCALE_T), "checking loc");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_f, strlen(fmt_f) + 1), "checking fmt_f");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &f, sizeof(f)), "checking f");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &lf, sizeof(lf)), "checking lf");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &Lf, sizeof(Lf)), "checking Lf");

    // Characters and Strings
    char c;
    char s[256];

    // Test
    char data_cs[] = "C, forty_two";
    char fmt_cs[] = "%c, %s";
    libc_hooks_log_start();
    sscanf_l(data_cs, loc, fmt_cs, &c, &s);
    libc_hooks_log_stop(5);

    // Check
    T_LOG("sscanf_l(\"%s\", loc, \"%s\", &c, &s)", data_cs, fmt_cs);
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, data_cs, strlen(data_cs) + 1), "checking data_cs");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, loc, SIZE_LOCALE_T), "checking loc");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_cs, strlen(fmt_cs) + 1), "checking fmt_cs");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &c, sizeof(c)), "checking c");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, &s, strlen(s) + 1), "checking s");

    // Wide characters and Strings
    wint_t lc;
    wint_t ls[256];

    char fmt_wcs[] = "%lc, %ls";
    char data_wcs[] = "É, ÉÉÉ";
    libc_hooks_log_start();
    sscanf_l(data_wcs, loc, fmt_wcs, &lc, &ls);
    libc_hooks_log_stop(3);

    // Check
    T_LOG("sscanf_l(\"%s\", loc, \"%s\", &lc, &ls) - %s", data_wcs, fmt_wcs);

    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, data_wcs, strlen(data_wcs) + 1), "checking data_wcs");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, loc, SIZE_LOCALE_T), "checking loc");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_wcs, strlen(fmt_wcs) + 1), "checking fmt_wcs");
#if 0 // TBD: Wide characters and strings
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &lc, sizeof(lc)), "checking lc");
    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, &ls, wcslen(ls) + 1), "checking ls");
#endif
}