mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Build everything as C++ (#1176)
This commit is contained in:
@@ -93,7 +93,7 @@ SpacesInConditionalStatement: false
|
|||||||
SpacesInContainerLiterals: false
|
SpacesInContainerLiterals: false
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
Standard: c++17
|
Standard: c++20
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
UseCRLF: false
|
UseCRLF: false
|
||||||
UseTab: ForIndentation
|
UseTab: ForIndentation
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ jobs:
|
|||||||
body: |
|
body: |
|
||||||
Please ensure that the four packages below work properly.
|
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.
|
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 <tag>` 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 <tag>` to delete it)
|
||||||
draft: true # Don't publish the release quite yet...
|
draft: true # Don't publish the release quite yet...
|
||||||
prerelease: ${{ contains(github.ref, '-rc') }}
|
prerelease: ${{ contains(github.ref, '-rc') }}
|
||||||
files: |
|
files: |
|
||||||
|
|||||||
5
.github/workflows/testing.yml
vendored
5
.github/workflows/testing.yml
vendored
@@ -195,12 +195,13 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
make mingw${{ matrix.bits }} -j Q=
|
make mingw${{ matrix.bits }} -j Q=
|
||||||
- name: Package binaries
|
- name: Package binaries
|
||||||
run: | # DLL dependencies can be figured out using e.g. Dependency Walker
|
run: | # DLL dependencies can be figured out using e.g. Dependency Walker or objdump -p
|
||||||
mkdir bins
|
mkdir bins
|
||||||
mv -v rgb{asm,link,fix,gfx}.exe bins/
|
mv -v rgb{asm,link,fix,gfx}.exe bins/
|
||||||
cp -v /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
|
cp -v /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
|
||||||
cp -v /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
|
cp -v /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
|
||||||
[ "${{ matrix.bits }}" -ne 32 ] || cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/lib{gcc_s_dw2-1,ssp-0,stdc++-6}.dll bins
|
cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/lib{ssp-0,stdc++-6}.dll bins
|
||||||
|
[ "${{ matrix.bits }}" -ne 32 ] || cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/libgcc_s_dw2-1.dll bins
|
||||||
- name: Upload Windows binaries
|
- name: Upload Windows binaries
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||||
|
|
||||||
project(rgbds
|
project(rgbds
|
||||||
LANGUAGES C CXX)
|
LANGUAGES CXX)
|
||||||
|
|
||||||
# get real path of source and binary directories
|
# get real path of source and binary directories
|
||||||
get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
|
get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
|
||||||
@@ -31,10 +31,6 @@ if(MSVC)
|
|||||||
# "macro expansion producing 'defined' has undefined behavior"
|
# "macro expansion producing 'defined' has undefined behavior"
|
||||||
add_compile_options(/MP /wd5105)
|
add_compile_options(/MP /wd5105)
|
||||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
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)
|
if(SANITIZERS)
|
||||||
set(SAN_FLAGS /fsanitize=address)
|
set(SAN_FLAGS /fsanitize=address)
|
||||||
@@ -42,8 +38,12 @@ if(MSVC)
|
|||||||
add_link_options(${SAN_FLAGS})
|
add_link_options(${SAN_FLAGS})
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
add_compile_options(-Wall -pedantic)
|
# TODO: use -pedantic after non-C++ idioms are gone
|
||||||
add_definitions(-D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE)
|
add_compile_options(-Wall)
|
||||||
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
add_compile_options(-Wno-c99-designator)
|
||||||
|
endif()
|
||||||
|
add_definitions(-D_POSIX_C_SOURCE=200809L)
|
||||||
if(SANITIZERS)
|
if(SANITIZERS)
|
||||||
set(SAN_FLAGS -fsanitize=shift -fsanitize=integer-divide-by-zero
|
set(SAN_FLAGS -fsanitize=shift -fsanitize=integer-divide-by-zero
|
||||||
-fsanitize=unreachable -fsanitize=vla-bound
|
-fsanitize=unreachable -fsanitize=vla-bound
|
||||||
@@ -55,7 +55,6 @@ else()
|
|||||||
add_definitions(-D_GLIBCXX_ASSERTIONS)
|
add_definitions(-D_GLIBCXX_ASSERTIONS)
|
||||||
# A non-zero optimization level is desired in debug mode, but allow overriding it nonetheless
|
# 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!
|
# 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)
|
set(CMAKE_CXX_FLAGS_DEBUG "-g -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE STRING "" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -98,9 +97,7 @@ endif()
|
|||||||
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/include")
|
include_directories("${PROJECT_SOURCE_DIR}/include")
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_C_STANDARD_REQUIRED True)
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|||||||
50
Makefile
50
Makefile
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SUFFIXES: .h .y .c .cpp .o
|
.SUFFIXES: .cpp .y .o
|
||||||
|
|
||||||
.PHONY: all clean install checkcodebase checkpatch checkdiff develop debug mingw32 mingw64 wine-shim dist
|
.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`
|
PNGLDFLAGS := `${PKG_CONFIG} --libs-only-L libpng`
|
||||||
PNGLDLIBS := `${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`
|
VERSION_STRING := `git describe --tags --dirty --always 2>/dev/null`
|
||||||
|
|
||||||
WARNFLAGS := -Wall -pedantic
|
# TODO: use -pedantic after non-C++ idioms are gone
|
||||||
|
WARNFLAGS := -Wall -Wno-unknown-warning-option -Wno-c99-designator
|
||||||
|
|
||||||
# Overridable CFLAGS
|
# Overridable CXXFLAGS
|
||||||
CFLAGS ?= -O3 -flto -DNDEBUG
|
|
||||||
CXXFLAGS ?= -O3 -flto -DNDEBUG
|
CXXFLAGS ?= -O3 -flto -DNDEBUG
|
||||||
# Non-overridable CFLAGS
|
# Non-overridable CXXFLAGS
|
||||||
# _ISOC11_SOURCE is required on certain platforms to get C11 on top of the C99-based POSIX 2008
|
REALCXXFLAGS := ${CXXFLAGS} ${WARNFLAGS} -x c++ -std=c++2a -I include \
|
||||||
REALCFLAGS := ${CFLAGS} ${WARNFLAGS} -std=gnu11 -I include \
|
|
||||||
-D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE
|
|
||||||
REALCXXFLAGS := ${CXXFLAGS} ${WARNFLAGS} -std=c++17 -I include \
|
|
||||||
-D_POSIX_C_SOURCE=200809L -fno-exceptions -fno-rtti
|
-D_POSIX_C_SOURCE=200809L -fno-exceptions -fno-rtti
|
||||||
# Overridable LDFLAGS
|
# Overridable LDFLAGS
|
||||||
LDFLAGS ?=
|
LDFLAGS ?=
|
||||||
@@ -84,7 +81,7 @@ rgbasm_obj := \
|
|||||||
src/linkdefs.o \
|
src/linkdefs.o \
|
||||||
src/opmath.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 := \
|
rgblink_obj := \
|
||||||
src/link/assign.o \
|
src/link/assign.o \
|
||||||
@@ -121,19 +118,19 @@ rgbgfx_obj := \
|
|||||||
src/error.o
|
src/error.o
|
||||||
|
|
||||||
rgbasm: ${rgbasm_obj}
|
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}
|
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}
|
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}
|
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
|
test/gfx/randtilegen: test/gfx/randtilegen.cpp
|
||||||
$Q${CC} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCFLAGS} ${PNGCFLAGS} ${PNGLDLIBS}
|
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGCFLAGS} ${PNGLDLIBS}
|
||||||
|
|
||||||
test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp
|
test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp
|
||||||
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGLDLIBS}
|
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGLDLIBS}
|
||||||
@@ -144,10 +141,10 @@ test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp
|
|||||||
.y.o:
|
.y.o:
|
||||||
|
|
||||||
# Bison-generated C files have an accompanying header
|
# 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 $@
|
$Qtouch $@
|
||||||
|
|
||||||
src/asm/parser.c: src/asm/parser.y
|
src/asm/parser.cpp: src/asm/parser.y
|
||||||
$QDEFS=; \
|
$QDEFS=; \
|
||||||
add_flag(){ \
|
add_flag(){ \
|
||||||
if src/check_bison_ver.sh $$1 $$2; then \
|
if src/check_bison_ver.sh $$1 $$2; then \
|
||||||
@@ -180,9 +177,6 @@ src/gfx/reverse.o: src/gfx/reverse.cpp
|
|||||||
src/gfx/rgba.o: src/gfx/rgba.cpp
|
src/gfx/rgba.o: src/gfx/rgba.cpp
|
||||||
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
|
||||||
|
|
||||||
.c.o:
|
|
||||||
$Q${CC} ${REALCFLAGS} -c -o $@ $<
|
|
||||||
|
|
||||||
.cpp.o:
|
.cpp.o:
|
||||||
$Q${CXX} ${REALCXXFLAGS} -c -o $@ $<
|
$Q${CXX} ${REALCXXFLAGS} -c -o $@ $<
|
||||||
|
|
||||||
@@ -195,7 +189,7 @@ clean:
|
|||||||
$Q${RM} rgbgfx rgbgfx.exe
|
$Q${RM} rgbgfx rgbgfx.exe
|
||||||
$Qfind src/ -name "*.o" -exec rm {} \;
|
$Qfind src/ -name "*.o" -exec rm {} \;
|
||||||
$Q${RM} rgbshim.sh
|
$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
|
$Q${RM} test/gfx/randtilegen test/gfx/rgbgfx_test
|
||||||
|
|
||||||
# Target used to install the binaries and man pages.
|
# Target used to install the binaries and man pages.
|
||||||
@@ -213,7 +207,7 @@ install: all
|
|||||||
# `.y` files aren't checked, unfortunately...
|
# `.y` files aren't checked, unfortunately...
|
||||||
|
|
||||||
checkcodebase:
|
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"; \
|
${CHECKPATCH} -f "$$file"; \
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -251,21 +245,18 @@ develop:
|
|||||||
-Wno-format-nonliteral -Wno-strict-overflow \
|
-Wno-format-nonliteral -Wno-strict-overflow \
|
||||||
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare \
|
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare \
|
||||||
-Wvla \
|
-Wvla \
|
||||||
-Wno-unknown-warning-option \
|
|
||||||
-D_GLIBCXX_ASSERTIONS \
|
-D_GLIBCXX_ASSERTIONS \
|
||||||
-fsanitize=shift -fsanitize=integer-divide-by-zero \
|
-fsanitize=shift -fsanitize=integer-divide-by-zero \
|
||||||
-fsanitize=unreachable -fsanitize=vla-bound \
|
-fsanitize=unreachable -fsanitize=vla-bound \
|
||||||
-fsanitize=signed-integer-overflow -fsanitize=bounds \
|
-fsanitize=signed-integer-overflow -fsanitize=bounds \
|
||||||
-fsanitize=object-size -fsanitize=bool -fsanitize=enum \
|
-fsanitize=object-size -fsanitize=bool -fsanitize=enum \
|
||||||
-fsanitize=alignment -fsanitize=null -fsanitize=address" \
|
-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"
|
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.
|
# This target is used during development in order to more easily debug with gdb.
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
$Qenv ${MAKE} \
|
$Qenv ${MAKE} \
|
||||||
CFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" \
|
|
||||||
CXXFLAGS="-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.
|
# Targets for the project maintainer to easily create Windows exes.
|
||||||
@@ -275,12 +266,13 @@ debug:
|
|||||||
|
|
||||||
mingw32:
|
mingw32:
|
||||||
$Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \
|
$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++ \
|
||||||
|
CXXFLAGS="-O3 -flto -DNDEBUG -static-libgcc" \
|
||||||
BISON=bison PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/i686-w64-mingw32 pkg-config"
|
BISON=bison PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/i686-w64-mingw32 pkg-config"
|
||||||
|
|
||||||
mingw64:
|
mingw64:
|
||||||
$Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \
|
$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"
|
BISON=bison PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/x86_64-w64-mingw32 pkg-config"
|
||||||
|
|
||||||
wine-shim:
|
wine-shim:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Releasing
|
|||||||
This describes for the maintainers of RGBDS how to publish a new release on
|
This describes for the maintainers of RGBDS how to publish a new release on
|
||||||
GitHub.
|
GitHub.
|
||||||
|
|
||||||
1. Update, commit, and push `include/version.h <include/version.h>`__ with
|
1. Update, commit, and push `include/version.hpp <include/version.hpp>`__ with
|
||||||
values for ``PACKAGE_VERSION_MAJOR``, ``PACKAGE_VERSION_MINOR``,
|
values for ``PACKAGE_VERSION_MAJOR``, ``PACKAGE_VERSION_MINOR``,
|
||||||
``PACKAGE_VERSION_PATCH``, and ``PACKAGE_VERSION_RC``, as well as
|
``PACKAGE_VERSION_PATCH``, and ``PACKAGE_VERSION_RC``, as well as
|
||||||
`Dockerfile <Dockerfile>`__ with a value for ``ARG version``. Only define
|
`Dockerfile <Dockerfile>`__ with a value for ``ARG version``. Only define
|
||||||
@@ -14,7 +14,7 @@ GitHub.
|
|||||||
2. Create a Git tag formatted as ``v<MAJOR>.<MINOR>.<PATCH>``, or
|
2. Create a Git tag formatted as ``v<MAJOR>.<MINOR>.<PATCH>``, or
|
||||||
``v<MAJOR>.<MINOR>.<PATCH>-rc<RC>`` for a release candidate. ``MAJOR``,
|
``v<MAJOR>.<MINOR>.<PATCH>-rc<RC>`` for a release candidate. ``MAJOR``,
|
||||||
``MINOR``, ``PATCH``, and ``RC`` should match their values from
|
``MINOR``, ``PATCH``, and ``RC`` should match their values from
|
||||||
`include/version.h <include/version.h>`__. You can use ``git tag <tag>``.
|
`include/version.hpp <include/version.hpp>`__. You can use ``git tag <tag>``.
|
||||||
|
|
||||||
3. Push the tag to GitHub. You can use ``git push origin <tag>``.
|
3. Push the tag to GitHub. You can use ``git push origin <tag>``.
|
||||||
|
|
||||||
|
|||||||
@@ -40,46 +40,46 @@ dependency () {
|
|||||||
# Pull requests that edit the first file without the second may be correct,
|
# Pull requests that edit the first file without the second may be correct,
|
||||||
# but are suspicious enough to require review.
|
# 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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"Should the object file revision be bumped?"
|
||||||
|
|
||||||
dependency Makefile CMakeLists.txt \
|
dependency Makefile CMakeLists.txt \
|
||||||
"Did the build process change?"
|
"Did the build process change?"
|
||||||
dependency Makefile src/CMakeLists.txt \
|
dependency Makefile src/CMakeLists.txt \
|
||||||
"Did the build process change?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"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?"
|
"Did the rgbgfx CLI change?"
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "asm/lexer.h"
|
#include "asm/lexer.hpp"
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
struct FileStackNode {
|
struct FileStackNode {
|
||||||
struct FileStackNode *parent; // Pointer to parent node, for error reporting
|
struct FileStackNode *parent; // Pointer to parent node, for error reporting
|
||||||
@@ -7,9 +7,9 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
struct MacroArgs;
|
struct MacroArgs;
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
extern bool haltNop;
|
extern bool haltNop;
|
||||||
extern bool warnOnHaltNop;
|
extern bool warnOnHaltNop;
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
struct Expression;
|
struct Expression;
|
||||||
struct FileStackNode;
|
struct FileStackNode;
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
#define MAXRPNLEN 1048576
|
#define MAXRPNLEN 1048576
|
||||||
|
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "platform.h" // NONNULL
|
#include "platform.hpp" // NONNULL
|
||||||
|
|
||||||
extern uint8_t fillByte;
|
extern uint8_t fillByte;
|
||||||
|
|
||||||
@@ -8,9 +8,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "asm/section.h"
|
#include "asm/section.hpp"
|
||||||
|
|
||||||
#include "platform.h" // MIN_NB_ELMS
|
#include "platform.hpp" // MIN_NB_ELMS
|
||||||
|
|
||||||
#define MAXSYMLEN 255
|
#define MAXSYMLEN 255
|
||||||
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
#ifndef WARNING_H
|
#ifndef WARNING_H
|
||||||
#define WARNING_H
|
#define WARNING_H
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
extern unsigned int nbErrors;
|
extern unsigned int nbErrors;
|
||||||
|
|
||||||
@@ -77,7 +77,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,
|
* It is also used when the assembler goes into an invalid state (for example,
|
||||||
* when it fails to allocate memory).
|
* 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
|
* Used for errors that make it impossible to assemble correctly, but don't
|
||||||
@@ -3,21 +3,17 @@
|
|||||||
#ifndef RGBDS_ERROR_H
|
#ifndef RGBDS_ERROR_H
|
||||||
#define RGBDS_ERROR_H
|
#define RGBDS_ERROR_H
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
|
||||||
|
|
||||||
void warn(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
void warn(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
||||||
void warnx(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 err(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
||||||
_Noreturn void errx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
[[noreturn]] void errx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RGBDS_ERROR_H
|
#endif // RGBDS_ERROR_H
|
||||||
@@ -26,9 +26,7 @@
|
|||||||
#ifndef RGBDS_EXTERN_GETOPT_H
|
#ifndef RGBDS_EXTERN_GETOPT_H
|
||||||
#define RGBDS_EXTERN_GETOPT_H
|
#define RGBDS_EXTERN_GETOPT_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
|
||||||
|
|
||||||
extern char *musl_optarg;
|
extern char *musl_optarg;
|
||||||
extern int musl_optind, musl_opterr, musl_optopt, musl_optreset;
|
extern int musl_optind, musl_opterr, musl_optopt, musl_optreset;
|
||||||
@@ -47,8 +45,6 @@ int musl_getopt_long_only(int argc, char **argv, char const *optstring,
|
|||||||
#define required_argument 1
|
#define required_argument 1
|
||||||
#define optional_argument 2
|
#define optional_argument 2
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
|
|
||||||
#include "gfx/main.hpp"
|
#include "gfx/main.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
#include "gfx/rgba.hpp"
|
#include "gfx/rgba.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,6 @@
|
|||||||
#ifndef HELPERS_H
|
#ifndef HELPERS_H
|
||||||
#define 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
|
// Ideally, we'd use `__has_attribute` and `__has_builtin`, but these were only introduced in GCC 9
|
||||||
#ifdef __GNUC__ // GCC or compatible
|
#ifdef __GNUC__ // GCC or compatible
|
||||||
#define format_(archetype, str_index, first_arg) \
|
#define format_(archetype, str_index, first_arg) \
|
||||||
@@ -24,8 +19,8 @@
|
|||||||
#define format_(archetype, str_index, first_arg)
|
#define format_(archetype, str_index, first_arg)
|
||||||
#define attr_(...)
|
#define attr_(...)
|
||||||
// This seems to generate similar code to __builtin_unreachable, despite different semantics
|
// This seems to generate similar code to __builtin_unreachable, despite different semantics
|
||||||
// Note that executing this is undefined behavior (declared _Noreturn, but does return)
|
// Note that executing this is undefined behavior (declared [[noreturn]], but does return)
|
||||||
static inline _Noreturn void unreachable_(void) {}
|
[[noreturn]] static inline void unreachable_(void) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use builtins whenever possible, and shim them otherwise
|
// Use builtins whenever possible, and shim them otherwise
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "platform.h" // __PRETTY_FUNCTION__
|
#include "platform.hpp" // __PRETTY_FUNCTION__
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
static inline void report() {
|
static inline void report() {
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
// Variables related to CLI options
|
// Variables related to CLI options
|
||||||
extern bool isDmgMode;
|
extern bool isDmgMode;
|
||||||
@@ -61,7 +61,7 @@ void warning(struct FileStackNode const *where, uint32_t lineNo,
|
|||||||
void error(struct FileStackNode const *where, uint32_t lineNo,
|
void error(struct FileStackNode const *where, uint32_t lineNo,
|
||||||
char const *fmt, ...) format_(printf, 3, 4);
|
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);
|
char const *fmt, ...) format_(printf, 3, 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Registers a section for output.
|
* Registers a section for output.
|
||||||
@@ -7,9 +7,9 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
struct Assertion {
|
struct Assertion {
|
||||||
struct Patch patch;
|
struct Patch patch;
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
extern FILE * linkerScript;
|
extern FILE * linkerScript;
|
||||||
|
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "link/main.h"
|
#include "link/main.hpp"
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
struct FileStackNode;
|
struct FileStackNode;
|
||||||
struct Section;
|
struct Section;
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
struct FileStackNode;
|
struct FileStackNode;
|
||||||
|
|
||||||
@@ -49,15 +49,17 @@
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MSVC doesn't support `[static N]` for array arguments from C99 or C11
|
// C++ doesn't support `[static N]` for array arguments from C99 or C11
|
||||||
#ifdef _MSC_VER
|
#define MIN_NB_ELMS(N) // static (N)
|
||||||
# define MIN_NB_ELMS(N)
|
#define ARR_QUALS(...) // __VA_ARGS__
|
||||||
# define ARR_QUALS(...)
|
#define NONNULL(ptr) *ptr // ptr[static 1]
|
||||||
# define NONNULL(ptr) *ptr
|
#define restrict
|
||||||
|
|
||||||
|
// C++ doesn't support designated array initializers, but they're a gcc extension
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define AT(index) [index] =
|
||||||
#else
|
#else
|
||||||
# define MIN_NB_ELMS(N) static (N)
|
# define AT(index)
|
||||||
# define ARR_QUALS(...) __VA_ARGS__
|
|
||||||
# define NONNULL(ptr) ptr[static 1]
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MSVC uses a different name for O_RDWR, and needs an additional _O_BINARY flag
|
// MSVC uses a different name for O_RDWR, and needs an additional _O_BINARY flag
|
||||||
@@ -3,9 +3,7 @@
|
|||||||
#ifndef EXTERN_VERSION_H
|
#ifndef EXTERN_VERSION_H
|
||||||
#define EXTERN_VERSION_H
|
#define EXTERN_VERSION_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PACKAGE_VERSION_MAJOR 0
|
#define PACKAGE_VERSION_MAJOR 0
|
||||||
#define PACKAGE_VERSION_MINOR 6
|
#define PACKAGE_VERSION_MINOR 6
|
||||||
@@ -13,8 +11,6 @@ extern "C" {
|
|||||||
|
|
||||||
char const *get_package_version_string(void);
|
char const *get_package_version_string(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // EXTERN_VERSION_H
|
#endif // EXTERN_VERSION_H
|
||||||
2
src/.gitignore
vendored
2
src/.gitignore
vendored
@@ -1,2 +1,2 @@
|
|||||||
# Generated by CMake
|
# Generated by CMake
|
||||||
/.version.c
|
/.version.cpp
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
configure_file(version.c _version.c ESCAPE_QUOTES)
|
configure_file(version.cpp _version.cpp ESCAPE_QUOTES)
|
||||||
|
|
||||||
set(common_src
|
set(common_src
|
||||||
"error.c"
|
"error.cpp"
|
||||||
"extern/getopt.c"
|
"extern/getopt.cpp"
|
||||||
"_version.c"
|
"_version.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_package(BISON 3.0.0 REQUIRED)
|
find_package(BISON 3.0.0 REQUIRED)
|
||||||
@@ -23,35 +23,35 @@ set(BISON_FLAGS "${BISON_FLAGS} -Dparse.lac=full")
|
|||||||
set(BISON_FLAGS "${BISON_FLAGS} -Dlr.type=ielr")
|
set(BISON_FLAGS "${BISON_FLAGS} -Dlr.type=ielr")
|
||||||
|
|
||||||
BISON_TARGET(PARSER "asm/parser.y"
|
BISON_TARGET(PARSER "asm/parser.y"
|
||||||
"${PROJECT_SOURCE_DIR}/src/asm/parser.c"
|
"${PROJECT_SOURCE_DIR}/src/asm/parser.cpp"
|
||||||
COMPILE_FLAGS "${BISON_FLAGS}"
|
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
|
set(rgbasm_src
|
||||||
"${BISON_PARSER_OUTPUT_SOURCE}"
|
"${BISON_PARSER_OUTPUT_SOURCE}"
|
||||||
"asm/charmap.c"
|
"asm/charmap.cpp"
|
||||||
"asm/fixpoint.c"
|
"asm/fixpoint.cpp"
|
||||||
"asm/format.c"
|
"asm/format.cpp"
|
||||||
"asm/fstack.c"
|
"asm/fstack.cpp"
|
||||||
"asm/lexer.c"
|
"asm/lexer.cpp"
|
||||||
"asm/macro.c"
|
"asm/macro.cpp"
|
||||||
"asm/main.c"
|
"asm/main.cpp"
|
||||||
"asm/opt.c"
|
"asm/opt.cpp"
|
||||||
"asm/output.c"
|
"asm/output.cpp"
|
||||||
"asm/rpn.c"
|
"asm/rpn.cpp"
|
||||||
"asm/section.c"
|
"asm/section.cpp"
|
||||||
"asm/symbol.c"
|
"asm/symbol.cpp"
|
||||||
"asm/util.c"
|
"asm/util.cpp"
|
||||||
"asm/warning.c"
|
"asm/warning.cpp"
|
||||||
"extern/utf8decoder.c"
|
"extern/utf8decoder.cpp"
|
||||||
"hashmap.c"
|
"hashmap.cpp"
|
||||||
"linkdefs.c"
|
"linkdefs.cpp"
|
||||||
"opmath.c"
|
"opmath.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(rgbfix_src
|
set(rgbfix_src
|
||||||
"fix/main.c"
|
"fix/main.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(rgbgfx_src
|
set(rgbgfx_src
|
||||||
@@ -63,24 +63,24 @@ set(rgbgfx_src
|
|||||||
"gfx/proto_palette.cpp"
|
"gfx/proto_palette.cpp"
|
||||||
"gfx/reverse.cpp"
|
"gfx/reverse.cpp"
|
||||||
"gfx/rgba.cpp"
|
"gfx/rgba.cpp"
|
||||||
"extern/getopt.c"
|
"extern/getopt.cpp"
|
||||||
"error.c"
|
"error.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(rgblink_src
|
set(rgblink_src
|
||||||
"link/assign.c"
|
"link/assign.cpp"
|
||||||
"link/main.c"
|
"link/main.cpp"
|
||||||
"link/object.c"
|
"link/object.cpp"
|
||||||
"link/output.c"
|
"link/output.cpp"
|
||||||
"link/patch.c"
|
"link/patch.cpp"
|
||||||
"link/script.c"
|
"link/script.cpp"
|
||||||
"link/sdas_obj.c"
|
"link/sdas_obj.cpp"
|
||||||
"link/section.c"
|
"link/section.cpp"
|
||||||
"link/symbol.c"
|
"link/symbol.cpp"
|
||||||
"extern/utf8decoder.c"
|
"extern/utf8decoder.cpp"
|
||||||
"hashmap.c"
|
"hashmap.cpp"
|
||||||
"linkdefs.c"
|
"linkdefs.cpp"
|
||||||
"opmath.c"
|
"opmath.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(PROG "asm" "fix" "gfx" "link")
|
foreach(PROG "asm" "fix" "gfx" "link")
|
||||||
|
|||||||
4
src/asm/.gitignore
vendored
4
src/asm/.gitignore
vendored
@@ -1,2 +1,2 @@
|
|||||||
/parser.c
|
/parser.cpp
|
||||||
/parser.h
|
/parser.hpp
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/charmap.h"
|
#include "asm/charmap.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/output.h"
|
#include "asm/output.hpp"
|
||||||
#include "asm/util.h"
|
#include "asm/util.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "hashmap.h"
|
#include "hashmap.hpp"
|
||||||
|
|
||||||
// Charmaps are stored using a structure known as "trie".
|
// Charmaps are stored using a structure known as "trie".
|
||||||
// Essentially a tree, where each nodes stores a single character's worth of info:
|
// Essentially a tree, where each nodes stores a single character's worth of info:
|
||||||
@@ -49,12 +49,12 @@ struct CharmapStackEntry *charmapStack;
|
|||||||
|
|
||||||
static struct Charmap *charmap_Get(char const *name)
|
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)
|
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)
|
if (!*map)
|
||||||
fatalerror("Failed to %s charmap: %s\n",
|
fatalerror("Failed to %s charmap: %s\n",
|
||||||
@@ -122,7 +122,7 @@ void charmap_Set(char const *name)
|
|||||||
|
|
||||||
void charmap_Push(void)
|
void charmap_Push(void)
|
||||||
{
|
{
|
||||||
struct CharmapStackEntry *stackEntry = malloc(sizeof(*stackEntry));
|
struct CharmapStackEntry *stackEntry = (struct CharmapStackEntry *)malloc(sizeof(*stackEntry));
|
||||||
|
|
||||||
if (stackEntry == NULL)
|
if (stackEntry == NULL)
|
||||||
fatalerror("Failed to alloc charmap stack entry: %s\n", strerror(errno));
|
fatalerror("Failed to alloc charmap stack entry: %s\n", strerror(errno));
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "asm/fixpoint.h"
|
#include "asm/fixpoint.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
#define M_PI 3.14159265358979323846
|
#define M_PI 3.14159265358979323846
|
||||||
@@ -9,13 +9,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/fixpoint.h"
|
#include "asm/fixpoint.hpp"
|
||||||
#include "asm/format.h"
|
#include "asm/format.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
struct FormatSpec fmt_NewSpec(void)
|
struct FormatSpec fmt_NewSpec(void)
|
||||||
{
|
{
|
||||||
struct FormatSpec fmt = {0};
|
struct FormatSpec fmt = {};
|
||||||
|
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
@@ -8,13 +8,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/macro.h"
|
#include "asm/macro.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "platform.h" // S_ISDIR (stat macro)
|
#include "platform.hpp" // S_ISDIR (stat macro)
|
||||||
|
|
||||||
#define MAXINCPATHS 128
|
#define MAXINCPATHS 128
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ void fstk_AddIncludePath(char const *path)
|
|||||||
}
|
}
|
||||||
size_t len = strlen(path);
|
size_t len = strlen(path);
|
||||||
size_t allocSize = len + (path[len - 1] != '/') + 1;
|
size_t allocSize = len + (path[len - 1] != '/') + 1;
|
||||||
char *str = malloc(allocSize);
|
char *str = (char *)malloc(allocSize);
|
||||||
|
|
||||||
if (!str) {
|
if (!str) {
|
||||||
// Attempt to continue without that path
|
// Attempt to continue without that path
|
||||||
@@ -163,7 +163,7 @@ bool fstk_FindFile(char const *path, char **fullPath, size_t *size)
|
|||||||
{
|
{
|
||||||
if (!*size) {
|
if (!*size) {
|
||||||
*size = 64; // This is arbitrary, really
|
*size = 64; // This is arbitrary, really
|
||||||
*fullPath = realloc(*fullPath, *size);
|
*fullPath = (char *)realloc(*fullPath, *size);
|
||||||
if (!*fullPath)
|
if (!*fullPath)
|
||||||
error("realloc error during include path search: %s\n",
|
error("realloc error during include path search: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -183,7 +183,7 @@ bool fstk_FindFile(char const *path, char **fullPath, size_t *size)
|
|||||||
// Oh how I wish `asnprintf` was standard...
|
// Oh how I wish `asnprintf` was standard...
|
||||||
if ((size_t)len >= *size) { // `size` includes the terminator, `len` doesn't
|
if ((size_t)len >= *size) { // `size` includes the terminator, `len` doesn't
|
||||||
*size = len + 1;
|
*size = len + 1;
|
||||||
*fullPath = realloc(*fullPath, *size);
|
*fullPath = (char *)realloc(*fullPath, *size);
|
||||||
if (!*fullPath) {
|
if (!*fullPath) {
|
||||||
error("realloc error during include path search: %s\n",
|
error("realloc error during include path search: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -225,7 +225,7 @@ bool yywrap(void)
|
|||||||
// If the node is referenced, we can't edit it; duplicate it
|
// If the node is referenced, we can't edit it; duplicate it
|
||||||
if (contextStack->fileInfo->referenced) {
|
if (contextStack->fileInfo->referenced) {
|
||||||
size_t size = sizeof(*fileInfo) + sizeof(fileInfo->iters[0]) * fileInfo->reptDepth;
|
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)
|
if (!copy)
|
||||||
fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno));
|
fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno));
|
||||||
@@ -295,7 +295,7 @@ static void newContext(struct FileStackNode *fileInfo)
|
|||||||
// Save the current `\@` value, to be restored when this context ends
|
// Save the current `\@` value, to be restored when this context ends
|
||||||
contextStack->uniqueID = macro_GetUniqueID();
|
contextStack->uniqueID = macro_GetUniqueID();
|
||||||
|
|
||||||
struct Context *context = malloc(sizeof(*context));
|
struct Context *context = (struct Context *)malloc(sizeof(*context));
|
||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
fatalerror("Failed to allocate memory for new context: %s\n", strerror(errno));
|
fatalerror("Failed to allocate memory for new context: %s\n", strerror(errno));
|
||||||
@@ -330,7 +330,8 @@ void fstk_RunInclude(char const *path)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + size);
|
struct FileStackNamedNode *fileInfo =
|
||||||
|
(struct FileStackNamedNode *)malloc(sizeof(*fileInfo) + size);
|
||||||
|
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
error("Failed to alloc file info for INCLUDE: %s\n", strerror(errno));
|
error("Failed to alloc file info for INCLUDE: %s\n", strerror(errno));
|
||||||
@@ -367,7 +368,8 @@ static void runPreIncludeFile(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + size);
|
struct FileStackNamedNode *fileInfo =
|
||||||
|
(struct FileStackNamedNode *)malloc(sizeof(*fileInfo) + size);
|
||||||
|
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
error("Failed to alloc file info for pre-include: %s\n", strerror(errno));
|
error("Failed to alloc file info for pre-include: %s\n", strerror(errno));
|
||||||
@@ -417,8 +419,8 @@ void fstk_RunMacro(char const *macroName, struct MacroArgs *args)
|
|||||||
struct FileStackNamedNode const *baseNode = (struct FileStackNamedNode const *)node;
|
struct FileStackNamedNode const *baseNode = (struct FileStackNamedNode const *)node;
|
||||||
size_t baseLen = strlen(baseNode->name);
|
size_t baseLen = strlen(baseNode->name);
|
||||||
size_t macroNameLen = strlen(macro->name);
|
size_t macroNameLen = strlen(macro->name);
|
||||||
struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + baseLen
|
struct FileStackNamedNode *fileInfo = (struct FileStackNamedNode *)malloc(sizeof(*fileInfo) +
|
||||||
+ reptNameLen + 2 + macroNameLen + 1);
|
baseLen + reptNameLen + 2 + macroNameLen + 1);
|
||||||
|
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
error("Failed to alloc file info for \"%s\": %s\n", macro->name, strerror(errno));
|
error("Failed to alloc file info for \"%s\": %s\n", macro->name, strerror(errno));
|
||||||
@@ -461,8 +463,8 @@ static bool newReptContext(int32_t reptLineNo, char *body, size_t size)
|
|||||||
uint32_t reptDepth = contextStack->fileInfo->type == NODE_REPT
|
uint32_t reptDepth = contextStack->fileInfo->type == NODE_REPT
|
||||||
? ((struct FileStackReptNode *)contextStack->fileInfo)->reptDepth
|
? ((struct FileStackReptNode *)contextStack->fileInfo)->reptDepth
|
||||||
: 0;
|
: 0;
|
||||||
struct FileStackReptNode *fileInfo = malloc(sizeof(*fileInfo)
|
struct FileStackReptNode *fileInfo = (struct FileStackReptNode *)malloc(sizeof(*fileInfo)
|
||||||
+ (reptDepth + 1) * sizeof(fileInfo->iters[0]));
|
+ (reptDepth + 1) * sizeof(fileInfo->iters[0]));
|
||||||
|
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
error("Failed to alloc file info for REPT: %s\n", strerror(errno));
|
error("Failed to alloc file info for REPT: %s\n", strerror(errno));
|
||||||
@@ -567,8 +569,9 @@ void fstk_Init(char const *mainPath, size_t maxDepth)
|
|||||||
lexer_SetState(state);
|
lexer_SetState(state);
|
||||||
char const *fileName = lexer_GetFileName();
|
char const *fileName = lexer_GetFileName();
|
||||||
size_t len = strlen(fileName);
|
size_t len = strlen(fileName);
|
||||||
struct Context *context = malloc(sizeof(*contextStack));
|
struct Context *context = (struct Context *)malloc(sizeof(*contextStack));
|
||||||
struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + len + 1);
|
struct FileStackNamedNode *fileInfo =
|
||||||
|
(struct FileStackNamedNode *)malloc(sizeof(*fileInfo) + len + 1);
|
||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
fatalerror("Failed to allocate memory for main context: %s\n", strerror(errno));
|
fatalerror("Failed to allocate memory for main context: %s\n", strerror(errno));
|
||||||
@@ -18,20 +18,20 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "platform.h" // For `ssize_t`
|
#include "platform.hpp" // For `ssize_t` and `AT`
|
||||||
|
|
||||||
#include "asm/lexer.h"
|
#include "asm/lexer.hpp"
|
||||||
#include "asm/fixpoint.h"
|
#include "asm/fixpoint.hpp"
|
||||||
#include "asm/format.h"
|
#include "asm/format.hpp"
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/macro.h"
|
#include "asm/macro.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/rpn.h"
|
#include "asm/rpn.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/util.h"
|
#include "asm/util.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
// Include this last so it gets all type & constant definitions
|
// 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`
|
// Neither MSVC nor MinGW provide `mmap`
|
||||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
@@ -390,7 +390,7 @@ uint32_t lexer_GetIFDepth(void)
|
|||||||
|
|
||||||
void lexer_IncIFDepth(void)
|
void lexer_IncIFDepth(void)
|
||||||
{
|
{
|
||||||
struct IfStack *ifStack = malloc(sizeof(*ifStack));
|
struct IfStack *ifStack = (struct IfStack *)malloc(sizeof(*ifStack));
|
||||||
|
|
||||||
if (!ifStack)
|
if (!ifStack)
|
||||||
fatalerror("Unable to allocate new IF depth: %s\n", strerror(errno));
|
fatalerror("Unable to allocate new IF depth: %s\n", strerror(errno));
|
||||||
@@ -437,7 +437,7 @@ void lexer_ReachELSEBlock(void)
|
|||||||
struct LexerState *lexer_OpenFile(char const *path)
|
struct LexerState *lexer_OpenFile(char const *path)
|
||||||
{
|
{
|
||||||
bool isStdin = !strcmp(path, "-");
|
bool isStdin = !strcmp(path, "-");
|
||||||
struct LexerState *state = malloc(sizeof(*state));
|
struct LexerState *state = (struct LexerState *)malloc(sizeof(*state));
|
||||||
struct stat fileInfo;
|
struct stat fileInfo;
|
||||||
|
|
||||||
// Give stdin a nicer file name
|
// Give stdin a nicer file name
|
||||||
@@ -479,7 +479,7 @@ struct LexerState *lexer_OpenFile(char const *path)
|
|||||||
|
|
||||||
state->isMmapped = true;
|
state->isMmapped = true;
|
||||||
state->isReferenced = false; // By default, a state isn't referenced
|
state->isReferenced = false; // By default, a state isn't referenced
|
||||||
state->ptr = mappingAddr;
|
state->ptr = (char *)mappingAddr;
|
||||||
assert(fileInfo.st_size >= 0);
|
assert(fileInfo.st_size >= 0);
|
||||||
state->size = (size_t)fileInfo.st_size;
|
state->size = (size_t)fileInfo.st_size;
|
||||||
state->offset = 0;
|
state->offset = 0;
|
||||||
@@ -510,7 +510,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 *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) {
|
if (!state) {
|
||||||
error("Failed to allocate memory for lexer state: %s\n", strerror(errno));
|
error("Failed to allocate memory for lexer state: %s\n", strerror(errno));
|
||||||
@@ -567,7 +567,7 @@ struct KeywordDictNode {
|
|||||||
uint16_t children[0x60 - ' '];
|
uint16_t children[0x60 - ' '];
|
||||||
struct KeywordMapping const *keyword;
|
struct KeywordMapping const *keyword;
|
||||||
// Since the keyword structure is invariant, the min number of nodes is known at compile time
|
// Since the keyword structure is invariant, the min number of nodes is known at compile time
|
||||||
} keywordDict[377] = {0}; // Make sure to keep this correct when adding keywords!
|
} keywordDict[377] = {}; // Make sure to keep this correct when adding keywords!
|
||||||
|
|
||||||
// Convert a char into its index into the dict
|
// Convert a char into its index into the dict
|
||||||
static uint8_t dictIndex(char c)
|
static uint8_t dictIndex(char c)
|
||||||
@@ -637,7 +637,7 @@ static void reallocCaptureBuf(void)
|
|||||||
lexerState->captureCapacity = SIZE_MAX;
|
lexerState->captureCapacity = SIZE_MAX;
|
||||||
else
|
else
|
||||||
lexerState->captureCapacity *= 2;
|
lexerState->captureCapacity *= 2;
|
||||||
lexerState->captureBuf = realloc(lexerState->captureBuf, lexerState->captureCapacity);
|
lexerState->captureBuf = (char *)realloc(lexerState->captureBuf, lexerState->captureCapacity);
|
||||||
if (!lexerState->captureBuf)
|
if (!lexerState->captureBuf)
|
||||||
fatalerror("realloc error while resizing capture buffer: %s\n", strerror(errno));
|
fatalerror("realloc error while resizing capture buffer: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
@@ -653,7 +653,7 @@ static void beginExpansion(char const *str, bool owned, char const *name)
|
|||||||
if (name)
|
if (name)
|
||||||
lexer_CheckRecursionDepth();
|
lexer_CheckRecursionDepth();
|
||||||
|
|
||||||
struct Expansion *exp = malloc(sizeof(*exp));
|
struct Expansion *exp = (struct Expansion *)malloc(sizeof(*exp));
|
||||||
|
|
||||||
if (!exp)
|
if (!exp)
|
||||||
fatalerror("Unable to allocate new expansion: %s\n", strerror(errno));
|
fatalerror("Unable to allocate new expansion: %s\n", strerror(errno));
|
||||||
@@ -2399,11 +2399,11 @@ int yylex(void)
|
|||||||
nextLine();
|
nextLine();
|
||||||
|
|
||||||
static int (* const lexerModeFuncs[])(void) = {
|
static int (* const lexerModeFuncs[])(void) = {
|
||||||
[LEXER_NORMAL] = yylex_NORMAL,
|
AT(LEXER_NORMAL) yylex_NORMAL,
|
||||||
[LEXER_RAW] = yylex_RAW,
|
AT(LEXER_RAW) yylex_RAW,
|
||||||
[LEXER_SKIP_TO_ELIF] = yylex_SKIP_TO_ELIF,
|
AT(LEXER_SKIP_TO_ELIF) yylex_SKIP_TO_ELIF,
|
||||||
[LEXER_SKIP_TO_ENDC] = yylex_SKIP_TO_ENDC,
|
AT(LEXER_SKIP_TO_ENDC) yylex_SKIP_TO_ENDC,
|
||||||
[LEXER_SKIP_TO_ENDR] = yylex_SKIP_TO_ENDR,
|
AT(LEXER_SKIP_TO_ENDR) yylex_SKIP_TO_ENDR,
|
||||||
};
|
};
|
||||||
int token = lexerModeFuncs[lexerState->mode]();
|
int token = lexerModeFuncs[lexerState->mode]();
|
||||||
|
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/macro.h"
|
#include "asm/macro.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#define MAXMACROARGS 99999
|
#define MAXMACROARGS 99999
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ struct MacroArgs {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define SIZEOF_ARGS(nbArgs) (sizeof(struct MacroArgs) + \
|
#define SIZEOF_ARGS(nbArgs) (sizeof(struct MacroArgs) + \
|
||||||
sizeof(((struct MacroArgs){0}).args[0]) * (nbArgs))
|
sizeof(((struct MacroArgs *)0)->args[0]) * (nbArgs))
|
||||||
|
|
||||||
static struct MacroArgs *macroArgs = NULL;
|
static struct MacroArgs *macroArgs = NULL;
|
||||||
static uint32_t uniqueID = 0;
|
static uint32_t uniqueID = 0;
|
||||||
@@ -44,7 +44,7 @@ struct MacroArgs *macro_GetCurrentArgs(void)
|
|||||||
|
|
||||||
struct MacroArgs *macro_NewArgs(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)
|
if (!args)
|
||||||
fatalerror("Unable to register macro arguments: %s\n", strerror(errno));
|
fatalerror("Unable to register macro arguments: %s\n", strerror(errno));
|
||||||
@@ -67,7 +67,7 @@ void macro_AppendArg(struct MacroArgs **argPtr, char *s)
|
|||||||
// Check that overflow didn't roll us back
|
// Check that overflow didn't roll us back
|
||||||
if (macArgs->capacity <= macArgs->nbArgs)
|
if (macArgs->capacity <= macArgs->nbArgs)
|
||||||
fatalerror("Failed to add new macro argument: capacity overflow\n");
|
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)
|
if (!macArgs)
|
||||||
fatalerror("Error adding new macro argument: %s\n", strerror(errno));
|
fatalerror("Error adding new macro argument: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ char const *macro_GetAllArgs(void)
|
|||||||
for (uint32_t i = macroArgs->shift; i < macroArgs->nbArgs; i++)
|
for (uint32_t i = macroArgs->shift; i < macroArgs->nbArgs; i++)
|
||||||
len += strlen(macroArgs->args[i]) + 1; // 1 for comma
|
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;
|
char *ptr = str;
|
||||||
|
|
||||||
if (!str)
|
if (!str)
|
||||||
@@ -12,24 +12,24 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "asm/charmap.h"
|
#include "asm/charmap.hpp"
|
||||||
#include "asm/fixpoint.h"
|
#include "asm/fixpoint.hpp"
|
||||||
#include "asm/format.h"
|
#include "asm/format.hpp"
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/lexer.h"
|
#include "asm/lexer.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/opt.h"
|
#include "asm/opt.hpp"
|
||||||
#include "asm/output.h"
|
#include "asm/output.hpp"
|
||||||
#include "asm/rpn.h"
|
#include "asm/rpn.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
#include "parser.h"
|
#include "parser.hpp"
|
||||||
|
|
||||||
#include "extern/getopt.h"
|
#include "extern/getopt.hpp"
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "version.h"
|
#include "version.hpp"
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#if __has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__)
|
#if __has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__)
|
||||||
@@ -40,7 +40,9 @@
|
|||||||
#ifdef __SANITIZE_ADDRESS__
|
#ifdef __SANITIZE_ADDRESS__
|
||||||
// There are known, non-trivial to fix leaks. We would still like to have `make develop'
|
// There are known, non-trivial to fix leaks. We would still like to have `make develop'
|
||||||
// detect memory corruption, though.
|
// detect memory corruption, though.
|
||||||
|
extern "C" {
|
||||||
char const *__asan_default_options(void) { return "detect_leaks=0"; }
|
char const *__asan_default_options(void) { return "detect_leaks=0"; }
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Old Bison versions (confirmed for 2.3) do not forward-declare `yyparse` in the generated header
|
// Old Bison versions (confirmed for 2.3) do not forward-declare `yyparse` in the generated header
|
||||||
@@ -63,7 +65,7 @@ bool warnings; // True to enable warnings, false to disable them.
|
|||||||
// Escapes Make-special chars from a string
|
// Escapes Make-special chars from a string
|
||||||
static char *make_escape(char const *str)
|
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;
|
char *dest = escaped_str;
|
||||||
|
|
||||||
if (escaped_str == NULL)
|
if (escaped_str == NULL)
|
||||||
@@ -166,7 +168,7 @@ int main(int argc, char *argv[])
|
|||||||
warnings = true;
|
warnings = true;
|
||||||
sym_SetExportAll(false);
|
sym_SetExportAll(false);
|
||||||
uint32_t maxDepth = DEFAULT_MAX_DEPTH;
|
uint32_t maxDepth = DEFAULT_MAX_DEPTH;
|
||||||
char *dependFileName = NULL;
|
char const *dependFileName = NULL;
|
||||||
size_t targetFileNameLen = 0;
|
size_t targetFileNameLen = 0;
|
||||||
|
|
||||||
for (int ch; (ch = musl_getopt_long_only(argc, argv, optstring, longopts, NULL)) != -1;) {
|
for (int ch; (ch = musl_getopt_long_only(argc, argv, optstring, longopts, NULL)) != -1;) {
|
||||||
@@ -333,7 +335,7 @@ int main(int argc, char *argv[])
|
|||||||
newTarget = make_escape(newTarget);
|
newTarget = make_escape(newTarget);
|
||||||
size_t newTargetLen = strlen(newTarget) + 1; // Plus the space
|
size_t newTargetLen = strlen(newTarget) + 1; // Plus the space
|
||||||
|
|
||||||
targetFileName = realloc(targetFileName,
|
targetFileName = (char *)realloc(targetFileName,
|
||||||
targetFileNameLen + newTargetLen + 1);
|
targetFileNameLen + newTargetLen + 1);
|
||||||
if (targetFileName == NULL)
|
if (targetFileName == NULL)
|
||||||
err("Cannot append new file to target file list");
|
err("Cannot append new file to target file list");
|
||||||
@@ -8,12 +8,14 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/fixpoint.h"
|
#include "asm/fixpoint.hpp"
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/lexer.h"
|
#include "asm/lexer.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/section.h"
|
#include "asm/section.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
|
static constexpr size_t numWarningStates = sizeof(warningStates);
|
||||||
|
|
||||||
struct OptStackEntry {
|
struct OptStackEntry {
|
||||||
char binary[2];
|
char binary[2];
|
||||||
@@ -26,8 +28,7 @@ struct OptStackEntry {
|
|||||||
bool warnOnLdOpt;
|
bool warnOnLdOpt;
|
||||||
bool warningsAreErrors;
|
bool warningsAreErrors;
|
||||||
size_t maxRecursionDepth;
|
size_t maxRecursionDepth;
|
||||||
// Don't be confused: we use the size of the **global variable** `warningStates`!
|
enum WarningState warningStates[numWarningStates];
|
||||||
enum WarningState warningStates[sizeof(warningStates)];
|
|
||||||
struct OptStackEntry *next;
|
struct OptStackEntry *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -241,12 +242,12 @@ void opt_Parse(char *s)
|
|||||||
|
|
||||||
void opt_Push(void)
|
void opt_Push(void)
|
||||||
{
|
{
|
||||||
struct OptStackEntry *entry = malloc(sizeof(*entry));
|
struct OptStackEntry *entry = (struct OptStackEntry *)malloc(sizeof(*entry));
|
||||||
|
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
fatalerror("Failed to alloc option stack entry: %s\n", strerror(errno));
|
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[0] = binDigits[0];
|
||||||
entry->binary[1] = binDigits[1];
|
entry->binary[1] = binDigits[1];
|
||||||
|
|
||||||
@@ -255,19 +256,19 @@ void opt_Push(void)
|
|||||||
entry->gbgfx[2] = gfxDigits[2];
|
entry->gbgfx[2] = gfxDigits[2];
|
||||||
entry->gbgfx[3] = gfxDigits[3];
|
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->warnOnHaltNop = warnOnHaltNop;
|
||||||
|
|
||||||
entry->optimizeLoads = optimizeLoads; // Pulled from main.h
|
entry->optimizeLoads = optimizeLoads; // Pulled from main.hpp
|
||||||
entry->warnOnLdOpt = warnOnLdOpt;
|
entry->warnOnLdOpt = warnOnLdOpt;
|
||||||
|
|
||||||
// Both of these pulled from warning.h
|
// Both of these pulled from warning.hpp
|
||||||
entry->warningsAreErrors = warningsAreErrors;
|
entry->warningsAreErrors = warningsAreErrors;
|
||||||
memcpy(entry->warningStates, warningStates, sizeof(warningStates));
|
memcpy(entry->warningStates, warningStates, numWarningStates);
|
||||||
|
|
||||||
entry->maxRecursionDepth = maxRecursionDepth; // Pulled from fstack.h
|
entry->maxRecursionDepth = maxRecursionDepth; // Pulled from fstack.h
|
||||||
|
|
||||||
@@ -296,7 +297,7 @@ void opt_Pop(void)
|
|||||||
|
|
||||||
// opt_W does not apply a whole warning state; it processes one flag string
|
// opt_W does not apply a whole warning state; it processes one flag string
|
||||||
warningsAreErrors = entry->warningsAreErrors;
|
warningsAreErrors = entry->warningsAreErrors;
|
||||||
memcpy(warningStates, entry->warningStates, sizeof(warningStates));
|
memcpy(warningStates, entry->warningStates, numWarningStates);
|
||||||
|
|
||||||
stack = entry->next;
|
stack = entry->next;
|
||||||
free(entry);
|
free(entry);
|
||||||
@@ -10,18 +10,18 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/charmap.h"
|
#include "asm/charmap.hpp"
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/output.h"
|
#include "asm/output.hpp"
|
||||||
#include "asm/rpn.h"
|
#include "asm/rpn.hpp"
|
||||||
#include "asm/section.h"
|
#include "asm/section.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "platform.h" // strdup
|
#include "platform.hpp" // strdup
|
||||||
|
|
||||||
struct Patch {
|
struct Patch {
|
||||||
struct FileStackNode const *src;
|
struct FileStackNode const *src;
|
||||||
@@ -366,14 +366,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
|
// 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)
|
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;
|
uint32_t rpnSize = expr->isKnown ? 5 : expr->rpnPatchSize;
|
||||||
struct FileStackNode *node = fstk_GetFileStack();
|
struct FileStackNode *node = fstk_GetFileStack();
|
||||||
|
|
||||||
if (!patch)
|
if (!patch)
|
||||||
fatalerror("No memory for patch: %s\n", strerror(errno));
|
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)
|
if (!patch->rpn)
|
||||||
fatalerror("No memory for patch's RPN rpnSize: %s\n", strerror(errno));
|
fatalerror("No memory for patch's RPN rpnSize: %s\n", strerror(errno));
|
||||||
|
|
||||||
@@ -421,7 +421,7 @@ void out_CreatePatch(uint32_t type, struct Expression const *expr, uint32_t ofs,
|
|||||||
bool out_CreateAssert(enum AssertionType type, struct Expression const *expr,
|
bool out_CreateAssert(enum AssertionType type, struct Expression const *expr,
|
||||||
char const *message, uint32_t ofs)
|
char const *message, uint32_t ofs)
|
||||||
{
|
{
|
||||||
struct Assertion *assertion = malloc(sizeof(*assertion));
|
struct Assertion *assertion = (struct Assertion *)malloc(sizeof(*assertion));
|
||||||
|
|
||||||
if (!assertion)
|
if (!assertion)
|
||||||
return false;
|
return false;
|
||||||
@@ -10,25 +10,25 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/charmap.h"
|
#include "asm/charmap.hpp"
|
||||||
#include "asm/fixpoint.h"
|
#include "asm/fixpoint.hpp"
|
||||||
#include "asm/format.h"
|
#include "asm/format.hpp"
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/lexer.h"
|
#include "asm/lexer.hpp"
|
||||||
#include "asm/macro.h"
|
#include "asm/macro.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/opt.h"
|
#include "asm/opt.hpp"
|
||||||
#include "asm/output.h"
|
#include "asm/output.hpp"
|
||||||
#include "asm/rpn.h"
|
#include "asm/rpn.hpp"
|
||||||
#include "asm/section.h"
|
#include "asm/section.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/util.h"
|
#include "asm/util.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "extern/utf8decoder.h"
|
#include "extern/utf8decoder.hpp"
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "platform.h" // strncasecmp, strdup
|
#include "platform.hpp" // strncasecmp, strdup
|
||||||
|
|
||||||
static struct CaptureBody captureBody; // Captures a REPT/FOR or MACRO
|
static struct CaptureBody captureBody; // Captures a REPT/FOR or MACRO
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ static void initStrFmtArgList(struct StrFmtArgList *args)
|
|||||||
{
|
{
|
||||||
args->nbArgs = 0;
|
args->nbArgs = 0;
|
||||||
args->capacity = INITIAL_STRFMT_ARG_SIZE;
|
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)
|
if (!args->args)
|
||||||
fatalerror("Failed to allocate memory for STRFMT arg list: %s\n",
|
fatalerror("Failed to allocate memory for STRFMT arg list: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -267,7 +267,7 @@ static size_t nextStrFmtArgListIndex(struct StrFmtArgList *args)
|
|||||||
{
|
{
|
||||||
if (args->nbArgs == args->capacity) {
|
if (args->nbArgs == args->capacity) {
|
||||||
args->capacity = (args->capacity + 1) * 2;
|
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)
|
if (!args->args)
|
||||||
fatalerror("realloc error while resizing STRFMT arg list: %s\n",
|
fatalerror("realloc error while resizing STRFMT arg list: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -369,7 +369,7 @@ static void initDsArgList(struct DsArgList *args)
|
|||||||
{
|
{
|
||||||
args->nbArgs = 0;
|
args->nbArgs = 0;
|
||||||
args->capacity = INITIAL_DS_ARG_SIZE;
|
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)
|
if (!args->args)
|
||||||
fatalerror("Failed to allocate memory for ds arg list: %s\n",
|
fatalerror("Failed to allocate memory for ds arg list: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -379,7 +379,7 @@ static void appendDsArgList(struct DsArgList *args, const struct Expression *exp
|
|||||||
{
|
{
|
||||||
if (args->nbArgs == args->capacity) {
|
if (args->nbArgs == args->capacity) {
|
||||||
args->capacity = (args->capacity + 1) * 2;
|
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)
|
if (!args->args)
|
||||||
fatalerror("realloc error while resizing ds arg list: %s\n",
|
fatalerror("realloc error while resizing ds arg list: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -396,7 +396,7 @@ static void initPurgeArgList(struct PurgeArgList *args)
|
|||||||
{
|
{
|
||||||
args->nbArgs = 0;
|
args->nbArgs = 0;
|
||||||
args->capacity = INITIAL_PURGE_ARG_SIZE;
|
args->capacity = INITIAL_PURGE_ARG_SIZE;
|
||||||
args->args = malloc(args->capacity * sizeof(*args->args));
|
args->args = (char **)malloc(args->capacity * sizeof(*args->args));
|
||||||
if (!args->args)
|
if (!args->args)
|
||||||
fatalerror("Failed to allocate memory for purge arg list: %s\n",
|
fatalerror("Failed to allocate memory for purge arg list: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -406,7 +406,7 @@ static void appendPurgeArgList(struct PurgeArgList *args, char *arg)
|
|||||||
{
|
{
|
||||||
if (args->nbArgs == args->capacity) {
|
if (args->nbArgs == args->capacity) {
|
||||||
args->capacity = (args->capacity + 1) * 2;
|
args->capacity = (args->capacity + 1) * 2;
|
||||||
args->args = realloc(args->args, args->capacity * sizeof(*args->args));
|
args->args = (char **)realloc(args->args, args->capacity * sizeof(*args->args));
|
||||||
if (!args->args)
|
if (!args->args)
|
||||||
fatalerror("realloc error while resizing purge arg list: %s\n",
|
fatalerror("realloc error while resizing purge arg list: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -966,21 +966,23 @@ assignment : T_LABEL T_POP_EQUAL const {
|
|||||||
sym_AddVar($1, $3);
|
sym_AddVar($1, $3);
|
||||||
}
|
}
|
||||||
| T_LABEL compoundeq const {
|
| T_LABEL compoundeq const {
|
||||||
static const char *compoundEqOperators[] = {
|
const char *compoundEqOperator = NULL;
|
||||||
[RPN_ADD] = "+=",
|
switch ($2) {
|
||||||
[RPN_SUB] = "-=",
|
case RPN_ADD: compoundEqOperator = "+="; break;
|
||||||
[RPN_MUL] = "*=",
|
case RPN_SUB: compoundEqOperator = "-="; break;
|
||||||
[RPN_DIV] = "/=",
|
case RPN_MUL: compoundEqOperator = "*="; break;
|
||||||
[RPN_MOD] = "%=",
|
case RPN_DIV: compoundEqOperator = "/="; break;
|
||||||
[RPN_XOR] = "^=",
|
case RPN_MOD: compoundEqOperator = "%="; break;
|
||||||
[RPN_OR] = "|=",
|
case RPN_XOR: compoundEqOperator = "^="; break;
|
||||||
[RPN_AND] = "&=",
|
case RPN_OR: compoundEqOperator = "|="; break;
|
||||||
[RPN_SHL] = "<<=",
|
case RPN_AND: compoundEqOperator = "&="; break;
|
||||||
[RPN_SHR] = ">>=",
|
case RPN_SHL: compoundEqOperator = "<<="; break;
|
||||||
};
|
case RPN_SHR: compoundEqOperator = ">>="; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
warning(WARNING_OBSOLETE, "`%s %s` is deprecated; use `DEF %s %s`\n",
|
warning(WARNING_OBSOLETE, "`%s %s` is deprecated; use `DEF %s %s`\n",
|
||||||
$1, compoundEqOperators[$2], $1, compoundEqOperators[$2]);
|
$1, compoundEqOperator, $1, compoundEqOperator);
|
||||||
compoundAssignment($1, $2, $3);
|
compoundAssignment($1, $2, $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -1106,7 +1108,7 @@ shift : T_POP_SHIFT { macro_ShiftCurrentArgs(1); }
|
|||||||
;
|
;
|
||||||
|
|
||||||
load : T_POP_LOAD sectmod string T_COMMA sectiontype sectorg sectattrs {
|
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(); }
|
| T_POP_ENDL { sect_EndLoadSection(); }
|
||||||
;
|
;
|
||||||
@@ -1365,7 +1367,7 @@ constlist_8bit_entry : reloc_8bit_no_str {
|
|||||||
sect_RelByte(&$1, 0);
|
sect_RelByte(&$1, 0);
|
||||||
}
|
}
|
||||||
| string {
|
| 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);
|
size_t length = charmap_Convert($1, output);
|
||||||
|
|
||||||
sect_AbsByteGroup(output, length);
|
sect_AbsByteGroup(output, length);
|
||||||
@@ -1381,7 +1383,7 @@ constlist_16bit_entry : reloc_16bit_no_str {
|
|||||||
sect_RelWord(&$1, 0);
|
sect_RelWord(&$1, 0);
|
||||||
}
|
}
|
||||||
| string {
|
| 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);
|
size_t length = charmap_Convert($1, output);
|
||||||
|
|
||||||
sect_AbsWordGroup(output, length);
|
sect_AbsWordGroup(output, length);
|
||||||
@@ -1398,7 +1400,7 @@ constlist_32bit_entry : relocexpr_no_str {
|
|||||||
}
|
}
|
||||||
| string {
|
| string {
|
||||||
// Charmaps cannot increase the length of a 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);
|
size_t length = charmap_Convert($1, output);
|
||||||
|
|
||||||
sect_AbsLongGroup(output, length);
|
sect_AbsLongGroup(output, length);
|
||||||
@@ -1444,7 +1446,7 @@ reloc_16bit_no_str : relocexpr_no_str {
|
|||||||
relocexpr : relocexpr_no_str
|
relocexpr : relocexpr_no_str
|
||||||
| string {
|
| string {
|
||||||
// Charmaps cannot increase the length of a 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 length = charmap_Convert($1, output);
|
||||||
uint32_t r = str2int2(output, length);
|
uint32_t r = str2int2(output, length);
|
||||||
|
|
||||||
@@ -1531,8 +1533,12 @@ relocexpr_no_str : scoped_anon_id { rpn_Symbol(&$$, $1); }
|
|||||||
| T_OP_BANK T_LPAREN string T_RPAREN { rpn_BankSection(&$$, $3); }
|
| T_OP_BANK T_LPAREN string T_RPAREN { rpn_BankSection(&$$, $3); }
|
||||||
| T_OP_SIZEOF T_LPAREN string T_RPAREN { rpn_SizeOfSection(&$$, $3); }
|
| T_OP_SIZEOF T_LPAREN string T_RPAREN { rpn_SizeOfSection(&$$, $3); }
|
||||||
| T_OP_STARTOF T_LPAREN string T_RPAREN { rpn_StartOfSection(&$$, $3); }
|
| T_OP_STARTOF T_LPAREN string T_RPAREN { rpn_StartOfSection(&$$, $3); }
|
||||||
| T_OP_SIZEOF T_LPAREN sectiontype T_RPAREN { rpn_SizeOfSectionType(&$$, $3); }
|
| T_OP_SIZEOF T_LPAREN sectiontype T_RPAREN {
|
||||||
| T_OP_STARTOF T_LPAREN sectiontype T_RPAREN { rpn_StartOfSectionType(&$$, $3); }
|
rpn_SizeOfSectionType(&$$, (enum SectionType)$3);
|
||||||
|
}
|
||||||
|
| T_OP_STARTOF T_LPAREN sectiontype T_RPAREN {
|
||||||
|
rpn_StartOfSectionType(&$$, (enum SectionType)$3);
|
||||||
|
}
|
||||||
| T_OP_DEF {
|
| T_OP_DEF {
|
||||||
lexer_ToggleStringExpansion(false);
|
lexer_ToggleStringExpansion(false);
|
||||||
} T_LPAREN scoped_anon_id T_RPAREN {
|
} T_LPAREN scoped_anon_id T_RPAREN {
|
||||||
@@ -1730,7 +1736,7 @@ strfmt_va_args : %empty {
|
|||||||
;
|
;
|
||||||
|
|
||||||
section : T_POP_SECTION sectmod string T_COMMA sectiontype sectorg sectattrs {
|
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);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -11,26 +11,26 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/output.h"
|
#include "asm/output.hpp"
|
||||||
#include "asm/rpn.h"
|
#include "asm/rpn.hpp"
|
||||||
#include "asm/section.h"
|
#include "asm/section.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "opmath.h"
|
#include "opmath.hpp"
|
||||||
|
|
||||||
// Makes an expression "not known", also setting its error message
|
// Makes an expression "not known", also setting its error message
|
||||||
#define makeUnknown(expr_, ...) do { \
|
#define makeUnknown(expr_, ...) do { \
|
||||||
struct Expression *_expr = expr_; \
|
struct Expression *_expr = expr_; \
|
||||||
_expr->isKnown = false; \
|
_expr->isKnown = false; \
|
||||||
/* If we had `asprintf` this would be great, but alas. */ \
|
/* 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) \
|
if (!_expr->reason) \
|
||||||
fatalerror("Can't allocate err string: %s\n", strerror(errno)); \
|
fatalerror("Can't allocate err string: %s\n", strerror(errno)); \
|
||||||
int size = snprintf(_expr->reason, 128, __VA_ARGS__); \
|
int size = snprintf(_expr->reason, 128, __VA_ARGS__); \
|
||||||
if (size >= 128) { /* If this wasn't enough, try again */ \
|
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) \
|
if (!_expr->reason) \
|
||||||
fatalerror("Can't allocate err string: %s\n", strerror(errno)); \
|
fatalerror("Can't allocate err string: %s\n", strerror(errno)); \
|
||||||
sprintf(_expr->reason, __VA_ARGS__); \
|
sprintf(_expr->reason, __VA_ARGS__); \
|
||||||
@@ -55,7 +55,7 @@ static uint8_t *reserveSpace(struct Expression *expr, uint32_t size)
|
|||||||
else
|
else
|
||||||
expr->rpnCapacity *= 2;
|
expr->rpnCapacity *= 2;
|
||||||
}
|
}
|
||||||
expr->rpn = realloc(expr->rpn, expr->rpnCapacity);
|
expr->rpn = (uint8_t *)realloc(expr->rpn, expr->rpnCapacity);
|
||||||
|
|
||||||
if (!expr->rpn)
|
if (!expr->rpn)
|
||||||
fatalerror("Failed to grow RPN expression: %s\n", strerror(errno));
|
fatalerror("Failed to grow RPN expression: %s\n", strerror(errno));
|
||||||
@@ -550,8 +550,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
|||||||
// Convert the left-hand expression if it's constant
|
// Convert the left-hand expression if it's constant
|
||||||
if (src1->isKnown) {
|
if (src1->isKnown) {
|
||||||
uint32_t lval = src1->val;
|
uint32_t lval = src1->val;
|
||||||
uint8_t bytes[] = {RPN_CONST, lval, lval >> 8,
|
uint8_t bytes[] = {RPN_CONST, (uint8_t)lval, (uint8_t)(lval >> 8),
|
||||||
lval >> 16, lval >> 24};
|
(uint8_t)(lval >> 16), (uint8_t)(lval >> 24)};
|
||||||
expr->rpnPatchSize = sizeof(bytes);
|
expr->rpnPatchSize = sizeof(bytes);
|
||||||
expr->rpn = NULL;
|
expr->rpn = NULL;
|
||||||
expr->rpnCapacity = 0;
|
expr->rpnCapacity = 0;
|
||||||
@@ -579,8 +579,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
|||||||
|
|
||||||
// If the right expression is constant, merge a shim instead
|
// If the right expression is constant, merge a shim instead
|
||||||
uint32_t rval = src2->val;
|
uint32_t rval = src2->val;
|
||||||
uint8_t bytes[] = {RPN_CONST, rval, rval >> 8, rval >> 16,
|
uint8_t bytes[] = {RPN_CONST, (uint8_t)rval, (uint8_t)(rval >> 8),
|
||||||
rval >> 24};
|
(uint8_t)(rval >> 16), (uint8_t)(rval >> 24)};
|
||||||
if (src2->isKnown) {
|
if (src2->isKnown) {
|
||||||
ptr = bytes;
|
ptr = bytes;
|
||||||
len = sizeof(bytes);
|
len = sizeof(bytes);
|
||||||
@@ -8,17 +8,17 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/output.h"
|
#include "asm/output.hpp"
|
||||||
#include "asm/rpn.h"
|
#include "asm/rpn.hpp"
|
||||||
#include "asm/section.h"
|
#include "asm/section.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "platform.h" // strdup
|
#include "platform.hpp" // strdup
|
||||||
|
|
||||||
uint8_t fillByte;
|
uint8_t fillByte;
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ static struct Section *createSection(char const *name, enum SectionType type,
|
|||||||
uint32_t org, uint32_t bank, uint8_t alignment,
|
uint32_t org, uint32_t bank, uint8_t alignment,
|
||||||
uint16_t alignOffset, enum SectionModifier mod)
|
uint16_t alignOffset, enum SectionModifier mod)
|
||||||
{
|
{
|
||||||
struct Section *sect = malloc(sizeof(*sect));
|
struct Section *sect = (struct Section *)malloc(sizeof(*sect));
|
||||||
|
|
||||||
if (sect == NULL)
|
if (sect == NULL)
|
||||||
fatalerror("Not enough memory for section: %s\n", strerror(errno));
|
fatalerror("Not enough memory for section: %s\n", strerror(errno));
|
||||||
@@ -288,7 +288,7 @@ static struct Section *createSection(char const *name, enum SectionType type,
|
|||||||
|
|
||||||
// It is only needed to allocate memory for ROM sections.
|
// It is only needed to allocate memory for ROM sections.
|
||||||
if (sect_HasData(type)) {
|
if (sect_HasData(type)) {
|
||||||
sect->data = malloc(sectionTypeInfo[type].size);
|
sect->data = (uint8_t *)malloc(sectionTypeInfo[type].size);
|
||||||
if (sect->data == NULL)
|
if (sect->data == NULL)
|
||||||
fatalerror("Not enough memory for section: %s\n", strerror(errno));
|
fatalerror("Not enough memory for section: %s\n", strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
@@ -547,7 +547,7 @@ void sect_StartUnion(void)
|
|||||||
error("Cannot use UNION inside of ROM0 or ROMX sections\n");
|
error("Cannot use UNION inside of ROM0 or ROMX sections\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct UnionStackEntry *entry = malloc(sizeof(*entry));
|
struct UnionStackEntry *entry = (struct UnionStackEntry *)malloc(sizeof(*entry));
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
fatalerror("Failed to allocate new union stack entry: %s\n", strerror(errno));
|
fatalerror("Failed to allocate new union stack entry: %s\n", strerror(errno));
|
||||||
@@ -933,7 +933,7 @@ cleanup:
|
|||||||
// Section stack routines
|
// Section stack routines
|
||||||
void sect_PushSection(void)
|
void sect_PushSection(void)
|
||||||
{
|
{
|
||||||
struct SectionStackEntry *entry = malloc(sizeof(*entry));
|
struct SectionStackEntry *entry = (struct SectionStackEntry *)malloc(sizeof(*entry));
|
||||||
|
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
fatalerror("No memory for section stack: %s\n", strerror(errno));
|
fatalerror("No memory for section stack: %s\n", strerror(errno));
|
||||||
@@ -11,20 +11,20 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "asm/fixpoint.h"
|
#include "asm/fixpoint.hpp"
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/macro.h"
|
#include "asm/macro.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/output.h"
|
#include "asm/output.hpp"
|
||||||
#include "asm/section.h"
|
#include "asm/section.hpp"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.hpp"
|
||||||
#include "asm/util.h"
|
#include "asm/util.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "hashmap.h"
|
#include "hashmap.hpp"
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "version.h"
|
#include "version.hpp"
|
||||||
|
|
||||||
HashMap symbols;
|
HashMap symbols;
|
||||||
|
|
||||||
@@ -49,8 +49,8 @@ struct ForEachArgs {
|
|||||||
|
|
||||||
static void forEachWrapper(void *_sym, void *_argWrapper)
|
static void forEachWrapper(void *_sym, void *_argWrapper)
|
||||||
{
|
{
|
||||||
struct ForEachArgs *argWrapper = _argWrapper;
|
struct ForEachArgs *argWrapper = (struct ForEachArgs *)_argWrapper;
|
||||||
struct Symbol *sym = _sym;
|
struct Symbol *sym = (struct Symbol *)_sym;
|
||||||
|
|
||||||
argWrapper->func(sym, argWrapper->arg);
|
argWrapper->func(sym, argWrapper->arg);
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ static void updateSymbolFilename(struct Symbol *sym)
|
|||||||
// Create a new symbol by name
|
// Create a new symbol by name
|
||||||
static struct Symbol *createsymbol(char const *symName)
|
static struct Symbol *createsymbol(char const *symName)
|
||||||
{
|
{
|
||||||
struct Symbol *sym = malloc(sizeof(*sym));
|
struct Symbol *sym = (struct Symbol *)malloc(sizeof(*sym));
|
||||||
|
|
||||||
if (!sym)
|
if (!sym)
|
||||||
fatalerror("Failed to create symbol '%s': %s\n", symName, strerror(errno));
|
fatalerror("Failed to create symbol '%s': %s\n", symName, strerror(errno));
|
||||||
@@ -170,7 +170,7 @@ static void assignStringSymbol(struct Symbol *sym, char const *value)
|
|||||||
|
|
||||||
struct Symbol *sym_FindExactSymbol(char const *symName)
|
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)
|
struct Symbol *sym_FindUnscopedSymbol(char const *symName)
|
||||||
@@ -3,11 +3,11 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/util.h"
|
#include "asm/util.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "extern/utf8decoder.h"
|
#include "extern/utf8decoder.hpp"
|
||||||
|
|
||||||
char const *printChar(int c)
|
char const *printChar(int c)
|
||||||
{
|
{
|
||||||
@@ -8,38 +8,38 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/main.h"
|
#include "asm/main.hpp"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
|
|
||||||
unsigned int nbErrors = 0;
|
unsigned int nbErrors = 0;
|
||||||
|
|
||||||
static const enum WarningState defaultWarnings[ARRAY_SIZE(warningStates)] = {
|
static const enum WarningState defaultWarnings[ARRAY_SIZE(warningStates)] = {
|
||||||
[WARNING_ASSERT] = WARNING_ENABLED,
|
AT(WARNING_ASSERT) WARNING_ENABLED,
|
||||||
[WARNING_BACKWARDS_FOR] = WARNING_DISABLED,
|
AT(WARNING_BACKWARDS_FOR) WARNING_DISABLED,
|
||||||
[WARNING_BUILTIN_ARG] = WARNING_DISABLED,
|
AT(WARNING_BUILTIN_ARG) WARNING_DISABLED,
|
||||||
[WARNING_CHARMAP_REDEF] = WARNING_DISABLED,
|
AT(WARNING_CHARMAP_REDEF) WARNING_DISABLED,
|
||||||
[WARNING_DIV] = WARNING_DISABLED,
|
AT(WARNING_DIV) WARNING_DISABLED,
|
||||||
[WARNING_EMPTY_DATA_DIRECTIVE] = WARNING_DISABLED,
|
AT(WARNING_EMPTY_DATA_DIRECTIVE) WARNING_DISABLED,
|
||||||
[WARNING_EMPTY_MACRO_ARG] = WARNING_DISABLED,
|
AT(WARNING_EMPTY_MACRO_ARG) WARNING_DISABLED,
|
||||||
[WARNING_EMPTY_STRRPL] = WARNING_DISABLED,
|
AT(WARNING_EMPTY_STRRPL) WARNING_DISABLED,
|
||||||
[WARNING_LARGE_CONSTANT] = WARNING_DISABLED,
|
AT(WARNING_LARGE_CONSTANT) WARNING_DISABLED,
|
||||||
[WARNING_LONG_STR] = WARNING_DISABLED,
|
AT(WARNING_LONG_STR) WARNING_DISABLED,
|
||||||
[WARNING_MACRO_SHIFT] = WARNING_DISABLED,
|
AT(WARNING_MACRO_SHIFT) WARNING_DISABLED,
|
||||||
[WARNING_NESTED_COMMENT] = WARNING_ENABLED,
|
AT(WARNING_NESTED_COMMENT) WARNING_ENABLED,
|
||||||
[WARNING_OBSOLETE] = WARNING_ENABLED,
|
AT(WARNING_OBSOLETE) WARNING_ENABLED,
|
||||||
[WARNING_SHIFT] = WARNING_DISABLED,
|
AT(WARNING_SHIFT) WARNING_DISABLED,
|
||||||
[WARNING_SHIFT_AMOUNT] = WARNING_DISABLED,
|
AT(WARNING_SHIFT_AMOUNT) WARNING_DISABLED,
|
||||||
[WARNING_USER] = WARNING_ENABLED,
|
AT(WARNING_USER) WARNING_ENABLED,
|
||||||
|
|
||||||
[WARNING_NUMERIC_STRING_1] = WARNING_ENABLED,
|
AT(WARNING_NUMERIC_STRING_1) WARNING_ENABLED,
|
||||||
[WARNING_NUMERIC_STRING_2] = WARNING_DISABLED,
|
AT(WARNING_NUMERIC_STRING_2) WARNING_DISABLED,
|
||||||
[WARNING_TRUNCATION_1] = WARNING_ENABLED,
|
AT(WARNING_TRUNCATION_1) WARNING_ENABLED,
|
||||||
[WARNING_TRUNCATION_2] = WARNING_DISABLED,
|
AT(WARNING_TRUNCATION_2) WARNING_DISABLED,
|
||||||
[WARNING_UNMAPPED_CHAR_1] = WARNING_ENABLED,
|
AT(WARNING_UNMAPPED_CHAR_1) WARNING_ENABLED,
|
||||||
[WARNING_UNMAPPED_CHAR_2] = WARNING_DISABLED,
|
AT(WARNING_UNMAPPED_CHAR_2) WARNING_DISABLED,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WarningState warningStates[ARRAY_SIZE(warningStates)];
|
enum WarningState warningStates[ARRAY_SIZE(warningStates)];
|
||||||
@@ -139,7 +139,7 @@ static bool tryProcessParamWarning(char const *flag, uint8_t param, enum Warning
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
baseID += maxParam;
|
baseID = (enum WarningID)(baseID + maxParam);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ void processWarningFlag(char *flag)
|
|||||||
static bool setError = false;
|
static bool setError = false;
|
||||||
|
|
||||||
// First, try to match against a "meta" warning
|
// 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?
|
// TODO: improve the matching performance?
|
||||||
if (!strcmp(flag, warningFlags[id])) {
|
if (!strcmp(flag, warningFlags[id])) {
|
||||||
// We got a match!
|
// We got a match!
|
||||||
@@ -309,7 +309,8 @@ void processWarningFlag(char *flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to match the flag against a "normal" 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])) {
|
if (!strcmp(rootFlag, warningFlags[id])) {
|
||||||
// We got a match!
|
// We got a match!
|
||||||
warningStates[id] = state;
|
warningStates[id] = state;
|
||||||
@@ -345,7 +346,7 @@ void error(char const *fmt, ...)
|
|||||||
nbErrors++;
|
nbErrors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Noreturn void fatalerror(char const *fmt, ...)
|
[[noreturn]] void fatalerror(char const *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
|
|
||||||
static void vwarn(char const NONNULL(fmt), va_list ap)
|
static void vwarn(char const NONNULL(fmt), va_list ap)
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,7 @@ static void vwarnx(char const NONNULL(fmt), va_list ap)
|
|||||||
putc('\n', stderr);
|
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: ");
|
fprintf(stderr, "error: ");
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
@@ -35,7 +35,7 @@ _Noreturn static void verr(char const NONNULL(fmt), va_list ap)
|
|||||||
exit(1);
|
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");
|
fprintf(stderr, "error");
|
||||||
fputs(": ", stderr);
|
fputs(": ", stderr);
|
||||||
@@ -62,7 +62,7 @@ void warnx(char const NONNULL(fmt), ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
_Noreturn void err(char const NONNULL(fmt), ...)
|
[[noreturn]] void err(char const NONNULL(fmt), ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ _Noreturn void err(char const NONNULL(fmt), ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
_Noreturn void errx(char const NONNULL(fmt), ...)
|
[[noreturn]] void errx(char const NONNULL(fmt), ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
2
src/extern/getopt.c → src/extern/getopt.cpp
vendored
2
src/extern/getopt.c → src/extern/getopt.cpp
vendored
@@ -13,7 +13,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "extern/getopt.h"
|
#include "extern/getopt.hpp"
|
||||||
|
|
||||||
char *musl_optarg;
|
char *musl_optarg;
|
||||||
int musl_optind = 1, musl_opterr = 1, musl_optopt;
|
int musl_optind = 1, musl_opterr = 1, musl_optopt;
|
||||||
@@ -13,11 +13,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "extern/getopt.h"
|
#include "extern/getopt.hpp"
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
#include "version.h"
|
#include "version.hpp"
|
||||||
|
|
||||||
#define UNSPECIFIED 0x200 // Should not be in byte range
|
#define UNSPECIFIED 0x200 // Should not be in byte range
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ static enum MbcType parseMBC(char const *name)
|
|||||||
return MBC_BAD;
|
return MBC_BAD;
|
||||||
if (mbc > 0xFF)
|
if (mbc > 0xFF)
|
||||||
return MBC_BAD_RANGE;
|
return MBC_BAD_RANGE;
|
||||||
return mbc;
|
return (enum MbcType)mbc;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Begin by reading the MBC type:
|
// Begin by reading the MBC type:
|
||||||
@@ -570,7 +570,7 @@ do { \
|
|||||||
if (*ptr)
|
if (*ptr)
|
||||||
return MBC_BAD;
|
return MBC_BAD;
|
||||||
|
|
||||||
return mbc;
|
return (enum MbcType)mbc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1000,7 +1000,7 @@ static void processFile(int input, int output, char const *name, off_t fileSize)
|
|||||||
} else if (rom0Len == BANK_SIZE) {
|
} else if (rom0Len == BANK_SIZE) {
|
||||||
// Copy ROMX when reading a pipe, and we're not at EOF yet
|
// Copy ROMX when reading a pipe, and we're not at EOF yet
|
||||||
for (;;) {
|
for (;;) {
|
||||||
romx = realloc(romx, nbBanks * BANK_SIZE);
|
romx = (uint8_t *)realloc(romx, nbBanks * BANK_SIZE);
|
||||||
if (!romx) {
|
if (!romx) {
|
||||||
report("FATAL: Failed to realloc ROMX buffer: %s\n",
|
report("FATAL: Failed to realloc ROMX buffer: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -1094,11 +1094,13 @@ static void processFile(int input, int output, char const *name, off_t fileSize)
|
|||||||
if (fixSpec & TRASH_GLOBAL_SUM)
|
if (fixSpec & TRASH_GLOBAL_SUM)
|
||||||
globalSum = ~globalSum;
|
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");
|
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
|
// In case the output depends on the input, reset to the beginning of the file, and only
|
||||||
// write the header
|
// write the header
|
||||||
if (input == output) {
|
if (input == output) {
|
||||||
@@ -1111,7 +1113,7 @@ static void processFile(int input, int output, char const *name, off_t fileSize)
|
|||||||
if (padValue == UNSPECIFIED)
|
if (padValue == UNSPECIFIED)
|
||||||
rom0Len = headerSize;
|
rom0Len = headerSize;
|
||||||
}
|
}
|
||||||
ssize_t writeLen = writeBytes(output, rom0, rom0Len);
|
writeLen = writeBytes(output, rom0, rom0Len);
|
||||||
|
|
||||||
if (writeLen == -1) {
|
if (writeLen == -1) {
|
||||||
report("FATAL: Failed to write \"%s\"'s ROM0: %s\n", name, strerror(errno));
|
report("FATAL: Failed to write \"%s\"'s ROM0: %s\n", name, strerror(errno));
|
||||||
@@ -19,10 +19,10 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "extern/getopt.h"
|
#include "extern/getopt.hpp"
|
||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
#include "version.h"
|
#include "version.hpp"
|
||||||
|
|
||||||
#include "gfx/pal_spec.hpp"
|
#include "gfx/pal_spec.hpp"
|
||||||
#include "gfx/process.hpp"
|
#include "gfx/process.hpp"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <png.h>
|
#include <png.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
#include "gfx/main.hpp"
|
#include "gfx/main.hpp"
|
||||||
#include "gfx/process.hpp"
|
#include "gfx/process.hpp"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
|
|
||||||
#include "gfx/main.hpp"
|
#include "gfx/main.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "defaultinitalloc.hpp"
|
#include "defaultinitalloc.hpp"
|
||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "itertools.hpp"
|
#include "itertools.hpp"
|
||||||
|
|
||||||
#include "gfx/main.hpp"
|
#include "gfx/main.hpp"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include "defaultinitalloc.hpp"
|
#include "defaultinitalloc.hpp"
|
||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "itertools.hpp"
|
#include "itertools.hpp"
|
||||||
|
|
||||||
#include "gfx/main.hpp"
|
#include "gfx/main.hpp"
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "hashmap.h"
|
#include "hashmap.hpp"
|
||||||
|
|
||||||
// The lower half of the hash is used to index the "master" table,
|
// The lower half of the hash is used to index the "master" table,
|
||||||
// the upper half is used to help resolve collisions more quickly
|
// the upper half is used to help resolve collisions more quickly
|
||||||
@@ -42,7 +42,7 @@ void **hash_AddElement(HashMap map, char const *key, void *element)
|
|||||||
{
|
{
|
||||||
HashType hashedKey = hash(key);
|
HashType hashedKey = hash(key);
|
||||||
HalfHashType index = hashedKey;
|
HalfHashType index = hashedKey;
|
||||||
struct HashMapEntry *newEntry = malloc(sizeof(*newEntry));
|
struct HashMapEntry *newEntry = (struct HashMapEntry *)malloc(sizeof(*newEntry));
|
||||||
|
|
||||||
if (!newEntry)
|
if (!newEntry)
|
||||||
err("%s: Failed to allocate new entry", __func__);
|
err("%s: Failed to allocate new entry", __func__);
|
||||||
@@ -6,16 +6,16 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "link/assign.h"
|
#include "link/assign.hpp"
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
#include "link/symbol.h"
|
#include "link/symbol.hpp"
|
||||||
#include "link/object.h"
|
#include "link/object.hpp"
|
||||||
#include "link/main.h"
|
#include "link/main.hpp"
|
||||||
#include "link/output.h"
|
#include "link/output.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
struct MemoryLocation {
|
struct MemoryLocation {
|
||||||
uint16_t address;
|
uint16_t address;
|
||||||
@@ -36,14 +36,14 @@ uint64_t nbSectionsToAssign;
|
|||||||
// Init the free space-modelling structs
|
// Init the free space-modelling structs
|
||||||
static void initFreeSpace(void)
|
static void initFreeSpace(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)) {
|
||||||
memory[type] = malloc(sizeof(*memory[type]) * nbbanks(type));
|
memory[type] = (struct FreeSpace *)malloc(sizeof(*memory[type]) * nbbanks(type));
|
||||||
if (!memory[type])
|
if (!memory[type])
|
||||||
err("Failed to init free space for region %d", type);
|
err("Failed to init free space for region %d", type);
|
||||||
|
|
||||||
for (uint32_t bank = 0; bank < nbbanks(type); bank++) {
|
for (uint32_t bank = 0; bank < nbbanks(type); bank++) {
|
||||||
memory[type][bank].next =
|
memory[type][bank].next =
|
||||||
malloc(sizeof(*memory[type][0].next));
|
(struct FreeSpace *)malloc(sizeof(*memory[type][0].next));
|
||||||
if (!memory[type][bank].next)
|
if (!memory[type][bank].next)
|
||||||
err("Failed to init free space for region %d bank %" PRIu32,
|
err("Failed to init free space for region %d bank %" PRIu32,
|
||||||
type, bank);
|
type, bank);
|
||||||
@@ -242,7 +242,7 @@ static void placeSection(struct Section *section)
|
|||||||
free(freeSpace);
|
free(freeSpace);
|
||||||
} else if (!noLeftSpace && !noRightSpace) {
|
} else if (!noLeftSpace && !noRightSpace) {
|
||||||
// The free space is split in two
|
// The free space is split in two
|
||||||
struct FreeSpace *newSpace = malloc(sizeof(*newSpace));
|
struct FreeSpace *newSpace = (struct FreeSpace *)malloc(sizeof(*newSpace));
|
||||||
|
|
||||||
if (!newSpace)
|
if (!newSpace)
|
||||||
err("Failed to split new free space");
|
err("Failed to split new free space");
|
||||||
@@ -318,7 +318,7 @@ struct UnassignedSection {
|
|||||||
#define BANK_CONSTRAINED (1 << 2)
|
#define BANK_CONSTRAINED (1 << 2)
|
||||||
#define ORG_CONSTRAINED (1 << 1)
|
#define ORG_CONSTRAINED (1 << 1)
|
||||||
#define ALIGN_CONSTRAINED (1 << 0)
|
#define ALIGN_CONSTRAINED (1 << 0)
|
||||||
static struct UnassignedSection *unassignedSections[1 << 3] = {0};
|
static struct UnassignedSection *unassignedSections[1 << 3] = {};
|
||||||
static struct UnassignedSection *sections;
|
static struct UnassignedSection *sections;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -360,7 +360,7 @@ void assign_AssignSections(void)
|
|||||||
// Initialize assignment
|
// Initialize assignment
|
||||||
|
|
||||||
// Generate linked lists of sections to assign
|
// Generate linked lists of sections to assign
|
||||||
sections = malloc(sizeof(*sections) * nbSectionsToAssign + 1);
|
sections = (struct UnassignedSection *)malloc(sizeof(*sections) * nbSectionsToAssign + 1);
|
||||||
if (!sections)
|
if (!sections)
|
||||||
err("Failed to allocate memory for section assignment");
|
err("Failed to allocate memory for section assignment");
|
||||||
|
|
||||||
@@ -428,7 +428,7 @@ max_out:
|
|||||||
|
|
||||||
void assign_Cleanup(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++) {
|
for (uint32_t bank = 0; bank < nbbanks(type); bank++) {
|
||||||
struct FreeSpace *ptr =
|
struct FreeSpace *ptr =
|
||||||
memory[type][bank].next;
|
memory[type][bank].next;
|
||||||
@@ -12,20 +12,20 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "link/assign.h"
|
#include "link/assign.hpp"
|
||||||
#include "link/object.h"
|
#include "link/object.hpp"
|
||||||
#include "link/output.h"
|
#include "link/output.hpp"
|
||||||
#include "link/patch.h"
|
#include "link/patch.hpp"
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
#include "link/script.h"
|
#include "link/script.hpp"
|
||||||
#include "link/symbol.h"
|
#include "link/symbol.hpp"
|
||||||
|
|
||||||
#include "extern/getopt.h"
|
#include "extern/getopt.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
#include "version.h"
|
#include "version.hpp"
|
||||||
|
|
||||||
bool isDmgMode; // -d
|
bool isDmgMode; // -d
|
||||||
char *linkerScriptName; // -l
|
char *linkerScriptName; // -l
|
||||||
@@ -117,7 +117,7 @@ void argErr(char flag, char const *fmt, ...)
|
|||||||
nbErrors++;
|
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;
|
va_list ap;
|
||||||
|
|
||||||
@@ -228,9 +228,9 @@ struct {
|
|||||||
char const *name;
|
char const *name;
|
||||||
uint16_t max;
|
uint16_t max;
|
||||||
} scrambleSpecs[SCRAMBLE_UNK] = {
|
} scrambleSpecs[SCRAMBLE_UNK] = {
|
||||||
[SCRAMBLE_ROMX] = { "romx", 65535 },
|
AT(SCRAMBLE_ROMX) { "romx", 65535 },
|
||||||
[SCRAMBLE_SRAM] = { "sram", 255 },
|
AT(SCRAMBLE_SRAM) { "sram", 255 },
|
||||||
[SCRAMBLE_WRAMX] = { "wramx", 7},
|
AT(SCRAMBLE_WRAMX) { "wramx", 7 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void parseScrambleSpec(char const *spec)
|
static void parseScrambleSpec(char const *spec)
|
||||||
@@ -249,6 +249,7 @@ static void parseScrambleSpec(char const *spec)
|
|||||||
size_t regionNameLen = strcspn(spec, "=, \t");
|
size_t regionNameLen = strcspn(spec, "=, \t");
|
||||||
// Length of region name string slice for printing, truncated if too long
|
// Length of region name string slice for printing, truncated if too long
|
||||||
int regionNamePrintLen = regionNameLen > INT_MAX ? INT_MAX : (int)regionNameLen;
|
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 this trips, `spec` must be pointing at a ',' or '=' (or NUL) due to the assert
|
||||||
if (regionNameLen == 0) {
|
if (regionNameLen == 0) {
|
||||||
@@ -271,9 +272,7 @@ static void parseScrambleSpec(char const *spec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now, determine which region type this is
|
// Now, determine which region type this is
|
||||||
enum ScrambledRegion region = 0;
|
for (; region < SCRAMBLE_UNK; region = (enum ScrambledRegion)(region + 1)) {
|
||||||
|
|
||||||
for (; region < SCRAMBLE_UNK; region++) {
|
|
||||||
// If the strings match (case-insensitively), we got it!
|
// If the strings match (case-insensitively), we got it!
|
||||||
// `strncasecmp` must be used here since `regionName` points
|
// `strncasecmp` must be used here since `regionName` points
|
||||||
// to the entire remaining argument.
|
// to the entire remaining argument.
|
||||||
@@ -341,7 +340,7 @@ next:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_Noreturn void reportErrors(void) {
|
[[noreturn]] void reportErrors(void) {
|
||||||
fprintf(stderr, "Linking failed with %" PRIu32 " error%s\n",
|
fprintf(stderr, "Linking failed with %" PRIu32 " error%s\n",
|
||||||
nbErrors, nbErrors == 1 ? "" : "s");
|
nbErrors, nbErrors == 1 ? "" : "s");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -8,18 +8,18 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "link/assign.h"
|
#include "link/assign.hpp"
|
||||||
#include "link/main.h"
|
#include "link/main.hpp"
|
||||||
#include "link/object.h"
|
#include "link/object.hpp"
|
||||||
#include "link/patch.h"
|
#include "link/patch.hpp"
|
||||||
#include "link/sdas_obj.h"
|
#include "link/sdas_obj.hpp"
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
#include "link/symbol.h"
|
#include "link/symbol.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "version.h"
|
#include "version.hpp"
|
||||||
|
|
||||||
static struct SymbolList {
|
static struct SymbolList {
|
||||||
size_t nbSymbols;
|
size_t nbSymbols;
|
||||||
@@ -38,7 +38,7 @@ static struct Assertion *assertions;
|
|||||||
|
|
||||||
// Internal, DO NOT USE.
|
// Internal, DO NOT USE.
|
||||||
// For helper wrapper macros defined below, such as `tryReadlong`
|
// 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 { \
|
do { \
|
||||||
FILE *tmpFile = file; \
|
FILE *tmpFile = file; \
|
||||||
type tmpVal = func(tmpFile); \
|
type tmpVal = func(tmpFile); \
|
||||||
@@ -48,7 +48,7 @@ static struct Assertion *assertions;
|
|||||||
? "Unexpected end of file" \
|
? "Unexpected end of file" \
|
||||||
: strerror(errno)); \
|
: strerror(errno)); \
|
||||||
} \
|
} \
|
||||||
var = tmpVal; \
|
var = (vartype)tmpVal; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -86,7 +86,7 @@ static int64_t readlong(FILE *file)
|
|||||||
* argument is provided, the reason for failure
|
* argument is provided, the reason for failure
|
||||||
*/
|
*/
|
||||||
#define tryReadlong(var, file, ...) \
|
#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`.
|
// There is no `readbyte`, just use `fgetc` or `getc`.
|
||||||
|
|
||||||
@@ -98,8 +98,8 @@ static int64_t readlong(FILE *file)
|
|||||||
* @param ... A format string and related arguments; note that an extra string
|
* @param ... A format string and related arguments; note that an extra string
|
||||||
* argument is provided, the reason for failure
|
* argument is provided, the reason for failure
|
||||||
*/
|
*/
|
||||||
#define tryGetc(var, file, ...) \
|
#define tryGetc(type, var, file, ...) \
|
||||||
tryRead(getc, int, EOF, var, file, __VA_ARGS__)
|
tryRead(getc, int, EOF, type, var, file, __VA_ARGS__)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads a '\0'-terminated string from a file.
|
* Reads a '\0'-terminated string from a file.
|
||||||
@@ -122,7 +122,7 @@ static char *readstr(FILE *file)
|
|||||||
// If the buffer isn't suitable to write the next char...
|
// If the buffer isn't suitable to write the next char...
|
||||||
if (index >= capacity || !str) {
|
if (index >= capacity || !str) {
|
||||||
capacity *= 2;
|
capacity *= 2;
|
||||||
str = realloc(str, capacity);
|
str = (char *)realloc(str, capacity);
|
||||||
// End now in case of error
|
// End now in case of error
|
||||||
if (!str)
|
if (!str)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -149,7 +149,7 @@ static char *readstr(FILE *file)
|
|||||||
* argument is provided, the reason for failure
|
* argument is provided, the reason for failure
|
||||||
*/
|
*/
|
||||||
#define tryReadstr(var, file, ...) \
|
#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
|
// Functions to parse object files
|
||||||
|
|
||||||
@@ -170,8 +170,8 @@ static void readFileStackNode(FILE *file, struct FileStackNode fileNodes[], uint
|
|||||||
fileNodes[i].parent = parentID == (uint32_t)-1 ? NULL : &fileNodes[parentID];
|
fileNodes[i].parent = parentID == (uint32_t)-1 ? NULL : &fileNodes[parentID];
|
||||||
tryReadlong(fileNodes[i].lineNo, file,
|
tryReadlong(fileNodes[i].lineNo, file,
|
||||||
"%s: Cannot read node #%" PRIu32 "'s line number: %s", fileName, i);
|
"%s: Cannot read node #%" PRIu32 "'s line number: %s", fileName, i);
|
||||||
tryGetc(fileNodes[i].type, file, "%s: Cannot read node #%" PRIu32 "'s type: %s",
|
tryGetc(enum FileStackNodeType, fileNodes[i].type, file,
|
||||||
fileName, i);
|
"%s: Cannot read node #%" PRIu32 "'s type: %s", fileName, i);
|
||||||
switch (fileNodes[i].type) {
|
switch (fileNodes[i].type) {
|
||||||
case NODE_FILE:
|
case NODE_FILE:
|
||||||
case NODE_MACRO:
|
case NODE_MACRO:
|
||||||
@@ -182,7 +182,8 @@ static void readFileStackNode(FILE *file, struct FileStackNode fileNodes[], uint
|
|||||||
case NODE_REPT:
|
case NODE_REPT:
|
||||||
tryReadlong(fileNodes[i].reptDepth, file,
|
tryReadlong(fileNodes[i].reptDepth, file,
|
||||||
"%s: Cannot read node #%" PRIu32 "'s rept depth: %s", fileName, i);
|
"%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)
|
if (!fileNodes[i].iters)
|
||||||
fatal(NULL, 0, "%s: Failed to alloc node #%" PRIu32 "'s iters: %s",
|
fatal(NULL, 0, "%s: Failed to alloc node #%" PRIu32 "'s iters: %s",
|
||||||
fileName, i, strerror(errno));
|
fileName, i, strerror(errno));
|
||||||
@@ -207,7 +208,7 @@ static void readSymbol(FILE *file, struct Symbol *symbol,
|
|||||||
{
|
{
|
||||||
tryReadstr(symbol->name, file, "%s: Cannot read symbol name: %s",
|
tryReadstr(symbol->name, file, "%s: Cannot read symbol name: %s",
|
||||||
fileName);
|
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);
|
fileName, symbol->name);
|
||||||
// If the symbol is defined in this file, read its definition
|
// If the symbol is defined in this file, read its definition
|
||||||
if (symbol->type != SYMTYPE_IMPORT) {
|
if (symbol->type != SYMTYPE_IMPORT) {
|
||||||
@@ -243,7 +244,7 @@ static void readPatch(FILE *file, struct Patch *patch, char const *fileName, cha
|
|||||||
uint32_t i, struct FileStackNode fileNodes[])
|
uint32_t i, struct FileStackNode fileNodes[])
|
||||||
{
|
{
|
||||||
uint32_t nodeID;
|
uint32_t nodeID;
|
||||||
uint8_t type;
|
enum PatchType type;
|
||||||
|
|
||||||
tryReadlong(nodeID, file,
|
tryReadlong(nodeID, file,
|
||||||
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s node ID: %s",
|
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s node ID: %s",
|
||||||
@@ -261,7 +262,7 @@ static void readPatch(FILE *file, struct Patch *patch, char const *fileName, cha
|
|||||||
tryReadlong(patch->pcOffset, file,
|
tryReadlong(patch->pcOffset, file,
|
||||||
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s PC offset: %s",
|
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s PC offset: %s",
|
||||||
fileName, sectName, i);
|
fileName, sectName, i);
|
||||||
tryGetc(type, file,
|
tryGetc(enum PatchType, type, file,
|
||||||
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s type: %s",
|
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s type: %s",
|
||||||
fileName, sectName, i);
|
fileName, sectName, i);
|
||||||
patch->type = type;
|
patch->type = type;
|
||||||
@@ -269,7 +270,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",
|
"%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s RPN size: %s",
|
||||||
fileName, sectName, i);
|
fileName, sectName, i);
|
||||||
|
|
||||||
patch->rpnExpression = malloc(sizeof(*patch->rpnExpression) * patch->rpnSize);
|
patch->rpnExpression = (uint8_t *)malloc(sizeof(*patch->rpnExpression) * patch->rpnSize);
|
||||||
if (!patch->rpnExpression)
|
if (!patch->rpnExpression)
|
||||||
err("%s: Failed to alloc \"%s\"'s patch #%" PRIu32 "'s RPN expression",
|
err("%s: Failed to alloc \"%s\"'s patch #%" PRIu32 "'s RPN expression",
|
||||||
fileName, sectName, i);
|
fileName, sectName, i);
|
||||||
@@ -313,9 +314,9 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
section->name, tmp);
|
section->name, tmp);
|
||||||
section->size = tmp;
|
section->size = tmp;
|
||||||
section->offset = 0;
|
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);
|
fileName, section->name);
|
||||||
section->type = byte & 0x3F;
|
section->type = (enum SectionType)(byte & 0x3F);
|
||||||
if (byte >> 7)
|
if (byte >> 7)
|
||||||
section->modifier = SECTION_UNION;
|
section->modifier = SECTION_UNION;
|
||||||
else if (byte >> 6)
|
else if (byte >> 6)
|
||||||
@@ -335,7 +336,7 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
fileName, section->name);
|
fileName, section->name);
|
||||||
section->isBankFixed = tmp >= 0;
|
section->isBankFixed = tmp >= 0;
|
||||||
section->bank = tmp;
|
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);
|
fileName, section->name);
|
||||||
if (byte > 16)
|
if (byte > 16)
|
||||||
byte = 16;
|
byte = 16;
|
||||||
@@ -352,7 +353,7 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
|
|
||||||
if (sect_HasData(section->type)) {
|
if (sect_HasData(section->type)) {
|
||||||
// Ensure we never allocate 0 bytes
|
// 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)
|
if (!data)
|
||||||
err("%s: Unable to read \"%s\"'s data", fileName,
|
err("%s: Unable to read \"%s\"'s data", fileName,
|
||||||
@@ -373,7 +374,7 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
fileName, section->name);
|
fileName, section->name);
|
||||||
|
|
||||||
struct Patch *patches =
|
struct Patch *patches =
|
||||||
malloc(sizeof(*patches) * section->nbPatches + 1);
|
(struct Patch *)malloc(sizeof(*patches) * section->nbPatches + 1);
|
||||||
|
|
||||||
if (!patches)
|
if (!patches)
|
||||||
err("%s: Unable to read \"%s\"'s patches", fileName, section->name);
|
err("%s: Unable to read \"%s\"'s patches", fileName, section->name);
|
||||||
@@ -469,7 +470,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
|
// Since SDCC does not provide line info, everything will be reported as coming from the
|
||||||
// object file. It's better than nothing.
|
// object file. It's better than nothing.
|
||||||
nodes[fileID].nbNodes = 1;
|
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)
|
if (!nodes[fileID].nodes)
|
||||||
err("Failed to get memory for %s's nodes", fileName);
|
err("Failed to get memory for %s's nodes", fileName);
|
||||||
struct FileStackNode *where = &nodes[fileID].nodes[0];
|
struct FileStackNode *where = &nodes[fileID].nodes[0];
|
||||||
@@ -517,7 +519,8 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
nbSectionsToAssign += nbSections;
|
nbSectionsToAssign += nbSections;
|
||||||
|
|
||||||
tryReadlong(nodes[fileID].nbNodes, file, "%s: Cannot read number of nodes: %s", fileName);
|
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)
|
if (!nodes[fileID].nodes)
|
||||||
err("Failed to get memory for %s's nodes", fileName);
|
err("Failed to get memory for %s's nodes", fileName);
|
||||||
verbosePrint("Reading %u nodes...\n", nodes[fileID].nbNodes);
|
verbosePrint("Reading %u nodes...\n", nodes[fileID].nbNodes);
|
||||||
@@ -525,12 +528,12 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
readFileStackNode(file, nodes[fileID].nodes, i, fileName);
|
readFileStackNode(file, nodes[fileID].nodes, i, fileName);
|
||||||
|
|
||||||
// This file's symbols, kept to link sections to them
|
// 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)
|
if (!fileSymbols)
|
||||||
err("Failed to get memory for %s's symbols", fileName);
|
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)
|
if (!symbolList)
|
||||||
err("Failed to register %s's symbol list", fileName);
|
err("Failed to register %s's symbol list", fileName);
|
||||||
@@ -539,13 +542,13 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
symbolList->next = symbolLists;
|
symbolList->next = symbolLists;
|
||||||
symbolLists = symbolList;
|
symbolLists = symbolList;
|
||||||
|
|
||||||
uint32_t *nbSymPerSect = calloc(nbSections ? nbSections : 1,
|
uint32_t *nbSymPerSect = (uint32_t *)calloc(nbSections ? nbSections : 1,
|
||||||
sizeof(*nbSymPerSect));
|
sizeof(*nbSymPerSect));
|
||||||
|
|
||||||
verbosePrint("Reading %" PRIu32 " symbols...\n", nbSymbols);
|
verbosePrint("Reading %" PRIu32 " symbols...\n", nbSymbols);
|
||||||
for (uint32_t i = 0; i < nbSymbols; i++) {
|
for (uint32_t i = 0; i < nbSymbols; i++) {
|
||||||
// Read symbol
|
// Read symbol
|
||||||
struct Symbol *symbol = malloc(sizeof(*symbol));
|
struct Symbol *symbol = (struct Symbol *)malloc(sizeof(*symbol));
|
||||||
|
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
err("%s: Couldn't create new symbol", fileName);
|
err("%s: Couldn't create new symbol", fileName);
|
||||||
@@ -559,13 +562,13 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This file's sections, stored in a table to link symbols to them
|
// This file's sections, stored in a table to link symbols to them
|
||||||
struct Section **fileSections = malloc(sizeof(*fileSections)
|
struct Section **fileSections =
|
||||||
* (nbSections ? nbSections : 1));
|
(struct Section **)malloc(sizeof(*fileSections) * (nbSections ? nbSections : 1));
|
||||||
|
|
||||||
verbosePrint("Reading %" PRIu32 " sections...\n", nbSections);
|
verbosePrint("Reading %" PRIu32 " sections...\n", nbSections);
|
||||||
for (uint32_t i = 0; i < nbSections; i++) {
|
for (uint32_t i = 0; i < nbSections; i++) {
|
||||||
// Read section
|
// Read section
|
||||||
fileSections[i] = malloc(sizeof(*fileSections[i]));
|
fileSections[i] = (struct Section *)malloc(sizeof(*fileSections[i]));
|
||||||
if (!fileSections[i])
|
if (!fileSections[i])
|
||||||
err("%s: Couldn't create new section", fileName);
|
err("%s: Couldn't create new section", fileName);
|
||||||
|
|
||||||
@@ -573,8 +576,8 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
readSection(file, fileSections[i], fileName, nodes[fileID].nodes);
|
readSection(file, fileSections[i], fileName, nodes[fileID].nodes);
|
||||||
fileSections[i]->fileSymbols = fileSymbols;
|
fileSections[i]->fileSymbols = fileSymbols;
|
||||||
if (nbSymPerSect[i]) {
|
if (nbSymPerSect[i]) {
|
||||||
fileSections[i]->symbols = malloc(nbSymPerSect[i]
|
fileSections[i]->symbols =
|
||||||
* sizeof(*fileSections[i]->symbols));
|
(struct Symbol **)malloc(nbSymPerSect[i] * sizeof(*fileSections[i]->symbols));
|
||||||
if (!fileSections[i]->symbols)
|
if (!fileSections[i]->symbols)
|
||||||
err("%s: Couldn't link to symbols",
|
err("%s: Couldn't link to symbols",
|
||||||
fileName);
|
fileName);
|
||||||
@@ -624,7 +627,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
fileName);
|
fileName);
|
||||||
verbosePrint("Reading %" PRIu32 " assertions...\n", nbAsserts);
|
verbosePrint("Reading %" PRIu32 " assertions...\n", nbAsserts);
|
||||||
for (uint32_t i = 0; i < nbAsserts; i++) {
|
for (uint32_t i = 0; i < nbAsserts; i++) {
|
||||||
struct Assertion *assertion = malloc(sizeof(*assertion));
|
struct Assertion *assertion = (struct Assertion *)malloc(sizeof(*assertion));
|
||||||
|
|
||||||
if (!assertion)
|
if (!assertion)
|
||||||
err("%s: Couldn't create new assertion", fileName);
|
err("%s: Couldn't create new assertion", fileName);
|
||||||
@@ -655,7 +658,7 @@ void obj_Setup(unsigned int nbFiles)
|
|||||||
|
|
||||||
if (nbFiles > SIZE_MAX / sizeof(*nodes))
|
if (nbFiles > SIZE_MAX / sizeof(*nodes))
|
||||||
fatal(NULL, 0, "Impossible to link more than %zu files!", 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)
|
static void freeNode(struct FileStackNode *node)
|
||||||
@@ -7,16 +7,16 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "link/output.h"
|
#include "link/output.hpp"
|
||||||
#include "link/main.h"
|
#include "link/main.hpp"
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
#include "link/symbol.h"
|
#include "link/symbol.hpp"
|
||||||
|
|
||||||
#include "extern/utf8decoder.h"
|
#include "extern/utf8decoder.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "platform.h" // MIN_NB_ELMS
|
#include "platform.hpp" // For `MIN_NB_ELMS` and `AT`
|
||||||
|
|
||||||
#define BANK_SIZE 0x4000
|
#define BANK_SIZE 0x4000
|
||||||
|
|
||||||
@@ -61,14 +61,14 @@ static enum SectionType typeMap[SECTTYPE_INVALID] = {
|
|||||||
void out_AddSection(struct Section const *section)
|
void out_AddSection(struct Section const *section)
|
||||||
{
|
{
|
||||||
static uint32_t maxNbBanks[] = {
|
static uint32_t maxNbBanks[] = {
|
||||||
[SECTTYPE_ROM0] = 1,
|
AT(SECTTYPE_WRAM0) 1,
|
||||||
[SECTTYPE_ROMX] = UINT32_MAX,
|
AT(SECTTYPE_VRAM) 2,
|
||||||
[SECTTYPE_VRAM] = 2,
|
AT(SECTTYPE_ROMX) UINT32_MAX,
|
||||||
[SECTTYPE_SRAM] = UINT32_MAX,
|
AT(SECTTYPE_ROM0) 1,
|
||||||
[SECTTYPE_WRAM0] = 1,
|
AT(SECTTYPE_HRAM) 1,
|
||||||
[SECTTYPE_WRAMX] = 7,
|
AT(SECTTYPE_WRAMX) 7,
|
||||||
[SECTTYPE_OAM] = 1,
|
AT(SECTTYPE_SRAM) UINT32_MAX,
|
||||||
[SECTTYPE_HRAM] = 1
|
AT(SECTTYPE_OAM) 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t targetBank = section->bank - sectionTypeInfo[section->type].firstBank;
|
uint32_t targetBank = section->bank - sectionTypeInfo[section->type].firstBank;
|
||||||
@@ -81,7 +81,7 @@ void out_AddSection(struct Section const *section)
|
|||||||
|
|
||||||
if (minNbBanks > sections[section->type].nbBanks) {
|
if (minNbBanks > sections[section->type].nbBanks) {
|
||||||
sections[section->type].banks =
|
sections[section->type].banks =
|
||||||
realloc(sections[section->type].banks,
|
(struct SortedSections *)realloc(sections[section->type].banks,
|
||||||
sizeof(*sections[0].banks) * minNbBanks);
|
sizeof(*sections[0].banks) * minNbBanks);
|
||||||
for (uint32_t i = sections[section->type].nbBanks; i < minNbBanks; i++) {
|
for (uint32_t i = sections[section->type].nbBanks; i < minNbBanks; i++) {
|
||||||
sections[section->type].banks[i].sections = NULL;
|
sections[section->type].banks[i].sections = NULL;
|
||||||
@@ -92,7 +92,7 @@ void out_AddSection(struct Section const *section)
|
|||||||
if (!sections[section->type].banks)
|
if (!sections[section->type].banks)
|
||||||
err("Failed to realloc 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
|
struct SortedSection **ptr = section->size
|
||||||
? §ions[section->type].banks[targetBank].sections
|
? §ions[section->type].banks[targetBank].sections
|
||||||
: §ions[section->type].banks[targetBank].zeroLenSections;
|
: §ions[section->type].banks[targetBank].zeroLenSections;
|
||||||
@@ -173,7 +173,7 @@ static void coverOverlayBanks(uint32_t nbOverlayBanks)
|
|||||||
|
|
||||||
if (nbUncoveredBanks > sections[SECTTYPE_ROMX].nbBanks) {
|
if (nbUncoveredBanks > sections[SECTTYPE_ROMX].nbBanks) {
|
||||||
sections[SECTTYPE_ROMX].banks =
|
sections[SECTTYPE_ROMX].banks =
|
||||||
realloc(sections[SECTTYPE_ROMX].banks,
|
(struct SortedSections *)realloc(sections[SECTTYPE_ROMX].banks,
|
||||||
sizeof(*sections[SECTTYPE_ROMX].banks) * nbUncoveredBanks);
|
sizeof(*sections[SECTTYPE_ROMX].banks) * nbUncoveredBanks);
|
||||||
if (!sections[SECTTYPE_ROMX].banks)
|
if (!sections[SECTTYPE_ROMX].banks)
|
||||||
err("Failed to realloc banks for overlay");
|
err("Failed to realloc banks for overlay");
|
||||||
@@ -376,7 +376,7 @@ static void writeSymBank(struct SortedSections const *bankSections,
|
|||||||
if (!nbSymbols)
|
if (!nbSymbols)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct SortedSymbol *symList = malloc(sizeof(*symList) * nbSymbols);
|
struct SortedSymbol *symList = (struct SortedSymbol *)malloc(sizeof(*symList) * nbSymbols);
|
||||||
|
|
||||||
if (!symList)
|
if (!symList)
|
||||||
err("Failed to allocate symbol list");
|
err("Failed to allocate symbol list");
|
||||||
@@ -604,7 +604,7 @@ static void cleanupSections(struct SortedSection *section)
|
|||||||
|
|
||||||
static void cleanup(void)
|
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)) {
|
||||||
for (uint32_t i = 0; i < sections[type].nbBanks; i++) {
|
for (uint32_t i = 0; i < sections[type].nbBanks; i++) {
|
||||||
struct SortedSections *bank = §ions[type].banks[i];
|
struct SortedSections *bank = §ions[type].banks[i];
|
||||||
|
|
||||||
@@ -6,14 +6,15 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "link/object.h"
|
#include "link/object.hpp"
|
||||||
#include "link/patch.h"
|
#include "link/patch.hpp"
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
#include "link/symbol.h"
|
#include "link/symbol.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "opmath.h"
|
#include "opmath.hpp"
|
||||||
|
#include "platform.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an "empty"-type stack. Apart from the actual values, we also remember
|
* This is an "empty"-type stack. Apart from the actual values, we also remember
|
||||||
@@ -33,8 +34,8 @@ struct RPNStack {
|
|||||||
static void initRPNStack(void)
|
static void initRPNStack(void)
|
||||||
{
|
{
|
||||||
stack.capacity = 64;
|
stack.capacity = 64;
|
||||||
stack.values = malloc(sizeof(*stack.values) * stack.capacity);
|
stack.values = (int32_t *)malloc(sizeof(*stack.values) * stack.capacity);
|
||||||
stack.errorFlags = malloc(sizeof(*stack.errorFlags) * stack.capacity);
|
stack.errorFlags = (bool *)malloc(sizeof(*stack.errorFlags) * stack.capacity);
|
||||||
if (!stack.values || !stack.errorFlags)
|
if (!stack.values || !stack.errorFlags)
|
||||||
err("Failed to init RPN stack");
|
err("Failed to init RPN stack");
|
||||||
}
|
}
|
||||||
@@ -54,9 +55,9 @@ static void pushRPN(int32_t value, bool comesFromError)
|
|||||||
|
|
||||||
stack.capacity *= increase_factor;
|
stack.capacity *= increase_factor;
|
||||||
stack.values =
|
stack.values =
|
||||||
realloc(stack.values, sizeof(*stack.values) * stack.capacity);
|
(int32_t *)realloc(stack.values, sizeof(*stack.values) * stack.capacity);
|
||||||
stack.errorFlags =
|
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
|
// Static analysis tools complain that the capacity might become
|
||||||
// zero due to overflow, but fail to realize that it's caught by
|
// zero due to overflow, but fail to realize that it's caught by
|
||||||
// the overflow check above. Hence the stringent check below.
|
// the overflow check above. Hence the stringent check below.
|
||||||
@@ -133,7 +134,7 @@ static int32_t computeRPNExpr(struct Patch const *patch,
|
|||||||
clearRPNStack();
|
clearRPNStack();
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
enum RPNCommand command = getRPNByte(&expression, &size,
|
enum RPNCommand command = (enum RPNCommand)getRPNByte(&expression, &size,
|
||||||
patch->src, patch->lineNo);
|
patch->src, patch->lineNo);
|
||||||
int32_t value;
|
int32_t value;
|
||||||
|
|
||||||
@@ -534,10 +535,10 @@ static void applyFilePatches(struct Section *section, struct Section *dataSectio
|
|||||||
uint8_t size;
|
uint8_t size;
|
||||||
int32_t min;
|
int32_t min;
|
||||||
int32_t max;
|
int32_t max;
|
||||||
} const types[] = {
|
} const types[PATCHTYPE_INVALID] = {
|
||||||
[PATCHTYPE_BYTE] = {1, -128, 255},
|
AT(PATCHTYPE_BYTE) { 1, -128, 255 },
|
||||||
[PATCHTYPE_WORD] = {2, -32768, 65536},
|
AT(PATCHTYPE_WORD) { 2, -32768, 65536 },
|
||||||
[PATCHTYPE_LONG] = {4, INT32_MIN, INT32_MAX}
|
AT(PATCHTYPE_LONG) { 4, INT32_MIN, INT32_MAX },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isError && (value < types[patch->type].min
|
if (!isError && (value < types[patch->type].min
|
||||||
@@ -7,23 +7,26 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "link/main.h"
|
#include "link/main.hpp"
|
||||||
#include "link/script.h"
|
#include "link/script.hpp"
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
#include "platform.hpp"
|
||||||
|
|
||||||
FILE *linkerScript;
|
FILE *linkerScript;
|
||||||
char *includeFileName;
|
char *includeFileName;
|
||||||
|
|
||||||
static uint32_t lineNo;
|
static uint32_t lineNo;
|
||||||
|
|
||||||
static struct FileNode {
|
struct FileNode {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
char *name;
|
char *name;
|
||||||
} *fileStack;
|
};
|
||||||
|
|
||||||
|
static struct FileNode *fileStack;
|
||||||
|
|
||||||
static uint32_t fileStackSize;
|
static uint32_t fileStackSize;
|
||||||
static uint32_t fileStackIndex;
|
static uint32_t fileStackIndex;
|
||||||
@@ -38,7 +41,7 @@ static void pushFile(char *newFileName)
|
|||||||
if (!fileStackSize) // Init file stack
|
if (!fileStackSize) // Init file stack
|
||||||
fileStackSize = 4;
|
fileStackSize = 4;
|
||||||
fileStackSize *= 2;
|
fileStackSize *= 2;
|
||||||
fileStack = realloc(fileStack, sizeof(*fileStack) * fileStackSize);
|
fileStack = (struct FileNode *)realloc(fileStack, sizeof(*fileStack) * fileStackSize);
|
||||||
if (!fileStack)
|
if (!fileStack)
|
||||||
err("%s(%" PRIu32 "): Internal INCLUDE error",
|
err("%s(%" PRIu32 "): Internal INCLUDE error",
|
||||||
linkerScriptName, lineNo);
|
linkerScriptName, lineNo);
|
||||||
@@ -136,13 +139,14 @@ enum LinkerScriptTokenType {
|
|||||||
TOKEN_INVALID
|
TOKEN_INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
char const *tokenTypes[] = {
|
char const *tokenTypes[TOKEN_INVALID] = {
|
||||||
[TOKEN_NEWLINE] = "newline",
|
AT(TOKEN_NEWLINE) "newline",
|
||||||
[TOKEN_COMMAND] = "command",
|
AT(TOKEN_COMMAND) "command",
|
||||||
[TOKEN_BANK] = "bank command",
|
AT(TOKEN_BANK) "bank command",
|
||||||
[TOKEN_NUMBER] = "number",
|
AT(TOKEN_INCLUDE) NULL,
|
||||||
[TOKEN_STRING] = "string",
|
AT(TOKEN_NUMBER) "number",
|
||||||
[TOKEN_EOF] = "end of file"
|
AT(TOKEN_STRING) "string",
|
||||||
|
AT(TOKEN_EOF) "end of file",
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LinkerScriptCommand {
|
enum LinkerScriptCommand {
|
||||||
@@ -160,15 +164,16 @@ union LinkerScriptTokenAttr {
|
|||||||
char *string;
|
char *string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct LinkerScriptToken {
|
struct LinkerScriptToken {
|
||||||
enum LinkerScriptTokenType type;
|
enum LinkerScriptTokenType type;
|
||||||
union LinkerScriptTokenAttr attr;
|
union LinkerScriptTokenAttr attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static char const * const commands[] = {
|
static char const * const commands[COMMAND_INVALID] = {
|
||||||
[COMMAND_ORG] = "ORG",
|
AT(COMMAND_ORG) "ORG",
|
||||||
[COMMAND_ALIGN] = "ALIGN",
|
AT(COMMAND_ALIGN) "ALIGN",
|
||||||
[COMMAND_DS] = "DS"
|
AT(COMMAND_DS) "DS"
|
||||||
};
|
};
|
||||||
|
|
||||||
static int nextChar(void)
|
static int nextChar(void)
|
||||||
@@ -249,7 +254,7 @@ static struct LinkerScriptToken *nextToken(void)
|
|||||||
|
|
||||||
if (size >= capacity || token.attr.string == NULL) {
|
if (size >= capacity || token.attr.string == NULL) {
|
||||||
capacity *= 2;
|
capacity *= 2;
|
||||||
token.attr.string = realloc(token.attr.string, capacity);
|
token.attr.string = (char *)realloc(token.attr.string, capacity);
|
||||||
if (!token.attr.string)
|
if (!token.attr.string)
|
||||||
err("%s: Failed to allocate memory for string",
|
err("%s: Failed to allocate memory for string",
|
||||||
__func__);
|
__func__);
|
||||||
@@ -265,7 +270,7 @@ static struct LinkerScriptToken *nextToken(void)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if (size >= capacity || str == NULL) {
|
if (size >= capacity || str == NULL) {
|
||||||
capacity *= 2;
|
capacity *= 2;
|
||||||
str = realloc(str, capacity);
|
str = (char *)realloc(str, capacity);
|
||||||
if (!str)
|
if (!str)
|
||||||
err("%s: Failed to allocate memory for token",
|
err("%s: Failed to allocate memory for token",
|
||||||
__func__);
|
__func__);
|
||||||
@@ -287,7 +292,7 @@ static struct LinkerScriptToken *nextToken(void)
|
|||||||
token.type = TOKEN_INVALID;
|
token.type = TOKEN_INVALID;
|
||||||
|
|
||||||
// Try to match a command
|
// 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)) {
|
if (!strcmp(commands[i], str)) {
|
||||||
token.type = TOKEN_COMMAND;
|
token.type = TOKEN_COMMAND;
|
||||||
token.attr.command = i;
|
token.attr.command = i;
|
||||||
@@ -297,7 +302,7 @@ static struct LinkerScriptToken *nextToken(void)
|
|||||||
|
|
||||||
if (token.type == TOKEN_INVALID) {
|
if (token.type == TOKEN_INVALID) {
|
||||||
// Try to match a bank specifier
|
// 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)) {
|
if (!strcmp(sectionTypeInfo[type].name, str)) {
|
||||||
token.type = TOKEN_BANK;
|
token.type = TOKEN_BANK;
|
||||||
token.attr.secttype = type;
|
token.attr.secttype = type;
|
||||||
@@ -379,8 +384,8 @@ struct SectionPlacement *script_NextSection(void)
|
|||||||
lineNo = 1;
|
lineNo = 1;
|
||||||
|
|
||||||
// Init PC for all banks
|
// Init PC for all banks
|
||||||
for (enum SectionType i = 0; i < SECTTYPE_INVALID; i++) {
|
for (enum SectionType i = (enum SectionType)0; i < SECTTYPE_INVALID; i = (enum SectionType)(i + 1)) {
|
||||||
curaddr[i] = malloc(sizeof(*curaddr[i]) * nbbanks(i));
|
curaddr[i] = (uint16_t *)malloc(sizeof(*curaddr[i]) * nbbanks(i));
|
||||||
for (uint32_t b = 0; b < nbbanks(i); b++)
|
for (uint32_t b = 0; b < nbbanks(i); b++)
|
||||||
curaddr[i][b] = sectionTypeInfo[i].startAddr;
|
curaddr[i][b] = sectionTypeInfo[i].startAddr;
|
||||||
}
|
}
|
||||||
@@ -539,6 +544,6 @@ lineend:
|
|||||||
|
|
||||||
void script_Cleanup(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]);
|
free(curaddr[type]);
|
||||||
}
|
}
|
||||||
@@ -9,14 +9,14 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
|
|
||||||
#include "link/assign.h"
|
#include "link/assign.hpp"
|
||||||
#include "link/main.h"
|
#include "link/main.hpp"
|
||||||
#include "link/sdas_obj.h"
|
#include "link/sdas_obj.hpp"
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
#include "link/symbol.h"
|
#include "link/symbol.hpp"
|
||||||
|
|
||||||
enum NumberType {
|
enum NumberType {
|
||||||
HEX = 16, // X
|
HEX = 16, // X
|
||||||
@@ -60,7 +60,7 @@ retry:
|
|||||||
if (i >= *bufLen) {
|
if (i >= *bufLen) {
|
||||||
assert(*bufLen != 0);
|
assert(*bufLen != 0);
|
||||||
*bufLen *= 2;
|
*bufLen *= 2;
|
||||||
*lineBuf = realloc(*lineBuf, *bufLen);
|
*lineBuf = (char *)realloc(*lineBuf, *bufLen);
|
||||||
if (!*lineBuf)
|
if (!*lineBuf)
|
||||||
fatal(where, *lineNo, "Failed to realloc: %s", strerror(errno));
|
fatal(where, *lineNo, "Failed to realloc: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ enum RelocFlags {
|
|||||||
|
|
||||||
void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
||||||
size_t bufLen = 256;
|
size_t bufLen = 256;
|
||||||
char *line = malloc(bufLen);
|
char *line = (char *)malloc(bufLen);
|
||||||
char const *token;
|
char const *token;
|
||||||
|
|
||||||
#define getToken(ptr, ...) do { \
|
#define getToken(ptr, ...) do { \
|
||||||
@@ -230,14 +230,14 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
uint16_t writeIndex;
|
uint16_t writeIndex;
|
||||||
};
|
};
|
||||||
struct FileSection *fileSections = NULL;
|
struct FileSection *fileSections = NULL;
|
||||||
struct Symbol **fileSymbols = malloc(sizeof(*fileSymbols) * expectedNbSymbols);
|
struct Symbol **fileSymbols = (struct Symbol **)malloc(sizeof(*fileSymbols) * expectedNbSymbols);
|
||||||
size_t nbSections = 0, nbSymbols = 0;
|
size_t nbSections = 0, nbSymbols = 0;
|
||||||
|
|
||||||
if (!fileSymbols)
|
if (!fileSymbols)
|
||||||
fatal(where, lineNo, "Failed to alloc file symbols table: %s", strerror(errno));
|
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 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
|
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)
|
if (!data)
|
||||||
fatal(where, lineNo, "Failed to alloc data buffer: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc data buffer: %s", strerror(errno));
|
||||||
@@ -255,12 +255,13 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
case 'A': {
|
case 'A': {
|
||||||
if (nbSections == expectedNbAreas)
|
if (nbSections == expectedNbAreas)
|
||||||
warning(where, lineNo, "Got more 'A' lines than the expected %" PRIu32, 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)
|
if (!fileSections)
|
||||||
fatal(where, lineNo, "Failed to realloc file areas: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to realloc file areas: %s", strerror(errno));
|
||||||
fileSections[nbSections].writeIndex = 0;
|
fileSections[nbSections].writeIndex = 0;
|
||||||
#define curSection (fileSections[nbSections].section)
|
#define curSection (fileSections[nbSections].section)
|
||||||
curSection = malloc(sizeof(*curSection));
|
curSection = (struct Section *)malloc(sizeof(*curSection));
|
||||||
if (!curSection)
|
if (!curSection)
|
||||||
fatal(where, lineNo, "Failed to alloc new area: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc new area: %s", strerror(errno));
|
||||||
|
|
||||||
@@ -297,7 +298,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
if (curSection->modifier == SECTION_NORMAL) {
|
if (curSection->modifier == SECTION_NORMAL) {
|
||||||
size_t len = strlen(where->name) + 1 + strlen(token);
|
size_t len = strlen(where->name) + 1 + strlen(token);
|
||||||
|
|
||||||
curSection->name = malloc(len + 1);
|
curSection->name = (char *)malloc(len + 1);
|
||||||
if (!curSection->name)
|
if (!curSection->name)
|
||||||
fatal(where, lineNo, "Failed to alloc new area's name: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc new area's name: %s", strerror(errno));
|
||||||
sprintf(curSection->name, "%s %s", where->name, sectionName);
|
sprintf(curSection->name, "%s %s", where->name, sectionName);
|
||||||
@@ -363,7 +364,8 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
// `realloc` is dangerous, as sections contain a pointer to `fileSymbols`.
|
// `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!
|
// We can try to be nice, but if the pointer moves, it's game over!
|
||||||
if (nbSymbols >= expectedNbSymbols) {
|
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)
|
if (!newFileSymbols)
|
||||||
fatal(where, lineNo, "Failed to alloc extra symbols: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc extra symbols: %s", strerror(errno));
|
||||||
@@ -372,7 +374,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
// No need to assign, obviously
|
// No need to assign, obviously
|
||||||
}
|
}
|
||||||
#define symbol (fileSymbols[nbSymbols])
|
#define symbol (fileSymbols[nbSymbols])
|
||||||
symbol = malloc(sizeof(*symbol));
|
symbol = (struct Symbol *)malloc(sizeof(*symbol));
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
fatal(where, lineNo, "Failed to alloc symbol: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc symbol: %s", strerror(errno));
|
||||||
|
|
||||||
@@ -434,7 +436,8 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
struct Section *section = fileSections[nbSections - 1].section;
|
struct Section *section = fileSections[nbSections - 1].section;
|
||||||
|
|
||||||
++section->nbSymbols;
|
++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)
|
if (!section->symbols)
|
||||||
fatal(where, lineNo, "Failed to realloc \"%s\"'s symbol list: %s", section->name, strerror(errno));
|
fatal(where, lineNo, "Failed to realloc \"%s\"'s symbol list: %s", section->name, strerror(errno));
|
||||||
section->symbols[section->nbSymbols - 1] = symbol;
|
section->symbols[section->nbSymbols - 1] = symbol;
|
||||||
@@ -455,7 +458,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
for (token = strtok(line, delim); token; token = strtok(NULL, delim)) {
|
for (token = strtok(line, delim); token; token = strtok(NULL, delim)) {
|
||||||
if (dataCapacity == nbBytes) {
|
if (dataCapacity == nbBytes) {
|
||||||
dataCapacity *= 2;
|
dataCapacity *= 2;
|
||||||
data = realloc(data, sizeof(*data) * dataCapacity);
|
data = (uint8_t *)realloc(data, sizeof(*data) * dataCapacity);
|
||||||
if (!data)
|
if (!data)
|
||||||
fatal(where, lineNo, "Failed to realloc data buffer: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to realloc data buffer: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
@@ -468,7 +471,8 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
// Importantly, now we know that `nbBytes != 0`, which means "pending data"
|
// Importantly, now we know that `nbBytes != 0`, which means "pending data"
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R': { // Supposed to directly follow `T`
|
case 'R': {
|
||||||
|
// Supposed to directly follow `T`
|
||||||
if (nbBytes == 0) {
|
if (nbBytes == 0) {
|
||||||
warning(where, lineNo, "'R' line with no 'T' line, ignoring");
|
warning(where, lineNo, "'R' line with no 'T' line, ignoring");
|
||||||
break;
|
break;
|
||||||
@@ -503,7 +507,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);
|
fatal(where, lineNo, "'T' lines which don't append to their section are not supported (%" PRIu16 " != %" PRIu16 ")", addr, *writeIndex);
|
||||||
if (!section->data) {
|
if (!section->data) {
|
||||||
assert(section->size != 0);
|
assert(section->size != 0);
|
||||||
section->data = malloc(section->size);
|
section->data = (uint8_t *)malloc(section->size);
|
||||||
if (!section->data)
|
if (!section->data)
|
||||||
fatal(where, lineNo, "Failed to alloc data for \"%s\": %s", section->name, strerror(errno));
|
fatal(where, lineNo, "Failed to alloc data for \"%s\": %s", section->name, strerror(errno));
|
||||||
}
|
}
|
||||||
@@ -551,7 +555,8 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
warning(where, lineNo, "Unknown reloc flags 0x%x", flags & ~RELOC_ALL_FLAGS);
|
warning(where, lineNo, "Unknown reloc flags 0x%x", flags & ~RELOC_ALL_FLAGS);
|
||||||
|
|
||||||
// Turn this into a Patch
|
// 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)
|
if (!section->patches)
|
||||||
fatal(where, lineNo, "Failed to alloc extra patch for \"%s\"", section->name);
|
fatal(where, lineNo, "Failed to alloc extra patch for \"%s\"", section->name);
|
||||||
struct Patch *patch = §ion->patches[section->nbPatches];
|
struct Patch *patch = §ion->patches[section->nbPatches];
|
||||||
@@ -578,7 +583,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
#define RPN_EXTRA_SIZE (5 + 1 + 5 + 1 + 5 + 1) // >> 8 & $FF, then + <baseValue>
|
#define RPN_EXTRA_SIZE (5 + 1 + 5 + 1 + 5 + 1) // >> 8 & $FF, then + <baseValue>
|
||||||
#define allocPatch(size) do { \
|
#define allocPatch(size) do { \
|
||||||
patch->rpnSize = (size); \
|
patch->rpnSize = (size); \
|
||||||
patch->rpnExpression = malloc(patch->rpnSize + RPN_EXTRA_SIZE); \
|
patch->rpnExpression = (uint8_t *)malloc(patch->rpnSize + RPN_EXTRA_SIZE); \
|
||||||
if (!patch->rpnExpression) \
|
if (!patch->rpnExpression) \
|
||||||
fatal(where, lineNo, "Failed to alloc RPN expression: %s", strerror(errno)); \
|
fatal(where, lineNo, "Failed to alloc RPN expression: %s", strerror(errno)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -649,7 +654,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
baseValue += other->size;
|
baseValue += other->size;
|
||||||
allocPatch(1 + strlen(name) + 1);
|
allocPatch(1 + strlen(name) + 1);
|
||||||
patch->rpnSize = 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)
|
if (!patch->rpnExpression)
|
||||||
fatal(where, lineNo, "Failed to alloc RPN expression: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc RPN expression: %s", strerror(errno));
|
||||||
patch->rpnExpression[0] = RPN_STARTOF_SECT;
|
patch->rpnExpression[0] = RPN_STARTOF_SECT;
|
||||||
@@ -6,12 +6,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "link/main.h"
|
#include "link/main.hpp"
|
||||||
#include "link/section.h"
|
#include "link/section.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "hashmap.h"
|
#include "hashmap.hpp"
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
HashMap sections;
|
HashMap sections;
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
|
|||||||
if (other->data) {
|
if (other->data) {
|
||||||
if (target->data) {
|
if (target->data) {
|
||||||
// Ensure we're not allocating 0 bytes
|
// 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);
|
sizeof(*target->data) * target->size + 1);
|
||||||
if (!target->data)
|
if (!target->data)
|
||||||
errx("Failed to concatenate \"%s\"'s fragments", target->name);
|
errx("Failed to concatenate \"%s\"'s fragments", target->name);
|
||||||
@@ -190,7 +190,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
|
|||||||
void sect_AddSection(struct Section *section)
|
void sect_AddSection(struct Section *section)
|
||||||
{
|
{
|
||||||
// Check if the section already exists
|
// 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 (other) {
|
||||||
if (section->modifier != other->modifier)
|
if (section->modifier != other->modifier)
|
||||||
@@ -4,12 +4,12 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "link/object.h"
|
#include "link/object.hpp"
|
||||||
#include "link/symbol.h"
|
#include "link/symbol.hpp"
|
||||||
#include "link/main.h"
|
#include "link/main.hpp"
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.hpp"
|
||||||
#include "hashmap.h"
|
#include "hashmap.hpp"
|
||||||
|
|
||||||
HashMap symbols;
|
HashMap symbols;
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ static void forEach(void *symbol, void *arg)
|
|||||||
|
|
||||||
void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg)
|
void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg)
|
||||||
{
|
{
|
||||||
struct ForEachSymbolArg callbackArg = { .callback = callback, .arg = arg};
|
struct ForEachSymbolArg callbackArg = { .callback = callback, .arg = arg };
|
||||||
|
|
||||||
hash_ForEach(symbols, forEach, &callbackArg);
|
hash_ForEach(symbols, forEach, &callbackArg);
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg)
|
|||||||
void sym_AddSymbol(struct Symbol *symbol)
|
void sym_AddSymbol(struct Symbol *symbol)
|
||||||
{
|
{
|
||||||
// Check if the symbol already exists
|
// 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) {
|
if (other) {
|
||||||
fprintf(stderr, "error: \"%s\" both in %s from ", symbol->name, symbol->objFileName);
|
fprintf(stderr, "error: \"%s\" both in %s from ", symbol->name, symbol->objFileName);
|
||||||
@@ -1,70 +1,71 @@
|
|||||||
/* SPDX-License-Identifier: MIT */
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.hpp"
|
||||||
|
#include "platform.hpp"
|
||||||
|
|
||||||
// The default values are the most lax, as they are used as-is by RGBASM; only RGBLINK has the full info,
|
// 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.
|
// so RGBASM's job is only to catch unconditional errors earlier.
|
||||||
struct SectionTypeInfo sectionTypeInfo[SECTTYPE_INVALID] = {
|
struct SectionTypeInfo sectionTypeInfo[SECTTYPE_INVALID] = {
|
||||||
[SECTTYPE_ROM0] = {
|
AT(SECTTYPE_WRAM0) {
|
||||||
.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",
|
.name = "WRAM0",
|
||||||
.startAddr = 0xC000,
|
.startAddr = 0xC000,
|
||||||
.size = 0x2000, // Patched to 0x1000 if !isWRA0Mode
|
.size = 0x2000, // Patched to 0x1000 if !isWRA0Mode
|
||||||
.firstBank = 0,
|
.firstBank = 0,
|
||||||
.lastBank = 0,
|
.lastBank = 0,
|
||||||
},
|
},
|
||||||
[SECTTYPE_WRAMX] = {
|
AT(SECTTYPE_VRAM) {
|
||||||
.name = "WRAMX",
|
.name = "VRAM",
|
||||||
.startAddr = 0xD000,
|
.startAddr = 0x8000,
|
||||||
.size = 0x1000,
|
.size = 0x2000,
|
||||||
.firstBank = 1,
|
.firstBank = 0,
|
||||||
.lastBank = 7,
|
.lastBank = 1, // Patched to 0 if isDmgMode
|
||||||
},
|
},
|
||||||
[SECTTYPE_OAM] = {
|
AT(SECTTYPE_ROMX) {
|
||||||
.name = "OAM",
|
.name = "ROMX",
|
||||||
.startAddr = 0xFE00,
|
.startAddr = 0x4000,
|
||||||
.size = 0x00A0,
|
.size = 0x4000,
|
||||||
|
.firstBank = 1,
|
||||||
|
.lastBank = 65535,
|
||||||
|
},
|
||||||
|
AT(SECTTYPE_ROM0) {
|
||||||
|
.name = "ROM0",
|
||||||
|
.startAddr = 0x0000,
|
||||||
|
.size = 0x8000, // Patched to 0x4000 if !is32kMode
|
||||||
.firstBank = 0,
|
.firstBank = 0,
|
||||||
.lastBank = 0,
|
.lastBank = 0,
|
||||||
},
|
},
|
||||||
[SECTTYPE_HRAM] = {
|
AT(SECTTYPE_HRAM) {
|
||||||
.name = "HRAM",
|
.name = "HRAM",
|
||||||
.startAddr = 0xFF80,
|
.startAddr = 0xFF80,
|
||||||
.size = 0x007F,
|
.size = 0x007F,
|
||||||
.firstBank = 0,
|
.firstBank = 0,
|
||||||
.lastBank = 0,
|
.lastBank = 0,
|
||||||
},
|
},
|
||||||
|
AT(SECTTYPE_WRAMX) {
|
||||||
|
.name = "WRAMX",
|
||||||
|
.startAddr = 0xD000,
|
||||||
|
.size = 0x1000,
|
||||||
|
.firstBank = 1,
|
||||||
|
.lastBank = 7,
|
||||||
|
},
|
||||||
|
AT(SECTTYPE_SRAM) {
|
||||||
|
.name = "SRAM",
|
||||||
|
.startAddr = 0xA000,
|
||||||
|
.size = 0x2000,
|
||||||
|
.firstBank = 0,
|
||||||
|
.lastBank = 255,
|
||||||
|
},
|
||||||
|
AT(SECTTYPE_OAM) {
|
||||||
|
.name = "OAM",
|
||||||
|
.startAddr = 0xFE00,
|
||||||
|
.size = 0x00A0,
|
||||||
|
.firstBank = 0,
|
||||||
|
.lastBank = 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
char const * const sectionModNames[] = {
|
char const * const sectionModNames[] = {
|
||||||
[SECTION_NORMAL] = "regular",
|
AT(SECTION_NORMAL) "regular",
|
||||||
[SECTION_UNION] = "union",
|
AT(SECTION_UNION) "union",
|
||||||
[SECTION_FRAGMENT] = "fragment",
|
AT(SECTION_FRAGMENT) "fragment",
|
||||||
};
|
};
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "opmath.h"
|
#include "opmath.hpp"
|
||||||
|
|
||||||
int32_t op_divide(int32_t dividend, int32_t divisor)
|
int32_t op_divide(int32_t dividend, int32_t divisor)
|
||||||
{
|
{
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.hpp"
|
||||||
#include "version.h"
|
#include "version.hpp"
|
||||||
|
|
||||||
// This variable is passed via `-D` from the Makefile, but not from CMake
|
// 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)
|
// (in which `configure_file()` is used on this file to replace some syntax)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
add_executable(randtilegen gfx/randtilegen.c)
|
add_executable(randtilegen gfx/randtilegen.cpp)
|
||||||
|
|
||||||
add_executable(rgbgfx_test gfx/rgbgfx_test.cpp)
|
add_executable(rgbgfx_test gfx/rgbgfx_test.cpp)
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.hpp"
|
||||||
|
|
||||||
#define STR(x) #x
|
#define STR(x) #x
|
||||||
#define XSTR(x) STR(x)
|
#define XSTR(x) STR(x)
|
||||||
@@ -32,7 +32,7 @@ struct Attributes {
|
|||||||
static unsigned long long randbits = 0;
|
static unsigned long long randbits = 0;
|
||||||
static unsigned char randcount = 0;
|
static unsigned char randcount = 0;
|
||||||
|
|
||||||
_Noreturn static void fatal(char const *error) {
|
[[noreturn]] static void fatal(char const *error) {
|
||||||
fprintf(stderr, "FATAL: %s\n", error);
|
fprintf(stderr, "FATAL: %s\n", error);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -189,8 +189,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)
|
uint8_t const SIZEOF_PIXEL = 4; // Each pixel is 4 bytes (RGBA @ 8 bits/component)
|
||||||
assert(width != 0);
|
assert(width != 0);
|
||||||
assert(height != 0);
|
assert(height != 0);
|
||||||
uint8_t *data = malloc(height * 8 * width * 8 * SIZEOF_PIXEL);
|
uint8_t *data = (uint8_t *)malloc(height * 8 * width * 8 * SIZEOF_PIXEL);
|
||||||
uint8_t **rowPtrs = malloc(height * 8 * sizeof(*rowPtrs));
|
uint8_t **rowPtrs = (uint8_t **)malloc(height * 8 * sizeof(*rowPtrs));
|
||||||
if (data == NULL || rowPtrs == NULL) {
|
if (data == NULL || rowPtrs == NULL) {
|
||||||
fatal("Out of memory");
|
fatal("Out of memory");
|
||||||
}
|
}
|
||||||
@@ -299,7 +299,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) {
|
if (!filename) {
|
||||||
fatal("out of memory");
|
fatal("out of memory");
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user