diff --git a/.github/workflows/create-release-artifacts.yaml b/.github/workflows/create-release-artifacts.yaml index ef779360f5..1a6c639b22 100644 --- a/.github/workflows/create-release-artifacts.yaml +++ b/.github/workflows/create-release-artifacts.yaml @@ -139,7 +139,7 @@ jobs: body: | Please ensure that the four packages below work properly. Once that's done, replace this text with the changelog, un-draft the release, and update the `release` branch. - By the way, if you forgot to update `include/version.h`, RGBASM's version test is gonna fail in the tag's regression testing! (Use `git push --delete origin ` to delete it) + By the way, if you forgot to update `include/version.hpp`, RGBASM's version test is gonna fail in the tag's regression testing! (Use `git push --delete origin ` to delete it) draft: true # Don't publish the release quite yet... prerelease: ${{ contains(github.ref, '-rc') }} files: | diff --git a/CMakeLists.txt b/CMakeLists.txt index b529451573..08c02c733b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.9 FATAL_ERROR) project(rgbds - LANGUAGES C CXX) + LANGUAGES CXX) # get real path of source and binary directories get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) @@ -31,10 +31,6 @@ if(MSVC) # "macro expansion producing 'defined' has undefined behavior" add_compile_options(/MP /wd5105) add_definitions(/D_CRT_SECURE_NO_WARNINGS) - # Also, CMake appears not to pass the C11-enabling flag, so we must add it manually... but only for C! - if(NOT CMAKE_C_FLAGS MATCHES "std:c11") # The flag may already have been injected by an earlier CMake invocation, so don't add it twice - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std:c11" CACHE STRING "Flags used by the C compiler during all build types." FORCE) - endif() if(SANITIZERS) set(SAN_FLAGS /fsanitize=address) @@ -42,8 +38,8 @@ if(MSVC) add_link_options(${SAN_FLAGS}) endif() else() - add_compile_options(-Wall -pedantic) - add_definitions(-D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE) + add_compile_options(-Wall) + add_definitions(-D_POSIX_C_SOURCE=200809L) if(SANITIZERS) set(SAN_FLAGS -fsanitize=shift -fsanitize=integer-divide-by-zero -fsanitize=unreachable -fsanitize=vla-bound @@ -55,7 +51,6 @@ else() add_definitions(-D_GLIBCXX_ASSERTIONS) # A non-zero optimization level is desired in debug mode, but allow overriding it nonetheless # TODO: this overrides anything previously set... that's a bit sloppy! - set(CMAKE_C_FLAGS_DEBUG "-g -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE STRING "" FORCE) set(CMAKE_CXX_FLAGS_DEBUG "-g -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE STRING "" FORCE) endif() @@ -98,8 +93,6 @@ endif() include_directories("${PROJECT_SOURCE_DIR}/include") -set(CMAKE_C_STANDARD 11) -set(CMAKE_C_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) diff --git a/Makefile b/Makefile index 6b005f31e3..05312d2d1a 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ # .SUFFIXES: -.SUFFIXES: .h .y .c .cpp .o +.SUFFIXES: .hpp .cpp .y .o .PHONY: all clean install checkcodebase checkpatch checkdiff develop debug mingw32 mingw64 wine-shim dist @@ -29,19 +29,16 @@ PNGCFLAGS := `${PKG_CONFIG} --cflags libpng` PNGLDFLAGS := `${PKG_CONFIG} --libs-only-L libpng` PNGLDLIBS := `${PKG_CONFIG} --libs-only-l libpng` -# Note: if this comes up empty, `version.c` will automatically fall back to last release number +# Note: if this comes up empty, `version.cpp` will automatically fall back to last release number VERSION_STRING := `git describe --tags --dirty --always 2>/dev/null` -WARNFLAGS := -Wall -pedantic +WARNFLAGS := -Wall + # -pedantic -# Overridable CFLAGS -CFLAGS ?= -O3 -flto -DNDEBUG +# Overridable CXXFLAGS CXXFLAGS ?= -O3 -flto -DNDEBUG -# Non-overridable CFLAGS -# _ISOC11_SOURCE is required on certain platforms to get C11 on top of the C99-based POSIX 2008 -REALCFLAGS := ${CFLAGS} ${WARNFLAGS} -std=gnu11 -I include \ - -D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE -REALCXXFLAGS := ${CXXFLAGS} ${WARNFLAGS} -std=c++17 -I include \ +# Non-overridable CXXFLAGS +REALCXXFLAGS := ${CXXFLAGS} ${WARNFLAGS} -x c++ -std=c++17 -I include \ -D_POSIX_C_SOURCE=200809L -fno-exceptions -fno-rtti # Overridable LDFLAGS LDFLAGS ?= @@ -84,7 +81,7 @@ rgbasm_obj := \ src/linkdefs.o \ src/opmath.o -src/asm/lexer.o src/asm/main.o: src/asm/parser.h +src/asm/lexer.o src/asm/main.o: src/asm/parser.hpp rgblink_obj := \ src/link/assign.o \ @@ -121,19 +118,19 @@ rgbgfx_obj := \ src/error.o rgbasm: ${rgbasm_obj} - $Q${CC} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCFLAGS} src/version.c -lm + $Q${CXX} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCXXFLAGS} src/version.cpp -lm rgblink: ${rgblink_obj} - $Q${CC} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCFLAGS} src/version.c + $Q${CXX} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCXXFLAGS} src/version.cpp rgbfix: ${rgbfix_obj} - $Q${CC} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCFLAGS} src/version.c + $Q${CXX} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCXXFLAGS} src/version.cpp rgbgfx: ${rgbgfx_obj} - $Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCXXFLAGS} ${PNGLDLIBS} -x c++ src/version.c + $Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCXXFLAGS} ${PNGLDLIBS} src/version.cpp -test/gfx/randtilegen: test/gfx/randtilegen.c - $Q${CC} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCFLAGS} ${PNGCFLAGS} ${PNGLDLIBS} +test/gfx/randtilegen: test/gfx/randtilegen.cpp + $Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGCFLAGS} ${PNGLDLIBS} test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp $Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGLDLIBS} @@ -144,10 +141,10 @@ test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp .y.o: # Bison-generated C files have an accompanying header -src/asm/parser.h: src/asm/parser.c +src/asm/parser.hpp: src/asm/parser.cpp $Qtouch $@ -src/asm/parser.c: src/asm/parser.y +src/asm/parser.cpp: src/asm/parser.y $QDEFS=; \ add_flag(){ \ if src/check_bison_ver.sh $$1 $$2; then \ @@ -162,9 +159,6 @@ src/asm/parser.c: src/asm/parser.y echo "DEFS=$$DEFS"; \ ${BISON} $$DEFS -d ${YFLAGS} -o $@ $< -.c.o: - $Q${CC} ${REALCFLAGS} -c -o $@ $< - .cpp.o: $Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $< @@ -177,7 +171,7 @@ clean: $Q${RM} rgbgfx rgbgfx.exe $Qfind src/ -name "*.o" -exec rm {} \; $Q${RM} rgbshim.sh - $Q${RM} src/asm/parser.c src/asm/parser.h + $Q${RM} src/asm/parser.cpp src/asm/parser.hpp $Q${RM} test/gfx/randtilegen test/gfx/rgbgfx_test # Target used to install the binaries and man pages. @@ -195,7 +189,7 @@ install: all # `.y` files aren't checked, unfortunately... checkcodebase: - $Qfor file in `git ls-files | grep -E '(\.c|\.h)$$' | grep -Ev '(src|include)/extern/'`; do \ + $Qfor file in `git ls-files | grep -E '(\.cpp|\.hpp)$$' | grep -Ev '(src|include)/extern/'`; do \ ${CHECKPATCH} -f "$$file"; \ done @@ -240,14 +234,12 @@ develop: -fsanitize=signed-integer-overflow -fsanitize=bounds \ -fsanitize=object-size -fsanitize=bool -fsanitize=enum \ -fsanitize=alignment -fsanitize=null -fsanitize=address" \ - CFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" \ CXXFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" # This target is used during development in order to more easily debug with gdb. debug: $Qenv ${MAKE} \ - CFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" \ CXXFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" # Targets for the project maintainer to easily create Windows exes. @@ -257,12 +249,12 @@ debug: mingw32: $Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \ - CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ \ + CXX=i686-w64-mingw32-g++ \ BISON=bison PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/i686-w64-mingw32 pkg-config" mingw64: $Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \ - CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ \ + CXX=x86_64-w64-mingw32-g++ \ BISON=bison PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/x86_64-w64-mingw32 pkg-config" wine-shim: diff --git a/RELEASE.rst b/RELEASE.rst index 2246e69e2b..caaccdb9d8 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -4,7 +4,7 @@ Releasing This describes for the maintainers of RGBDS how to publish a new release on GitHub. -1. Update, commit, and push `include/version.h `__ with +1. Update, commit, and push `include/version.hpp `__ with values for ``PACKAGE_VERSION_MAJOR``, ``PACKAGE_VERSION_MINOR``, ``PACKAGE_VERSION_PATCH``, and ``PACKAGE_VERSION_RC``. Only define ``PACKAGE_VERSION_RC`` if you are publishing a release candidate! You can @@ -13,7 +13,7 @@ GitHub. 2. Create a Git tag formatted as ``v..``, or ``v..-rc`` for a release candidate. ``MAJOR``, ``MINOR``, ``PATCH``, and ``RC`` should match their values from - `include/version.h `__. You can use ``git tag ``. + `include/version.hpp `__. You can use ``git tag ``. 3. Push the tag to GitHub. You can use ``git push origin ``. diff --git a/contrib/checkdiff.bash b/contrib/checkdiff.bash index fc180044a4..3061549025 100755 --- a/contrib/checkdiff.bash +++ b/contrib/checkdiff.bash @@ -40,46 +40,46 @@ dependency () { # Pull requests that edit the first file without the second may be correct, # but are suspicious enough to require review. -dependency include/linkdefs.h man/rgbds.5 \ +dependency include/linkdefs.hpp man/rgbds.5 \ "Was the object file format changed?" -dependency src/asm/parser.y man/rgbasm.5 \ +dependency src/asm/parser.y man/rgbasm.5 \ "Was the rgbasm grammar changed?" -dependency include/asm/warning.h man/rgbasm.1 \ +dependency include/asm/warning.hpp man/rgbasm.1 \ "Were the rgbasm warnings changed?" -dependency src/asm/object.c include/linkdefs.h \ +dependency src/asm/object.cpp include/linkdefs.hpp \ "Should the object file revision be bumped?" -dependency src/link/object.c include/linkdefs.h \ +dependency src/link/object.cpp include/linkdefs.hpp \ "Should the object file revision be bumped?" -dependency Makefile CMakeLists.txt \ +dependency Makefile CMakeLists.txt \ "Did the build process change?" -dependency Makefile src/CMakeLists.txt \ +dependency Makefile src/CMakeLists.txt \ "Did the build process change?" -dependency src/asm/main.c man/rgbasm.1 \ +dependency src/asm/main.cpp man/rgbasm.1 \ "Did the rgbasm CLI change?" -dependency src/asm/main.c contrib/zsh_compl/_rgbasm \ +dependency src/asm/main.cpp contrib/zsh_compl/_rgbasm \ "Did the rgbasm CLI change?" -dependency src/asm/main.c contrib/bash_compl/_rgbasm.bash \ +dependency src/asm/main.cpp contrib/bash_compl/_rgbasm.bash \ "Did the rgbasm CLI change?" -dependency src/link/main.c man/rgblink.1 \ +dependency src/link/main.cpp man/rgblink.1 \ "Did the rgblink CLI change?" -dependency src/link/main.c contrib/zsh_compl/_rgblink \ +dependency src/link/main.cpp contrib/zsh_compl/_rgblink \ "Did the rgblink CLI change?" -dependency src/link/main.c contrib/bash_compl/_rgblink.bash \ +dependency src/link/main.cpp contrib/bash_compl/_rgblink.bash \ "Did the rgblink CLI change?" -dependency src/fix/main.c man/rgbfix.1 \ +dependency src/fix/main.cpp man/rgbfix.1 \ "Did the rgbfix CLI change?" -dependency src/fix/main.c contrib/zsh_compl/_rgbfix \ +dependency src/fix/main.cpp contrib/zsh_compl/_rgbfix \ "Did the rgbfix CLI change?" -dependency src/fix/main.c contrib/bash_compl/_rgbfix.bash \ +dependency src/fix/main.cpp contrib/bash_compl/_rgbfix.bash \ "Did the rgbfix CLI change?" -dependency src/gfx/main.cpp man/rgbgfx.1 \ +dependency src/gfx/main.cpp man/rgbgfx.1 \ "Did the rgbgfx CLI change?" -dependency src/gfx/main.cpp contrib/zsh_compl/_rgbgfx \ +dependency src/gfx/main.cpp contrib/zsh_compl/_rgbgfx \ "Did the rgbgfx CLI change?" -dependency src/gfx/main.cpp contrib/bash_compl/_rgbgfx.bash \ +dependency src/gfx/main.cpp contrib/bash_compl/_rgbgfx.bash \ "Did the rgbgfx CLI change?" diff --git a/include/asm/charmap.h b/include/asm/charmap.hpp similarity index 100% rename from include/asm/charmap.h rename to include/asm/charmap.hpp diff --git a/include/asm/fixpoint.h b/include/asm/fixpoint.hpp similarity index 100% rename from include/asm/fixpoint.h rename to include/asm/fixpoint.hpp diff --git a/include/asm/format.h b/include/asm/format.hpp similarity index 100% rename from include/asm/format.h rename to include/asm/format.hpp diff --git a/include/asm/fstack.h b/include/asm/fstack.hpp similarity index 95% rename from include/asm/fstack.h rename to include/asm/fstack.hpp index 5f1851a71e..27ed3118ed 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.hpp @@ -15,9 +15,15 @@ #include #include -#include "asm/lexer.h" +#include "asm/lexer.hpp" +enum FileStackNodeType { + NODE_REPT, + NODE_FILE, + NODE_MACRO, +}; + struct FileStackNode { struct FileStackNode *parent; // Pointer to parent node, for error reporting // Line at which the parent context was exited; meaningless for the root level @@ -27,11 +33,7 @@ struct FileStackNode { bool referenced; // If referenced, don't free! uint32_t ID; // Set only if referenced: ID within the object file, -1 if not output yet - enum { - NODE_REPT, - NODE_FILE, - NODE_MACRO, - } type; + enum FileStackNodeType type; }; struct FileStackReptNode { // NODE_REPT diff --git a/include/asm/lexer.h b/include/asm/lexer.hpp similarity index 100% rename from include/asm/lexer.h rename to include/asm/lexer.hpp diff --git a/include/asm/macro.h b/include/asm/macro.hpp similarity index 94% rename from include/asm/macro.h rename to include/asm/macro.hpp index e0988ee95a..e4005ddce5 100644 --- a/include/asm/macro.h +++ b/include/asm/macro.hpp @@ -13,9 +13,9 @@ #include #include -#include "asm/warning.h" +#include "asm/warning.hpp" -#include "helpers.h" +#include "helpers.hpp" struct MacroArgs; diff --git a/include/asm/main.h b/include/asm/main.hpp similarity index 96% rename from include/asm/main.h rename to include/asm/main.hpp index 3653252745..ecfa779f6b 100644 --- a/include/asm/main.h +++ b/include/asm/main.hpp @@ -13,7 +13,7 @@ #include #include -#include "helpers.h" +#include "helpers.hpp" extern bool haltnop; extern bool warnOnHaltNop; diff --git a/include/asm/opt.h b/include/asm/opt.hpp similarity index 86% rename from include/asm/opt.h rename to include/asm/opt.hpp index f9e9345b92..1819e302b7 100644 --- a/include/asm/opt.h +++ b/include/asm/opt.hpp @@ -17,8 +17,8 @@ void opt_G(char const chars[4]); void opt_P(uint8_t padByte); void opt_Q(uint8_t precision); void opt_L(bool optimize); -void opt_W(char const *flag); -void opt_Parse(char const *option); +void opt_W(char *flag); +void opt_Parse(char *option); void opt_Push(void); void opt_Pop(void); diff --git a/include/asm/output.h b/include/asm/output.hpp similarity index 96% rename from include/asm/output.h rename to include/asm/output.hpp index 579e9a45f5..bd0fd2cb5c 100644 --- a/include/asm/output.h +++ b/include/asm/output.hpp @@ -11,7 +11,7 @@ #include -#include "linkdefs.h" +#include "linkdefs.hpp" struct Expression; struct FileStackNode; diff --git a/include/asm/rpn.h b/include/asm/rpn.hpp similarity index 99% rename from include/asm/rpn.h rename to include/asm/rpn.hpp index 4ca3cdd97f..1678863235 100644 --- a/include/asm/rpn.h +++ b/include/asm/rpn.hpp @@ -12,7 +12,7 @@ #include #include -#include "linkdefs.h" +#include "linkdefs.hpp" #define MAXRPNLEN 1048576 diff --git a/include/asm/section.h b/include/asm/section.hpp similarity index 91% rename from include/asm/section.h rename to include/asm/section.hpp index d92aca67f1..648eb1f68f 100644 --- a/include/asm/section.h +++ b/include/asm/section.hpp @@ -12,8 +12,8 @@ #include #include -#include "linkdefs.h" -#include "platform.h" // NONNULL +#include "linkdefs.hpp" +#include "platform.hpp" // NONNULL extern uint8_t fillByte; @@ -44,9 +44,9 @@ struct SectionSpec { extern struct Section *currentSection; struct Section *sect_FindSectionByName(char const *name); -void sect_NewSection(char const *name, uint32_t secttype, uint32_t org, +void sect_NewSection(char const *name, enum SectionType type, uint32_t org, struct SectionSpec const *attributes, enum SectionModifier mod); -void sect_SetLoadSection(char const *name, uint32_t secttype, uint32_t org, +void sect_SetLoadSection(char const *name, enum SectionType type, uint32_t org, struct SectionSpec const *attributes, enum SectionModifier mod); void sect_EndLoadSection(void); diff --git a/include/asm/symbol.h b/include/asm/symbol.hpp similarity index 98% rename from include/asm/symbol.h rename to include/asm/symbol.hpp index 627868f4f9..8736e4d0ad 100644 --- a/include/asm/symbol.h +++ b/include/asm/symbol.hpp @@ -14,9 +14,9 @@ #include #include -#include "asm/section.h" +#include "asm/section.hpp" -#include "platform.h" // MIN_NB_ELMS +#include "platform.hpp" // MIN_NB_ELMS #define MAXSYMLEN 255 diff --git a/include/asm/util.h b/include/asm/util.hpp similarity index 100% rename from include/asm/util.h rename to include/asm/util.hpp diff --git a/include/asm/warning.h b/include/asm/warning.hpp similarity index 96% rename from include/asm/warning.h rename to include/asm/warning.hpp index 12b17a5c6f..7cbf143d1a 100644 --- a/include/asm/warning.h +++ b/include/asm/warning.hpp @@ -9,7 +9,7 @@ #ifndef WARNING_H #define WARNING_H -#include "helpers.h" +#include "helpers.hpp" extern unsigned int nbErrors; @@ -83,7 +83,7 @@ void warning(enum WarningID id, char const *fmt, ...) format_(printf, 2, 3); * It is also used when the assembler goes into an invalid state (for example, * when it fails to allocate memory). */ -_Noreturn void fatalerror(char const *fmt, ...) format_(printf, 1, 2); +[[noreturn]] void fatalerror(char const *fmt, ...) format_(printf, 1, 2); /* * Used for errors that make it impossible to assemble correctly, but don't diff --git a/include/error.h b/include/error.hpp similarity index 66% rename from include/error.h rename to include/error.hpp index f7ad06a438..d203047b3d 100644 --- a/include/error.h +++ b/include/error.hpp @@ -9,8 +9,8 @@ #ifndef RGBDS_ERROR_H #define RGBDS_ERROR_H -#include "helpers.h" -#include "platform.h" +#include "helpers.hpp" +#include "platform.hpp" #ifdef __cplusplus extern "C" { @@ -19,8 +19,8 @@ extern "C" { void warn(char const NONNULL(fmt), ...) format_(printf, 1, 2); void warnx(char const NONNULL(fmt), ...) format_(printf, 1, 2); -_Noreturn void err(char const NONNULL(fmt), ...) format_(printf, 1, 2); -_Noreturn void errx(char const NONNULL(fmt), ...) format_(printf, 1, 2); +[[noreturn]] void err(char const NONNULL(fmt), ...) format_(printf, 1, 2); +[[noreturn]] void errx(char const NONNULL(fmt), ...) format_(printf, 1, 2); #ifdef __cplusplus } diff --git a/include/extern/getopt.h b/include/extern/getopt.hpp similarity index 100% rename from include/extern/getopt.h rename to include/extern/getopt.hpp diff --git a/include/extern/utf8decoder.h b/include/extern/utf8decoder.hpp similarity index 100% rename from include/extern/utf8decoder.h rename to include/extern/utf8decoder.hpp diff --git a/include/file.hpp b/include/file.hpp index 38ca3763fe..ace857a90b 100644 --- a/include/file.hpp +++ b/include/file.hpp @@ -22,8 +22,8 @@ #include #include -#include "helpers.h" -#include "platform.h" +#include "helpers.hpp" +#include "platform.hpp" #include "gfx/main.hpp" diff --git a/include/gfx/main.hpp b/include/gfx/main.hpp index 7a5b02133c..feaf273052 100644 --- a/include/gfx/main.hpp +++ b/include/gfx/main.hpp @@ -16,7 +16,7 @@ #include #include -#include "helpers.h" +#include "helpers.hpp" #include "gfx/rgba.hpp" diff --git a/include/hashmap.h b/include/hashmap.hpp similarity index 100% rename from include/hashmap.h rename to include/hashmap.hpp diff --git a/include/helpers.h b/include/helpers.hpp similarity index 88% rename from include/helpers.h rename to include/helpers.hpp index 63002cf3d7..4411f07ec0 100644 --- a/include/helpers.h +++ b/include/helpers.hpp @@ -9,11 +9,6 @@ #ifndef HELPERS_H #define HELPERS_H -// Of course, MSVC does not support C11, so no _Noreturn there... -#ifdef _MSC_VER - #define _Noreturn __declspec(noreturn) -#endif - // Ideally, we'd use `__has_attribute` and `__has_builtin`, but these were only introduced in GCC 9 #ifdef __GNUC__ // GCC or compatible #define format_(archetype, str_index, first_arg) \ @@ -30,8 +25,8 @@ #define format_(archetype, str_index, first_arg) #define attr_(...) // This seems to generate similar code to __builtin_unreachable, despite different semantics - // Note that executing this is undefined behavior (declared _Noreturn, but does return) - static inline _Noreturn void unreachable_(void) {} + // Note that executing this is undefined behavior (declared [[noreturn]], but does return) + static inline [[noreturn]] void unreachable_(void) {} #endif // Use builtins whenever possible, and shim them otherwise diff --git a/include/link/assign.h b/include/link/assign.hpp similarity index 100% rename from include/link/assign.h rename to include/link/assign.hpp diff --git a/include/link/main.h b/include/link/main.hpp similarity index 91% rename from include/link/main.h rename to include/link/main.hpp index c7ca7dcebd..2f07ba7758 100644 --- a/include/link/main.h +++ b/include/link/main.hpp @@ -14,7 +14,7 @@ #include #include -#include "helpers.h" +#include "helpers.hpp" // Variables related to CLI options extern bool isDmgMode; @@ -33,16 +33,18 @@ extern bool beVerbose; extern bool isWRA0Mode; extern bool disablePadding; +enum FileStackNodeType { + NODE_REPT, + NODE_FILE, + NODE_MACRO, +}; + struct FileStackNode { struct FileStackNode *parent; // Line at which the parent context was exited; meaningless for the root level uint32_t lineNo; - enum { - NODE_REPT, - NODE_FILE, - NODE_MACRO, - } type; + enum FileStackNodeType type; union { char *name; // NODE_FILE, NODE_MACRO struct { // NODE_REPT @@ -70,7 +72,7 @@ void warning(struct FileStackNode const *where, uint32_t lineNo, void error(struct FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) format_(printf, 3, 4); -_Noreturn void fatal(struct FileStackNode const *where, uint32_t lineNo, +[[noreturn]] void fatal(struct FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) format_(printf, 3, 4); /* diff --git a/include/link/object.h b/include/link/object.hpp similarity index 100% rename from include/link/object.h rename to include/link/object.hpp diff --git a/include/link/output.h b/include/link/output.hpp similarity index 96% rename from include/link/output.h rename to include/link/output.hpp index d68f254c01..85ff4fe323 100644 --- a/include/link/output.h +++ b/include/link/output.hpp @@ -12,7 +12,7 @@ #include -#include "link/section.h" +#include "link/section.hpp" /* * Registers a section for output. diff --git a/include/link/patch.h b/include/link/patch.hpp similarity index 93% rename from include/link/patch.h rename to include/link/patch.hpp index 37c1f8f927..eac381532c 100644 --- a/include/link/patch.h +++ b/include/link/patch.hpp @@ -13,9 +13,9 @@ #include #include -#include "link/section.h" +#include "link/section.hpp" -#include "linkdefs.h" +#include "linkdefs.hpp" struct Assertion { struct Patch patch; diff --git a/include/link/script.h b/include/link/script.hpp similarity index 96% rename from include/link/script.h rename to include/link/script.hpp index a736bcb0af..17902dfa30 100644 --- a/include/link/script.h +++ b/include/link/script.hpp @@ -11,7 +11,8 @@ #define RGBDS_LINK_SCRIPT_H #include -#include "linkdefs.h" + +#include "linkdefs.hpp" extern FILE * linkerScript; diff --git a/include/link/sdas_obj.h b/include/link/sdas_obj.hpp similarity index 100% rename from include/link/sdas_obj.h rename to include/link/sdas_obj.hpp diff --git a/include/link/section.h b/include/link/section.hpp similarity index 98% rename from include/link/section.h rename to include/link/section.hpp index 8f34417a3d..997149aa02 100644 --- a/include/link/section.h +++ b/include/link/section.hpp @@ -15,9 +15,9 @@ #include #include -#include "link/main.h" +#include "link/main.hpp" -#include "linkdefs.h" +#include "linkdefs.hpp" struct FileStackNode; struct Section; diff --git a/include/link/symbol.h b/include/link/symbol.hpp similarity index 98% rename from include/link/symbol.h rename to include/link/symbol.hpp index 2a1611302f..4e4ffdd83a 100644 --- a/include/link/symbol.h +++ b/include/link/symbol.hpp @@ -14,7 +14,7 @@ #include -#include "linkdefs.h" +#include "linkdefs.hpp" struct FileStackNode; diff --git a/include/linkdefs.h b/include/linkdefs.hpp similarity index 100% rename from include/linkdefs.h rename to include/linkdefs.hpp diff --git a/include/opmath.h b/include/opmath.hpp similarity index 100% rename from include/opmath.h rename to include/opmath.hpp diff --git a/include/platform.h b/include/platform.hpp similarity index 85% rename from include/platform.h rename to include/platform.hpp index 3362fa4eeb..dfddba27ca 100644 --- a/include/platform.h +++ b/include/platform.hpp @@ -46,16 +46,11 @@ # include #endif -// MSVC doesn't support `[static N]` for array arguments from C99 or C11 -#ifdef _MSC_VER -# define MIN_NB_ELMS(N) -# define ARR_QUALS(...) -# define NONNULL(ptr) *ptr -#else -# define MIN_NB_ELMS(N) static (N) -# define ARR_QUALS(...) __VA_ARGS__ -# define NONNULL(ptr) ptr[static 1] -#endif +// C++ doesn't support `[static N]` for array arguments from C99 or C11 +#define MIN_NB_ELMS(N) // static (N) +#define ARR_QUALS(...) // __VA_ARGS__ +#define NONNULL(ptr) *ptr // ptr[static 1] +#define restrict // MSVC uses a different name for O_RDWR, and needs an additional _O_BINARY flag #ifdef _MSC_VER diff --git a/include/version.h b/include/version.hpp similarity index 100% rename from include/version.h rename to include/version.hpp diff --git a/src/.gitignore b/src/.gitignore index eca8b32e35..889920df26 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,2 +1,2 @@ # Generated by CMake -/.version.c +/.version.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78d1472b10..d4a933f656 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,12 +6,12 @@ # SPDX-License-Identifier: MIT # -configure_file(version.c _version.c ESCAPE_QUOTES) +configure_file(version.cpp _version.cpp ESCAPE_QUOTES) set(common_src - "error.c" - "extern/getopt.c" - "_version.c" + "error.cpp" + "extern/getopt.cpp" + "_version.cpp" ) find_package(BISON 3.0.0 REQUIRED) @@ -29,35 +29,35 @@ set(BISON_FLAGS "${BISON_FLAGS} -Dparse.lac=full") set(BISON_FLAGS "${BISON_FLAGS} -Dlr.type=ielr") BISON_TARGET(PARSER "asm/parser.y" - "${PROJECT_SOURCE_DIR}/src/asm/parser.c" + "${PROJECT_SOURCE_DIR}/src/asm/parser.cpp" COMPILE_FLAGS "${BISON_FLAGS}" - DEFINES_FILE "${PROJECT_SOURCE_DIR}/src/asm/parser.h" + DEFINES_FILE "${PROJECT_SOURCE_DIR}/src/asm/parser.hpp" ) set(rgbasm_src "${BISON_PARSER_OUTPUT_SOURCE}" - "asm/charmap.c" - "asm/fixpoint.c" - "asm/format.c" - "asm/fstack.c" - "asm/lexer.c" - "asm/macro.c" - "asm/main.c" - "asm/opt.c" - "asm/output.c" - "asm/rpn.c" - "asm/section.c" - "asm/symbol.c" - "asm/util.c" - "asm/warning.c" - "extern/utf8decoder.c" - "hashmap.c" - "linkdefs.c" - "opmath.c" + "asm/charmap.cpp" + "asm/fixpoint.cpp" + "asm/format.cpp" + "asm/fstack.cpp" + "asm/lexer.cpp" + "asm/macro.cpp" + "asm/main.cpp" + "asm/opt.cpp" + "asm/output.cpp" + "asm/rpn.cpp" + "asm/section.cpp" + "asm/symbol.cpp" + "asm/util.cpp" + "asm/warning.cpp" + "extern/utf8decoder.cpp" + "hashmap.cpp" + "linkdefs.cpp" + "opmath.cpp" ) set(rgbfix_src - "fix/main.c" + "fix/main.cpp" ) set(rgbgfx_src @@ -69,24 +69,24 @@ set(rgbgfx_src "gfx/proto_palette.cpp" "gfx/reverse.cpp" "gfx/rgba.cpp" - "extern/getopt.c" - "error.c" + "extern/getopt.cpp" + "error.cpp" ) set(rgblink_src - "link/assign.c" - "link/main.c" - "link/object.c" - "link/output.c" - "link/patch.c" - "link/script.c" - "link/sdas_obj.c" - "link/section.c" - "link/symbol.c" - "extern/utf8decoder.c" - "hashmap.c" - "linkdefs.c" - "opmath.c" + "link/assign.cpp" + "link/main.cpp" + "link/object.cpp" + "link/output.cpp" + "link/patch.cpp" + "link/script.cpp" + "link/sdas_obj.cpp" + "link/section.cpp" + "link/symbol.cpp" + "extern/utf8decoder.cpp" + "hashmap.cpp" + "linkdefs.cpp" + "opmath.cpp" ) foreach(PROG "asm" "fix" "gfx" "link") diff --git a/src/asm/.gitignore b/src/asm/.gitignore index b73e7fb41d..4b4029a348 100644 --- a/src/asm/.gitignore +++ b/src/asm/.gitignore @@ -1,2 +1,2 @@ -/parser.c -/parser.h +/parser.cpp +/parser.hpp diff --git a/src/asm/charmap.c b/src/asm/charmap.cpp similarity index 94% rename from src/asm/charmap.c rename to src/asm/charmap.cpp index bbf428c728..a2371b2737 100644 --- a/src/asm/charmap.c +++ b/src/asm/charmap.cpp @@ -13,13 +13,13 @@ #include #include -#include "asm/charmap.h" -#include "asm/main.h" -#include "asm/output.h" -#include "asm/util.h" -#include "asm/warning.h" +#include "asm/charmap.hpp" +#include "asm/main.hpp" +#include "asm/output.hpp" +#include "asm/util.hpp" +#include "asm/warning.hpp" -#include "hashmap.h" +#include "hashmap.hpp" // Charmaps are stored using a structure known as "trie". // Essentially a tree, where each nodes stores a single character's worth of info: @@ -55,12 +55,12 @@ struct CharmapStackEntry *charmapStack; static struct Charmap *charmap_Get(char const *name) { - return hash_GetElement(charmaps, name); + return (struct Charmap *)hash_GetElement(charmaps, name); } static void resizeCharmap(struct Charmap **map, size_t capacity) { - *map = realloc(*map, sizeof(**map) + sizeof(*(*map)->nodes) * capacity); + *map = (struct Charmap *)realloc(*map, sizeof(**map) + sizeof(*(*map)->nodes) * capacity); if (!*map) fatalerror("Failed to %s charmap: %s\n", @@ -128,9 +128,8 @@ void charmap_Set(char const *name) void charmap_Push(void) { - struct CharmapStackEntry *stackEntry; + struct CharmapStackEntry *stackEntry = (struct CharmapStackEntry *)malloc(sizeof(*stackEntry)); - stackEntry = malloc(sizeof(*stackEntry)); if (stackEntry == NULL) fatalerror("Failed to alloc charmap stack entry: %s\n", strerror(errno)); diff --git a/src/asm/fixpoint.c b/src/asm/fixpoint.cpp similarity index 96% rename from src/asm/fixpoint.c rename to src/asm/fixpoint.cpp index 861fd1ce9d..f3f13b2eb4 100644 --- a/src/asm/fixpoint.c +++ b/src/asm/fixpoint.cpp @@ -12,9 +12,9 @@ #include #include -#include "asm/fixpoint.h" -#include "asm/symbol.h" -#include "asm/warning.h" +#include "asm/fixpoint.hpp" +#include "asm/symbol.hpp" +#include "asm/warning.hpp" #ifndef M_PI #define M_PI 3.14159265358979323846 diff --git a/src/asm/format.c b/src/asm/format.cpp similarity index 98% rename from src/asm/format.c rename to src/asm/format.cpp index 960775d60b..5fe2f5691c 100644 --- a/src/asm/format.c +++ b/src/asm/format.cpp @@ -15,13 +15,13 @@ #include #include -#include "asm/fixpoint.h" -#include "asm/format.h" -#include "asm/warning.h" +#include "asm/fixpoint.hpp" +#include "asm/format.hpp" +#include "asm/warning.hpp" struct FormatSpec fmt_NewSpec(void) { - struct FormatSpec fmt = {0}; + struct FormatSpec fmt = {}; return fmt; } diff --git a/src/asm/fstack.c b/src/asm/fstack.cpp similarity index 93% rename from src/asm/fstack.c rename to src/asm/fstack.cpp index 4f12fc493c..8d24adde4c 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.cpp @@ -14,13 +14,13 @@ #include #include -#include "asm/fstack.h" -#include "asm/macro.h" -#include "asm/main.h" -#include "asm/symbol.h" -#include "asm/warning.h" -#include "error.h" -#include "platform.h" // S_ISDIR (stat macro) +#include "asm/fstack.hpp" +#include "asm/macro.hpp" +#include "asm/main.hpp" +#include "asm/symbol.hpp" +#include "asm/warning.hpp" +#include "error.hpp" +#include "platform.hpp" // S_ISDIR (stat macro) #define MAXINCPATHS 128 @@ -120,7 +120,7 @@ void fstk_AddIncludePath(char const *path) } size_t len = strlen(path); size_t allocSize = len + (path[len - 1] != '/') + 1; - char *str = malloc(allocSize); + char *str = (char *)malloc(allocSize); if (!str) { // Attempt to continue without that path @@ -169,7 +169,7 @@ bool fstk_FindFile(char const *path, char **fullPath, size_t *size) { if (!*size) { *size = 64; // This is arbitrary, really - *fullPath = realloc(*fullPath, *size); + *fullPath = (char *)realloc(*fullPath, *size); if (!*fullPath) error("realloc error during include path search: %s\n", strerror(errno)); @@ -189,7 +189,7 @@ bool fstk_FindFile(char const *path, char **fullPath, size_t *size) // Oh how I wish `asnprintf` was standard... if ((size_t)len >= *size) { // `size` includes the terminator, `len` doesn't *size = len + 1; - *fullPath = realloc(*fullPath, *size); + *fullPath = (char *)realloc(*fullPath, *size); if (!*fullPath) { error("realloc error during include path search: %s\n", strerror(errno)); @@ -231,7 +231,7 @@ bool yywrap(void) // If the node is referenced, we can't edit it; duplicate it if (contextStack->fileInfo->referenced) { size_t size = sizeof(*fileInfo) + sizeof(fileInfo->iters[0]) * fileInfo->reptDepth; - struct FileStackReptNode *copy = malloc(size); + struct FileStackReptNode *copy = (struct FileStackReptNode *)malloc(size); if (!copy) fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno)); @@ -301,7 +301,7 @@ static void newContext(struct FileStackNode *fileInfo) // Save the current `\@` value, to be restored when this context ends contextStack->uniqueID = macro_GetUniqueID(); - struct Context *context = malloc(sizeof(*context)); + struct Context *context = (struct Context *)malloc(sizeof(*context)); if (!context) fatalerror("Failed to allocate memory for new context: %s\n", strerror(errno)); @@ -336,7 +336,8 @@ void fstk_RunInclude(char const *path) return; } - struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + size); + struct FileStackNamedNode *fileInfo = + (struct FileStackNamedNode *)malloc(sizeof(*fileInfo) + size); if (!fileInfo) { error("Failed to alloc file info for INCLUDE: %s\n", strerror(errno)); @@ -373,7 +374,8 @@ static void runPreIncludeFile(void) return; } - struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + size); + struct FileStackNamedNode *fileInfo = + (struct FileStackNamedNode *)malloc(sizeof(*fileInfo) + size); if (!fileInfo) { error("Failed to alloc file info for pre-include: %s\n", strerror(errno)); @@ -423,8 +425,8 @@ void fstk_RunMacro(char const *macroName, struct MacroArgs *args) struct FileStackNamedNode const *baseNode = (struct FileStackNamedNode const *)node; size_t baseLen = strlen(baseNode->name); size_t macroNameLen = strlen(macro->name); - struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + baseLen - + reptNameLen + 2 + macroNameLen + 1); + struct FileStackNamedNode *fileInfo = (struct FileStackNamedNode *)malloc(sizeof(*fileInfo) + + baseLen + reptNameLen + 2 + macroNameLen + 1); if (!fileInfo) { error("Failed to alloc file info for \"%s\": %s\n", macro->name, strerror(errno)); @@ -467,8 +469,8 @@ static bool newReptContext(int32_t reptLineNo, char *body, size_t size) uint32_t reptDepth = contextStack->fileInfo->type == NODE_REPT ? ((struct FileStackReptNode *)contextStack->fileInfo)->reptDepth : 0; - struct FileStackReptNode *fileInfo = malloc(sizeof(*fileInfo) - + (reptDepth + 1) * sizeof(fileInfo->iters[0])); + struct FileStackReptNode *fileInfo = (struct FileStackReptNode *)malloc(sizeof(*fileInfo) + + (reptDepth + 1) * sizeof(fileInfo->iters[0])); if (!fileInfo) { error("Failed to alloc file info for REPT: %s\n", strerror(errno)); @@ -573,8 +575,9 @@ void fstk_Init(char const *mainPath, size_t maxDepth) lexer_SetState(state); char const *fileName = lexer_GetFileName(); size_t len = strlen(fileName); - struct Context *context = malloc(sizeof(*contextStack)); - struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + len + 1); + struct Context *context = (struct Context *)malloc(sizeof(*contextStack)); + struct FileStackNamedNode *fileInfo = + (struct FileStackNamedNode *)malloc(sizeof(*fileInfo) + len + 1); if (!context) fatalerror("Failed to allocate memory for main context: %s\n", strerror(errno)); diff --git a/src/asm/lexer.c b/src/asm/lexer.cpp similarity index 98% rename from src/asm/lexer.c rename to src/asm/lexer.cpp index 443caf72a2..c74f73c280 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.cpp @@ -24,20 +24,20 @@ #include #endif -#include "platform.h" // For `ssize_t` - -#include "asm/lexer.h" -#include "asm/fixpoint.h" -#include "asm/format.h" -#include "asm/fstack.h" -#include "asm/macro.h" -#include "asm/main.h" -#include "asm/rpn.h" -#include "asm/symbol.h" -#include "asm/util.h" -#include "asm/warning.h" +#include "platform.hpp" // For `ssize_t` + +#include "asm/lexer.hpp" +#include "asm/fixpoint.hpp" +#include "asm/format.hpp" +#include "asm/fstack.hpp" +#include "asm/macro.hpp" +#include "asm/main.hpp" +#include "asm/rpn.hpp" +#include "asm/symbol.hpp" +#include "asm/util.hpp" +#include "asm/warning.hpp" // Include this last so it gets all type & constant definitions -#include "parser.h" // For token definitions, generated from parser.y +#include "parser.hpp" // For token definitions, generated from parser.y // Neither MSVC nor MinGW provide `mmap` #if defined(_MSC_VER) || defined(__MINGW32__) @@ -394,7 +394,7 @@ uint32_t lexer_GetIFDepth(void) void lexer_IncIFDepth(void) { - struct IfStack *ifStack = malloc(sizeof(*ifStack)); + struct IfStack *ifStack = (struct IfStack *)malloc(sizeof(*ifStack)); if (!ifStack) fatalerror("Unable to allocate new IF depth: %s\n", strerror(errno)); @@ -441,7 +441,7 @@ void lexer_ReachELSEBlock(void) struct LexerState *lexer_OpenFile(char const *path) { bool isStdin = !strcmp(path, "-"); - struct LexerState *state = malloc(sizeof(*state)); + struct LexerState *state = (struct LexerState *)malloc(sizeof(*state)); struct stat fileInfo; // Give stdin a nicer file name @@ -483,7 +483,7 @@ struct LexerState *lexer_OpenFile(char const *path) state->isMmapped = true; state->isReferenced = false; // By default, a state isn't referenced - state->ptr = mappingAddr; + state->ptr = (char *)mappingAddr; assert(fileInfo.st_size >= 0); state->size = (size_t)fileInfo.st_size; state->offset = 0; @@ -514,7 +514,7 @@ struct LexerState *lexer_OpenFile(char const *path) struct LexerState *lexer_OpenFileView(char const *path, char *buf, size_t size, uint32_t lineNo) { - struct LexerState *state = malloc(sizeof(*state)); + struct LexerState *state = (struct LexerState *)malloc(sizeof(*state)); if (!state) { error("Failed to allocate memory for lexer state: %s\n", strerror(errno)); @@ -571,7 +571,7 @@ struct KeywordDictNode { uint16_t children[0x60 - ' ']; struct KeywordMapping const *keyword; // Since the keyword structure is invariant, the min number of nodes is known at compile time -} keywordDict[365] = {0}; // Make sure to keep this correct when adding keywords! +} keywordDict[365] = {}; // Make sure to keep this correct when adding keywords! // Convert a char into its index into the dict static uint8_t dictIndex(char c) @@ -641,7 +641,7 @@ static void reallocCaptureBuf(void) lexerState->captureCapacity = SIZE_MAX; else lexerState->captureCapacity *= 2; - lexerState->captureBuf = realloc(lexerState->captureBuf, lexerState->captureCapacity); + lexerState->captureBuf = (char *)realloc(lexerState->captureBuf, lexerState->captureCapacity); if (!lexerState->captureBuf) fatalerror("realloc error while resizing capture buffer: %s\n", strerror(errno)); } @@ -657,7 +657,7 @@ static void beginExpansion(char const *str, bool owned, char const *name) if (name) lexer_CheckRecursionDepth(); - struct Expansion *exp = malloc(sizeof(*exp)); + struct Expansion *exp = (struct Expansion *)malloc(sizeof(*exp)); if (!exp) fatalerror("Unable to allocate new expansion: %s\n", strerror(errno)); @@ -2407,11 +2407,11 @@ int yylex(void) nextLine(); static int (* const lexerModeFuncs[])(void) = { - [LEXER_NORMAL] = yylex_NORMAL, - [LEXER_RAW] = yylex_RAW, - [LEXER_SKIP_TO_ELIF] = yylex_SKIP_TO_ELIF, - [LEXER_SKIP_TO_ENDC] = yylex_SKIP_TO_ENDC, - [LEXER_SKIP_TO_ENDR] = yylex_SKIP_TO_ENDR, + yylex_NORMAL, // LEXER_NORMAL + yylex_RAW, // LEXER_RAW + yylex_SKIP_TO_ELIF, // LEXER_SKIP_TO_ELIF + yylex_SKIP_TO_ENDC, // LEXER_SKIP_TO_ENDC + yylex_SKIP_TO_ENDR, // LEXER_SKIP_TO_ENDR }; int token = lexerModeFuncs[lexerState->mode](); diff --git a/src/asm/macro.c b/src/asm/macro.cpp similarity index 93% rename from src/asm/macro.c rename to src/asm/macro.cpp index 655d3d03f5..6453420277 100644 --- a/src/asm/macro.c +++ b/src/asm/macro.cpp @@ -13,8 +13,8 @@ #include #include -#include "asm/macro.h" -#include "asm/warning.h" +#include "asm/macro.hpp" +#include "asm/warning.hpp" #define MAXMACROARGS 99999 @@ -32,7 +32,7 @@ struct MacroArgs { }; #define SIZEOF_ARGS(nbArgs) (sizeof(struct MacroArgs) + \ - sizeof(((struct MacroArgs){0}).args[0]) * (nbArgs)) + sizeof(((struct MacroArgs){}).args[0]) * (nbArgs)) static struct MacroArgs *macroArgs = NULL; static uint32_t uniqueID = 0; @@ -50,7 +50,7 @@ struct MacroArgs *macro_GetCurrentArgs(void) struct MacroArgs *macro_NewArgs(void) { - struct MacroArgs *args = malloc(SIZEOF_ARGS(INITIAL_ARG_SIZE)); + struct MacroArgs *args = (struct MacroArgs *)malloc(SIZEOF_ARGS(INITIAL_ARG_SIZE)); if (!args) fatalerror("Unable to register macro arguments: %s\n", strerror(errno)); @@ -73,7 +73,7 @@ void macro_AppendArg(struct MacroArgs **argPtr, char *s) // Check that overflow didn't roll us back if (macArgs->capacity <= macArgs->nbArgs) fatalerror("Failed to add new macro argument: capacity overflow\n"); - macArgs = realloc(macArgs, SIZEOF_ARGS(macArgs->capacity)); + macArgs = (struct MacroArgs *)realloc(macArgs, SIZEOF_ARGS(macArgs->capacity)); if (!macArgs) fatalerror("Error adding new macro argument: %s\n", strerror(errno)); } @@ -116,7 +116,7 @@ char const *macro_GetAllArgs(void) for (uint32_t i = macroArgs->shift; i < macroArgs->nbArgs; i++) len += strlen(macroArgs->args[i]) + 1; // 1 for comma - char *str = malloc(len + 1); // 1 for '\0' + char *str = (char *)malloc(len + 1); // 1 for '\0' char *ptr = str; if (!str) diff --git a/src/asm/main.c b/src/asm/main.cpp similarity index 94% rename from src/asm/main.c rename to src/asm/main.cpp index a1d7b98949..f2eb1527d0 100644 --- a/src/asm/main.c +++ b/src/asm/main.cpp @@ -18,24 +18,24 @@ #include #include -#include "asm/charmap.h" -#include "asm/fixpoint.h" -#include "asm/format.h" -#include "asm/fstack.h" -#include "asm/lexer.h" -#include "asm/main.h" -#include "asm/opt.h" -#include "asm/output.h" -#include "asm/rpn.h" -#include "asm/symbol.h" -#include "asm/warning.h" -#include "parser.h" - -#include "extern/getopt.h" - -#include "helpers.h" -#include "error.h" -#include "version.h" +#include "asm/charmap.hpp" +#include "asm/fixpoint.hpp" +#include "asm/format.hpp" +#include "asm/fstack.hpp" +#include "asm/lexer.hpp" +#include "asm/main.hpp" +#include "asm/opt.hpp" +#include "asm/output.hpp" +#include "asm/rpn.hpp" +#include "asm/symbol.hpp" +#include "asm/warning.hpp" +#include "parser.hpp" + +#include "extern/getopt.hpp" + +#include "helpers.hpp" +#include "error.hpp" +#include "version.hpp" #ifdef __clang__ #if __has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__) @@ -46,7 +46,13 @@ #ifdef __SANITIZE_ADDRESS__ // There are known, non-trivial to fix leaks. We would still like to have `make develop' // detect memory corruption, though. +#ifdef __cplusplus +extern "C" { +#endif char const *__asan_default_options(void) { return "detect_leaks=0"; } +#ifdef __cplusplus +} +#endif #endif // Old Bison versions (confirmed for 2.3) do not forward-declare `yyparse` in the generated header @@ -69,7 +75,7 @@ bool warnings; // True to enable warnings, false to disable them. // Escapes Make-special chars from a string static char *make_escape(char const *str) { - char * const escaped_str = malloc(strlen(str) * 2 + 1); + char *escaped_str = (char *)malloc(strlen(str) * 2 + 1); char *dest = escaped_str; if (escaped_str == NULL) @@ -173,7 +179,7 @@ int main(int argc, char *argv[]) warnings = true; sym_SetExportAll(false); uint32_t maxDepth = DEFAULT_MAX_DEPTH; - char *dependFileName = NULL; + char const *dependFileName = NULL; size_t targetFileNameLen = 0; int ch; @@ -333,7 +339,7 @@ int main(int argc, char *argv[]) newTarget = make_escape(newTarget); size_t newTargetLen = strlen(newTarget) + 1; // Plus the space - targetFileName = realloc(targetFileName, + targetFileName = (char *)realloc(targetFileName, targetFileNameLen + newTargetLen + 1); if (targetFileName == NULL) err("Cannot append new file to target file list"); diff --git a/src/asm/opt.c b/src/asm/opt.cpp similarity index 86% rename from src/asm/opt.c rename to src/asm/opt.cpp index e31afd54d3..b7eac7a4e9 100644 --- a/src/asm/opt.c +++ b/src/asm/opt.cpp @@ -14,12 +14,14 @@ #include #include -#include "asm/fixpoint.h" -#include "asm/fstack.h" -#include "asm/lexer.h" -#include "asm/main.h" -#include "asm/section.h" -#include "asm/warning.h" +#include "asm/fixpoint.hpp" +#include "asm/fstack.hpp" +#include "asm/lexer.hpp" +#include "asm/main.hpp" +#include "asm/section.hpp" +#include "asm/warning.hpp" + +static constexpr size_t numWarningStates = sizeof(warningStates); struct OptStackEntry { char binary[2]; @@ -32,8 +34,7 @@ struct OptStackEntry { bool warnOnLdOpt; bool warningsAreErrors; size_t maxRecursionDepth; - // Don't be confused: we use the size of the **global variable** `warningStates`! - enum WarningState warningStates[sizeof(warningStates)]; + enum WarningState warningStates[numWarningStates]; struct OptStackEntry *next; }; @@ -247,12 +248,12 @@ void opt_Parse(char *s) void opt_Push(void) { - struct OptStackEntry *entry = malloc(sizeof(*entry)); + struct OptStackEntry *entry = (struct OptStackEntry *)malloc(sizeof(*entry)); if (entry == NULL) fatalerror("Failed to alloc option stack entry: %s\n", strerror(errno)); - // Both of these pulled from lexer.h + // Both of these pulled from lexer.hpp entry->binary[0] = binDigits[0]; entry->binary[1] = binDigits[1]; @@ -261,19 +262,19 @@ void opt_Push(void) entry->gbgfx[2] = gfxDigits[2]; entry->gbgfx[3] = gfxDigits[3]; - entry->fixPrecision = fixPrecision; // Pulled from fixpoint.h + entry->fixPrecision = fixPrecision; // Pulled from fixpoint.hpp - entry->fillByte = fillByte; // Pulled from section.h + entry->fillByte = fillByte; // Pulled from section.hpp - entry->haltnop = haltnop; // Pulled from main.h + entry->haltnop = haltnop; // Pulled from main.hpp entry->warnOnHaltNop = warnOnHaltNop; - entry->optimizeLoads = optimizeLoads; // Pulled from main.h + entry->optimizeLoads = optimizeLoads; // Pulled from main.hpp entry->warnOnLdOpt = warnOnLdOpt; - // Both of these pulled from warning.h + // Both of these pulled from warning.hpp entry->warningsAreErrors = warningsAreErrors; - memcpy(entry->warningStates, warningStates, sizeof(warningStates)); + memcpy(entry->warningStates, warningStates, numWarningStates); entry->next = stack; stack = entry; @@ -299,7 +300,7 @@ void opt_Pop(void) // opt_W does not apply a whole warning state; it processes one flag string warningsAreErrors = entry->warningsAreErrors; - memcpy(warningStates, entry->warningStates, sizeof(warningStates)); + memcpy(warningStates, entry->warningStates, numWarningStates); stack = entry->next; free(entry); diff --git a/src/asm/output.c b/src/asm/output.cpp similarity index 96% rename from src/asm/output.c rename to src/asm/output.cpp index 4ca96bb7a4..3905e53fc2 100644 --- a/src/asm/output.c +++ b/src/asm/output.cpp @@ -16,18 +16,18 @@ #include #include -#include "asm/charmap.h" -#include "asm/fstack.h" -#include "asm/main.h" -#include "asm/output.h" -#include "asm/rpn.h" -#include "asm/section.h" -#include "asm/symbol.h" -#include "asm/warning.h" - -#include "error.h" -#include "linkdefs.h" -#include "platform.h" // strdup +#include "asm/charmap.hpp" +#include "asm/fstack.hpp" +#include "asm/main.hpp" +#include "asm/output.hpp" +#include "asm/rpn.hpp" +#include "asm/section.hpp" +#include "asm/symbol.hpp" +#include "asm/warning.hpp" + +#include "error.hpp" +#include "linkdefs.hpp" +#include "platform.hpp" // strdup struct Patch { struct FileStackNode const *src; @@ -372,14 +372,14 @@ static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn, // WARNING: all patches are assumed to eventually be written, so the file stack node is registered static struct Patch *allocpatch(uint32_t type, struct Expression const *expr, uint32_t ofs) { - struct Patch *patch = malloc(sizeof(struct Patch)); + struct Patch *patch = (struct Patch *)malloc(sizeof(*patch)); uint32_t rpnSize = expr->isKnown ? 5 : expr->rpnPatchSize; struct FileStackNode *node = fstk_GetFileStack(); if (!patch) fatalerror("No memory for patch: %s\n", strerror(errno)); - patch->rpn = malloc(sizeof(*patch->rpn) * rpnSize); + patch->rpn = (uint8_t *)malloc(sizeof(*patch->rpn) * rpnSize); if (!patch->rpn) fatalerror("No memory for patch's RPN rpnSize: %s\n", strerror(errno)); @@ -427,7 +427,7 @@ void out_CreatePatch(uint32_t type, struct Expression const *expr, uint32_t ofs, bool out_CreateAssert(enum AssertionType type, struct Expression const *expr, char const *message, uint32_t ofs) { - struct Assertion *assertion = malloc(sizeof(*assertion)); + struct Assertion *assertion = (struct Assertion *)malloc(sizeof(*assertion)); if (!assertion) return false; diff --git a/src/asm/parser.y b/src/asm/parser.y index 21d6a53621..22c9712a4f 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -16,25 +16,25 @@ #include #include -#include "asm/charmap.h" -#include "asm/fixpoint.h" -#include "asm/format.h" -#include "asm/fstack.h" -#include "asm/lexer.h" -#include "asm/macro.h" -#include "asm/main.h" -#include "asm/opt.h" -#include "asm/output.h" -#include "asm/rpn.h" -#include "asm/section.h" -#include "asm/symbol.h" -#include "asm/util.h" -#include "asm/warning.h" - -#include "extern/utf8decoder.h" - -#include "linkdefs.h" -#include "platform.h" // strncasecmp, strdup +#include "asm/charmap.hpp" +#include "asm/fixpoint.hpp" +#include "asm/format.hpp" +#include "asm/fstack.hpp" +#include "asm/lexer.hpp" +#include "asm/macro.hpp" +#include "asm/main.hpp" +#include "asm/opt.hpp" +#include "asm/output.hpp" +#include "asm/rpn.hpp" +#include "asm/section.hpp" +#include "asm/symbol.hpp" +#include "asm/util.hpp" +#include "asm/warning.hpp" + +#include "extern/utf8decoder.hpp" + +#include "linkdefs.hpp" +#include "platform.hpp" // strncasecmp, strdup static struct CaptureBody captureBody; // Captures a REPT/FOR or MACRO @@ -263,7 +263,7 @@ static void initStrFmtArgList(struct StrFmtArgList *args) { args->nbArgs = 0; args->capacity = INITIAL_STRFMT_ARG_SIZE; - args->args = malloc(args->capacity * sizeof(*args->args)); + args->args = (struct StrFmtArg *)malloc(args->capacity * sizeof(*args->args)); if (!args->args) fatalerror("Failed to allocate memory for STRFMT arg list: %s\n", strerror(errno)); @@ -273,7 +273,7 @@ static size_t nextStrFmtArgListIndex(struct StrFmtArgList *args) { if (args->nbArgs == args->capacity) { args->capacity = (args->capacity + 1) * 2; - args->args = realloc(args->args, args->capacity * sizeof(*args->args)); + args->args = (struct StrFmtArg *)realloc(args->args, args->capacity * sizeof(*args->args)); if (!args->args) fatalerror("realloc error while resizing STRFMT arg list: %s\n", strerror(errno)); @@ -375,7 +375,7 @@ static void initDsArgList(struct DsArgList *args) { args->nbArgs = 0; args->capacity = INITIAL_DS_ARG_SIZE; - args->args = malloc(args->capacity * sizeof(*args->args)); + args->args = (struct Expression *)malloc(args->capacity * sizeof(*args->args)); if (!args->args) fatalerror("Failed to allocate memory for ds arg list: %s\n", strerror(errno)); @@ -385,7 +385,7 @@ static void appendDsArgList(struct DsArgList *args, const struct Expression *exp { if (args->nbArgs == args->capacity) { args->capacity = (args->capacity + 1) * 2; - args->args = realloc(args->args, args->capacity * sizeof(*args->args)); + args->args = (struct Expression *)realloc(args->args, args->capacity * sizeof(*args->args)); if (!args->args) fatalerror("realloc error while resizing ds arg list: %s\n", strerror(errno)); @@ -1043,7 +1043,7 @@ shift : T_POP_SHIFT { macro_ShiftCurrentArgs(1); } ; load : T_POP_LOAD sectmod string T_COMMA sectiontype sectorg sectattrs { - sect_SetLoadSection($3, $5, $6, &$7, $2); + sect_SetLoadSection($3, (enum SectionType)$5, $6, &$7, $2); } | T_POP_ENDL { sect_EndLoadSection(); } ; @@ -1304,7 +1304,7 @@ constlist_8bit_entry : reloc_8bit_no_str { sect_RelByte(&$1, 0); } | string { - uint8_t *output = malloc(strlen($1)); // Cannot be larger than that + uint8_t *output = (uint8_t *)malloc(strlen($1)); // Cannot be larger than that size_t length = charmap_Convert($1, output); sect_AbsByteGroup(output, length); @@ -1320,7 +1320,7 @@ constlist_16bit_entry : reloc_16bit_no_str { sect_RelWord(&$1, 0); } | string { - uint8_t *output = malloc(strlen($1)); // Cannot be larger than that + uint8_t *output = (uint8_t *)malloc(strlen($1)); // Cannot be larger than that size_t length = charmap_Convert($1, output); sect_AbsWordGroup(output, length); @@ -1337,7 +1337,7 @@ constlist_32bit_entry : relocexpr_no_str { } | string { // Charmaps cannot increase the length of a string - uint8_t *output = malloc(strlen($1)); + uint8_t *output = (uint8_t *)malloc(strlen($1)); size_t length = charmap_Convert($1, output); sect_AbsLongGroup(output, length); @@ -1383,7 +1383,7 @@ reloc_16bit_no_str : relocexpr_no_str { relocexpr : relocexpr_no_str | string { // Charmaps cannot increase the length of a string - uint8_t *output = malloc(strlen($1)); + uint8_t *output = (uint8_t *)malloc(strlen($1)); uint32_t length = charmap_Convert($1, output); uint32_t r = str2int2(output, length); @@ -1664,7 +1664,7 @@ strfmt_va_args : %empty { ; section : T_POP_SECTION sectmod string T_COMMA sectiontype sectorg sectattrs { - sect_NewSection($3, $5, $6, &$7, $2); + sect_NewSection($3, (enum SectionType)$5, $6, &$7, $2); } ; diff --git a/src/asm/rpn.c b/src/asm/rpn.cpp similarity index 96% rename from src/asm/rpn.c rename to src/asm/rpn.cpp index b233ecbf8a..0fcc065ade 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.cpp @@ -17,26 +17,26 @@ #include #include -#include "asm/main.h" -#include "asm/output.h" -#include "asm/rpn.h" -#include "asm/section.h" -#include "asm/symbol.h" -#include "asm/warning.h" +#include "asm/main.hpp" +#include "asm/output.hpp" +#include "asm/rpn.hpp" +#include "asm/section.hpp" +#include "asm/symbol.hpp" +#include "asm/warning.hpp" -#include "opmath.h" +#include "opmath.hpp" // Makes an expression "not known", also setting its error message #define makeUnknown(expr_, ...) do { \ struct Expression *_expr = expr_; \ _expr->isKnown = false; \ /* If we had `asprintf` this would be great, but alas. */ \ - _expr->reason = malloc(128); /* Use an initial reasonable size */ \ + _expr->reason = (char *)malloc(128); /* Use an initial reasonable size */ \ if (!_expr->reason) \ fatalerror("Can't allocate err string: %s\n", strerror(errno)); \ int size = snprintf(_expr->reason, 128, __VA_ARGS__); \ if (size >= 128) { /* If this wasn't enough, try again */ \ - _expr->reason = realloc(_expr->reason, size + 1); \ + _expr->reason = (char *)realloc(_expr->reason, size + 1); \ if (!_expr->reason) \ fatalerror("Can't allocate err string: %s\n", strerror(errno)); \ sprintf(_expr->reason, __VA_ARGS__); \ @@ -61,7 +61,7 @@ static uint8_t *reserveSpace(struct Expression *expr, uint32_t size) else expr->rpnCapacity *= 2; } - expr->rpn = realloc(expr->rpn, expr->rpnCapacity); + expr->rpn = (uint8_t *)realloc(expr->rpn, expr->rpnCapacity); if (!expr->rpn) fatalerror("Failed to grow RPN expression: %s\n", strerror(errno)); @@ -530,8 +530,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr, // Convert the left-hand expression if it's constant if (src1->isKnown) { uint32_t lval = src1->val; - uint8_t bytes[] = {RPN_CONST, lval, lval >> 8, - lval >> 16, lval >> 24}; + uint8_t bytes[] = {RPN_CONST, (uint8_t)lval, (uint8_t)(lval >> 8), + (uint8_t)(lval >> 16), (uint8_t)(lval >> 24)}; expr->rpnPatchSize = sizeof(bytes); expr->rpn = NULL; expr->rpnCapacity = 0; @@ -559,8 +559,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr, // If the right expression is constant, merge a shim instead uint32_t rval = src2->val; - uint8_t bytes[] = {RPN_CONST, rval, rval >> 8, rval >> 16, - rval >> 24}; + uint8_t bytes[] = {RPN_CONST, (uint8_t)rval, (uint8_t)(rval >> 8), + (uint8_t)(rval >> 16), (uint8_t)(rval >> 24)}; if (src2->isKnown) { ptr = bytes; len = sizeof(bytes); diff --git a/src/asm/section.c b/src/asm/section.cpp similarity index 97% rename from src/asm/section.c rename to src/asm/section.cpp index d33f55cb47..81b9179c9b 100644 --- a/src/asm/section.c +++ b/src/asm/section.cpp @@ -14,17 +14,17 @@ #include #include -#include "asm/fstack.h" -#include "asm/main.h" -#include "asm/output.h" -#include "asm/rpn.h" -#include "asm/section.h" -#include "asm/symbol.h" -#include "asm/warning.h" - -#include "error.h" -#include "linkdefs.h" -#include "platform.h" // strdup +#include "asm/fstack.hpp" +#include "asm/main.hpp" +#include "asm/output.hpp" +#include "asm/rpn.hpp" +#include "asm/section.hpp" +#include "asm/symbol.hpp" +#include "asm/warning.hpp" + +#include "error.hpp" +#include "linkdefs.hpp" +#include "platform.hpp" // strdup uint8_t fillByte; @@ -270,7 +270,7 @@ static struct Section *createSection(char const *name, enum SectionType type, uint32_t org, uint32_t bank, uint8_t alignment, uint16_t alignOffset, enum SectionModifier mod) { - struct Section *sect = malloc(sizeof(*sect)); + struct Section *sect = (struct Section *)malloc(sizeof(*sect)); if (sect == NULL) fatalerror("Not enough memory for section: %s\n", strerror(errno)); @@ -293,7 +293,7 @@ static struct Section *createSection(char const *name, enum SectionType type, // It is only needed to allocate memory for ROM sections. if (sect_HasData(type)) { - sect->data = malloc(sectionTypeInfo[type].size); + sect->data = (uint8_t *)malloc(sectionTypeInfo[type].size); if (sect->data == NULL) fatalerror("Not enough memory for section: %s\n", strerror(errno)); } else { @@ -391,7 +391,7 @@ static void changeSection(void) } // Set the current section by name and type -void sect_NewSection(char const *name, uint32_t type, uint32_t org, +void sect_NewSection(char const *name, enum SectionType type, uint32_t org, struct SectionSpec const *attribs, enum SectionModifier mod) { if (currentLoadSection) @@ -411,7 +411,7 @@ void sect_NewSection(char const *name, uint32_t type, uint32_t org, } // Set the current section by name and type -void sect_SetLoadSection(char const *name, uint32_t type, uint32_t org, +void sect_SetLoadSection(char const *name, enum SectionType type, uint32_t org, struct SectionSpec const *attribs, enum SectionModifier mod) { // Important info: currently, UNION and LOAD cannot interact, since UNION is prohibited in @@ -550,7 +550,7 @@ void sect_StartUnion(void) error("Cannot use UNION inside of ROM0 or ROMX sections\n"); return; } - struct UnionStackEntry *entry = malloc(sizeof(*entry)); + struct UnionStackEntry *entry = (struct UnionStackEntry *)malloc(sizeof(*entry)); if (!entry) fatalerror("Failed to allocate new union stack entry: %s\n", strerror(errno)); @@ -936,7 +936,7 @@ void sect_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length) // Section stack routines void sect_PushSection(void) { - struct SectionStackEntry *entry = malloc(sizeof(*entry)); + struct SectionStackEntry *entry = (struct SectionStackEntry *)malloc(sizeof(*entry)); if (entry == NULL) fatalerror("No memory for section stack: %s\n", strerror(errno)); diff --git a/src/asm/symbol.c b/src/asm/symbol.cpp similarity index 97% rename from src/asm/symbol.c rename to src/asm/symbol.cpp index d54fff9c18..37ecb7f4b9 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.cpp @@ -17,20 +17,20 @@ #include #include -#include "asm/fixpoint.h" -#include "asm/fstack.h" -#include "asm/macro.h" -#include "asm/main.h" -#include "asm/output.h" -#include "asm/section.h" -#include "asm/symbol.h" -#include "asm/util.h" -#include "asm/warning.h" - -#include "error.h" -#include "hashmap.h" -#include "helpers.h" -#include "version.h" +#include "asm/fixpoint.hpp" +#include "asm/fstack.hpp" +#include "asm/macro.hpp" +#include "asm/main.hpp" +#include "asm/output.hpp" +#include "asm/section.hpp" +#include "asm/symbol.hpp" +#include "asm/util.hpp" +#include "asm/warning.hpp" + +#include "error.hpp" +#include "hashmap.hpp" +#include "helpers.hpp" +#include "version.hpp" HashMap symbols; @@ -55,8 +55,8 @@ struct ForEachArgs { static void forEachWrapper(void *_sym, void *_argWrapper) { - struct ForEachArgs *argWrapper = _argWrapper; - struct Symbol *sym = _sym; + struct ForEachArgs *argWrapper = (struct ForEachArgs *)_argWrapper; + struct Symbol *sym = (struct Symbol *)_sym; argWrapper->func(sym, argWrapper->arg); } @@ -104,7 +104,7 @@ static char const *Callback__FILE__(void) // Ensure there will be enough room; DO NOT PRINT ANYTHING ABOVE THIS! if (j + 2 >= bufsize) { // Always keep room for 2 tail chars bufsize = bufsize ? bufsize * 2 : 64; - buf = realloc(buf, bufsize); + buf = (char *)realloc(buf, bufsize); if (!buf) fatalerror("Failed to grow buffer for file name: %s\n", strerror(errno)); @@ -173,7 +173,7 @@ static void updateSymbolFilename(struct Symbol *sym) // Create a new symbol by name static struct Symbol *createsymbol(char const *symName) { - struct Symbol *sym = malloc(sizeof(*sym)); + struct Symbol *sym = (struct Symbol *)malloc(sizeof(*sym)); if (!sym) fatalerror("Failed to create symbol '%s': %s\n", symName, strerror(errno)); @@ -220,7 +220,7 @@ static void assignStringSymbol(struct Symbol *sym, char const *value) struct Symbol *sym_FindExactSymbol(char const *symName) { - return hash_GetElement(symbols, symName); + return (struct Symbol *)hash_GetElement(symbols, symName); } struct Symbol *sym_FindUnscopedSymbol(char const *symName) diff --git a/src/asm/util.c b/src/asm/util.cpp similarity index 90% rename from src/asm/util.c rename to src/asm/util.cpp index 8a4f57ae03..507813072d 100644 --- a/src/asm/util.c +++ b/src/asm/util.cpp @@ -9,11 +9,11 @@ #include #include -#include "asm/main.h" -#include "asm/util.h" -#include "asm/warning.h" +#include "asm/main.hpp" +#include "asm/util.hpp" +#include "asm/warning.hpp" -#include "extern/utf8decoder.h" +#include "extern/utf8decoder.hpp" char const *printChar(int c) { diff --git a/src/asm/warning.c b/src/asm/warning.cpp similarity index 86% rename from src/asm/warning.c rename to src/asm/warning.cpp index e501da2352..7eccd2da3e 100644 --- a/src/asm/warning.c +++ b/src/asm/warning.cpp @@ -14,38 +14,38 @@ #include #include -#include "asm/fstack.h" -#include "asm/main.h" -#include "asm/warning.h" +#include "asm/fstack.hpp" +#include "asm/main.hpp" +#include "asm/warning.hpp" -#include "error.h" +#include "error.hpp" unsigned int nbErrors = 0; static const enum WarningState defaultWarnings[ARRAY_SIZE(warningStates)] = { - [WARNING_ASSERT] = WARNING_ENABLED, - [WARNING_BACKWARDS_FOR] = WARNING_DISABLED, - [WARNING_BUILTIN_ARG] = WARNING_DISABLED, - [WARNING_CHARMAP_REDEF] = WARNING_DISABLED, - [WARNING_DIV] = WARNING_DISABLED, - [WARNING_EMPTY_DATA_DIRECTIVE] = WARNING_DISABLED, - [WARNING_EMPTY_MACRO_ARG] = WARNING_DISABLED, - [WARNING_EMPTY_STRRPL] = WARNING_DISABLED, - [WARNING_LARGE_CONSTANT] = WARNING_DISABLED, - [WARNING_LONG_STR] = WARNING_DISABLED, - [WARNING_MACRO_SHIFT] = WARNING_DISABLED, - [WARNING_NESTED_COMMENT] = WARNING_ENABLED, - [WARNING_OBSOLETE] = WARNING_ENABLED, - [WARNING_SHIFT] = WARNING_DISABLED, - [WARNING_SHIFT_AMOUNT] = WARNING_DISABLED, - [WARNING_USER] = WARNING_ENABLED, - - [WARNING_NUMERIC_STRING_1] = WARNING_ENABLED, - [WARNING_NUMERIC_STRING_2] = WARNING_DISABLED, - [WARNING_TRUNCATION_1] = WARNING_ENABLED, - [WARNING_TRUNCATION_2] = WARNING_DISABLED, - [WARNING_UNMAPPED_CHAR_1] = WARNING_ENABLED, - [WARNING_UNMAPPED_CHAR_2] = WARNING_DISABLED, + WARNING_ENABLED, // WARNING_ASSERT + WARNING_DISABLED, // WARNING_BACKWARDS_FOR + WARNING_DISABLED, // WARNING_BUILTIN_ARG + WARNING_DISABLED, // WARNING_CHARMAP_REDEF + WARNING_DISABLED, // WARNING_DIV + WARNING_DISABLED, // WARNING_EMPTY_DATA_DIRECTIVE + WARNING_DISABLED, // WARNING_EMPTY_MACRO_ARG + WARNING_DISABLED, // WARNING_EMPTY_STRRPL + WARNING_DISABLED, // WARNING_LARGE_CONSTANT + WARNING_DISABLED, // WARNING_LONG_STR + WARNING_DISABLED, // WARNING_MACRO_SHIFT + WARNING_ENABLED, // WARNING_NESTED_COMMENT + WARNING_ENABLED, // WARNING_OBSOLETE + WARNING_DISABLED, // WARNING_SHIFT + WARNING_DISABLED, // WARNING_SHIFT_AMOUNT + WARNING_ENABLED, // WARNING_USER + + WARNING_ENABLED, // WARNING_NUMERIC_STRING_1 + WARNING_DISABLED, // WARNING_NUMERIC_STRING_2 + WARNING_ENABLED, // WARNING_TRUNCATION_1 + WARNING_DISABLED, // WARNING_TRUNCATION_2 + WARNING_ENABLED, // WARNING_UNMAPPED_CHAR_1 + WARNING_DISABLED, // WARNING_UNMAPPED_CHAR_2 }; enum WarningState warningStates[ARRAY_SIZE(warningStates)]; @@ -145,7 +145,7 @@ static bool tryProcessParamWarning(char const *flag, uint8_t param, enum Warning return true; } - baseID += maxParam; + baseID = (enum WarningID)(baseID + maxParam); } return false; } @@ -220,7 +220,7 @@ void processWarningFlag(char *flag) static bool setError = false; // First, try to match against a "meta" warning - for (enum WarningID id = META_WARNINGS_START; id < NB_WARNINGS; id++) { + for (enum WarningID id = META_WARNINGS_START; id < NB_WARNINGS; id = (enum WarningID)(id + 1)) { // TODO: improve the matching performance? if (!strcmp(flag, warningFlags[id])) { // We got a match! @@ -266,7 +266,7 @@ void processWarningFlag(char *flag) // Not an error, then check if this is a negation strncmp(flag, "no-", strlen("no-")) ? WARNING_ENABLED : WARNING_DISABLED; - char const *rootFlag = state == WARNING_DISABLED ? flag + strlen("no-") : flag; + char *rootFlag = state == WARNING_DISABLED ? flag + strlen("no-") : flag; // Is this a "parametric" warning? if (state != WARNING_DISABLED) { // The `no-` form cannot be parametrized @@ -315,7 +315,8 @@ void processWarningFlag(char *flag) } // Try to match the flag against a "normal" flag - for (enum WarningID id = 0; id < NB_PLAIN_WARNINGS; id++) { + for (enum WarningID id = (enum WarningID)0; id < NB_PLAIN_WARNINGS; + id = (enum WarningID)(id + 1)) { if (!strcmp(rootFlag, warningFlags[id])) { // We got a match! warningStates[id] = state; @@ -351,7 +352,7 @@ void error(char const *fmt, ...) nbErrors++; } -_Noreturn void fatalerror(char const *fmt, ...) +[[noreturn]] void fatalerror(char const *fmt, ...) { va_list args; diff --git a/src/error.c b/src/error.cpp similarity index 80% rename from src/error.c rename to src/error.cpp index aec68e6560..b79f5cd4c2 100644 --- a/src/error.c +++ b/src/error.cpp @@ -12,8 +12,8 @@ #include #include -#include "error.h" -#include "platform.h" +#include "error.hpp" +#include "platform.hpp" static void vwarn(char const NONNULL(fmt), va_list ap) { @@ -31,7 +31,7 @@ static void vwarnx(char const NONNULL(fmt), va_list ap) putc('\n', stderr); } -_Noreturn static void verr(char const NONNULL(fmt), va_list ap) +[[noreturn]] static void verr(char const NONNULL(fmt), va_list ap) { fprintf(stderr, "error: "); vfprintf(stderr, fmt, ap); @@ -41,7 +41,7 @@ _Noreturn static void verr(char const NONNULL(fmt), va_list ap) exit(1); } -_Noreturn static void verrx(char const NONNULL(fmt), va_list ap) +[[noreturn]] static void verrx(char const NONNULL(fmt), va_list ap) { fprintf(stderr, "error"); fputs(": ", stderr); @@ -68,7 +68,7 @@ void warnx(char const NONNULL(fmt), ...) va_end(ap); } -_Noreturn void err(char const NONNULL(fmt), ...) +[[noreturn]] void err(char const NONNULL(fmt), ...) { va_list ap; @@ -77,7 +77,7 @@ _Noreturn void err(char const NONNULL(fmt), ...) va_end(ap); } -_Noreturn void errx(char const NONNULL(fmt), ...) +[[noreturn]] void errx(char const NONNULL(fmt), ...) { va_list ap; diff --git a/src/extern/getopt.c b/src/extern/getopt.cpp similarity index 99% rename from src/extern/getopt.c rename to src/extern/getopt.cpp index 08c8b08d7e..cd23bf1dc9 100644 --- a/src/extern/getopt.c +++ b/src/extern/getopt.cpp @@ -30,7 +30,7 @@ #include #include -#include "extern/getopt.h" +#include "extern/getopt.hpp" char *musl_optarg; int musl_optind = 1, musl_opterr = 1, musl_optopt; diff --git a/src/extern/utf8decoder.c b/src/extern/utf8decoder.cpp similarity index 100% rename from src/extern/utf8decoder.c rename to src/extern/utf8decoder.cpp diff --git a/src/fix/main.c b/src/fix/main.cpp similarity index 98% rename from src/fix/main.c rename to src/fix/main.cpp index 1a872c962f..73051d71e4 100644 --- a/src/fix/main.c +++ b/src/fix/main.cpp @@ -19,11 +19,11 @@ #include #include -#include "extern/getopt.h" +#include "extern/getopt.hpp" -#include "helpers.h" -#include "platform.h" -#include "version.h" +#include "helpers.hpp" +#include "platform.hpp" +#include "version.hpp" #define UNSPECIFIED 0x200 // Should not be in byte range @@ -236,7 +236,7 @@ static enum MbcType parseMBC(char const *name) return MBC_BAD; if (mbc > 0xFF) return MBC_BAD_RANGE; - return mbc; + return (enum MbcType)mbc; } else { // Begin by reading the MBC type: @@ -253,6 +253,9 @@ do { \ return MBC_BAD; \ } while (0) + char *endptr; + unsigned long val; + switch (*ptr++) { case 'R': // ROM / ROM_ONLY case 'r': @@ -337,8 +340,7 @@ do { \ while (*ptr == ' ' || *ptr == '_') ptr++; // Major - char *endptr; - unsigned long val = strtoul(ptr, &endptr, 10); + val = strtoul(ptr, &endptr, 10); if (endptr == ptr) { report("error: Failed to parse TPP1 major revision number\n"); @@ -575,7 +577,7 @@ do { \ if (*ptr) return MBC_BAD; - return mbc; + return (enum MbcType)mbc; } } @@ -1001,7 +1003,7 @@ static void processFile(int input, int output, char const *name, off_t fileSize) } else if (rom0Len == BANK_SIZE) { // Copy ROMX when reading a pipe, and we're not at EOF yet for (;;) { - romx = realloc(romx, nbBanks * BANK_SIZE); + romx = (uint8_t *)realloc(romx, nbBanks * BANK_SIZE); if (!romx) { report("FATAL: Failed to realloc ROMX buffer: %s\n", strerror(errno)); @@ -1095,11 +1097,13 @@ static void processFile(int input, int output, char const *name, off_t fileSize) if (fixSpec & TRASH_GLOBAL_SUM) globalSum = ~globalSum; - uint8_t bytes[2] = {globalSum >> 8, globalSum & 0xFF}; + uint8_t bytes[2] = {(uint8_t)(globalSum >> 8), (uint8_t)(globalSum & 0xFF)}; overwriteBytes(rom0, 0x14E, bytes, sizeof(bytes), "global checksum"); } + ssize_t writeLen; + // In case the output depends on the input, reset to the beginning of the file, and only // write the header if (input == output) { @@ -1112,7 +1116,7 @@ static void processFile(int input, int output, char const *name, off_t fileSize) if (padValue == UNSPECIFIED) rom0Len = headerSize; } - ssize_t writeLen = writeBytes(output, rom0, rom0Len); + writeLen = writeBytes(output, rom0, rom0Len); if (writeLen == -1) { report("FATAL: Failed to write \"%s\"'s ROM0: %s\n", name, strerror(errno)); @@ -1221,6 +1225,7 @@ int main(int argc, char *argv[]) { nbErrors = 0; int ch; + uint8_t maxLen; while ((ch = musl_getopt_long_only(argc, argv, optstring, longopts, NULL)) != -1) { switch (ch) { @@ -1382,7 +1387,7 @@ do { \ case 't': title = musl_optarg; len = strlen(title); - uint8_t maxLen = maxTitleLen(); + maxLen = maxTitleLen(); if (len > maxLen) { len = maxLen; diff --git a/src/gfx/main.cpp b/src/gfx/main.cpp index 377305277a..3e2cf92757 100644 --- a/src/gfx/main.cpp +++ b/src/gfx/main.cpp @@ -25,10 +25,10 @@ #include #include -#include "extern/getopt.h" +#include "extern/getopt.hpp" #include "file.hpp" -#include "platform.h" -#include "version.h" +#include "platform.hpp" +#include "version.hpp" #include "gfx/pal_spec.hpp" #include "gfx/process.hpp" diff --git a/src/gfx/pal_sorting.cpp b/src/gfx/pal_sorting.cpp index 924f359de0..28ed6bc9b5 100644 --- a/src/gfx/pal_sorting.cpp +++ b/src/gfx/pal_sorting.cpp @@ -12,7 +12,7 @@ #include #include -#include "helpers.h" +#include "helpers.hpp" #include "gfx/main.hpp" #include "gfx/process.hpp" diff --git a/src/gfx/pal_spec.cpp b/src/gfx/pal_spec.cpp index 613eada677..cb3c4824e5 100644 --- a/src/gfx/pal_spec.cpp +++ b/src/gfx/pal_spec.cpp @@ -26,7 +26,7 @@ #include #include -#include "platform.h" +#include "platform.hpp" #include "gfx/main.hpp" diff --git a/src/gfx/process.cpp b/src/gfx/process.cpp index 4de48b4ab0..7644a6a4e7 100644 --- a/src/gfx/process.cpp +++ b/src/gfx/process.cpp @@ -28,7 +28,7 @@ #include "defaultinitalloc.hpp" #include "file.hpp" -#include "helpers.h" +#include "helpers.hpp" #include "itertools.hpp" #include "gfx/main.hpp" diff --git a/src/gfx/reverse.cpp b/src/gfx/reverse.cpp index 9003706ae8..c2b7e1df8b 100644 --- a/src/gfx/reverse.cpp +++ b/src/gfx/reverse.cpp @@ -22,7 +22,7 @@ #include "defaultinitalloc.hpp" #include "file.hpp" -#include "helpers.h" +#include "helpers.hpp" #include "itertools.hpp" #include "gfx/main.hpp" diff --git a/src/hashmap.c b/src/hashmap.cpp similarity index 95% rename from src/hashmap.c rename to src/hashmap.cpp index c6ce7b6ad6..56381e6380 100644 --- a/src/hashmap.c +++ b/src/hashmap.cpp @@ -12,8 +12,8 @@ #include #include -#include "error.h" -#include "hashmap.h" +#include "error.hpp" +#include "hashmap.hpp" // The lower half of the hash is used to index the "master" table, // the upper half is used to help resolve collisions more quickly @@ -48,7 +48,7 @@ void **hash_AddElement(HashMap map, char const *key, void *element) { HashType hashedKey = hash(key); HalfHashType index = hashedKey; - struct HashMapEntry *newEntry = malloc(sizeof(*newEntry)); + struct HashMapEntry *newEntry = (struct HashMapEntry *)malloc(sizeof(*newEntry)); if (!newEntry) err("%s: Failed to allocate new entry", __func__); diff --git a/src/link/assign.c b/src/link/assign.cpp similarity index 94% rename from src/link/assign.c rename to src/link/assign.cpp index 930803e3e2..bcc34aa942 100644 --- a/src/link/assign.c +++ b/src/link/assign.cpp @@ -12,16 +12,16 @@ #include #include -#include "link/assign.h" -#include "link/section.h" -#include "link/symbol.h" -#include "link/object.h" -#include "link/main.h" -#include "link/output.h" +#include "link/assign.hpp" +#include "link/section.hpp" +#include "link/symbol.hpp" +#include "link/object.hpp" +#include "link/main.hpp" +#include "link/output.hpp" -#include "error.h" -#include "helpers.h" -#include "linkdefs.h" +#include "error.hpp" +#include "helpers.hpp" +#include "linkdefs.hpp" struct MemoryLocation { uint16_t address; @@ -42,14 +42,14 @@ uint64_t nbSectionsToAssign; // Init the free space-modelling structs static void initFreeSpace(void) { - for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) { - memory[type] = malloc(sizeof(*memory[type]) * nbbanks(type)); + for (enum SectionType type = (enum SectionType)0; type < SECTTYPE_INVALID; type = (enum SectionType)(type + 1)) { + memory[type] = (struct FreeSpace *)malloc(sizeof(*memory[type]) * nbbanks(type)); if (!memory[type]) err("Failed to init free space for region %d", type); for (uint32_t bank = 0; bank < nbbanks(type); bank++) { memory[type][bank].next = - malloc(sizeof(*memory[type][0].next)); + (struct FreeSpace *)malloc(sizeof(*memory[type][0].next)); if (!memory[type][bank].next) err("Failed to init free space for region %d bank %" PRIu32, type, bank); @@ -248,7 +248,7 @@ static void placeSection(struct Section *section) free(freeSpace); } else if (!noLeftSpace && !noRightSpace) { // The free space is split in two - struct FreeSpace *newSpace = malloc(sizeof(*newSpace)); + struct FreeSpace *newSpace = (struct FreeSpace *)malloc(sizeof(*newSpace)); if (!newSpace) err("Failed to split new free space"); @@ -324,7 +324,7 @@ struct UnassignedSection { #define BANK_CONSTRAINED (1 << 2) #define ORG_CONSTRAINED (1 << 1) #define ALIGN_CONSTRAINED (1 << 0) -static struct UnassignedSection *unassignedSections[1 << 3] = {0}; +static struct UnassignedSection *unassignedSections[1 << 3] = {}; static struct UnassignedSection *sections; /* @@ -366,7 +366,7 @@ void assign_AssignSections(void) // Initialize assignment // Generate linked lists of sections to assign - sections = malloc(sizeof(*sections) * nbSectionsToAssign + 1); + sections = (struct UnassignedSection *)malloc(sizeof(*sections) * nbSectionsToAssign + 1); if (!sections) err("Failed to allocate memory for section assignment"); @@ -434,7 +434,7 @@ void assign_AssignSections(void) void assign_Cleanup(void) { - for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) { + for (enum SectionType type = (enum SectionType)0; type < SECTTYPE_INVALID; type = (enum SectionType)(type + 1)) { for (uint32_t bank = 0; bank < nbbanks(type); bank++) { struct FreeSpace *ptr = memory[type][bank].next; diff --git a/src/link/main.c b/src/link/main.cpp similarity index 95% rename from src/link/main.c rename to src/link/main.cpp index 7ad9dad817..7b6bb8a0e2 100644 --- a/src/link/main.c +++ b/src/link/main.cpp @@ -18,20 +18,20 @@ #include #include -#include "link/assign.h" -#include "link/object.h" -#include "link/output.h" -#include "link/patch.h" -#include "link/section.h" -#include "link/script.h" -#include "link/symbol.h" +#include "link/assign.hpp" +#include "link/object.hpp" +#include "link/output.hpp" +#include "link/patch.hpp" +#include "link/section.hpp" +#include "link/script.hpp" +#include "link/symbol.hpp" -#include "extern/getopt.h" +#include "extern/getopt.hpp" -#include "error.h" -#include "linkdefs.h" -#include "platform.h" -#include "version.h" +#include "error.hpp" +#include "linkdefs.hpp" +#include "platform.hpp" +#include "version.hpp" bool isDmgMode; // -d char *linkerScriptName; // -l @@ -123,7 +123,7 @@ void argErr(char flag, char const *fmt, ...) nbErrors++; } -_Noreturn void fatal(struct FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) +[[noreturn]] void fatal(struct FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) { va_list ap; @@ -235,9 +235,9 @@ struct { char const *name; uint16_t max; } scrambleSpecs[SCRAMBLE_UNK] = { - [SCRAMBLE_ROMX] = { "romx", 65535 }, - [SCRAMBLE_SRAM] = { "sram", 255 }, - [SCRAMBLE_WRAMX] = { "wramx", 7}, + { "romx", 65535 }, // SCRAMBLE_ROMX + { "sram", 255 }, // SCRAMBLE_SRAM + { "wramx", 7}, // SCRAMBLE_WRAMX }; static void parseScrambleSpec(char const *spec) @@ -256,6 +256,7 @@ static void parseScrambleSpec(char const *spec) size_t regionNameLen = strcspn(spec, "=, \t"); // Length of region name string slice for printing, truncated if too long int regionNamePrintLen = regionNameLen > INT_MAX ? INT_MAX : (int)regionNameLen; + enum ScrambledRegion region = (enum ScrambledRegion)0; // If this trips, `spec` must be pointing at a ',' or '=' (or NUL) due to the assert if (regionNameLen == 0) { @@ -278,9 +279,7 @@ static void parseScrambleSpec(char const *spec) } // Now, determine which region type this is - enum ScrambledRegion region = 0; - - for (; region < SCRAMBLE_UNK; region++) { + for (; region < SCRAMBLE_UNK; region = (enum ScrambledRegion)(region + 1)) { // If the strings match (case-insensitively), we got it! // `strncasecmp` must be used here since `regionName` points // to the entire remaining argument. @@ -348,7 +347,7 @@ static void parseScrambleSpec(char const *spec) } } -_Noreturn void reportErrors(void) { +[[noreturn]] void reportErrors(void) { fprintf(stderr, "Linking failed with %" PRIu32 " error%s\n", nbErrors, nbErrors == 1 ? "" : "s"); exit(1); diff --git a/src/link/object.c b/src/link/object.cpp similarity index 88% rename from src/link/object.c rename to src/link/object.cpp index d55afa1cf7..a3bc6b10b2 100644 --- a/src/link/object.c +++ b/src/link/object.cpp @@ -14,17 +14,17 @@ #include #include -#include "link/assign.h" -#include "link/main.h" -#include "link/object.h" -#include "link/patch.h" -#include "link/sdas_obj.h" -#include "link/section.h" -#include "link/symbol.h" - -#include "error.h" -#include "helpers.h" -#include "linkdefs.h" +#include "link/assign.hpp" +#include "link/main.hpp" +#include "link/object.hpp" +#include "link/patch.hpp" +#include "link/sdas_obj.hpp" +#include "link/section.hpp" +#include "link/symbol.hpp" + +#include "error.hpp" +#include "helpers.hpp" +#include "linkdefs.hpp" static struct SymbolList { size_t nbSymbols; @@ -33,7 +33,7 @@ static struct SymbolList { } *symbolLists; unsigned int nbObjFiles; -static struct { +static struct FileStackNodes { struct FileStackNode *nodes; uint32_t nbNodes; } *nodes; @@ -43,7 +43,7 @@ static struct Assertion *assertions; // Internal, DO NOT USE. // For helper wrapper macros defined below, such as `tryReadlong` -#define tryRead(func, type, errval, var, file, ...) \ +#define tryRead(func, type, errval, vartype, var, file, ...) \ do { \ FILE *tmpFile = file; \ type tmpVal = func(tmpFile); \ @@ -53,7 +53,7 @@ static struct Assertion *assertions; ? "Unexpected end of file" \ : strerror(errno)); \ } \ - var = tmpVal; \ + var = (vartype)tmpVal; \ } while (0) /* @@ -91,33 +91,20 @@ static int64_t readlong(FILE *file) * argument is provided, the reason for failure */ #define tryReadlong(var, file, ...) \ - tryRead(readlong, int64_t, INT64_MAX, var, file, __VA_ARGS__) + tryRead(readlong, int64_t, INT64_MAX, long, var, file, __VA_ARGS__) // There is no `readbyte`, just use `fgetc` or `getc`. /* * Helper macro for reading bytes from a file, and errors out if it fails to. - * Differs from `tryGetc` in that the backing function is fgetc(1). * Not as a function to avoid overhead in the general case. * @param var The variable to stash the number into * @param file The file to read from. Its position will be advanced * @param ... A format string and related arguments; note that an extra string * argument is provided, the reason for failure */ -#define tryFgetc(var, file, ...) \ - tryRead(fgetc, int, EOF, var, file, __VA_ARGS__) - -/* - * Helper macro for reading bytes from a file, and errors out if it fails to. - * Differs from `tryGetc` in that the backing function is fgetc(1). - * Not as a function to avoid overhead in the general case. - * @param var The variable to stash the number into - * @param file The file to read from. Its position will be advanced - * @param ... A format string and related arguments; note that an extra string - * argument is provided, the reason for failure - */ -#define tryGetc(var, file, ...) \ - tryRead(getc, int, EOF, var, file, __VA_ARGS__) +#define tryGetc(type, var, file, ...) \ + tryRead(getc, int, EOF, type, var, file, __VA_ARGS__) /* * Reads a '\0'-terminated string from a file. @@ -140,7 +127,7 @@ static char *readstr(FILE *file) // If the buffer isn't suitable to write the next char... if (index >= capacity || !str) { capacity *= 2; - str = realloc(str, capacity); + str = (char *)realloc(str, capacity); // End now in case of error if (!str) return NULL; @@ -167,7 +154,7 @@ static char *readstr(FILE *file) * argument is provided, the reason for failure */ #define tryReadstr(var, file, ...) \ - tryRead(readstr, char*, NULL, var, file, __VA_ARGS__) + tryRead(readstr, char *, NULL, char *, var, file, __VA_ARGS__) // Functions to parse object files @@ -188,8 +175,8 @@ static void readFileStackNode(FILE *file, struct FileStackNode fileNodes[], uint fileNodes[i].parent = parentID == (uint32_t)-1 ? NULL : &fileNodes[parentID]; tryReadlong(fileNodes[i].lineNo, file, "%s: Cannot read node #%" PRIu32 "'s line number: %s", fileName, i); - tryGetc(fileNodes[i].type, file, "%s: Cannot read node #%" PRIu32 "'s type: %s", - fileName, i); + tryGetc(enum FileStackNodeType, fileNodes[i].type, file, + "%s: Cannot read node #%" PRIu32 "'s type: %s", fileName, i); switch (fileNodes[i].type) { case NODE_FILE: case NODE_MACRO: @@ -200,7 +187,8 @@ static void readFileStackNode(FILE *file, struct FileStackNode fileNodes[], uint case NODE_REPT: tryReadlong(fileNodes[i].reptDepth, file, "%s: Cannot read node #%" PRIu32 "'s rept depth: %s", fileName, i); - fileNodes[i].iters = malloc(sizeof(*fileNodes[i].iters) * fileNodes[i].reptDepth); + fileNodes[i].iters = + (uint32_t *)malloc(sizeof(*fileNodes[i].iters) * fileNodes[i].reptDepth); if (!fileNodes[i].iters) fatal(NULL, 0, "%s: Failed to alloc node #%" PRIu32 "'s iters: %s", fileName, i, strerror(errno)); @@ -225,7 +213,7 @@ static void readSymbol(FILE *file, struct Symbol *symbol, { tryReadstr(symbol->name, file, "%s: Cannot read symbol name: %s", fileName); - tryGetc(symbol->type, file, "%s: Cannot read \"%s\"'s type: %s", + tryGetc(enum ExportLevel, symbol->type, file, "%s: Cannot read \"%s\"'s type: %s", fileName, symbol->name); // If the symbol is defined in this file, read its definition if (symbol->type != SYMTYPE_IMPORT) { @@ -261,7 +249,7 @@ static void readPatch(FILE *file, struct Patch *patch, char const *fileName, cha uint32_t i, struct FileStackNode fileNodes[]) { uint32_t nodeID; - uint8_t type; + enum PatchType type; tryReadlong(nodeID, file, "%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s node ID: %s", @@ -279,7 +267,7 @@ static void readPatch(FILE *file, struct Patch *patch, char const *fileName, cha tryReadlong(patch->pcOffset, file, "%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s PC offset: %s", fileName, sectName, i); - tryGetc(type, file, + tryGetc(enum PatchType, type, file, "%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s type: %s", fileName, sectName, i); patch->type = type; @@ -287,7 +275,7 @@ static void readPatch(FILE *file, struct Patch *patch, char const *fileName, cha "%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s RPN size: %s", fileName, sectName, i); - patch->rpnExpression = malloc(sizeof(*patch->rpnExpression) * patch->rpnSize); + patch->rpnExpression = (uint8_t *)malloc(sizeof(*patch->rpnExpression) * patch->rpnSize); if (!patch->rpnExpression) err("%s: Failed to alloc \"%s\"'s patch #%" PRIu32 "'s RPN expression", fileName, sectName, i); @@ -331,9 +319,9 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam section->name, tmp); section->size = tmp; section->offset = 0; - tryGetc(byte, file, "%s: Cannot read \"%s\"'s type: %s", + tryGetc(uint8_t, byte, file, "%s: Cannot read \"%s\"'s type: %s", fileName, section->name); - section->type = byte & 0x3F; + section->type = (enum SectionType)(byte & 0x3F); if (byte >> 7) section->modifier = SECTION_UNION; else if (byte >> 6) @@ -353,7 +341,7 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam fileName, section->name); section->isBankFixed = tmp >= 0; section->bank = tmp; - tryGetc(byte, file, "%s: Cannot read \"%s\"'s alignment: %s", + tryGetc(uint8_t, byte, file, "%s: Cannot read \"%s\"'s alignment: %s", fileName, section->name); if (byte > 16) byte = 16; @@ -370,7 +358,7 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam if (sect_HasData(section->type)) { // Ensure we never allocate 0 bytes - uint8_t *data = malloc(sizeof(*data) * section->size + 1); + uint8_t *data = (uint8_t *)malloc(sizeof(*data) * section->size + 1); if (!data) err("%s: Unable to read \"%s\"'s data", fileName, @@ -391,7 +379,7 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam fileName, section->name); struct Patch *patches = - malloc(sizeof(*patches) * section->nbPatches + 1); + (struct Patch *)malloc(sizeof(*patches) * section->nbPatches + 1); if (!patches) err("%s: Unable to read \"%s\"'s patches", fileName, section->name); @@ -487,7 +475,8 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) // Since SDCC does not provide line info, everything will be reported as coming from the // object file. It's better than nothing. nodes[fileID].nbNodes = 1; - nodes[fileID].nodes = malloc(sizeof(nodes[fileID].nodes[0]) * nodes[fileID].nbNodes); + nodes[fileID].nodes = + (struct FileStackNode *)malloc(sizeof(nodes[fileID].nodes[0]) * nodes[fileID].nbNodes); if (!nodes[fileID].nodes) err("Failed to get memory for %s's nodes", fileName); struct FileStackNode *where = &nodes[fileID].nodes[0]; @@ -533,7 +522,8 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) nbSectionsToAssign += nbSections; tryReadlong(nodes[fileID].nbNodes, file, "%s: Cannot read number of nodes: %s", fileName); - nodes[fileID].nodes = calloc(nodes[fileID].nbNodes, sizeof(nodes[fileID].nodes[0])); + nodes[fileID].nodes = + (struct FileStackNode *)calloc(nodes[fileID].nbNodes, sizeof(nodes[fileID].nodes[0])); if (!nodes[fileID].nodes) err("Failed to get memory for %s's nodes", fileName); verbosePrint("Reading %u nodes...\n", nodes[fileID].nbNodes); @@ -541,12 +531,12 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) readFileStackNode(file, nodes[fileID].nodes, i, fileName); // This file's symbols, kept to link sections to them - struct Symbol **fileSymbols = malloc(sizeof(*fileSymbols) * nbSymbols + 1); + struct Symbol **fileSymbols = (struct Symbol **)malloc(sizeof(*fileSymbols) * nbSymbols + 1); if (!fileSymbols) err("Failed to get memory for %s's symbols", fileName); - struct SymbolList *symbolList = malloc(sizeof(*symbolList)); + struct SymbolList *symbolList = (struct SymbolList *)malloc(sizeof(*symbolList)); if (!symbolList) err("Failed to register %s's symbol list", fileName); @@ -555,13 +545,13 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) symbolList->next = symbolLists; symbolLists = symbolList; - uint32_t *nbSymPerSect = calloc(nbSections ? nbSections : 1, + uint32_t *nbSymPerSect = (uint32_t *)calloc(nbSections ? nbSections : 1, sizeof(*nbSymPerSect)); verbosePrint("Reading %" PRIu32 " symbols...\n", nbSymbols); for (uint32_t i = 0; i < nbSymbols; i++) { // Read symbol - struct Symbol *symbol = malloc(sizeof(*symbol)); + struct Symbol *symbol = (struct Symbol *)malloc(sizeof(*symbol)); if (!symbol) err("%s: Couldn't create new symbol", fileName); @@ -575,13 +565,13 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) } // This file's sections, stored in a table to link symbols to them - struct Section **fileSections = malloc(sizeof(*fileSections) - * (nbSections ? nbSections : 1)); + struct Section **fileSections = + (struct Section **)malloc(sizeof(*fileSections) * (nbSections ? nbSections : 1)); verbosePrint("Reading %" PRIu32 " sections...\n", nbSections); for (uint32_t i = 0; i < nbSections; i++) { // Read section - fileSections[i] = malloc(sizeof(*fileSections[i])); + fileSections[i] = (struct Section *)malloc(sizeof(*fileSections[i])); if (!fileSections[i]) err("%s: Couldn't create new section", fileName); @@ -589,8 +579,8 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) readSection(file, fileSections[i], fileName, nodes[fileID].nodes); fileSections[i]->fileSymbols = fileSymbols; if (nbSymPerSect[i]) { - fileSections[i]->symbols = malloc(nbSymPerSect[i] - * sizeof(*fileSections[i]->symbols)); + fileSections[i]->symbols = + (struct Symbol **)malloc(nbSymPerSect[i] * sizeof(*fileSections[i]->symbols)); if (!fileSections[i]->symbols) err("%s: Couldn't link to symbols", fileName); @@ -640,7 +630,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) fileName); verbosePrint("Reading %" PRIu32 " assertions...\n", nbAsserts); for (uint32_t i = 0; i < nbAsserts; i++) { - struct Assertion *assertion = malloc(sizeof(*assertion)); + struct Assertion *assertion = (struct Assertion *)malloc(sizeof(*assertion)); if (!assertion) err("%s: Couldn't create new assertion", fileName); @@ -671,7 +661,7 @@ void obj_Setup(unsigned int nbFiles) if (nbFiles > SIZE_MAX / sizeof(*nodes)) fatal(NULL, 0, "Impossible to link more than %zu files!", SIZE_MAX / sizeof(*nodes)); - nodes = malloc(sizeof(*nodes) * nbFiles); + nodes = (struct FileStackNodes *)malloc(sizeof(*nodes) * nbFiles); } static void freeNode(struct FileStackNode *node) diff --git a/src/link/output.c b/src/link/output.cpp similarity index 93% rename from src/link/output.c rename to src/link/output.cpp index 0407a99ce1..8ad62f8f5e 100644 --- a/src/link/output.c +++ b/src/link/output.cpp @@ -12,16 +12,16 @@ #include #include -#include "link/output.h" -#include "link/main.h" -#include "link/section.h" -#include "link/symbol.h" +#include "link/output.hpp" +#include "link/main.hpp" +#include "link/section.hpp" +#include "link/symbol.hpp" -#include "extern/utf8decoder.h" +#include "extern/utf8decoder.hpp" -#include "error.h" -#include "linkdefs.h" -#include "platform.h" // MIN_NB_ELMS +#include "error.hpp" +#include "linkdefs.hpp" +#include "platform.hpp" // MIN_NB_ELMS #define BANK_SIZE 0x4000 @@ -41,12 +41,14 @@ struct SortedSymbol { uint16_t addr; }; +struct SortedSections { + struct SortedSection *sections; + struct SortedSection *zeroLenSections; +}; + static struct { uint32_t nbBanks; // Size of the array below (which may be NULL if this is 0) - struct SortedSections { - struct SortedSection *sections; - struct SortedSection *zeroLenSections; - } *banks; + struct SortedSections *banks; } sections[SECTTYPE_INVALID]; // Defines the order in which types are output to the sym and map files @@ -64,14 +66,14 @@ static enum SectionType typeMap[SECTTYPE_INVALID] = { void out_AddSection(struct Section const *section) { static uint32_t maxNbBanks[] = { - [SECTTYPE_ROM0] = 1, - [SECTTYPE_ROMX] = UINT32_MAX, - [SECTTYPE_VRAM] = 2, - [SECTTYPE_SRAM] = UINT32_MAX, - [SECTTYPE_WRAM0] = 1, - [SECTTYPE_WRAMX] = 7, - [SECTTYPE_OAM] = 1, - [SECTTYPE_HRAM] = 1 + 1, // SECTTYPE_WRAM0 + 2, // SECTTYPE_VRAM + UINT32_MAX, // SECTTYPE_ROMX + 1, // SECTTYPE_ROM0 + 1, // SECTTYPE_HRAM + 7, // SECTTYPE_WRAMX + UINT32_MAX, // SECTTYPE_SRAM + 1, // SECTTYPE_OAM }; uint32_t targetBank = section->bank - sectionTypeInfo[section->type].firstBank; @@ -84,7 +86,7 @@ void out_AddSection(struct Section const *section) if (minNbBanks > sections[section->type].nbBanks) { sections[section->type].banks = - realloc(sections[section->type].banks, + (struct SortedSections *)realloc(sections[section->type].banks, sizeof(*sections[0].banks) * minNbBanks); for (uint32_t i = sections[section->type].nbBanks; i < minNbBanks; i++) { sections[section->type].banks[i].sections = NULL; @@ -95,7 +97,7 @@ void out_AddSection(struct Section const *section) if (!sections[section->type].banks) err("Failed to realloc banks"); - struct SortedSection *newSection = malloc(sizeof(*newSection)); + struct SortedSection *newSection = (struct SortedSection *)malloc(sizeof(*newSection)); struct SortedSection **ptr = section->size ? §ions[section->type].banks[targetBank].sections : §ions[section->type].banks[targetBank].zeroLenSections; @@ -176,7 +178,7 @@ static void coverOverlayBanks(uint32_t nbOverlayBanks) if (nbUncoveredBanks > sections[SECTTYPE_ROMX].nbBanks) { sections[SECTTYPE_ROMX].banks = - realloc(sections[SECTTYPE_ROMX].banks, + (struct SortedSections *)realloc(sections[SECTTYPE_ROMX].banks, sizeof(*sections[SECTTYPE_ROMX].banks) * nbUncoveredBanks); if (!sections[SECTTYPE_ROMX].banks) err("Failed to realloc banks for overlay"); @@ -367,7 +369,7 @@ static void writeSymBank(struct SortedSections const *bankSections, if (!nbSymbols) return; - struct SortedSymbol *symList = malloc(sizeof(*symList) * nbSymbols); + struct SortedSymbol *symList = (struct SortedSymbol *)malloc(sizeof(*symList) * nbSymbols); if (!symList) err("Failed to allocate symbol list"); @@ -538,7 +540,7 @@ static void writeSymAndMap(void) if (!symFileName && !mapFileName) return; - uint32_t usedMap[SECTTYPE_INVALID] = {0}; + uint32_t usedMap[SECTTYPE_INVALID] = {}; symFile = openFile(symFileName, "w"); mapFile = openFile(mapFileName, "w"); @@ -575,7 +577,7 @@ static void cleanupSections(struct SortedSection *section) static void cleanup(void) { - for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) { + for (enum SectionType type = (enum SectionType)0; type < SECTTYPE_INVALID; type = (enum SectionType)(type + 1)) { if (sections[type].nbBanks > 0) { for (uint32_t i = 0; i < sections[type].nbBanks; i++) { struct SortedSections *bank = diff --git a/src/link/patch.c b/src/link/patch.cpp similarity index 94% rename from src/link/patch.c rename to src/link/patch.cpp index 9eb901347e..56a25d0904 100644 --- a/src/link/patch.c +++ b/src/link/patch.cpp @@ -12,14 +12,14 @@ #include #include -#include "link/object.h" -#include "link/patch.h" -#include "link/section.h" -#include "link/symbol.h" +#include "link/object.hpp" +#include "link/patch.hpp" +#include "link/section.hpp" +#include "link/symbol.hpp" -#include "error.h" -#include "linkdefs.h" -#include "opmath.h" +#include "error.hpp" +#include "linkdefs.hpp" +#include "opmath.hpp" /* * This is an "empty"-type stack. Apart from the actual values, we also remember @@ -39,8 +39,8 @@ struct RPNStack { static void initRPNStack(void) { stack.capacity = 64; - stack.values = malloc(sizeof(*stack.values) * stack.capacity); - stack.errorFlags = malloc(sizeof(*stack.errorFlags) * stack.capacity); + stack.values = (int32_t *)malloc(sizeof(*stack.values) * stack.capacity); + stack.errorFlags = (bool *)malloc(sizeof(*stack.errorFlags) * stack.capacity); if (!stack.values || !stack.errorFlags) err("Failed to init RPN stack"); } @@ -60,9 +60,9 @@ static void pushRPN(int32_t value, bool comesFromError) stack.capacity *= increase_factor; stack.values = - realloc(stack.values, sizeof(*stack.values) * stack.capacity); + (int32_t *)realloc(stack.values, sizeof(*stack.values) * stack.capacity); stack.errorFlags = - realloc(stack.errorFlags, sizeof(*stack.errorFlags) * stack.capacity); + (bool *)realloc(stack.errorFlags, sizeof(*stack.errorFlags) * stack.capacity); // Static analysis tools complain that the capacity might become // zero due to overflow, but fail to realize that it's caught by // the overflow check above. Hence the stringent check below. @@ -139,7 +139,7 @@ static int32_t computeRPNExpr(struct Patch const *patch, clearRPNStack(); while (size > 0) { - enum RPNCommand command = getRPNByte(&expression, &size, + enum RPNCommand command = (enum RPNCommand)getRPNByte(&expression, &size, patch->src, patch->lineNo); int32_t value; @@ -516,10 +516,11 @@ static void applyFilePatches(struct Section *section, struct Section *dataSectio uint8_t size; int32_t min; int32_t max; - } const types[] = { - [PATCHTYPE_BYTE] = {1, -128, 255}, - [PATCHTYPE_WORD] = {2, -32768, 65536}, - [PATCHTYPE_LONG] = {4, INT32_MIN, INT32_MAX} + } const types[PATCHTYPE_INVALID] = { + {1, -128, 255}, // PATCHTYPE_BYTE + {2, -32768, 65536}, // PATCHTYPE_WORD + {4, INT32_MIN, INT32_MAX}, // PATCHTYPE_LONG + {}, // PATCHTYPE_JR }; if (!isError && (value < types[patch->type].min diff --git a/src/link/script.c b/src/link/script.cpp similarity index 89% rename from src/link/script.c rename to src/link/script.cpp index ebd4ca98d5..4d384acecb 100644 --- a/src/link/script.c +++ b/src/link/script.cpp @@ -13,23 +13,25 @@ #include #include -#include "link/main.h" -#include "link/script.h" -#include "link/section.h" +#include "link/main.hpp" +#include "link/script.hpp" +#include "link/section.hpp" -#include "error.h" -#include "linkdefs.h" +#include "error.hpp" +#include "linkdefs.hpp" FILE *linkerScript; char *includeFileName; static uint32_t lineNo; -static struct { +struct FileNode { FILE *file; uint32_t lineNo; char *name; -} *fileStack; +}; + +static struct FileNode *fileStack; static uint32_t fileStackSize; static uint32_t fileStackIndex; @@ -44,7 +46,7 @@ static void pushFile(char *newFileName) if (!fileStackSize) // Init file stack fileStackSize = 4; fileStackSize *= 2; - fileStack = realloc(fileStack, sizeof(*fileStack) * fileStackSize); + fileStack = (struct FileNode *)realloc(fileStack, sizeof(*fileStack) * fileStackSize); if (!fileStack) err("%s(%" PRIu32 "): Internal INCLUDE error", linkerScriptName, lineNo); @@ -142,13 +144,14 @@ enum LinkerScriptTokenType { TOKEN_INVALID }; -char const *tokenTypes[] = { - [TOKEN_NEWLINE] = "newline", - [TOKEN_COMMAND] = "command", - [TOKEN_BANK] = "bank command", - [TOKEN_NUMBER] = "number", - [TOKEN_STRING] = "string", - [TOKEN_EOF] = "end of file" +char const *tokenTypes[TOKEN_INVALID] = { + "newline", // TOKEN_NEWLINE + "command", // TOKEN_COMMAND + "bank command", // TOKEN_BANK + NULL, // TOKEN_INCLUDE + "number", // TOKEN_NUMBER + "string", // TOKEN_STRING + "end of file", // TOKEN_EOF }; enum LinkerScriptCommand { @@ -158,19 +161,21 @@ enum LinkerScriptCommand { COMMAND_INVALID }; +union LinkerScriptTokenAttr { + enum LinkerScriptCommand command; + enum SectionType secttype; + uint32_t number; + char *string; +}; + struct LinkerScriptToken { enum LinkerScriptTokenType type; - union LinkerScriptTokenAttr { - enum LinkerScriptCommand command; - enum SectionType secttype; - uint32_t number; - char *string; - } attr; + union LinkerScriptTokenAttr attr; }; -static char const * const commands[] = { - [COMMAND_ORG] = "ORG", - [COMMAND_ALIGN] = "ALIGN" +static char const * const commands[COMMAND_INVALID] = { + "ORG", // COMMAND_ORG + "ALIGN", // COMMAND_ALIGN }; static int nextChar(void) @@ -251,7 +256,7 @@ static struct LinkerScriptToken *nextToken(void) if (size >= capacity || token.attr.string == NULL) { capacity *= 2; - token.attr.string = realloc(token.attr.string, capacity); + token.attr.string = (char *)realloc(token.attr.string, capacity); if (!token.attr.string) err("%s: Failed to allocate memory for string", __func__); @@ -267,7 +272,7 @@ static struct LinkerScriptToken *nextToken(void) for (;;) { if (size >= capacity || str == NULL) { capacity *= 2; - str = realloc(str, capacity); + str = (char *)realloc(str, capacity); if (!str) err("%s: Failed to allocate memory for token", __func__); @@ -289,7 +294,7 @@ static struct LinkerScriptToken *nextToken(void) token.type = TOKEN_INVALID; // Try to match a command - for (enum LinkerScriptCommand i = 0; i < COMMAND_INVALID; i++) { + for (enum LinkerScriptCommand i = (enum LinkerScriptCommand)0; i < COMMAND_INVALID; i = (enum LinkerScriptCommand)(i + 1)) { if (!strcmp(commands[i], str)) { token.type = TOKEN_COMMAND; token.attr.command = i; @@ -299,7 +304,7 @@ static struct LinkerScriptToken *nextToken(void) if (token.type == TOKEN_INVALID) { // Try to match a bank specifier - for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) { + for (enum SectionType type = (enum SectionType)0; type < SECTTYPE_INVALID; type = (enum SectionType)(type + 1)) { if (!strcmp(sectionTypeInfo[type].name, str)) { token.type = TOKEN_BANK; token.attr.secttype = type; @@ -374,8 +379,8 @@ struct SectionPlacement *script_NextSection(void) lineNo = 1; // Init PC for all banks - for (enum SectionType i = 0; i < SECTTYPE_INVALID; i++) { - curaddr[i] = malloc(sizeof(*curaddr[i]) * nbbanks(i)); + for (enum SectionType i = (enum SectionType)0; i < SECTTYPE_INVALID; i = (enum SectionType)(i + 1)) { + curaddr[i] = (uint16_t *)malloc(sizeof(*curaddr[i]) * nbbanks(i)); for (uint32_t b = 0; b < nbbanks(i); b++) curaddr[i][b] = sectionTypeInfo[i].startAddr; } @@ -534,6 +539,6 @@ struct SectionPlacement *script_NextSection(void) void script_Cleanup(void) { - for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) + for (enum SectionType type = (enum SectionType)0; type < SECTTYPE_INVALID; type = (enum SectionType)(type + 1)) free(curaddr[type]); } diff --git a/src/link/sdas_obj.c b/src/link/sdas_obj.cpp similarity index 94% rename from src/link/sdas_obj.c rename to src/link/sdas_obj.cpp index 075650d45c..7d26476625 100644 --- a/src/link/sdas_obj.c +++ b/src/link/sdas_obj.cpp @@ -15,14 +15,14 @@ #include #include -#include "linkdefs.h" -#include "platform.h" +#include "linkdefs.hpp" +#include "platform.hpp" -#include "link/assign.h" -#include "link/main.h" -#include "link/sdas_obj.h" -#include "link/section.h" -#include "link/symbol.h" +#include "link/assign.hpp" +#include "link/main.hpp" +#include "link/sdas_obj.hpp" +#include "link/section.hpp" +#include "link/symbol.hpp" enum NumberType { HEX = 16, // X @@ -66,7 +66,7 @@ static int nextLine(char **restrict lineBuf, size_t *restrict bufLen, uint32_t * if (i >= *bufLen) { assert(*bufLen != 0); *bufLen *= 2; - *lineBuf = realloc(*lineBuf, *bufLen); + *lineBuf = (char *)realloc(*lineBuf, *bufLen); if (!*lineBuf) fatal(where, *lineNo, "Failed to realloc: %s", strerror(errno)); } @@ -150,7 +150,7 @@ enum RelocFlags { void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { size_t bufLen = 256; - char *line = malloc(bufLen); + char *line = (char *)malloc(bufLen); char const *token; #define getToken(ptr, ...) do { \ @@ -231,42 +231,43 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { // Now, let's parse the rest of the lines as they come! - struct { + struct FileSection { struct Section *section; uint16_t writeIndex; - } *fileSections = NULL; - struct Symbol **fileSymbols = malloc(sizeof(*fileSymbols) * expectedNbSymbols); + }; + struct FileSection *fileSections = NULL; + struct Symbol **fileSymbols = (struct Symbol **)malloc(sizeof(*fileSymbols) * expectedNbSymbols); size_t nbSections = 0, nbSymbols = 0; if (!fileSymbols) fatal(where, lineNo, "Failed to alloc file symbols table: %s", strerror(errno)); size_t nbBytes = 0; // How many bytes are in `data`, including the ADDR_SIZE "header" bytes size_t dataCapacity = 16 + ADDR_SIZE; // SDCC object files usually contain 16 bytes per T line - uint8_t *data = malloc(sizeof(*data) * dataCapacity); + uint8_t *data = (uint8_t *)malloc(sizeof(*data) * dataCapacity); if (!data) fatal(where, lineNo, "Failed to alloc data buffer: %s", strerror(errno)); + for (;;) { lineType = nextLine(&line, &bufLen, &lineNo, where, file); if (lineType == EOF) break; switch (lineType) { - uint32_t tmp; - case 'M': // Module name case 'O': // Assembler flags // Ignored break; - case 'A': + case 'A': { if (nbSections == expectedNbAreas) warning(where, lineNo, "Got more 'A' lines than the expected %" PRIu32, expectedNbAreas); - fileSections = realloc(fileSections, sizeof(*fileSections) * (nbSections + 1)); + fileSections = (struct FileSection *)realloc(fileSections, + sizeof(*fileSections) * (nbSections + 1)); if (!fileSections) fatal(where, lineNo, "Failed to realloc file areas: %s", strerror(errno)); fileSections[nbSections].writeIndex = 0; #define curSection (fileSections[nbSections].section) - curSection = malloc(sizeof(*curSection)); + curSection = (struct Section *)malloc(sizeof(*curSection)); if (!curSection) fatal(where, lineNo, "Failed to alloc new area: %s", strerror(errno)); @@ -282,7 +283,9 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { expectToken("size", 'A'); getToken(NULL, "'A' line is too short"); - tmp = parseNumber(where, lineNo, token, numberType); + + uint32_t tmp = parseNumber(where, lineNo, token, numberType); + if (tmp > UINT16_MAX) fatal(where, lineNo, "Area \"%s\" is larger than the GB address space!?", curSection->name); curSection->size = tmp; @@ -301,7 +304,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { if (curSection->modifier == SECTION_NORMAL) { size_t len = strlen(where->name) + 1 + strlen(token); - curSection->name = malloc(len + 1); + curSection->name = (char *)malloc(len + 1); if (!curSection->name) fatal(where, lineNo, "Failed to alloc new area's name: %s", strerror(errno)); sprintf(curSection->name, "%s %s", where->name, sectionName); @@ -359,6 +362,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { #undef curSection ++nbSections; break; + } case 'S': if (nbSymbols == expectedNbSymbols) @@ -366,7 +370,8 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { // `realloc` is dangerous, as sections contain a pointer to `fileSymbols`. // We can try to be nice, but if the pointer moves, it's game over! if (nbSymbols >= expectedNbSymbols) { - struct Symbol **newFileSymbols = realloc(fileSymbols, sizeof(*fileSymbols) * (nbSymbols + 1)); + struct Symbol **newFileSymbols = (struct Symbol **)realloc(fileSymbols, + sizeof(*fileSymbols) * (nbSymbols + 1)); if (!newFileSymbols) fatal(where, lineNo, "Failed to alloc extra symbols: %s", strerror(errno)); @@ -375,7 +380,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { // No need to assign, obviously } #define symbol (fileSymbols[nbSymbols]) - symbol = malloc(sizeof(*symbol)); + symbol = (struct Symbol *)malloc(sizeof(*symbol)); if (!symbol) fatal(where, lineNo, "Failed to alloc symbol: %s", strerror(errno)); @@ -437,7 +442,8 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { struct Section *section = fileSections[nbSections - 1].section; ++section->nbSymbols; - section->symbols = realloc(section->symbols, sizeof(section->symbols[0]) * section->nbSymbols); + section->symbols = (struct Symbol **)realloc(section->symbols, + sizeof(section->symbols[0]) * section->nbSymbols); if (!section->symbols) fatal(where, lineNo, "Failed to realloc \"%s\"'s symbol list: %s", section->name, strerror(errno)); section->symbols[section->nbSymbols - 1] = symbol; @@ -458,7 +464,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { for (token = strtok(line, delim); token; token = strtok(NULL, delim)) { if (dataCapacity == nbBytes) { dataCapacity *= 2; - data = realloc(data, sizeof(*data) * dataCapacity); + data = (uint8_t *)realloc(data, sizeof(*data) * dataCapacity); if (!data) fatal(where, lineNo, "Failed to realloc data buffer: %s", strerror(errno)); } @@ -471,7 +477,8 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { // Importantly, now we know that `nbBytes != 0`, which means "pending data" break; - case 'R': // Supposed to directly follow `T` + case 'R': { + // Supposed to directly follow `T` if (nbBytes == 0) { warning(where, lineNo, "'R' line with no 'T' line, ignoring"); break; @@ -506,7 +513,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { fatal(where, lineNo, "'T' lines which don't append to their section are not supported (%" PRIu16 " != %" PRIu16 ")", addr, *writeIndex); if (!section->data) { assert(section->size != 0); - section->data = malloc(section->size); + section->data = (uint8_t *)malloc(section->size); if (!section->data) fatal(where, lineNo, "Failed to alloc data for \"%s\": %s", section->name, strerror(errno)); } @@ -554,7 +561,8 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { warning(where, lineNo, "Unknown reloc flags 0x%x", flags & ~RELOC_ALL_FLAGS); // Turn this into a Patch - section->patches = realloc(section->patches, sizeof(section->patches[0]) * (section->nbPatches + 1)); + section->patches = (struct Patch *)realloc(section->patches, + sizeof(section->patches[0]) * (section->nbPatches + 1)); if (!section->patches) fatal(where, lineNo, "Failed to alloc extra patch for \"%s\"", section->name); struct Patch *patch = §ion->patches[section->nbPatches]; @@ -581,7 +589,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { #define RPN_EXTRA_SIZE (5 + 1 + 5 + 1 + 5 + 1) // >> 8 & $FF, then + #define allocPatch(size) do { \ patch->rpnSize = (size); \ - patch->rpnExpression = malloc(patch->rpnSize + RPN_EXTRA_SIZE); \ + patch->rpnExpression = (uint8_t *)malloc(patch->rpnSize + RPN_EXTRA_SIZE); \ if (!patch->rpnExpression) \ fatal(where, lineNo, "Failed to alloc RPN expression: %s", strerror(errno)); \ } while (0) @@ -652,7 +660,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { baseValue += other->size; allocPatch(1 + strlen(name) + 1); patch->rpnSize = 1 + strlen(name) + 1; - patch->rpnExpression = malloc(patch->rpnSize + RPN_EXTRA_SIZE); + patch->rpnExpression = (uint8_t *)malloc(patch->rpnSize + RPN_EXTRA_SIZE); if (!patch->rpnExpression) fatal(where, lineNo, "Failed to alloc RPN expression: %s", strerror(errno)); patch->rpnExpression[0] = RPN_STARTOF_SECT; @@ -733,6 +741,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { nbBytes = 0; // Do not allow two R lines to refer to the same T line break; + } case 'P': default: diff --git a/src/link/section.c b/src/link/section.cpp similarity index 95% rename from src/link/section.c rename to src/link/section.cpp index 74aabc0598..b8b1427e27 100644 --- a/src/link/section.c +++ b/src/link/section.cpp @@ -12,30 +12,30 @@ #include #include -#include "link/main.h" -#include "link/section.h" +#include "link/main.hpp" +#include "link/section.hpp" -#include "error.h" -#include "hashmap.h" -#include "linkdefs.h" +#include "error.hpp" +#include "hashmap.hpp" +#include "linkdefs.hpp" HashMap sections; -struct ForEachArg { +struct ForEachSectionArg { void (*callback)(struct Section *section, void *arg); void *arg; }; static void forEach(void *section, void *arg) { - struct ForEachArg *callbackArg = (struct ForEachArg *)arg; + struct ForEachSectionArg *callbackArg = (struct ForEachSectionArg *)arg; callbackArg->callback((struct Section *)section, callbackArg->arg); } void sect_ForEach(void (*callback)(struct Section *, void *), void *arg) { - struct ForEachArg callbackArg = { .callback = callback, .arg = arg}; + struct ForEachSectionArg callbackArg = { .callback = callback, .arg = arg}; hash_ForEach(sections, forEach, &callbackArg); } @@ -167,7 +167,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se if (other->data) { if (target->data) { // Ensure we're not allocating 0 bytes - target->data = realloc(target->data, + target->data = (uint8_t *)realloc(target->data, sizeof(*target->data) * target->size + 1); if (!target->data) errx("Failed to concatenate \"%s\"'s fragments", target->name); @@ -196,7 +196,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se void sect_AddSection(struct Section *section) { // Check if the section already exists - struct Section *other = hash_GetElement(sections, section->name); + struct Section *other = (struct Section *)hash_GetElement(sections, section->name); if (other) { if (section->modifier != other->modifier) diff --git a/src/link/symbol.c b/src/link/symbol.cpp similarity index 75% rename from src/link/symbol.c rename to src/link/symbol.cpp index c270c8fc90..935ff9263e 100644 --- a/src/link/symbol.c +++ b/src/link/symbol.cpp @@ -10,30 +10,30 @@ #include #include -#include "link/object.h" -#include "link/symbol.h" -#include "link/main.h" +#include "link/object.hpp" +#include "link/symbol.hpp" +#include "link/main.hpp" -#include "error.h" -#include "hashmap.h" +#include "error.hpp" +#include "hashmap.hpp" HashMap symbols; -struct ForEachArg { +struct ForEachSymbolArg { void (*callback)(struct Symbol *symbol, void *arg); void *arg; }; static void forEach(void *symbol, void *arg) { - struct ForEachArg *callbackArg = (struct ForEachArg *)arg; + struct ForEachSymbolArg *callbackArg = (struct ForEachSymbolArg *)arg; callbackArg->callback((struct Symbol *)symbol, callbackArg->arg); } void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg) { - struct ForEachArg callbackArg = { .callback = callback, .arg = arg}; + struct ForEachSymbolArg callbackArg = { .callback = callback, .arg = arg}; hash_ForEach(symbols, forEach, &callbackArg); } @@ -41,7 +41,7 @@ void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg) void sym_AddSymbol(struct Symbol *symbol) { // Check if the symbol already exists - struct Symbol *other = hash_GetElement(symbols, symbol->name); + struct Symbol *other = (struct Symbol *)hash_GetElement(symbols, symbol->name); if (other) { fprintf(stderr, "error: \"%s\" both in %s from ", symbol->name, symbol->objFileName); diff --git a/src/linkdefs.c b/src/linkdefs.c deleted file mode 100644 index 337603eecc..0000000000 --- a/src/linkdefs.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of RGBDS. - * - * Copyright (c) 2022, RGBDS contributors. - * - * SPDX-License-Identifier: MIT - */ - -#include "linkdefs.h" - -// The default values are the most lax, as they are used as-is by RGBASM; only RGBLINK has the full info, -// so RGBASM's job is only to catch unconditional errors earlier. -struct SectionTypeInfo sectionTypeInfo[SECTTYPE_INVALID] = { - [SECTTYPE_ROM0] = { - .name = "ROM0", - .startAddr = 0x0000, - .size = 0x8000, // Patched to 0x4000 if !is32kMode - .firstBank = 0, - .lastBank = 0, - }, - [SECTTYPE_ROMX] = { - .name = "ROMX", - .startAddr = 0x4000, - .size = 0x4000, - .firstBank = 1, - .lastBank = 65535, - }, - [SECTTYPE_VRAM] = { - .name = "VRAM", - .startAddr = 0x8000, - .size = 0x2000, - .firstBank = 0, - .lastBank = 1, // Patched to 0 if isDmgMode - }, - [SECTTYPE_SRAM] = { - .name = "SRAM", - .startAddr = 0xA000, - .size = 0x2000, - .firstBank = 0, - .lastBank = 255, - }, - [SECTTYPE_WRAM0] = { - .name = "WRAM0", - .startAddr = 0xC000, - .size = 0x2000, // Patched to 0x1000 if !isWRA0Mode - .firstBank = 0, - .lastBank = 0, - }, - [SECTTYPE_WRAMX] = { - .name = "WRAMX", - .startAddr = 0xD000, - .size = 0x1000, - .firstBank = 1, - .lastBank = 7, - }, - [SECTTYPE_OAM] = { - .name = "OAM", - .startAddr = 0xFE00, - .size = 0x00A0, - .firstBank = 0, - .lastBank = 0, - }, - [SECTTYPE_HRAM] = { - .name = "HRAM", - .startAddr = 0xFF80, - .size = 0x007F, - .firstBank = 0, - .lastBank = 0, - }, -}; - -char const * const sectionModNames[] = { - [SECTION_NORMAL] = "regular", - [SECTION_UNION] = "union", - [SECTION_FRAGMENT] = "fragment", -}; diff --git a/src/linkdefs.cpp b/src/linkdefs.cpp new file mode 100644 index 0000000000..b0d6d2e139 --- /dev/null +++ b/src/linkdefs.cpp @@ -0,0 +1,76 @@ +/* + * This file is part of RGBDS. + * + * Copyright (c) 2022, RGBDS contributors. + * + * SPDX-License-Identifier: MIT + */ + +#include "linkdefs.hpp" + +// The default values are the most lax, as they are used as-is by RGBASM; only RGBLINK has the full info, +// so RGBASM's job is only to catch unconditional errors earlier. +struct SectionTypeInfo sectionTypeInfo[SECTTYPE_INVALID] = { + { // SECTTYPE_WRAM0 + "WRAM0", // name + 0xC000, // startAddr + 0x2000, // size (Patched to 0x1000 if !isWRA0Mode) + 0, // firstBank + 0, // lastBank + }, + { // SECTTYPE_VRAM + "VRAM", // name + 0x8000, // startAddr + 0x2000, // size + 0, // firstBank + 1, // lastBank (Patched to 0 if isDmgMode) + }, + { // SECTTYPE_ROMX + "ROMX", // name + 0x4000, // startAddr + 0x4000, // size + 1, // firstBank + 65535, // lastBank + }, + { // SECTTYPE_ROM0 + "ROM0", // name + 0x0000, // startAddr + 0x8000, // size (Patched to 0x4000 if !is32kMode) + 0, // firstBank + 0, // lastBank + }, + { // SECTTYPE_HRAM + "HRAM", // name + 0xFF80, // startAddr + 0x007F, // size + 0, // firstBank + 0, // lastBank + }, + { // SECTTYPE_WRAMX + "WRAMX", // name + 0xD000, // startAddr + 0x1000, // size + 1, // firstBank + 7, // lastBank + }, + { // SECTTYPE_SRAM + "SRAM", // name + 0xA000, // startAddr + 0x2000, // size + 0, // firstBank + 255, // lastBank + }, + { // SECTTYPE_OAM + "OAM", // name + 0xFE00, // startAddr + 0x00A0, // size + 0, // firstBank + 0, // lastBank + }, +}; + +char const * const sectionModNames[] = { + "regular", // SECTION_NORMAL + "union", // SECTION_UNION + "fragment", // SECTION_FRAGMENT +}; diff --git a/src/opmath.c b/src/opmath.cpp similarity index 99% rename from src/opmath.c rename to src/opmath.cpp index f5832ddb60..f4f3148cb9 100644 --- a/src/opmath.c +++ b/src/opmath.cpp @@ -10,7 +10,7 @@ #include -#include "opmath.h" +#include "opmath.hpp" int32_t op_divide(int32_t dividend, int32_t divisor) { diff --git a/src/version.c b/src/version.cpp similarity index 95% rename from src/version.c rename to src/version.cpp index d9d4401dc6..33d9fd489a 100644 --- a/src/version.c +++ b/src/version.cpp @@ -9,8 +9,8 @@ #include #include -#include "helpers.h" -#include "version.h" +#include "helpers.hpp" +#include "version.hpp" // This variable is passed via `-D` from the Makefile, but not from CMake // (in which `configure_file()` is used on this file to replace some syntax) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4044e66d20..dd3fc8fff2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ -add_executable(randtilegen gfx/randtilegen.c) +add_executable(randtilegen gfx/randtilegen.cpp) add_executable(rgbgfx_test gfx/rgbgfx_test.cpp) diff --git a/test/gfx/randtilegen.c b/test/gfx/randtilegen.cpp similarity index 97% rename from test/gfx/randtilegen.c rename to test/gfx/randtilegen.cpp index 639ace5703..051fd6feb8 100644 --- a/test/gfx/randtilegen.c +++ b/test/gfx/randtilegen.cpp @@ -22,7 +22,7 @@ #include #include -#include "platform.h" +#include "platform.hpp" #define STR(x) #x #define XSTR(x) STR(x) @@ -35,7 +35,7 @@ struct Attributes { static unsigned long long randbits = 0; static unsigned char randcount = 0; -static _Noreturn void fatal(char const *error) { +static [[noreturn]] void fatal(char const *error) { fprintf(stderr, "FATAL: %s\n", error); exit(1); } @@ -192,8 +192,8 @@ static void write_image(char const *filename, uint16_t /* const */ palettes[MIN_ uint8_t const SIZEOF_PIXEL = 4; // Each pixel is 4 bytes (RGBA @ 8 bits/component) assert(width != 0); assert(height != 0); - uint8_t *data = malloc(height * 8 * width * 8 * SIZEOF_PIXEL); - uint8_t **rowPtrs = malloc(height * 8 * sizeof(*rowPtrs)); + uint8_t *data = (uint8_t *)malloc(height * 8 * width * 8 * SIZEOF_PIXEL); + uint8_t **rowPtrs = (uint8_t **)malloc(height * 8 * sizeof(*rowPtrs)); if (data == NULL || rowPtrs == NULL) { fatal("Out of memory"); } @@ -302,7 +302,7 @@ int main(int argc, char **argv) { } } - char *filename = malloc(nameLen + sizeof(XSTR(ULLONG_MAX) ".png")); + char *filename = (char *)malloc(nameLen + sizeof(XSTR(ULLONG_MAX) ".png")); if (!filename) { fatal("out of memory"); }