Merge changes I946cde38,I4b8e0ea1,I2e8141a8
* changes:
Mark LIBC_O as being a future version.
Mark LIBC_N as being introduced in android-24.
Annotate the libc version map with NDK info.
diff --git a/libc/Android.bp b/libc/Android.bp
index 36dfbc8..4776f90 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -154,7 +154,8 @@
"-DTM_GMTOFF=tm_gmtoff",
// Where we store our tzdata.
"-DTZDIR=\\\"/system/usr/share/zoneinfo\\\"",
- // Include timezone and daylight globals.
+ // Include `tzname`, `timezone`, and `daylight` globals.
+ "-DHAVE_POSIX_DECLS=0",
"-DUSG_COMPAT=1",
// Use the empty string (instead of " ") as the timezone abbreviation
// fallback.
diff --git a/libc/bionic/locale.cpp b/libc/bionic/locale.cpp
index f26a5f2..2a4ce68 100644
--- a/libc/bionic/locale.cpp
+++ b/libc/bionic/locale.cpp
@@ -192,10 +192,6 @@
return strerror(error);
}
-size_t strftime_l(char* s, size_t max, const char* format, const struct tm* tm, locale_t) {
- return strftime(s, max, format, tm);
-}
-
int strncasecmp_l(const char* s1, const char* s2, size_t n, locale_t) {
return strncasecmp(s1, s2, n);
}
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 165dd2d..0861015 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -178,11 +178,6 @@
static char lcl_TZname[TZ_STRLEN_MAX + 1];
static int lcl_is_set;
-char * tzname[2] = {
- (char *) wildabbr,
- (char *) wildabbr
-};
-
/*
** Section 4.12.3 of X3.159-1989 requires that
** Except for the strftime function, these functions [asctime,
@@ -193,10 +188,16 @@
static struct tm tm;
+#if !HAVE_POSIX_DECLS
+char * tzname[2] = {
+ (char *) wildabbr,
+ (char *) wildabbr
+};
#ifdef USG_COMPAT
long timezone;
int daylight;
-#endif /* defined USG_COMPAT */
+# endif
+#endif
#ifdef ALTZONE
long altzone;
diff --git a/libc/tzcode/private.h b/libc/tzcode/private.h
index 1c176e6..941e91b 100644
--- a/libc/tzcode/private.h
+++ b/libc/tzcode/private.h
@@ -22,6 +22,10 @@
** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
*/
+#ifndef HAVE_DECL_ASCTIME_R
+#define HAVE_DECL_ASCTIME_R 1
+#endif
+
#ifndef HAVE_GETTEXT
#define HAVE_GETTEXT 0
#endif /* !defined HAVE_GETTEXT */
@@ -34,6 +38,10 @@
#define HAVE_LINK 1
#endif /* !defined HAVE_LINK */
+#ifndef HAVE_POSIX_DECLS
+#define HAVE_POSIX_DECLS 1
+#endif
+
#ifndef HAVE_STRDUP
#define HAVE_STRDUP 1
#endif
@@ -106,6 +114,9 @@
#ifndef ENAMETOOLONG
# define ENAMETOOLONG EINVAL
#endif
+#ifndef ENOTSUP
+# define ENOTSUP EINVAL
+#endif
#ifndef EOVERFLOW
# define EOVERFLOW EINVAL
#endif
@@ -379,25 +390,21 @@
void tzset(void);
#endif
-/*
-** Some time.h implementations don't declare asctime_r.
-** Others might define it as a macro.
-** Fix the former without affecting the latter.
-** Similarly for timezone, daylight, and altzone.
-*/
-
-#ifndef asctime_r
-extern char * asctime_r(struct tm const *restrict, char *restrict);
+#if !HAVE_DECL_ASCTIME_R && !defined asctime_r
+extern char *asctime_r(struct tm const *restrict, char *restrict);
#endif
-#ifdef USG_COMPAT
-# ifndef timezone
+#if !HAVE_POSIX_DECLS
+# ifdef USG_COMPAT
+# ifndef timezone
extern long timezone;
-# endif
-# ifndef daylight
+# endif
+# ifndef daylight
extern int daylight;
+# endif
# endif
#endif
+
#if defined ALTZONE && !defined altzone
extern long altzone;
#endif
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index 4349cf6..b1e0d1c 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -1,29 +1,40 @@
+/* Convert a broken-down time stamp to a string. */
+
+/* Copyright 1989 The Regents of the University of California.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */
+
/*
-** Based on the UCB version with the copyright notice and sccsid
-** appearing below.
+** Based on the UCB version with the copyright notice appearing above.
**
** This is ANSIish only when "multibyte character == plain character".
*/
#include "private.h"
-/*
-** Copyright (c) 1989 The Regents of the University of California.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms are permitted
-** provided that the above copyright notice and this paragraph are
-** duplicated in all such forms and that any documentation,
-** advertising materials, and other materials related to such
-** distribution and use acknowledge that the software was developed
-** by the University of California, Berkeley. The name of the
-** University may not be used to endorse or promote products derived
-** from this software without specific prior written permission.
-** THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-*/
-
#include "tzfile.h"
#include "fcntl.h"
#include "locale.h"
@@ -108,9 +119,10 @@
static char * _fmt(const char *, const struct tm *, char *, const char *,
int *);
static char * _yconv(int, int, bool, bool, char *, const char *, int);
-static char * getformat(int, char *, char *, char *, char *);
+#if !HAVE_POSIX_DECLS
extern char * tzname[];
+#endif
#ifndef YEAR_2000_NAME
#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
@@ -121,7 +133,17 @@
#define IN_THIS 2
#define IN_ALL 3
-#define FORCE_LOWER_CASE 0x100
+#if HAVE_STRFTIME_L
+size_t
+strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
+ locale_t locale)
+{
+ /* Just call strftime, as only the C locale is supported. */
+ return strftime(s, maxsize, format, t);
+}
+#endif
+
+#define FORCE_LOWER_CASE 0x100 /* Android extension. */
size_t
strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
diff --git a/linker/linker_allocator.cpp b/linker/linker_allocator.cpp
index 7deddea..dc6dfc1 100644
--- a/linker/linker_allocator.cpp
+++ b/linker/linker_allocator.cpp
@@ -70,8 +70,8 @@
return result;
}
-LinkerSmallObjectAllocator::LinkerSmallObjectAllocator()
- : type_(0), block_size_(0), free_pages_cnt_(0), free_blocks_list_(nullptr) {}
+LinkerSmallObjectAllocator::LinkerSmallObjectAllocator(uint32_t type, size_t block_size)
+ : type_(type), block_size_(block_size), free_pages_cnt_(0), free_blocks_list_(nullptr) {}
void* LinkerSmallObjectAllocator::alloc() {
CHECK(block_size_ != 0);
@@ -159,11 +159,6 @@
}
}
-void LinkerSmallObjectAllocator::init(uint32_t type, size_t block_size) {
- type_ = type;
- block_size_ = block_size;
-}
-
linker_vector_t::iterator LinkerSmallObjectAllocator::find_page_record(void* ptr) {
void* addr = reinterpret_cast<void*>(PAGE_START(reinterpret_cast<uintptr_t>(ptr)));
small_object_page_record boundary;
@@ -221,11 +216,20 @@
}
-LinkerMemoryAllocator::LinkerMemoryAllocator() {
+void LinkerMemoryAllocator::initialize_allocators() {
+ if (allocators_ != nullptr) {
+ return;
+ }
+
+ LinkerSmallObjectAllocator* allocators =
+ reinterpret_cast<LinkerSmallObjectAllocator*>(allocators_buf_);
+
for (size_t i = 0; i < kSmallObjectAllocatorsCount; ++i) {
uint32_t type = i + kSmallObjectMinSizeLog2;
- allocators_[i].init(type, 1 << type);
+ new (allocators + i) LinkerSmallObjectAllocator(type, 1 << type);
}
+
+ allocators_ = allocators;
}
void* LinkerMemoryAllocator::alloc_mmap(size_t size) {
@@ -336,5 +340,6 @@
__libc_fatal("invalid type: %u", type);
}
+ initialize_allocators();
return &allocators_[type - kSmallObjectMinSizeLog2];
}
diff --git a/linker/linker_allocator.h b/linker/linker_allocator.h
index 22a337a..8f90dbf 100644
--- a/linker/linker_allocator.h
+++ b/linker/linker_allocator.h
@@ -100,8 +100,7 @@
class LinkerSmallObjectAllocator {
public:
- LinkerSmallObjectAllocator();
- void init(uint32_t type, size_t block_size);
+ LinkerSmallObjectAllocator(uint32_t type, size_t block_size);
void* alloc();
void free(void* ptr);
@@ -124,7 +123,7 @@
class LinkerMemoryAllocator {
public:
- LinkerMemoryAllocator();
+ constexpr LinkerMemoryAllocator() : allocators_(nullptr), allocators_buf_() {}
void* alloc(size_t size);
// Note that this implementation of realloc never shrinks allocation
@@ -134,8 +133,10 @@
void* alloc_mmap(size_t size);
page_info* get_page_info(void* ptr);
LinkerSmallObjectAllocator* get_small_object_allocator(uint32_t type);
+ void initialize_allocators();
- LinkerSmallObjectAllocator allocators_[kSmallObjectAllocatorsCount];
+ LinkerSmallObjectAllocator* allocators_;
+ uint8_t allocators_buf_[sizeof(LinkerSmallObjectAllocator)*kSmallObjectAllocatorsCount];
};
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 10399c5..028a359 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -176,6 +176,27 @@
#endif
}
+TEST(time, strftime_l) {
+ locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0);
+ locale_t old_locale = uselocale(cloc);
+
+ setenv("TZ", "UTC", 1);
+
+ struct tm t;
+ memset(&t, 0, sizeof(tm));
+ t.tm_year = 200;
+ t.tm_mon = 2;
+ t.tm_mday = 10;
+
+ // Date and time as text.
+ char buf[64];
+ EXPECT_EQ(24U, strftime_l(buf, sizeof(buf), "%c", &t, cloc));
+ EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
+
+ uselocale(old_locale);
+ freelocale(cloc);
+}
+
TEST(time, strptime) {
setenv("TZ", "UTC", 1);