mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-28 22:03:12 +00:00
a928517e95
The existing code is inconsistent, and in a couple of cases wrong, about dealing with strings that are not valid ints. For example, there are locations that call wcstol() and check errno without first setting errno to zero. Normalize the code to a consistent pattern. This is mostly to deal with inconsistencies between BSD, GNU, and other UNIXes. This does make some syntax more liberal. For example `echo $PATH[1 .. 3]` is now valid due to uniformly allowing leading and trailing whitespace around numbers. Whereas prior to this change you would get a "Invalid index value" error. Contrast this with `echo $PATH[ 1.. 3 ]` which was valid and still is.
73 lines
1.8 KiB
C++
73 lines
1.8 KiB
C++
// 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)) {
|
|
const wchar_t *aend, *bend;
|
|
long al;
|
|
long bl;
|
|
long diff;
|
|
|
|
al = fish_wcstol(a, &aend);
|
|
int a1_errno = errno;
|
|
bl = fish_wcstol(b, &bend);
|
|
if (a1_errno || 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; //!OCLINT(parameter reassignment)
|
|
b = bend - 1; //!OCLINT(parameter reassignment)
|
|
} 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 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;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
long long get_time() {
|
|
struct timeval time_struct;
|
|
gettimeofday(&time_struct, 0);
|
|
return 1000000ll * time_struct.tv_sec + time_struct.tv_usec;
|
|
}
|