diff options
| author | 2013-05-08 07:35:34 +0000 | |
|---|---|---|
| committer | 2013-05-08 07:35:34 +0000 | |
| commit | 3b9831f6a2f991fb492d052cc07817db402f2340 (patch) | |
| tree | 4346272d6d6258b06f9430bdcace0510176a8488 | |
| parent | 60e510af804b5b583d835a0f1f1e676d08b812bc (diff) | |
| parent | 823abb63145c7a7db2b766cf7bb816cbdac1de66 (diff) | |
Merge "aapt: move qsort_r_compat here as it is sole client"
| -rw-r--r-- | tools/aapt/Android.mk | 3 | ||||
| -rw-r--r-- | tools/aapt/StringPool.cpp | 2 | ||||
| -rw-r--r-- | tools/aapt/qsort_r_compat.c | 90 | ||||
| -rw-r--r-- | tools/aapt/qsort_r_compat.h | 39 |
4 files changed, 132 insertions, 2 deletions
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk index 635f19b33dba..61180a0e634f 100644 --- a/tools/aapt/Android.mk +++ b/tools/aapt/Android.mk @@ -26,7 +26,8 @@ aapt_src_files := \ SourcePos.cpp \ WorkQueue.cpp \ ZipEntry.cpp \ - ZipFile.cpp + ZipFile.cpp \ + qsort_r_compat.c LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp index 839eda5151b0..158b39196cb3 100644 --- a/tools/aapt/StringPool.cpp +++ b/tools/aapt/StringPool.cpp @@ -9,7 +9,7 @@ #include <utils/ByteOrder.h> #include <utils/SortedVector.h> -#include <cutils/qsort_r_compat.h> +#include "qsort_r_compat.h" #if HAVE_PRINTF_ZD # define ZD "%zd" diff --git a/tools/aapt/qsort_r_compat.c b/tools/aapt/qsort_r_compat.c new file mode 100644 index 000000000000..2a8dbe85f4c9 --- /dev/null +++ b/tools/aapt/qsort_r_compat.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include "qsort_r_compat.h" + +/* + * Note: This code is only used on the host, and is primarily here for + * Mac OS compatibility. Apparently, glibc and Apple's libc disagree on + * the parameter order for qsort_r. + */ + +#if HAVE_BSD_QSORT_R + +/* + * BSD qsort_r parameter order is as we have defined here. + */ + +void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk, + int (*compar)(void*, const void* , const void*)) { + qsort_r(base, nel, width, thunk, compar); +} + +#elif HAVE_GNU_QSORT_R + +/* + * GNU qsort_r parameter order places the thunk parameter last. + */ + +struct compar_data { + void* thunk; + int (*compar)(void*, const void* , const void*); +}; + +static int compar_wrapper(const void* a, const void* b, void* data) { + struct compar_data* compar_data = (struct compar_data*)data; + return compar_data->compar(compar_data->thunk, a, b); +} + +void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk, + int (*compar)(void*, const void* , const void*)) { + struct compar_data compar_data; + compar_data.thunk = thunk; + compar_data.compar = compar; + qsort_r(base, nel, width, compar_wrapper, &compar_data); +} + +#else + +/* + * Emulate qsort_r using thread local storage to access the thunk data. + */ + +#include <cutils/threads.h> + +static thread_store_t compar_data_key = THREAD_STORE_INITIALIZER; + +struct compar_data { + void* thunk; + int (*compar)(void*, const void* , const void*); +}; + +static int compar_wrapper(const void* a, const void* b) { + struct compar_data* compar_data = (struct compar_data*)thread_store_get(&compar_data_key); + return compar_data->compar(compar_data->thunk, a, b); +} + +void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk, + int (*compar)(void*, const void* , const void*)) { + struct compar_data compar_data; + compar_data.thunk = thunk; + compar_data.compar = compar; + thread_store_set(&compar_data_key, &compar_data, NULL); + qsort(base, nel, width, compar_wrapper); +} + +#endif diff --git a/tools/aapt/qsort_r_compat.h b/tools/aapt/qsort_r_compat.h new file mode 100644 index 000000000000..e14f999f736a --- /dev/null +++ b/tools/aapt/qsort_r_compat.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Provides a portable version of qsort_r, called qsort_r_compat, which is a + * reentrant variant of qsort that passes a user data pointer to its comparator. + * This implementation follows the BSD parameter convention. + */ + +#ifndef ___QSORT_R_COMPAT_H +#define ___QSORT_R_COMPAT_H + +#include <stdlib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk, + int (*compar)(void*, const void* , const void* )); + +#ifdef __cplusplus +} +#endif + +#endif // ___QSORT_R_COMPAT_H |