Merge "Speed up __sfileext initialization."
diff --git a/libc/bionic/strtol.cpp b/libc/bionic/strtol.cpp
index f83a317..f4c8c5f 100644
--- a/libc/bionic/strtol.cpp
+++ b/libc/bionic/strtol.cpp
@@ -27,12 +27,13 @@
* SUCH DAMAGE.
*/
-#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
+#include <private/bionic_ctype.h>
+
template <typename T, T Min, T Max> T StrToI(const char* nptr, char** endptr, int base) {
// Ensure that base is between 2 and 36 inclusive, or the special value of 0.
if (base < 0 || base == 1 || base > 36) {
@@ -47,8 +48,8 @@
const char* s = nptr;
int c;
do {
- c = static_cast<unsigned char>(*s++);
- } while (isspace(c));
+ c = *s++;
+ } while (IsSpace(c));
int neg;
if (c == '-') {
neg = 1;
@@ -58,7 +59,7 @@
if (c == '+') c = *s++;
}
if ((base == 0 || base == 16) && c == '0' &&
- (*s == 'x' || *s == 'X') && isxdigit(static_cast<unsigned char>(s[1]))) {
+ (*s == 'x' || *s == 'X') && IsXDigit(s[1])) {
c = s[1];
s += 2;
base = 16;
@@ -92,11 +93,11 @@
// Set `any` if any digits consumed; make it negative to indicate overflow.
int any = 0;
T acc = 0;
- for (; ; c = static_cast<unsigned char>(*s++)) {
- if (isdigit(c)) {
+ for (; ; c = *s++) {
+ if (IsDigit(c)) {
c -= '0';
- } else if (isalpha(c)) {
- c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ } else if (IsAlpha(c)) {
+ c -= IsUpper(c) ? 'A' - 10 : 'a' - 10;
} else {
break;
}
@@ -138,8 +139,8 @@
const char* s = nptr;
int c;
do {
- c = static_cast<unsigned char>(*s++);
- } while (isspace(c));
+ c = *s++;
+ } while (IsSpace(c));
int neg;
if (c == '-') {
neg = 1;
@@ -149,7 +150,7 @@
if (c == '+') c = *s++;
}
if ((base == 0 || base == 16) && c == '0' &&
- (*s == 'x' || *s == 'X') && isxdigit(static_cast<unsigned char>(s[1]))) {
+ (*s == 'x' || *s == 'X') && IsXDigit(s[1])) {
c = s[1];
s += 2;
base = 16;
@@ -160,11 +161,11 @@
int cutlim = Max % static_cast<T>(base);
T acc = 0;
int any = 0;
- for (; ; c = static_cast<unsigned char>(*s++)) {
- if (isdigit(c)) {
+ for (; ; c = *s++) {
+ if (IsDigit(c)) {
c -= '0';
- } else if (isalpha(c)) {
- c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ } else if (IsAlpha(c)) {
+ c -= IsUpper(c) ? 'A' - 10 : 'a' - 10;
} else {
break;
}
diff --git a/libc/private/bionic_ctype.h b/libc/private/bionic_ctype.h
new file mode 100644
index 0000000..96df974
--- /dev/null
+++ b/libc/private/bionic_ctype.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __BIONIC_PRIVATE_BIONIC_CTYPE_H_
+#define __BIONIC_PRIVATE_BIONIC_CTYPE_H_
+
+static inline bool IsAlpha(int ch) {
+ return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
+}
+
+static inline bool IsDigit(int ch) {
+ return (ch >= '0' && ch <= '9');
+}
+
+static inline bool IsSpace(int ch) {
+ return (ch == ' ') || (ch >= '\t' && ch <= '\r');
+}
+
+static inline bool IsUpper(int ch) {
+ return (ch >= 'A' && ch <= 'Z');
+}
+
+static inline bool IsXDigit(int ch) {
+ return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
+}
+
+#endif
diff --git a/libc/stdio/vfscanf.c b/libc/stdio/vfscanf.c
index c9e4385..f0ed4ae 100644
--- a/libc/stdio/vfscanf.c
+++ b/libc/stdio/vfscanf.c
@@ -31,7 +31,6 @@
* SUCH DAMAGE.
*/
-#include <ctype.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stddef.h>
@@ -41,6 +40,8 @@
#include <wctype.h>
#include "local.h"
+#include <private/bionic_ctype.h>
+
#define BUF 513 /* Maximum length of numeric string. */
/*
@@ -116,8 +117,8 @@
for (;;) {
c = *fmt++;
if (c == 0) return (nassigned);
- if (isspace(c)) {
- while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p)) nread++, fp->_r--, fp->_p++;
+ if (IsSpace(c)) {
+ while ((fp->_r > 0 || __srefill(fp) == 0) && IsSpace(*fp->_p)) nread++, fp->_r--, fp->_p++;
continue;
}
if (c != '%') goto literal;
@@ -127,11 +128,11 @@
* switch on the format. continue if done;
* break once format type is derived.
*/
- again:
+again:
c = *fmt++;
switch (c) {
case '%':
- literal:
+literal:
if (fp->_r <= 0 && __srefill(fp)) goto input_failure;
if (*fp->_p != c) goto match_failure;
fp->_r--, fp->_p++;
@@ -286,7 +287,7 @@
return (EOF);
default: /* compat */
- if (isupper(c)) flags |= LONG;
+ if (IsUpper(c)) flags |= LONG;
c = CT_INT;
base = 10;
break;
@@ -302,12 +303,13 @@
* that suppress this.
*/
if ((flags & NOSKIP) == 0) {
- while (isspace(*fp->_p)) {
+ while (IsSpace(*fp->_p)) {
nread++;
- if (--fp->_r > 0)
+ if (--fp->_r > 0) {
fp->_p++;
- else if (__srefill(fp))
+ } else if (__srefill(fp)) {
goto input_failure;
+ }
}
/*
* Note that there is at least one character in
@@ -395,7 +397,7 @@
wcp = (flags & SUPPRESS) == 0 ? va_arg(ap, wchar_t*) : &twc;
n = 0;
- while ((c == CT_CCL || !isspace(*fp->_p)) && width != 0) {
+ while ((c == CT_CCL || !IsSpace(*fp->_p)) && width != 0) {
if (n == (int)MB_CUR_MAX) {
fp->_flags |= __SERR;
goto input_failure;
@@ -439,7 +441,7 @@
n = nchars;
} else if (flags & SUPPRESS) {
n = 0;
- while ((c == CT_CCL && ccltab[*fp->_p]) || (c == CT_STRING && !isspace(*fp->_p))) {
+ while ((c == CT_CCL && ccltab[*fp->_p]) || (c == CT_STRING && !IsSpace(*fp->_p))) {
n++, fp->_r--, fp->_p++;
if (--width == 0) break;
if (fp->_r <= 0 && __srefill(fp)) {
@@ -449,7 +451,7 @@
}
} else {
p0 = p = va_arg(ap, char*);
- while ((c == CT_CCL && ccltab[*fp->_p]) || (c == CT_STRING && !isspace(*fp->_p))) {
+ while ((c == CT_CCL && ccltab[*fp->_p]) || (c == CT_STRING && !IsSpace(*fp->_p))) {
fp->_r--;
*p++ = *fp->_p++;
if (--width == 0) break;
diff --git a/tests/dlfcn_symlink_support.cpp b/tests/dlfcn_symlink_support.cpp
index be1839e..a5d3c3e 100644
--- a/tests/dlfcn_symlink_support.cpp
+++ b/tests/dlfcn_symlink_support.cpp
@@ -44,7 +44,7 @@
return 0;
}
- if (android::base::EndsWith(info->dlpi_name, suffix.c_str())) {
+ if (android::base::EndsWith(info->dlpi_name, suffix)) {
std::string* path = reinterpret_cast<std::string*>(data);
*path = info->dlpi_name;
return 1; // found
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 7a96760..fccff67 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -31,6 +31,31 @@
#include "private/bionic_constants.h"
+TEST(time, time) {
+ // Acquire time
+ time_t p1, t1 = time(&p1);
+ // valid?
+ ASSERT_NE(static_cast<time_t>(0), t1);
+ ASSERT_NE(static_cast<time_t>(-1), t1);
+ ASSERT_EQ(p1, t1);
+
+ // Acquire time one+ second later
+ usleep(1010000);
+ time_t p2, t2 = time(&p2);
+ // valid?
+ ASSERT_NE(static_cast<time_t>(0), t2);
+ ASSERT_NE(static_cast<time_t>(-1), t2);
+ ASSERT_EQ(p2, t2);
+
+ // Expect time progression
+ ASSERT_LT(p1, p2);
+ ASSERT_LE(t2 - t1, static_cast<time_t>(2));
+
+ // Expect nullptr call to produce same results
+ ASSERT_LE(t2, time(nullptr));
+ ASSERT_LE(time(nullptr) - t2, static_cast<time_t>(1));
+}
+
TEST(time, gmtime) {
time_t t = 0;
tm* broken_down = gmtime(&t);