aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/util.cpp
blob: f13334807d546ed2f6b601ce0ec09ecbccd4ee89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Generic utilities library.
//
// Contains data structures such as automatically growing array lists, priority queues, etc.
#include "config.h"  // IWYU pragma: keep

#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
#include <wchar.h>
#include <wctype.h>

#include "common.h"
#include "fallback.h"  // IWYU pragma: keep
#include "util.h"
#include "wutil.h"  // IWYU pragma: keep

int wcsfilecmp(const wchar_t *a, const wchar_t *b) {
    CHECK(a, 0);
    CHECK(b, 0);

    if (*a == 0) {
        if (*b == 0) return 0;
        return -1;
    }
    if (*b == 0) {
        return 1;
    }

    long secondary_diff = 0;
    if (iswdigit(*a) && iswdigit(*b)) {
        wchar_t *aend, *bend;
        long al;
        long bl;
        long diff;

        errno = 0;
        al = wcstol(a, &aend, 10);
        bl = wcstol(b, &bend, 10);

        if (errno) {
            // Huge numbers - fall back to regular string comparison.
            return wcscmp(a, b);
        }

        diff = al - bl;
        if (diff) return diff > 0 ? 2 : -2;

        secondary_diff = (aend - a) - (bend - b);

        a = aend - 1;
        b = bend - 1;
    } else {
        int diff = towlower(*a) - towlower(*b);
        if (diff != 0) return diff > 0 ? 2 : -2;

        secondary_diff = *a - *b;
    }

    int res = wcsfilecmp(a + 1, b + 1);

    if (abs(res) < 2) {
        // No primary difference in rest of string. Use secondary difference on this element if
        // found.
        if (secondary_diff) {
            return secondary_diff > 0 ? 1 : -1;
        }
    }

    return res;
}

long long get_time() {
    struct timeval time_struct;
    gettimeofday(&time_struct, 0);
    return 1000000ll * time_struct.tv_sec + time_struct.tv_usec;
}