Skip to content
StrCmpIgnoreCase

StrCmpIgnoreCase

Description

Case-insensitive (ASCII) comparison of a Str against another string. Non-ASCII bytes are compared verbatim; there is no Unicode case folding.

Three call shapes via OVERLOAD + _Generic on other: StrCmpIgnoreCase(s, other)other is Str * or Zstr. StrCmpIgnoreCase(s, other, other_len)other is a fixed-length view (Zstr, size).

Parameters

Name Direction Description
s in Str to compare.
other in Other string (Str * / Zstr).
other_len in Length of other for the 3-arg fixed-length form.

Success

Returns 0 when equal, <0 when s < other, >0 when s > other (ASCII case-folded). Neither string is modified.

Failure

Function cannot fail; the return value carries the order.

Usage example (Cross-references)

Usage examples (Cross-references)
        ValidateStr(value);
    
        if (StrCmpIgnoreCase(value, "true") == 0 || StrCmpIgnoreCase(value, "yes") == 0 ||
            StrCmpIgnoreCase(value, "on") == 0 || StrCmpIgnoreCase(value, "1") == 0) {
            *out = true;
    
        if (StrCmpIgnoreCase(value, "true") == 0 || StrCmpIgnoreCase(value, "yes") == 0 ||
            StrCmpIgnoreCase(value, "on") == 0 || StrCmpIgnoreCase(value, "1") == 0) {
            *out = true;
            return true;
        }
    
        if (StrCmpIgnoreCase(value, "false") == 0 || StrCmpIgnoreCase(value, "no") == 0 ||
            StrCmpIgnoreCase(value, "off") == 0 || StrCmpIgnoreCase(value, "0") == 0) {
            *out = false;
    
        if (StrCmpIgnoreCase(value, "false") == 0 || StrCmpIgnoreCase(value, "no") == 0 ||
            StrCmpIgnoreCase(value, "off") == 0 || StrCmpIgnoreCase(value, "0") == 0) {
            *out = false;
            return true;
    
        // Equal under ASCII case folding.
        bool ok = StrCmpIgnoreCase(&hello_lc, &hello_uc) == 0;
        ok      = ok && StrCmpIgnoreCase(&hello_lc, &hello_mc) == 0;
        // Equal under ASCII case folding.
        bool ok = StrCmpIgnoreCase(&hello_lc, &hello_uc) == 0;
        ok      = ok && StrCmpIgnoreCase(&hello_lc, &hello_mc) == 0;
    
        // 'h' lowers to 'h' (0x68), 'w' to 'w' (0x77); negative.
    
        // 'h' lowers to 'h' (0x68), 'w' to 'w' (0x77); negative.
        ok = ok && StrCmpIgnoreCase(&hello_lc, &world) < 0;
        // Reverse direction.
        ok = ok && StrCmpIgnoreCase(&world, &hello_uc) > 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, &world) < 0;
        // Reverse direction.
        ok = ok && StrCmpIgnoreCase(&world, &hello_uc) > 0;
    
        // Length mismatch: hello < hellox under case-insensitive compare.
    
        // Length mismatch: hello < hellox under case-insensitive compare.
        ok = ok && StrCmpIgnoreCase(&hello_lc, &hello_x) < 0;
    
        // Cstr / Zstr variants share the same underlying helper.
    
        // Cstr / Zstr variants share the same underlying helper.
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HELLO") == 0;
        ok = ok && StrCmpIgnoreCase(&hello_uc, "world") < 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HELLO_extra", 5) == 0;
        // Cstr / Zstr variants share the same underlying helper.
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HELLO") == 0;
        ok = ok && StrCmpIgnoreCase(&hello_uc, "world") < 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HELLO_extra", 5) == 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HellX", 5) != 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HELLO") == 0;
        ok = ok && StrCmpIgnoreCase(&hello_uc, "world") < 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HELLO_extra", 5) == 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HellX", 5) != 0;
        ok = ok && StrCmpIgnoreCase(&hello_uc, "world") < 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HELLO_extra", 5) == 0;
        ok = ok && StrCmpIgnoreCase(&hello_lc, "HellX", 5) != 0;
    
        // Non-ASCII bytes pass through verbatim (no Unicode folding).
        Str non_ascii_a = StrInitFromZstr("ABC\xC0", &alloc);
        Str non_ascii_b = StrInitFromZstr("abc\xC0", &alloc);
        ok              = ok && StrCmpIgnoreCase(&non_ascii_a, &non_ascii_b) == 0;
    
        StrDeinit(&hello_lc);
    // a corrupt-magic Str must abort (Str.Mutants6).
    static bool test_cmp_zstr_ignore_case_corrupt_magic_aborts(void) {
        WriteFmt("Testing StrCmpIgnoreCase aborts on corrupt magic\n");
        DefaultAllocator alloc = DefaultAllocatorInit();
        Str s                     = StrInitFromZstr("hello", &alloc);
        GENERIC_VEC(&s)->__magic ^= 0x1;
        (void)StrCmpIgnoreCase(&s, "HELLO");
    
        GENERIC_VEC(&s)->__magic ^= 0x1;
    // must abort (Str.Mutants7).
    static bool test_cmp_cstr_ignore_case_validates(void) {
        WriteFmt("Testing StrCmpIgnoreCase (Cstr form) validates its Str (deadend)\n");
        DefaultAllocator alloc = DefaultAllocatorInit();
        Str s     = StrInitFromZstr("Hello", &alloc);
        s.__magic = 0;
        int cmp   = StrCmpIgnoreCase(&s, "x", 1);
        (void)cmp;
        s.__magic = 0;
    
        (void)StrCmpIgnoreCase(&s, &other);
    
        StrDeinit(&other);
        other.__magic = 0;
    
        (void)StrCmpIgnoreCase(&s, &other);
    
        StrDeinit(&s);
Last updated on