2016-05-03 22:18:24 +00:00
|
|
|
// Generic utilities library.
|
|
|
|
//
|
|
|
|
// Contains data structures such as automatically growing array lists, priority queues, etc.
|
2016-05-18 22:30:21 +00:00
|
|
|
#include "config.h" // IWYU pragma: keep
|
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
#include <errno.h>
|
2005-09-20 13:26:39 +00:00
|
|
|
#include <stdlib.h>
|
2016-05-03 22:18:24 +00:00
|
|
|
#include <sys/time.h>
|
2005-09-20 13:26:39 +00:00
|
|
|
#include <wchar.h>
|
|
|
|
#include <wctype.h>
|
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
#include "common.h"
|
2016-04-21 06:00:54 +00:00
|
|
|
#include "fallback.h" // IWYU pragma: keep
|
2005-09-20 13:26:39 +00:00
|
|
|
#include "util.h"
|
2016-04-21 06:00:54 +00:00
|
|
|
#include "wutil.h" // IWYU pragma: keep
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
int wcsfilecmp(const wchar_t *a, const wchar_t *b) {
|
2012-11-19 00:30:30 +00:00
|
|
|
CHECK(a, 0);
|
|
|
|
CHECK(b, 0);
|
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
if (*a == 0) {
|
|
|
|
if (*b == 0) return 0;
|
2012-11-19 00:30:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2016-05-03 22:18:24 +00:00
|
|
|
if (*b == 0) {
|
2012-11-19 00:30:30 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
long secondary_diff = 0;
|
|
|
|
if (iswdigit(*a) && iswdigit(*b)) {
|
2016-11-23 04:24:03 +00:00
|
|
|
const wchar_t *aend, *bend;
|
2012-11-19 00:30:30 +00:00
|
|
|
long al;
|
|
|
|
long bl;
|
|
|
|
long diff;
|
|
|
|
|
2016-11-23 04:24:03 +00:00
|
|
|
al = fish_wcstol(a, &aend);
|
|
|
|
int a1_errno = errno;
|
|
|
|
bl = fish_wcstol(b, &bend);
|
|
|
|
if (a1_errno || errno) {
|
2016-05-03 22:18:24 +00:00
|
|
|
// Huge numbers - fall back to regular string comparison.
|
2012-11-19 00:30:30 +00:00
|
|
|
return wcscmp(a, b);
|
|
|
|
}
|
|
|
|
|
|
|
|
diff = al - bl;
|
2016-05-03 22:18:24 +00:00
|
|
|
if (diff) return diff > 0 ? 2 : -2;
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
secondary_diff = (aend - a) - (bend - b);
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2016-10-21 01:53:31 +00:00
|
|
|
a = aend - 1; //!OCLINT(parameter reassignment)
|
|
|
|
b = bend - 1; //!OCLINT(parameter reassignment)
|
2016-05-03 22:18:24 +00:00
|
|
|
} else {
|
2012-11-19 00:30:30 +00:00
|
|
|
int diff = towlower(*a) - towlower(*b);
|
2016-05-04 22:19:47 +00:00
|
|
|
if (diff != 0) return diff > 0 ? 2 : -2;
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
secondary_diff = *a - *b;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
int res = wcsfilecmp(a + 1, b + 1);
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-10-22 18:21:13 +00:00
|
|
|
// If no primary difference in rest of string use secondary difference on this element if
|
|
|
|
// found.
|
|
|
|
if (abs(res) < 2 && secondary_diff) {
|
|
|
|
return secondary_diff > 0 ? 1 : -1;
|
2012-11-18 10:23:22 +00:00
|
|
|
}
|
|
|
|
|
2012-11-19 00:30:30 +00:00
|
|
|
return res;
|
2005-09-20 13:26:39 +00:00
|
|
|
}
|
|
|
|
|
2016-05-03 22:18:24 +00:00
|
|
|
long long get_time() {
|
2012-11-19 00:30:30 +00:00
|
|
|
struct timeval time_struct;
|
|
|
|
gettimeofday(&time_struct, 0);
|
2016-05-03 22:18:24 +00:00
|
|
|
return 1000000ll * time_struct.tv_sec + time_struct.tv_usec;
|
2005-09-20 13:26:39 +00:00
|
|
|
}
|