diff --git a/CMakeLists.txt b/CMakeLists.txt index 993e42c1..3f10dfd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ if(NOT DEFINED CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo" FORCE) endif() -project(VanillaConquer CXX) +project(VanillaConquer C CXX) option(BUILD_REMASTERTD "Build Tiberian Dawn remaster dll." OFF) option(BUILD_REMASTERRA "Build Red Alert remaster dll." OFF) @@ -140,6 +140,7 @@ if(BUILD_TESTS) add_subdirectory(tests) endif() +add_subdirectory(compat) add_subdirectory(common) add_subdirectory(tiberiandawn) add_subdirectory(redalert) diff --git a/cmake/ClangFormat.cmake b/cmake/ClangFormat.cmake index 6dc6ed57..c5e70de3 100644 --- a/cmake/ClangFormat.cmake +++ b/cmake/ClangFormat.cmake @@ -8,6 +8,8 @@ if(CLANG_FORMAT_FOUND) endif() set(GLOB_PATTERNS + compat/*.c + compat/*.h common/*.cpp common/*.h tiberiandawn/*.cpp diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e689f6b1..81ffbd7b 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -164,7 +164,7 @@ endif() file(GLOB_RECURSE COMMON_HEADERS "*.h") add_library(common STATIC ${COMMON_SRC} ${COMMON_HEADERS}) -target_link_libraries(common PUBLIC ${COMMON_LIBS}) +target_link_libraries(common PUBLIC vc_compat ${COMMON_LIBS}) target_include_directories(common PUBLIC .) target_compile_definitions(common PRIVATE FIXIT_FAST_LOAD $<$:_DEBUG>) # Make build check state of git to check for uncommitted changes. diff --git a/common/misc.cpp b/common/misc.cpp index cbbe8c93..7bb705a2 100644 --- a/common/misc.cpp +++ b/common/misc.cpp @@ -116,50 +116,3 @@ int Reverse_Long(int number) unsigned num = number; return ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | ((num >> 8) & 0xff00) | ((num << 24) & 0xff000000); } - -void strtrim(char* str) -{ - size_t len = 0; - char* frontp = str; - char* endp = NULL; - - if (str == NULL || str[0] == '\0') { - return; - } - - len = strlen(str); - endp = str + len; - - /* - * Move the front and back pointers to address the first non-whitespace - * characters from each end. - */ - while (isspace((unsigned char)*frontp)) { - ++frontp; - } - - if (endp != frontp) { - while (isspace((unsigned char)*(--endp)) && endp != frontp) { - } - } - - if (str + len - 1 != endp) { - *(endp + 1) = '\0'; - } else if (frontp != str && endp == frontp) { - *str = '\0'; - } - - /* - * Shift the string so that it starts at str so that if it's dynamically - * allocated, we can still free it on the returned pointer. Note the reuse - * of endp to mean the front of the string buffer now. - */ - endp = str; - if (frontp != str) { - while (*frontp) { - *endp++ = *frontp++; - } - - *endp = '\0'; - } -} diff --git a/common/miscasm.h b/common/miscasm.h index fefc1065..757b7ebb 100644 --- a/common/miscasm.h +++ b/common/miscasm.h @@ -12,6 +12,5 @@ int First_False_Bit(void const* array); int _Bound(int original, int min, int max); #define Bound _Bound int Reverse_Long(int number); -void strtrim(char* buffer); #endif diff --git a/common/rawfile.cpp b/common/rawfile.cpp index 4db8be8b..e94f609c 100644 --- a/common/rawfile.cpp +++ b/common/rawfile.cpp @@ -170,7 +170,7 @@ char const* RawFileClass::Set_Name(char const* filename) ** if Resolve_File finds an actual file on-disk we use the real name ** instead. */ - _strlwr(Filename); + strlwr(Filename); /* ** Try to locate an existing file ignoring case, updates Filename diff --git a/common/utfargs.h b/common/utfargs.h index 30be920f..f029ef4e 100644 --- a/common/utfargs.h +++ b/common/utfargs.h @@ -12,6 +12,10 @@ #ifndef UTFARGS_H #define UTFARGS_H +#ifdef _WIN32 +#include +#endif + class UtfArgs { public: diff --git a/common/vqaaudio.h b/common/vqaaudio.h index ee4ef5e9..d17e6164 100644 --- a/common/vqaaudio.h +++ b/common/vqaaudio.h @@ -17,6 +17,7 @@ #ifdef _WIN32 #include +#include #ifndef OPENAL_BUILD #include #endif diff --git a/common/wwstd.h b/common/wwstd.h index ab99bcc1..3bcc526a 100644 --- a/common/wwstd.h +++ b/common/wwstd.h @@ -258,33 +258,6 @@ inline static void _splitpath(const char* path, char* drive, char* dir, char* fn } } -inline static char* strupr(char* str) -{ - for (int i = 0; i < strlen(str); i++) - str[i] = toupper(str[i]); - return str; -} - -inline static void strrev(char* str) -{ - int len = strlen(str); - - for (int i = 0; i < len / 2; i++) { - char c = str[i]; - str[i] = str[len - i - 1]; - str[len - i - 1] = c; - } -} - -inline static void _strlwr(char* str) -{ - int len = strlen(str); - - for (int i = 0; i < len; i++) { - str[i] = tolower(str[i]); - } -} - #endif // not _WIN32 #endif // WWSTD_H diff --git a/compat/CMakeLists.txt b/compat/CMakeLists.txt new file mode 100644 index 00000000..cf60f366 --- /dev/null +++ b/compat/CMakeLists.txt @@ -0,0 +1,69 @@ +include(CheckIncludeFile) + +# Check if we are missing any posix headers we consider required. +check_include_file(strings.h HAVE_STRINGS_H) +check_include_file(libgen.h HAVE_LIBGEN_H) +check_include_file(dirent.h HAVE_DIRENT_H) +check_include_file(getopt.h HAVE_GETOPT_H) +check_include_file(unistd.h HAVE_UNISTD_H) +check_include_file(fnmatch.h HAVE_FNMATCH_H) +include(CheckSymbolExists) + +# Check if we are missing any functions known to exist in platform specific runtimes. +check_symbol_exists(strtrim "string.h" HAVE_STRTRIM) +check_symbol_exists(strlwr "string.h" HAVE_STRLWR) +check_symbol_exists(strupr "string.h" HAVE_STRUPR) +check_symbol_exists(strlcat "string.h" HAVE_STRLCAT) +check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY) +check_symbol_exists(strrev "string.h" HAVE_STRREV) +configure_file(string.h.in string.h @ONLY) + +if(HAVE_FNMATCH_H) + check_symbol_exists(fnmatch "fnmatch.h" HAVE_FNMATCH) +endif() + +add_library(vc_compat STATIC) + +if(WIN32) + target_compile_definitions(vc_compat PUBLIC _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN) +endif() + +target_sources(vc_compat PRIVATE + compat/endianness.h + string.c + ${CMAKE_CURRENT_BINARY_DIR}/string.h +) + +target_include_directories(vc_compat PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/compat ${CMAKE_CURRENT_BINARY_DIR}) + +if(NOT HAVE_STRINGS_H) + target_sources(vc_compat PRIVATE strings/strings.c strings/strings.h) + target_include_directories(vc_compat PUBLIC strings) +endif() + +if(NOT HAVE_LIBGEN_H) + target_sources(vc_compat PRIVATE libgen/libgen.c libgen/libgen.h) + target_include_directories(vc_compat PUBLIC libgen) +endif() + +if(NOT HAVE_DIRENT_H) + target_sources(vc_compat PRIVATE dirent/dirent.c dirent/dirent.h) + target_include_directories(vc_compat PUBLIC dirent) +endif() + +if(NOT HAVE_UNISTD_H) + target_sources(vc_compat PRIVATE unistd/unistd.h) + target_include_directories(vc_compat PUBLIC unistd) +endif() + +if(NOT HAVE_GETOPT_H) + target_sources(vc_compat PRIVATE getopt/getopt.c getopt/getopt.h) + target_include_directories(vc_compat PUBLIC getopt) +endif() + +if(NOT HAVE_FNMATCH) + # TODO this should cover both windows and Vita SDK as it currently stands. + # Option remains to split header and imlementation inclusion if needed. + target_sources(vc_compat PRIVATE fnmatch/fnmatch.c fnmatch/fnmatch.h) + target_include_directories(vc_compat PUBLIC fnmatch) +endif() diff --git a/common/endianness.h b/compat/compat/endianness.h similarity index 100% rename from common/endianness.h rename to compat/compat/endianness.h diff --git a/tools/miniposix/dirent/dirent.c b/compat/dirent/dirent.c similarity index 77% rename from tools/miniposix/dirent/dirent.c rename to compat/dirent/dirent.c index 4e356d6d..36ff670e 100644 --- a/tools/miniposix/dirent/dirent.c +++ b/compat/dirent/dirent.c @@ -5,7 +5,7 @@ struct __dir { - struct dirent *entries; + struct dirent* entries; HANDLE fd; long int count; long int index; @@ -15,26 +15,26 @@ static void __seterrno(int value) { #ifdef _MSC_VER _set_errno(value); -#else /* _MSC_VER */ +#else /* _MSC_VER */ errno = value; #endif /* _MSC_VER */ } -int closedir(DIR *dirp) +int closedir(DIR* dirp) { - struct __dir *data = NULL; + struct __dir* data = NULL; if (!dirp) { __seterrno(EBADF); return -1; } - data = (struct __dir *)dirp; + data = (struct __dir*)dirp; CloseHandle((HANDLE)data->fd); free(data->entries); free(data); return 0; } -static int __islink(const wchar_t *name, char *buffer) +static int __islink(const wchar_t* name, char* buffer) { DWORD io_result = 0; DWORD bytes_returned = 0; @@ -51,7 +51,7 @@ static int __islink(const wchar_t *name, char *buffer) if (io_result == 0) return 0; - return ((REPARSE_GUID_DATA_BUFFER *)buffer)->ReparseTag == IO_REPARSE_TAG_SYMLINK; + return ((REPARSE_GUID_DATA_BUFFER*)buffer)->ReparseTag == IO_REPARSE_TAG_SYMLINK; } static unsigned long long __inode(const wchar_t* name) @@ -78,19 +78,19 @@ static unsigned long long __inode(const wchar_t* name) return value; } -static DIR *__internal_opendir(wchar_t *wname, int size) +static DIR* __internal_opendir(wchar_t* wname, size_t size) { - struct __dir *data = NULL; - struct dirent *tmp_entries = NULL; + struct __dir* data = NULL; + struct dirent* tmp_entries = NULL; static char default_char = '?'; - static wchar_t *prefix = L"\\\\?\\"; - static wchar_t *suffix = L"\\*.*"; - int extra_prefix = 4; /* use prefix "\\?\" to handle long file names */ + static wchar_t* prefix = L"\\\\?\\"; + static wchar_t* suffix = L"\\*.*"; + int extra_prefix = 4; /* use prefix "\\?\" to handle long file names */ static int extra_suffix = 4; /* use suffix "\*.*" to find everything */ - WIN32_FIND_DATAW w32fd = { 0 }; + WIN32_FIND_DATAW w32fd = {0}; HANDLE hFindFile = INVALID_HANDLE_VALUE; static int grow_factor = 2; - char *buffer = NULL; + char* buffer = NULL; /* Ensure path only uses windows separator, of FindFirstFileW will fail. */ wchar_t* rep = wname; @@ -112,7 +112,7 @@ static DIR *__internal_opendir(wchar_t *wname, int size) return NULL; } - data = (struct __dir *)malloc(sizeof(struct __dir)); + data = (struct __dir*)malloc(sizeof(struct __dir)); if (!data) goto out_of_memory; wname[extra_prefix + size - 1] = 0; @@ -120,7 +120,7 @@ static DIR *__internal_opendir(wchar_t *wname, int size) wname[extra_prefix + size - 1] = L'\\'; data->count = 16; data->index = 0; - data->entries = (struct dirent *)malloc(sizeof(struct dirent) * data->count); + data->entries = (struct dirent*)malloc(sizeof(struct dirent) * data->count); if (!data->entries) goto out_of_memory; buffer = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); @@ -148,7 +148,7 @@ static DIR *__internal_opendir(wchar_t *wname, int size) data->entries[data->index].d_off = 0; if (++data->index == data->count) { - tmp_entries = (struct dirent *)realloc(data->entries, sizeof(struct dirent) * data->count * grow_factor); + tmp_entries = (struct dirent*)realloc(data->entries, sizeof(struct dirent) * data->count * grow_factor); if (!tmp_entries) goto out_of_memory; data->entries = tmp_entries; @@ -161,7 +161,7 @@ static DIR *__internal_opendir(wchar_t *wname, int size) data->count = data->index; data->index = 0; - return (DIR *)data; + return (DIR*)data; out_of_memory: if (data) { if (INVALID_HANDLE_VALUE != (HANDLE)data->fd) @@ -176,9 +176,9 @@ static DIR *__internal_opendir(wchar_t *wname, int size) return NULL; } -static wchar_t *__get_buffer() +static wchar_t* __get_buffer() { - wchar_t *name = malloc(sizeof(wchar_t) * (NTFS_MAX_PATH + NAME_MAX + 8)); + wchar_t* name = malloc(sizeof(wchar_t) * (NTFS_MAX_PATH + NAME_MAX + 8)); if (name) memcpy(name, L"\\\\?\\", sizeof(wchar_t) * 4); return name; @@ -193,11 +193,11 @@ static int __internal_absolutepath(const char* path) return path && (path[1] == ':' || (path[0] == '\\' && path[1] == '\\')); } -DIR *opendir(const char *name) +DIR* opendir(const char* name) { - DIR *dirp = NULL; - wchar_t *wname = __get_buffer(); - int size = 0; + DIR* dirp = NULL; + wchar_t* wname = __get_buffer(); + size_t size = 0; if (!wname) { __seterrno(ENOMEM); return NULL; @@ -233,10 +233,10 @@ DIR *opendir(const char *name) return dirp; } -DIR *_wopendir(const wchar_t *name) +DIR* _wopendir(const wchar_t* name) { - DIR *dirp = NULL; - wchar_t *wname = __get_buffer(); + DIR* dirp = NULL; + wchar_t* wname = __get_buffer(); int size = 0; if (!wname) { __seterrno(ENOMEM); @@ -253,10 +253,10 @@ DIR *_wopendir(const wchar_t *name) return dirp; } -DIR *fdopendir(int fd) +DIR* fdopendir(int fd) { - DIR *dirp = NULL; - wchar_t *wname = __get_buffer(); + DIR* dirp = NULL; + wchar_t* wname = __get_buffer(); int size = 0; if (!wname) { __seterrno(ENOMEM); @@ -273,9 +273,9 @@ DIR *fdopendir(int fd) return dirp; } -struct dirent *readdir(DIR *dirp) +struct dirent* readdir(DIR* dirp) { - struct __dir *data = (struct __dir *)dirp; + struct __dir* data = (struct __dir*)dirp; if (!data) { __seterrno(EBADF); return NULL; @@ -286,9 +286,9 @@ struct dirent *readdir(DIR *dirp) return NULL; } -int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) +int readdir_r(DIR* dirp, struct dirent* entry, struct dirent** result) { - struct __dir *data = (struct __dir *)dirp; + struct __dir* data = (struct __dir*)dirp; if (!data) { return EBADF; } @@ -302,52 +302,52 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) return 0; } -void seekdir(DIR *dirp, long int offset) +void seekdir(DIR* dirp, long int offset) { if (dirp) { - struct __dir *data = (struct __dir *)dirp; + struct __dir* data = (struct __dir*)dirp; data->index = (offset < data->count) ? offset : data->index; } } -void rewinddir(DIR *dirp) +void rewinddir(DIR* dirp) { seekdir(dirp, 0); } -long int telldir(DIR *dirp) +long int telldir(DIR* dirp) { if (!dirp) { __seterrno(EBADF); return -1; } - return ((struct __dir *)dirp)->count; + return ((struct __dir*)dirp)->count; } -int dirfd(DIR *dirp) +int dirfd(DIR* dirp) { if (!dirp) { __seterrno(EINVAL); return -1; } - return (int)(long long)((struct __dir *)dirp)->fd; + return (int)(long long)((struct __dir*)dirp)->fd; } -int scandir(const char *dirp, - struct dirent ***namelist, - int (*filter)(const struct dirent *), - int (*compar)(const struct dirent **, const struct dirent **)) +int scandir(const char* dirp, + struct dirent*** namelist, + int (*filter)(const struct dirent*), + int (*compar)(const struct dirent**, const struct dirent**)) { struct dirent **entries = NULL, **tmp_entries = NULL; long int i = 0, index = 0, count = 16; - DIR *d = opendir(dirp); - struct __dir *data = (struct __dir *)d; + DIR* d = opendir(dirp); + struct __dir* data = (struct __dir*)d; if (!data) { closedir(d); __seterrno(ENOENT); return -1; } - entries = (struct dirent **)malloc(sizeof(struct dirent *) * count); + entries = (struct dirent**)malloc(sizeof(struct dirent*) * count); if (!entries) { closedir(d); __seterrno(ENOMEM); @@ -355,7 +355,7 @@ int scandir(const char *dirp, } for (i = 0; i < data->count; ++i) { if (!filter || filter(&data->entries[i])) { - entries[index] = (struct dirent *)malloc(sizeof(struct dirent)); + entries[index] = (struct dirent*)malloc(sizeof(struct dirent)); if (!entries[index]) { closedir(d); for (i = 0; i < index; ++i) @@ -366,7 +366,7 @@ int scandir(const char *dirp, } memcpy(entries[index], &data->entries[i], sizeof(struct dirent)); if (++index == count) { - tmp_entries = (struct dirent **)realloc(entries, sizeof(struct dirent *) * count * 2); + tmp_entries = (struct dirent**)realloc(entries, sizeof(struct dirent*) * count * 2); if (!tmp_entries) { closedir(d); for (i = 0; i < index; ++i) @@ -380,7 +380,7 @@ int scandir(const char *dirp, } } } - qsort(entries, index, sizeof(struct dirent *), compar); + qsort(entries, index, sizeof(struct dirent*), compar); entries[index] = NULL; if (namelist) *namelist = entries; @@ -388,22 +388,22 @@ int scandir(const char *dirp, return 0; } -int alphasort(const void *a, const void *b) +int alphasort(const void* a, const void* b) { - struct dirent **dira = (struct dirent **)a, **dirb = (struct dirent **)b; + struct dirent **dira = (struct dirent**)a, **dirb = (struct dirent**)b; if (!dira || !dirb) return 0; return strcoll((*dira)->d_name, (*dirb)->d_name); } -static int __strverscmp(const char *s1, const char *s2) +static int __strverscmp(const char* s1, const char* s2) { return alphasort(s1, s2); } -int versionsort(const void *a, const void *b) +int versionsort(const void* a, const void* b) { - struct dirent **dira = (struct dirent **)a, **dirb = (struct dirent **)b; + struct dirent **dira = (struct dirent**)a, **dirb = (struct dirent**)b; if (!dira || !dirb) return 0; return __strverscmp((*dira)->d_name, (*dirb)->d_name); diff --git a/tools/miniposix/dirent/dirent.h b/compat/dirent/dirent.h similarity index 97% rename from tools/miniposix/dirent/dirent.h rename to compat/dirent/dirent.h index 563aa259..ae6e3008 100644 --- a/tools/miniposix/dirent/dirent.h +++ b/compat/dirent/dirent.h @@ -23,11 +23,7 @@ SOFTWARE. #ifndef MINIPOSIX_DIRENT_H #define MINIPOSIX_DIRENT_H -#ifndef _WIN32 - -#pragma message("this dirent.h implementation is for Windows only!") - -#else +#ifdef _WIN32 #ifdef __cplusplus extern "C" { diff --git a/compat/fnmatch/fnmatch.c b/compat/fnmatch/fnmatch.c new file mode 100644 index 00000000..174c3257 --- /dev/null +++ b/compat/fnmatch/fnmatch.c @@ -0,0 +1,295 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * 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. + */ + +/* + * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. + * Compares a filename or pathname to a pattern. + */ + +/* + * Some notes on multibyte character support: + * 1. Patterns with illegal byte sequences match nothing. + * 2. Illegal byte sequences in the "string" argument are handled by treating + * them as single-byte characters with a value of the first byte of the + * sequence cast to wchar_t. + * 3. Multibyte conversion state objects (mbstate_t) are passed around and + * used for most, but not all, conversions. Further work will be required + * to support state-dependent encodings. + */ + +#include +#include +#include +#include +#include + +#define EOS '\0' + +#define RANGE_MATCH 1 +#define RANGE_NOMATCH 0 +#define RANGE_ERROR (-1) + +static int rangematch(const char*, wchar_t, int, char**, mbstate_t*); +static int fnmatch1(const char*, const char*, const char*, int, mbstate_t, mbstate_t); + +int fnmatch(const char* pattern, const char* string, int flags) +{ + static const mbstate_t initial; + + return (fnmatch1(pattern, string, string, flags, initial, initial)); +} + +static int fnmatch1(const char* pattern, + const char* string, + const char* stringstart, + int flags, + mbstate_t patmbs, + mbstate_t strmbs) +{ + const char *bt_pattern, *bt_string; + mbstate_t bt_patmbs, bt_strmbs; + char* newp; + char c; + wchar_t pc, sc; + size_t pclen, sclen; + + bt_pattern = bt_string = NULL; + for (;;) { + pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (FNM_NOMATCH); + pattern += pclen; + sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); + if (sclen == (size_t)-1 || sclen == (size_t)-2) { + sc = (unsigned char)*string; + sclen = 1; + memset(&strmbs, 0, sizeof(strmbs)); + } + switch (pc) { + case EOS: + if ((flags & FNM_LEADING_DIR) && sc == '/') + return (0); + if (sc == EOS) + return (0); + goto backtrack; + case '?': + if (sc == EOS) + return (FNM_NOMATCH); + if (sc == '/' && (flags & FNM_PATHNAME)) + goto backtrack; + if (sc == '.' && (flags & FNM_PERIOD) + && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + goto backtrack; + string += sclen; + break; + case '*': + c = *pattern; + /* Collapse multiple stars. */ + while (c == '*') + c = *++pattern; + + if (sc == '.' && (flags & FNM_PERIOD) + && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + goto backtrack; + + /* Optimize for pattern with * at end or before /. */ + if (c == EOS) + if (flags & FNM_PATHNAME) + return ((flags & FNM_LEADING_DIR) || strchr(string, '/') == NULL ? 0 : FNM_NOMATCH); + else + return (0); + else if (c == '/' && flags & FNM_PATHNAME) { + if ((string = strchr(string, '/')) == NULL) + return (FNM_NOMATCH); + break; + } + + /* + * First try the shortest match for the '*' that + * could work. We can forget any earlier '*' since + * there is no way having it match more characters + * can help us, given that we are already here. + */ + bt_pattern = pattern, bt_patmbs = patmbs; + bt_string = string, bt_strmbs = strmbs; + break; + case '[': + if (sc == EOS) + return (FNM_NOMATCH); + if (sc == '/' && (flags & FNM_PATHNAME)) + goto backtrack; + if (sc == '.' && (flags & FNM_PERIOD) + && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + goto backtrack; + + switch (rangematch(pattern, sc, flags, &newp, &patmbs)) { + case RANGE_ERROR: + goto norm; + case RANGE_MATCH: + pattern = newp; + break; + case RANGE_NOMATCH: + goto backtrack; + } + string += sclen; + break; + case '\\': + if (!(flags & FNM_NOESCAPE)) { + pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); + if (pclen == 0 || pclen == (size_t)-1 || pclen == (size_t)-2) + return (FNM_NOMATCH); + pattern += pclen; + } + /* FALLTHROUGH */ + default: + norm: + string += sclen; + if (pc == sc) + ; + else if ((flags & FNM_CASEFOLD) && (towlower(pc) == towlower(sc))) + ; + else { + backtrack: + /* + * If we have a mismatch (other than hitting + * the end of the string), go back to the last + * '*' seen and have it match one additional + * character. + */ + if (bt_pattern == NULL) + return (FNM_NOMATCH); + sclen = mbrtowc(&sc, bt_string, MB_LEN_MAX, &bt_strmbs); + if (sclen == (size_t)-1 || sclen == (size_t)-2) { + sc = (unsigned char)*bt_string; + sclen = 1; + memset(&bt_strmbs, 0, sizeof(bt_strmbs)); + } + if (sc == EOS) + return (FNM_NOMATCH); + if (sc == '/' && flags & FNM_PATHNAME) + return (FNM_NOMATCH); + bt_string += sclen; + pattern = bt_pattern, patmbs = bt_patmbs; + string = bt_string, strmbs = bt_strmbs; + } + break; + } + } + /* NOTREACHED */ +} + +static int __wcollate_range_cmp(wchar_t c1, wchar_t c2) +{ + wchar_t s1[2], s2[2]; + + s1[0] = c1; + s1[1] = L'\0'; + s2[0] = c2; + s2[1] = L'\0'; + return (wcscoll(s1, s2)); +} + +static int rangematch(const char* pattern, wchar_t test, int flags, char** newp, mbstate_t* patmbs) +{ + int negate, ok; + wchar_t c, c2; + size_t pclen; + const char* origpat; + + /* + * A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). This implementation treats it like '!', for + * consistency with the regular expression syntax. + * J.T. Conklin (conklin@ngai.kaleida.com) + */ + if ((negate = (*pattern == '!' || *pattern == '^'))) + ++pattern; + + if (flags & FNM_CASEFOLD) + test = towlower(test); + + /* + * A right bracket shall lose its special meaning and represent + * itself in a bracket expression if it occurs first in the list. + * -- POSIX.2 2.8.3.2 + */ + ok = 0; + origpat = pattern; + for (;;) { + if (*pattern == ']' && pattern > origpat) { + pattern++; + break; + } else if (*pattern == '\0') { + return (RANGE_ERROR); + } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { + return (RANGE_NOMATCH); + } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) + pattern++; + pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (RANGE_NOMATCH); + pattern += pclen; + + if (flags & FNM_CASEFOLD) + c = towlower(c); + + if (*pattern == '-' && *(pattern + 1) != EOS && *(pattern + 1) != ']') { + if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) + if (*pattern != EOS) + pattern++; + pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (RANGE_NOMATCH); + pattern += pclen; + if (c2 == EOS) + return (RANGE_ERROR); + + if (flags & FNM_CASEFOLD) + c2 = towlower(c2); + + if (__wcollate_range_cmp(c, test) <= 0 && __wcollate_range_cmp(test, c2) <= 0) + ok = 1; + } else if (c == test) + ok = 1; + } + + *newp = (char*)pattern; + return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); +} diff --git a/compat/fnmatch/fnmatch.h b/compat/fnmatch/fnmatch.h new file mode 100644 index 00000000..d2af7e4a --- /dev/null +++ b/compat/fnmatch/fnmatch.h @@ -0,0 +1,66 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1992, 1993 + * 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. + * + * $FreeBSD$ + * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef MINIPOSIX_FNMATCH_H +#define MINIPOSIX_FNMATCH_H + +#ifndef _WIN32 +/* Assuming this is the Vita SDK at the moment where we have the symbol, but not the function */ +#include_next + +#ifndef FNM_CASEFOLD +#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ +#define FNM_IGNORECASE FNM_CASEFOLD +#endif + +#else +#define FNM_NOMATCH 1 /* Match failed. */ + +#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ +#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ + +#if __XSI_VISIBLE +#define FNM_NOSYS (-1) /* Reserved. */ +#endif + +#define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ +#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ +#define FNM_IGNORECASE FNM_CASEFOLD +#define FNM_FILE_NAME FNM_PATHNAME + +int fnmatch(const char*, const char*, int); +#endif + +#endif /* !MINIPOSIX_FNMATCH_H */ diff --git a/tools/miniposix/getopt/getopt.c b/compat/getopt/getopt.c similarity index 72% rename from tools/miniposix/getopt/getopt.c rename to compat/getopt/getopt.c index d58b5177..5db5d88e 100644 --- a/tools/miniposix/getopt/getopt.c +++ b/compat/getopt/getopt.c @@ -108,7 +108,7 @@ typedef enum GETOPT_ORDERING_T } GETOPT_ORDERING_T; /* globally-defined variables */ -char *optarg = NULL; +char* optarg = NULL; int optind = 0; int opterr = 1; int optopt = '?'; @@ -116,10 +116,10 @@ int optopt = '?'; /* functions */ /* reverse_argv_elements: reverses num elements starting at argv */ -static void reverse_argv_elements(char **argv, int num) +static void reverse_argv_elements(char** argv, int num) { int i; - char *tmp; + char* tmp; for (i = 0; i < (num >> 1); i++) { tmp = argv[i]; @@ -129,7 +129,7 @@ static void reverse_argv_elements(char **argv, int num) } /* permute: swap two blocks of argv-elements given their lengths */ -static void permute(char **argv, int len1, int len2) +static void permute(char** argv, int len1, int len2) { reverse_argv_elements(argv, len1); reverse_argv_elements(argv, len1 + len2); @@ -137,13 +137,13 @@ static void permute(char **argv, int len1, int len2) } /* is_option: is this argv-element an option or the end of the option list? */ -static int is_option(char *argv_element, int only) +static int is_option(char* argv_element, int only) { return ((argv_element == NULL) || (argv_element[0] == '-') || (only && argv_element[0] == '+')); } /* getopt_internal: the function that does all the dirty work */ -static int getopt_internal(int argc, char **argv, char *shortopts, option *longopts, int *longind, int only) +static int getopt_internal(int argc, char** argv, char* shortopts, option* longopts, int* longind, int only) { GETOPT_ORDERING_T ordering = PERMUTE; static size_t optwhere = 0; @@ -151,10 +151,10 @@ static int getopt_internal(int argc, char **argv, char *shortopts, option *longo int num_nonopts = 0; int optindex = 0; size_t match_chars = 0; - char *possible_arg = NULL; + char* possible_arg = NULL; int longopt_match = -1; int has_arg = -1; - char *cp = NULL; + char* cp = NULL; int arg_next = 0; /* first, deal with silly parameters and easy stuff */ @@ -185,40 +185,41 @@ static int getopt_internal(int argc, char **argv, char *shortopts, option *longo */ if (optwhere == 1) { switch (ordering) { - case PERMUTE: - permute_from = optind; - num_nonopts = 0; - while (!is_option(argv[optind], only)) { - optind++; - num_nonopts++; - } - if (argv[optind] == NULL) { - /* no more options */ - optind = (int)permute_from; - return EOF; - } else if (strcmp(argv[optind], "--") == 0) { - /* no more options, but have to get `--' out of the way */ - permute(argv + permute_from, num_nonopts, 1); - optind = (int)(permute_from + 1); - return EOF; - } - break; - case RETURN_IN_ORDER: - if (!is_option(argv[optind], only)) { - optarg = argv[optind++]; - return (optopt = 1); - } - break; - case REQUIRE_ORDER: - if (!is_option(argv[optind], only)) - return EOF; - break; + case PERMUTE: + permute_from = optind; + num_nonopts = 0; + while (!is_option(argv[optind], only)) { + optind++; + num_nonopts++; + } + if (argv[optind] == NULL) { + /* no more options */ + optind = (int)permute_from; + return EOF; + } else if (strcmp(argv[optind], "--") == 0) { + /* no more options, but have to get `--' out of the way */ + permute(argv + permute_from, num_nonopts, 1); + optind = (int)(permute_from + 1); + return EOF; + } + break; + case RETURN_IN_ORDER: + if (!is_option(argv[optind], only)) { + optarg = argv[optind++]; + return (optopt = 1); + } + break; + case REQUIRE_ORDER: + if (!is_option(argv[optind], only)) + return EOF; + break; } } /* we've got an option, so parse it */ /* first, is it a long option? */ - if (longopts != NULL && (strncmp(argv[optind], "--", 2) == 0 || (only && argv[optind][0] == '+')) && optwhere == 1) { + if (longopts != NULL && (strncmp(argv[optind], "--", 2) == 0 || (only && argv[optind][0] == '+')) + && optwhere == 1) { /* handle long options */ if (strncmp(argv[optind], "--", 2) == 0) optwhere = 2; @@ -246,12 +247,12 @@ static int getopt_internal(int argc, char **argv, char *shortopts, option *longo /* we have ambiguous options */ if (opterr) fprintf(stderr, - "%s: option `%s' is ambiguous " - "(could be `--%s' or `--%s')\n", - argv[0], - argv[optind], - longopts[longopt_match].name, - longopts[optindex].name); + "%s: option `%s' is ambiguous " + "(could be `--%s' or `--%s')\n", + argv[0], + argv[optind], + longopts[longopt_match].name, + longopts[optindex].name); return (optopt = '?'); } } @@ -281,46 +282,46 @@ static int getopt_internal(int argc, char **argv, char *shortopts, option *longo /* get argument and reset optwhere */ arg_next = 0; switch (has_arg) { - case optional_argument: - if (*possible_arg == '=') - possible_arg++; - if (*possible_arg != '\0') { - optarg = possible_arg; - optwhere = 1; - } else - optarg = NULL; - break; - case required_argument: - if (*possible_arg == '=') - possible_arg++; - if (*possible_arg != '\0') { - optarg = possible_arg; - optwhere = 1; - } else if (optind + 1 >= argc) { - if (opterr) { - fprintf(stderr, "%s: argument required for option `", argv[0]); - if (longopt_match >= 0) - fprintf(stderr, "--%s'\n", longopts[longopt_match].name); - else - fprintf(stderr, "-%c'\n", *cp); - } - optind++; - return (optopt = ':'); - } else { - optarg = argv[optind + 1]; - arg_next = 1; - optwhere = 1; + case optional_argument: + if (*possible_arg == '=') + possible_arg++; + if (*possible_arg != '\0') { + optarg = possible_arg; + optwhere = 1; + } else + optarg = NULL; + break; + case required_argument: + if (*possible_arg == '=') + possible_arg++; + if (*possible_arg != '\0') { + optarg = possible_arg; + optwhere = 1; + } else if (optind + 1 >= argc) { + if (opterr) { + fprintf(stderr, "%s: argument required for option `", argv[0]); + if (longopt_match >= 0) + fprintf(stderr, "--%s'\n", longopts[longopt_match].name); + else + fprintf(stderr, "-%c'\n", *cp); } - break; - case no_argument: - if (longopt_match < 0) { - optwhere++; - if (argv[optind][optwhere] == '\0') - optwhere = 1; - } else + optind++; + return (optopt = ':'); + } else { + optarg = argv[optind + 1]; + arg_next = 1; + optwhere = 1; + } + break; + case no_argument: + if (longopt_match < 0) { + optwhere++; + if (argv[optind][optwhere] == '\0') optwhere = 1; - optarg = NULL; - break; + } else + optwhere = 1; + optarg = NULL; + break; } /* do we have to permute or otherwise modify optind? */ @@ -343,19 +344,19 @@ static int getopt_internal(int argc, char **argv, char *shortopts, option *longo return optopt; } -int getopt(int argc, char **argv, char *optstring) +int getopt(int argc, char** argv, char* optstring) { return getopt_internal(argc, argv, optstring, NULL, NULL, 0); } -int getopt_long(int argc, char **argv, const char *shortopts, const option *longopts, int *longind) +int getopt_long(int argc, char** argv, const char* shortopts, const option* longopts, int* longind) { - return getopt_internal(argc, argv, (char *)shortopts, (option *)longopts, longind, 0); + return getopt_internal(argc, argv, (char*)shortopts, (option*)longopts, longind, 0); } -int getopt_long_only(int argc, char **argv, const char *shortopts, const option *longopts, int *longind) +int getopt_long_only(int argc, char** argv, const char* shortopts, const option* longopts, int* longind) { - return getopt_internal(argc, argv, (char *)shortopts, (option *)longopts, longind, 1); + return getopt_internal(argc, argv, (char*)shortopts, (option*)longopts, longind, 1); } /* end of file GETOPT.C */ diff --git a/tools/miniposix/getopt/getopt.h b/compat/getopt/getopt.h similarity index 100% rename from tools/miniposix/getopt/getopt.h rename to compat/getopt/getopt.h diff --git a/tools/miniposix/libgen/libgen.c b/compat/libgen/libgen.c similarity index 96% rename from tools/miniposix/libgen/libgen.c rename to compat/libgen/libgen.c index a0afbc1f..d13a5d09 100644 --- a/tools/miniposix/libgen/libgen.c +++ b/compat/libgen/libgen.c @@ -26,14 +26,14 @@ #include #include -char *basename(char *path) +char* basename(char* path) { - static char *retfail = NULL; + static char* retfail = NULL; size_t len; /* to handle path names for files in multibyte character locales, * we need to set up LC_CTYPE to match the host file system locale */ - char *locale = setlocale(LC_CTYPE, NULL); + char* locale = setlocale(LC_CTYPE, NULL); if (locale != NULL) locale = strdup(locale); @@ -44,11 +44,11 @@ char *basename(char *path) * in which to create a wide character reference copy of path */ len = mbstowcs(NULL, path, 0); - wchar_t *refcopy = malloc(sizeof(wchar_t) * (1 + len)); + wchar_t* refcopy = malloc(sizeof(wchar_t) * (1 + len)); /* create the wide character reference copy of path, * and step over the drive designator, if present ... */ - wchar_t *refpath = refcopy; + wchar_t* refpath = refcopy; if ((len = mbstowcs(refpath, path, len)) > 1 && refpath[1] == L':') { /* FIXME: maybe should confirm *refpath is a valid drive designator */ @@ -60,7 +60,7 @@ char *basename(char *path) if (*refpath) { /* and, when we do, process it in the wide character domain ... * scanning from left to right, to the char after the final dir separator. */ - wchar_t *refname; + wchar_t* refname; for (refname = refpath; *refpath; ++refpath) { if (*refpath == L'/' || *refpath == L'\\') { @@ -124,13 +124,13 @@ char *basename(char *path) return retfail; } -char *dirname(char *path) +char* dirname(char* path) { - static char *retfail = NULL; + static char* retfail = NULL; size_t len; /* to handle path names for files in multibyte character locales, * we need to set up LC_CTYPE to match the host file system locale. */ - char *locale = setlocale(LC_CTYPE, NULL); + char* locale = setlocale(LC_CTYPE, NULL); if (locale != NULL) locale = strdup(locale); @@ -140,9 +140,9 @@ char *dirname(char *path) /* allocate sufficient local storage space, * in which to create a wide character reference copy of path. */ len = mbstowcs(NULL, path, 0); - wchar_t *refcopy = malloc(sizeof(wchar_t) * (1 + len)); + wchar_t* refcopy = malloc(sizeof(wchar_t) * (1 + len)); /* create the wide character reference copy of path */ - wchar_t *refpath = refcopy; + wchar_t* refpath = refcopy; len = mbstowcs(refpath, path, len); refcopy[len] = L'\0'; diff --git a/tools/miniposix/libgen/libgen.h b/compat/libgen/libgen.h similarity index 100% rename from tools/miniposix/libgen/libgen.h rename to compat/libgen/libgen.h diff --git a/compat/string.c b/compat/string.c new file mode 100644 index 00000000..98a5c851 --- /dev/null +++ b/compat/string.c @@ -0,0 +1,152 @@ +#include "string.h" + +#ifndef HAVE_STRTRIM +char* strtrim(char* str) +{ + size_t len = 0; + char* frontp = str; + char* endp = NULL; + + if (str == NULL) { + return NULL; + } + + if (str[0] == '\0') { + return str; + } + + len = strlen(str); + endp = str + len; + + /* Move the front and back pointers to address the first non-whitespace + * characters from each end. + */ + while (isspace((unsigned char)*frontp)) { + ++frontp; + } + + if (endp != frontp) { + while (isspace((unsigned char)*(--endp)) && endp != frontp) { + } + } + + if (str + len - 1 != endp) { + *(endp + 1) = '\0'; + } else if (frontp != str && endp == frontp) { + *str = '\0'; + } + + /* Shift the string so that it starts at str so that if it's dynamically + * allocated, we can still free it on the returned pointer. Note the reuse + * of endp to mean the front of the string buffer now. + */ + endp = str; + if (frontp != str) { + while (*frontp) { + *endp++ = *frontp++; + } + + *endp = '\0'; + } + + return str; +} +#endif + +#ifndef HAVE_STRLWR +char* strlwr(char* str) +{ + char* p = str; + + while (*p) { + *p = tolower((unsigned char)*p); + p++; + } + + return str; +} +#endif + +#ifndef HAVE_STRUPR +char* strupr(char* str) +{ + char* p = str; + + while (*p) { + *p = toupper((unsigned char)*p); + p++; + } + + return str; +} +#endif + +#ifndef HAVE_STRREV +char* strrev(char* str) +{ + int len = strlen(str); + + for (int i = 0; i < len / 2; ++i) { + char c = str[i]; + str[i] = str[len - i - 1]; + str[len - i - 1] = c; + } + + return str; +} +#endif + +#ifndef HAVE_STRLCAT +size_t strlcat(char* dst, const char* src, size_t dsize) +{ + const char* odst = dst; + const char* osrc = src; + size_t n = dsize; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end. */ + while (n-- != 0 && *dst != '\0') + dst++; + dlen = dst - odst; + n = dsize - dlen; + + if (n-- == 0) + return (dlen + strlen(src)); + while (*src != '\0') { + if (n != 0) { + *dst++ = *src; + n--; + } + src++; + } + *dst = '\0'; + + return (dlen + (src - osrc)); /* count does not include NUL */ +} +#endif + +#ifndef HAVE_STRLCPY +size_t strlcpy(char* dst, const char* src, size_t dsize) +{ + const char* osrc = src; + size_t nleft = dsize; + + /* Copy as many bytes as will fit. */ + if (nleft != 0) { + while (--nleft != 0) { + if ((*dst++ = *src++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src. */ + if (nleft == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + + return (src - osrc - 1); /* count does not include NUL */ +} +#endif diff --git a/compat/string.h.in b/compat/string.h.in new file mode 100644 index 00000000..a90a1f7d --- /dev/null +++ b/compat/string.h.in @@ -0,0 +1,52 @@ +#ifndef STRINGCOMPAT_H +#define STRINGCOMPAT_H + +#cmakedefine HAVE_STRTRIM +#cmakedefine HAVE_STRLWR +#cmakedefine HAVE_STRUPR +#cmakedefine HAVE_STRREV +#cmakedefine HAVE_STRLCAT +#cmakedefine HAVE_STRLCPY + +#include + +/* Vodoo to extend platform string.h file. */ +#ifdef _MSC_VER +#include <../ucrt/string.h> +#else +#include_next +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_STRTRIM +char *strtrim(char *str); +#endif + +#ifndef HAVE_STRLWR +char *strlwr(char *str); +#endif + +#ifndef HAVE_STRUPR +char *strupr(char *str); +#endif + +#ifndef HAVE_STRREV +char *strrev(char *str); +#endif + +#ifndef HAVE_STRLCAT +size_t strlcat(char *dst, const char *src, size_t dsize); +#endif + +#ifndef HAVE_STRLCPY +size_t strlcpy(char *dst, const char *src, size_t dsize); +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/tools/miniposix/strings/strings.c b/compat/strings/strings.c similarity index 95% rename from tools/miniposix/strings/strings.c rename to compat/strings/strings.c index 440a1e3e..9ec7a59e 100644 --- a/tools/miniposix/strings/strings.c +++ b/compat/strings/strings.c @@ -19,7 +19,7 @@ SOFTWARE. */ #include -extern inline void explicit_bzero(void *s, size_t n); +extern inline void explicit_bzero(void* s, size_t n); extern inline int ffs(int i); extern inline int ffsl(long i); extern inline int ffsll(long long i); diff --git a/tools/miniposix/strings/strings.h b/compat/strings/strings.h similarity index 100% rename from tools/miniposix/strings/strings.h rename to compat/strings/strings.h diff --git a/tools/miniposix/unistd/unistd.h b/compat/unistd/unistd.h similarity index 100% rename from tools/miniposix/unistd/unistd.h rename to compat/unistd/unistd.h diff --git a/redalert/session.cpp b/redalert/session.cpp index fd68d0e5..01b784d4 100644 --- a/redalert/session.cpp +++ b/redalert/session.cpp @@ -689,7 +689,7 @@ bool Is_Mission_Aftermath(char* file_name) // Must start with "scm". char szCopy[_MAX_PATH + 1]; strcpy(szCopy, file_name); - _strlwr(szCopy); + strlwr(szCopy); if (strstr(szCopy, "scm") != szCopy) return false; diff --git a/redalert/stats.cpp b/redalert/stats.cpp index b90ec5d4..0521eae9 100644 --- a/redalert/stats.cpp +++ b/redalert/stats.cpp @@ -40,7 +40,7 @@ #include "function.h" #include "utracker.h" #include "common/packet.h" -#include "common/endianness.h" +#include "endianness.h" #include "common/internet.h" #include "common/gitinfo.h" diff --git a/tiberiandawn/externs.h b/tiberiandawn/externs.h index ff588bfa..3d30d664 100644 --- a/tiberiandawn/externs.h +++ b/tiberiandawn/externs.h @@ -50,7 +50,9 @@ #include "options.h" #include "infantry.h" #include "jshell.h" +#ifndef REMASTER_BUILD #include "common/vqaconfig.h" +#endif #include "common/winstub.h" #include "ccini.h" diff --git a/tiberiandawn/function.h b/tiberiandawn/function.h index e4df3b53..696f6715 100644 --- a/tiberiandawn/function.h +++ b/tiberiandawn/function.h @@ -688,7 +688,6 @@ int Fetch_Difficulty(void); void Remove_From_List(void** list, int* index, void* ptr); void* Conquer_Build_Fading_Table(void const* palette, void* dest, int color, int frac); void Fat_Put_Pixel(int x, int y, int color, int size, GraphicViewPortClass&); -void strtrim(char* buffer); long Get_EAX(void); /* diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 23e72463..e8c26795 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,5 +1,3 @@ -if (BUILD_TOOLS) - enable_language(C) # For miniposix. - add_subdirectory(miniposix) +if(BUILD_TOOLS) add_subdirectory(mixtool) endif() diff --git a/tools/miniposix/CMakeLists.txt b/tools/miniposix/CMakeLists.txt deleted file mode 100644 index 6f0a33cf..00000000 --- a/tools/miniposix/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -include(CheckIncludeFile) - -# Check if we are missing any posix headers we consider required. -check_include_file(strings.h HAVE_STRINGS_H) -check_include_file(libgen.h HAVE_LIBGEN_H) -check_include_file(dirent.h HAVE_DIRENT_H) -check_include_file(getopt.h HAVE_GETOPT_H) -check_include_file(unistd.h HAVE_UNISTD_H) - -if(HAVE_STRINGS_H AND HAVE_UNISTD_H AND HAVE_LIBGEN_H AND HAVE_DIRENT_H AND HAVE_GETOPT_H) - add_library(miniposix INTERFACE) -else() - add_library(miniposix STATIC) - - # Only win32 targets should really need miniposix at all, but just to be safe. - if(WIN32) - target_compile_definitions(miniposix PUBLIC _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN) - endif() -endif() - -if(NOT HAVE_STRINGS_H) - target_sources(miniposix PRIVATE strings/strings.c strings/strings.h) - target_include_directories(miniposix PUBLIC strings) -endif() - -if(NOT HAVE_LIBGEN_H) - target_sources(miniposix PRIVATE libgen/libgen.c libgen/libgen.h) - target_include_directories(miniposix PUBLIC libgen) -endif() - -if(NOT HAVE_DIRENT_H) - target_sources(miniposix PRIVATE dirent/dirent.c dirent/dirent.h) - target_include_directories(miniposix PUBLIC dirent) -endif() - -if(NOT HAVE_UNISTD_H) - target_sources(miniposix PRIVATE unistd/unistd.h) - target_include_directories(miniposix PUBLIC unistd) -endif() - -if(NOT HAVE_GETOPT_H) - target_sources(miniposix PRIVATE getopt/getopt.c getopt/getopt.h) - target_include_directories(miniposix PUBLIC getopt) -endif() diff --git a/tools/mixtool/CMakeLists.txt b/tools/mixtool/CMakeLists.txt index d9af8081..f95a5ccd 100644 --- a/tools/mixtool/CMakeLists.txt +++ b/tools/mixtool/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable(vanillamix makemix.cpp mixnamedb.cpp mixnamedb.h mixnamedb_data.cpp crc32.cpp crc32.h fastini.cpp fastini.h) -target_link_libraries(vanillamix PUBLIC common miniposix) +target_link_libraries(vanillamix PUBLIC common) if (WIN32) target_compile_definitions(vanillamix PRIVATE -DNOMINMAX)