diff --git a/.gitignore b/.gitignore
index 4b7da9f..e50a283 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@
*.save
*.autosav
*.autosave
+.DS_Store
# Tests
/tests/Makefile
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 55c6e56..e599244 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,10 +45,6 @@ include(CMakePackageConfigHelpers)
option(BUILD_SHARED_LIBS "Default to building shared libraries" ON)
option(BUILD_STATIC_LIBS "Default to building static libraries" ON)
-if (BUILD_SHARED_LIBS)
- add_definitions(-D JSON_C_DLL)
-endif()
-
# Generate a release merge and test it to verify the correctness of republishing the package.
ADD_CUSTOM_TARGET(distcheck
COMMAND make package_source
@@ -73,12 +69,57 @@ option(DISABLE_JSON_PATCH "Disable JSON patch (RFC6902) support."
option(NEWLOCALE_NEEDS_FREELOCALE "Work around newlocale bugs in old FreeBSD by calling freelocale" OFF)
option(BUILD_APPS "Default to building apps" ON)
+if (AMIGA)
+ set(DISABLE_THREAD_LOCAL_STORAGE ON)
+ set(ENABLE_THREADING OFF)
+ set(BUILD_SHARED_LIBS OFF)
+ set(BUILD_APPS OFF)
+ set(DISABLE_STATIC_FPIC ON)
+ if ($ENV{CROSS_PFX} STREQUAL "m68k-amigaos")
+ set(AMIGA_M68K ON)
+ set(BUILD_TESTING OFF)
+ if (${M68K_CRT} STREQUAL "newlib")
+ set(NEWLIB ON)
+ elseif(${M68K_CRT} STREQUAL "clib2")
+ set(CLIB2 ON)
+ elseif(${M68K_CRT} STREQUAL "ixemul")
+ set(IXEMUL ON)
+ elseif(${M68K_CRT} STREQUAL "nix20")
+ set(NIX20 ON)
+ elseif(${M68K_CRT} STREQUAL "nix13")
+ set(NIX13 ON)
+ else()
+ set(NEWLIB ON)
+ endif()
+ message(STATUS "Building for Motorola 68k AmigaOS using CRT: ${M68K_CRT}")
+ elseif ($ENV{CROSS_PFX} STREQUAL "ppc-amigaos")
+ set(AMIGA_PPC ON)
+ message(STATUS "Building for PowerPC AmigaOS")
+ elseif($ENV{CROSS_PFX} STREQUAL "ppc-morphos")
+ set(MORPHOS ON)
+ if (NOIXEMUL)
+ message(STATUS "Building for PowerPC MorphOS without ixemul")
+ set(DISABLE_WERROR ON)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -noixemul")
+ else()
+ message(STATUS "Building for PowerPC MorphOS with ixemul")
+ endif()
+ else()
+ message(FATAL_ERROR "Unsupported AmigaOS target")
+ endif()
+else()
+ message(STATUS "Building for ${CMAKE_SYSTEM_NAME}")
+endif()
-if (UNIX OR MINGW OR CYGWIN)
+if (UNIX OR MINGW OR CYGWIN OR AMIGA)
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
endif()
-if (UNIX)
+if (BUILD_SHARED_LIBS)
+ add_definitions(-D JSON_C_DLL)
+endif()
+
+if (UNIX OR AMIGA)
list(APPEND CMAKE_REQUIRED_LIBRARIES m)
endif()
@@ -136,7 +177,7 @@ endif()
check_symbol_exists(_isnan "float.h" HAVE_DECL__ISNAN)
check_symbol_exists(_finite "float.h" HAVE_DECL__FINITE)
-if ((MSVC AND NOT (MSVC_VERSION LESS 1800)) OR MINGW OR CYGWIN OR UNIX)
+if ((MSVC AND NOT (MSVC_VERSION LESS 1800)) OR MINGW OR CYGWIN OR UNIX OR AMIGA)
check_symbol_exists(INFINITY "math.h" HAVE_DECL_INFINITY)
check_symbol_exists(isinf "math.h" HAVE_DECL_ISINF)
check_symbol_exists(isnan "math.h" HAVE_DECL_ISNAN)
@@ -144,22 +185,23 @@ if ((MSVC AND NOT (MSVC_VERSION LESS 1800)) OR MINGW OR CYGWIN OR UNIX)
endif()
check_symbol_exists(_doprnt "stdio.h" HAVE_DOPRNT)
-if (UNIX OR MINGW OR CYGWIN)
+if (UNIX OR MINGW OR CYGWIN OR AMIGA)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
endif()
check_symbol_exists(vasprintf "stdio.h" HAVE_VASPRINTF)
check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
check_symbol_exists(vprintf "stdio.h" HAVE_VPRINTF)
-
-check_symbol_exists(arc4random "stdlib.h" HAVE_ARC4RANDOM)
+if (NOT AMIGA_M68K)
+ check_symbol_exists(arc4random "stdlib.h" HAVE_ARC4RANDOM)
+endif()
if (NOT HAVE_ARC4RANDOM AND DISABLE_EXTRA_LIBS STREQUAL "OFF")
check_include_file(bsd/stdlib.h HAVE_BSD_STDLIB_H)
if (HAVE_BSD_STDLIB_H)
- list(APPEND CMAKE_REQUIRED_LIBRARIES "bsd")
- unset(HAVE_ARC4RANDOM CACHE)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "bsd")
+ unset(HAVE_ARC4RANDOM CACHE)
check_symbol_exists(arc4random "bsd/stdlib.h" HAVE_ARC4RANDOM)
if (NOT HAVE_ARC4RANDOM)
- list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "bsd")
+ list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "bsd")
endif()
endif()
endif()
@@ -173,6 +215,10 @@ endif()
if (HAVE_LOCALE_H)
check_symbol_exists(setlocale "locale.h" HAVE_SETLOCALE)
check_symbol_exists(uselocale "locale.h" HAVE_USELOCALE)
+ if (NOT NIX20 AND NOT NIX13)
+ # libnix does not fully support this yet
+ check_symbol_exists(duplocale "locale.h" HAVE_DUPLOCALE)
+ endif()
endif()
# uClibc *intentionally* crashes in duplocale(), at least as of:
@@ -298,6 +344,9 @@ if ("${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER
if ("${DISABLE_WERROR}" STREQUAL "OFF")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
endif()
+ if (AMIGA_M68K)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fbaserel")
+ endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-qual")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=deprecated-declarations")
diff --git a/README.md b/README.md
index 38e8fb5..d15fa41 100644
--- a/README.md
+++ b/README.md
@@ -12,8 +12,9 @@ json-c
5. [Testing](#testing)
6. [Building with `vcpkg`](#buildvcpkg)
7. [Building for Android](#android)
-7. [Linking to libjson-c](#linking)
-8. [Using json-c](#using)
+8. [Building for Commodore Amiga or MorphOS](#amiga)
+9. [Linking to libjson-c](#linking)
+10. [Using json-c](#using)
JSON-C - A JSON implementation in C
@@ -270,6 +271,63 @@ cmake \
make install
```
+
+Building for Commodore Amiga or MorphOS
+----------------------
+
+Building for Commodore Amiga is supported for both Motorola 68k (AmigaOS 3) and PowerPC (AmigaOS 4) architectures. MorphOS on compatible PowerPC hardware is also supported. You can set up a cross compiler locally, however it is much easier to use the already preconfigured Amiga development environment wtthin a Docker container.
+
+Install Docker on your machine if you don't already have it. You can download Docker Desktop for Windows/macOS/Linux [here](https://www.docker.com/products/docker-desktop/).
+
+### To build for Motorola 68k Amiga:
+
+```
+mkdir build
+docker run --rm \
+ -v ${PWD}:/work \
+ -e USER=$( id -u ) -e GROUP=$( id -g ) \
+ -it sacredbanana/amiga-compiler:m68k-amigaos bash
+cd build
+cmake -DM68K_CRT=newlib ..
+make
+```
+
+libjson-c.a will get created in the build directory.
+
+You can change newlib to nix20, nix13, ixemul or clib2 if you would like to build the library suited for libnix or clib2 instead. Newlib is default.
+
+### To build for PowerPC Amiga:
+
+```
+mkdir build
+docker run --rm \
+ -v ${PWD}:/work \
+ -e USER=$( id -u ) -e GROUP=$( id -g ) \
+ -it sacredbanana/amiga-compiler:ppc-amigaos bash
+cd build
+cmake ..
+make
+```
+
+libjson-c.a will get created in the build directory.
+
+### To build for PowerPC MorphOS:
+
+```
+mkdir build
+docker run --rm \
+ -v ${PWD}:/work \
+ -e USER=$( id -u ) -e GROUP=$( id -g ) \
+ -it sacredbanana/amiga-compiler:ppc-morphos bash
+cd build
+cmake -DNOIXEMUL=1 ..
+make
+```
+
+If you are making an application that absolutely requires ixemul, then remove the `-DNOIXEMUL=1`.
+
+libjson-c.a will get created in the build directory.
+
Linking to `libjson-c`
----------------------
diff --git a/cmake/config.h.in b/cmake/config.h.in
index 1e6359d..6517340 100644
--- a/cmake/config.h.in
+++ b/cmake/config.h.in
@@ -137,6 +137,9 @@
/* Define to 1 if you have the `uselocale' function. */
#cmakedefine HAVE_USELOCALE
+/* Define to 1 if you have the `duplocale' function. */
+#cmakedefine HAVE_DUPLOCALE
+
/* Define to 1 if newlocale() needs freelocale() called on it's `base` argument */
#cmakedefine NEWLOCALE_NEEDS_FREELOCALE
diff --git a/json_tokener.c b/json_tokener.c
index 20bad14..53ef209 100644
--- a/json_tokener.c
+++ b/json_tokener.c
@@ -345,6 +345,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
#ifdef HAVE_USELOCALE
{
+#ifdef HAVE_DUPLOCALE
locale_t duploc = duplocale(oldlocale);
if (duploc == NULL && errno == ENOMEM)
{
@@ -352,16 +353,23 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
return NULL;
}
newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
+#else
+ newloc = newlocale(LC_NUMERIC_MASK, "C", oldlocale);
+#endif
if (newloc == NULL)
{
tok->err = json_tokener_error_memory;
+#ifdef HAVE_DUPLOCALE
freelocale(duploc);
+#endif
return NULL;
}
#ifdef NEWLOCALE_NEEDS_FREELOCALE
+#ifdef HAVE_DUPLOCALE
// Older versions of FreeBSD (<12.4) don't free the locale
// passed to newlocale(), so do it here
freelocale(duploc);
+#endif
#endif
uselocale(newloc);
}