Compare commits

..
22 Commits
Author SHA1 Message Date
ISSOtm 76c1995559 Fix CI 2021-04-01 11:38:07 +02:00
Rangi ae84570f04 Revise RGBASM manual 2021-03-31 18:35:09 -04:00
Rangi 094a31ef8c Update RGBASM command-line manual 2021-03-31 18:17:18 -04:00
ISSOtm 291dcf3b6c Update RGBASM manual 2021-04-01 00:11:41 +02:00
Rangi a890bd072b Fix "INCBIN"
Examples: (...s are optional)

ld [b @:...] = "Dockerfile"
ld [b @:...] = "Dockerfile"[451:...]
ld [b @:...] = "Dockerfile"[23:5]
ld [b @:5] = "Dockerfile"[23:...]
2021-03-31 18:06:14 -04:00
Rangi 2f6c808ccb Revise instruction reference 2021-03-31 17:59:12 -04:00
ISSOtm e80907abd0 Update instruction reference 2021-03-31 23:26:57 +02:00
Rangi 25d39155d3 Support ld a, a±c±LOW(bc) as well as ld a, a±c±c 2021-03-30 12:36:11 -04:00
Rangi 77021d229b Support ld [c], a and ld a, [c] 2021-03-30 12:02:29 -04:00
Rangi 1b250b90b2 Implement ds <len> ==> ld [b @:<len>], ? 2021-03-30 11:54:39 -04:00
Rangi e2b4723489 Fix lexing @ 2021-03-30 11:52:25 -04:00
Rangi 2507413162 Fix lexing a., b., etc 2021-03-30 11:41:44 -04:00
Rangi e023a84d04 Allow 'ld a, a±c±<r8>' or 'ld a, a±<r8>±c' for adc/sbc 2021-03-30 11:27:19 -04:00
Rangi 34c127d9c3 Allow ld [b @:<len>] = "file.bin"[<ofs>:...] 2021-03-30 10:51:48 -04:00
Rangi 9a930988c2 Implement db, dw, dl, ds, and INCBIN with ld
To do: let the `b` in `ld [b @]` be optional, and allow
`ld [b @:<len>] = "file.bin"[<ofs>:...]`
2021-03-30 10:47:05 -04:00
Rangi 8c4204c542 Make 'w' and '...' tokens, and make '@' a separate token
Now '@' is valid as a relocexpr_no_str, in 'BANK(@)', and
in 'DEF(@)', but not in general T_ID or T_LABEL contexts

This will make it easier to implement INCBIN with 'ld'
2021-03-30 10:17:09 -04:00
Rangi 663c1930ec Factor out 'ld a, a+c+' and 'ld a, a-c-' prefixes
This fixes all the shift/reduce and reduce/reduce conflicts
2021-03-30 09:57:08 -04:00
Rangi 30ccf43f44 Factor out individual 'ld <r16>,' prefixes 2021-03-30 09:43:34 -04:00
Rangi fdc17adbcb Factor out common ld a, prefix 2021-03-30 09:19:58 -04:00
Rangi cc196954f3 Consolidate some parser rules with reg_ss and reg_r
There are now 5 shift/reduce conflicts and 3 reduce/reduce conflicts
2021-03-29 20:52:24 -04:00
Rangi 55b6cfff84 Prevent GitHub Actions from running any workflows 2021-03-29 19:50:13 -04:00
Rangi 1fc73b04eb Parse ld instructions as discussed
There are 13 shift/reduce conflicts, so some instructions
may need different formats.

This also does not yet implement `db`, `dw`, `dl`, `ds`,
or `INCBIN` using `ld`.

The `lexerState->nextToken` solution to lexing something
like "a.2" as three tokens instead of one identifier
is taken from the first commit in rgbds PR #799.
2021-03-29 19:42:18 -04:00
2153 changed files with 26864 additions and 50974 deletions
+88
View File
@@ -0,0 +1,88 @@
# Configuration for checkpatch.pl
# ===============================
# Enable more tests
--strict
# Quiet
--quiet
# No per-file summary
--no-summary
# Don't expect the Linux kernel tree
--no-tree
# Show file line, not input line
--showfile
# Don't expect SPDX tag in the first line of a file
--ignore SPDX_LICENSE_TAG
# Don't expect Signed-off-by lines in commit messages
--no-signoff
# List of ignored rules
# ---------------------
# There's no BIT macro
--ignore BIT_MACRO
# Don't complain when bools are used in structs
--ignore BOOL_MEMBER
# Allow CamelCase
--ignore CAMELCASE
# Comparing to NULL explicitly isn't a bad thing
--ignore COMPARISON_TO_NULL
# Causes false positives
--ignore COMPLEX_MACRO
# Don't complain about structs not being const
--ignore CONST_STRUCT
# Don't complain about printing "warning:" without the function name, as warning
# printing is relevant to the code being parsed, not RGBDS' code
--ignore EMBEDDED_FUNCTION_NAME
# Do not check the format of commit messages
--ignore GIT_COMMIT_ID
# Do not check for global initializers (this is specific to the kernel)
--ignore GLOBAL_INITIALISERS
# Don't complain about initializing statics (this is specific to the kernel)
--ignore INITIALISED_STATIC
# We don't have a MAINTAINERS file, don't complain about it.
--ignore FILE_PATH_CHANGES
# Writing the continuation on the start of the line can make it clearer
--ignore LOGICAL_CONTINUATIONS
# Don't complain if a line that contains a string is too long. It's better to
# have a really long line that can be found with grep.
--ignore LONG_LINE_STRING
# Don't complain when files are modified in 'include/asm'
--ignore MODIFIED_INCLUDE_ASM
# Allow new typedefs
--ignore NEW_TYPEDEFS
# We allow lines ending with parentheses for the usage prints
--ignore OPEN_ENDED_LINE
# Prefer stdint.h types over kernel types
--ignore PREFER_KERNEL_TYPES
# Don't ask to replace sscanf by kstrto
--ignore SSCANF_TO_KSTRTO
# Parentheses can make the code clearer
--ignore UNNECESSARY_PARENTHESES
# We don't have `fallthrough;` */
--ignore PREFER_FALLTHROUGH
-106
View File
@@ -1,106 +0,0 @@
AccessModifierOffset: -4
AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: Left
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: Consecutive
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: Consecutive
AlignEscapedNewlines: DontAlign
AlignOperands: Align
AlignTrailingComments: true
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros:
- format_
- attr_
BinPackArguments: false
BinPackParameters: false
BitFieldColonSpacing: Both
BreakAfterAttributes: Always
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Attach
BreakBeforeConceptDeclarations: true
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: AfterComma
BreakStringLiterals: true
ColumnLimit: 100
CompactNamespaces: false
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
EmptyLineBeforeAccessModifier: Leave
FixNamespaceComments: false
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<sys/'
Priority: 0
- Regex: '^<'
Priority: 1
- Regex: '^"extern/'
Priority: 2
- Regex: '^"(asm|link|fix|gfx)/'
Priority: 3
- Regex: '^"'
Priority: 2
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: Indent
IndentGotoLabels: false
IndentPPDirectives: BeforeHash
IndentRequires: true
IndentWidth: 4
IndentWrappedFunctionNames: true
InsertBraces: true
InsertNewlineAtEOF: true
# Only support for Javascript as of clang-format 14...
# InsertTrailingCommas: Wrapped
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
Language: Cpp
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PPIndentWidth: -1
PenaltyBreakScopeResolution: 1000
PointerAlignment: Right
QualifierAlignment: Right
ReflowComments: true
RemoveParentheses: ReturnStatement
RemoveSemicolon: true
SortIncludes: CaseSensitive
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceAroundPointerQualifiers: Both
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: c++20
TabWidth: 4
UseCRLF: false
UseTab: ForIndentation
-6
View File
@@ -1,6 +0,0 @@
---
Checks: ''
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none
SystemHeaders: false
+5
View File
@@ -1,2 +1,7 @@
# This file is part of RGBDS.
#
# Copyright (c) 2018-2019, Phil Smith and RGBDS contributors.
#
# SPDX-License-Identifier: MIT
.git
docs
-18
View File
@@ -1,18 +0,0 @@
root = true
[*]
indent_style = tab
indent_size = tab
tab_width = 4
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
[{CMakeLists.txt,*.cmake}]
indent_style = space
indent_size = 2
[*.yml]
indent_style = space
indent_size = 2
-19
View File
@@ -1,19 +0,0 @@
# This file contains a list of commits that are probably not what you
# are looking for in a `git blame`, such as mass reformatting or renaming.
#
# You can set this file as a default ignore file for `git blame` by running
# the following command:
#
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs
# 2024-03-04: Run `clang-format` on everything
e74073e4805fa3cce90a99946fc9994ae2970f9b
# 2009-06-11: Run `indent' on the whole tree
b6c749ffbd30138de7beef13fb9265372a461a96
# 2009-06-11: Switch line terminators from CRLF to LF
94fad97aedcd8bd85c53a505db28390e3f82577b
# 2009-06-11: Use spaces instead of tabs after CPP directives
0d9739535e313b0a2ad19c89b9c85fc7b75237a3
-19
View File
@@ -1,19 +0,0 @@
# Shell scripts need Unix line endings (see https://github.com/gbdev/rgbds/issues/841)
*.sh text eol=lf
*.bash text eol=lf
*.cfg text eol=lf
# Flags also need Unix line endings (see https://github.com/gbdev/rgbds/issues/955)
*.flags text eol=lf
# Binary files need exact bytes
*.bin binary
*.gb binary
*.1bpp binary
*.2bpp binary
*.pal binary
*.attrmap binary
*.tilemap binary
*.palmap binary
*.patch binary
*.png binary
+3
View File
@@ -0,0 +1,3 @@
github: avivace
patreon: gbdev01
open_collective: gbdev
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/awk -f
/^\s+<td><b class="Sy">.+<\/b><\/td>$/ {
# Assuming that all cells whose contents are bold are heading cells,
# use the HTML tag for those
sub(/td><b class="Sy"/, "th");
sub(/b><\/td/, "th");
}
# The whole page is being generated, so it's not meant to contain any Liquid
BEGIN {
print "{% raw %}"
}
END {
print "{% endraw %}"
}
BEGIN {
in_synopsis = 0
}
/<table class="Nm">/ {
in_synopsis = 1
}
/<\/table>/ {
# Resets synopsis state even when already reset, but whatever
in_synopsis = 0
}
/<code class="Fl">-[a-zA-Z]/ {
# Add links to arg descr in synopsis section
if (in_synopsis) {
while (match($0, /<code class="Fl">-[a-zA-Z]+/)) {
# 123456789012345678 -> 18 chars
optchars = substr($0, RSTART + 18, RLENGTH - 18)
i = length(optchars)
while (i) {
end = RSTART + 18 + i
i -= 1
len = i ? 1 : 2
$0 = sprintf("%s<a href=\"#%s\">%s</a>%s",
substr($0, 0, end - len - 1),
substr($0, end - 1, 1),
substr($0, end - len, len),
substr($0, end))
}
}
}
}
{
# Make long opts (defined using `Fl Fl`) into a single tag
gsub(/<code class="Fl">-<\/code>\s*<code class="Fl">/, "<code class=\"Fl\">-")
}
{
print
}
+113
View File
@@ -0,0 +1,113 @@
#!/bin/bash
usage() {
cat <<EOF
Usage: $0 [-h] [-r] <rgbds-www> <version>
Copy renders from RGBDS repository to rgbds-www documentation
Execute from the root folder of the RGBDS repo, checked out at the desired tag
<rgbds-www> : Path to the rgbds-www repository
<version> : Version to be copied, such as 'v0.4.1' or 'master'
-h Display this help message
-r Update "latest stable" redirection pages and add a new entry to the index
(use for releases, not master)
EOF
}
is_release=0
bad_usage=0
while getopts ":hr" opt; do
case $opt in
r)
is_release=1
;;
h)
usage
exit 0
;;
\?)
echo "Unknown option '$OPTARG'"
bad_usage=1
;;
esac
done
if [ $bad_usage -ne 0 ]; then
usage
exit 1
fi
shift $(($OPTIND - 1))
declare -A PAGES
PAGES=(
[rgbasm.1.html]=src/asm/rgbasm.1
[rgbasm.5.html]=src/asm/rgbasm.5
[rgblink.1.html]=src/link/rgblink.1
[rgblink.5.html]=src/link/rgblink.5
[rgbfix.1.html]=src/fix/rgbfix.1
[rgbgfx.1.html]=src/gfx/rgbgfx.1
[rgbds.5.html]=src/rgbds.5
[rgbds.7.html]=src/rgbds.7
[gbz80.7.html]=src/gbz80.7
)
WWWPATH="/docs"
mkdir -p "$1/_documentation/$2"
# `mandoc` uses a different format for referring to man pages present in the **current** directory.
# We want that format for RGBDS man pages, and the other one for the rest;
# we thus need to copy all pages to a temporary directory, and process them there.
# Copy all pages to current dir
cp "${PAGES[@]}" .
for page in "${!PAGES[@]}"; do
stem="${page%.html}"
manpage="${stem%.?}(${stem#*.})"
descr="$(awk -v 'FS=.Nd ' '/.Nd/ { print $2; }' "${PAGES[$page]}")"
cat >"$1/_documentation/$2/$page" <<EOF
---
layout: doc
title: $manpage [$2]
description: RGBDS $2 — $descr
---
EOF
options=fragment,man='%N.%S;https://linux.die.net/man/%S/%N'
if [ $stem = rgbasm.5 ]; then
options+=,toc
fi
mandoc -Thtml -I os=Linux -O$options "${PAGES[$page]##*/}" | .github/actions/doc_postproc.awk >> "$1/_documentation/$2/$page"
groff -Tpdf -mdoc -wall "${PAGES[$page]##*/}" >"$1/_documentation/$2/$stem.pdf"
if [ $is_release -ne 0 ]; then
cat - >"$1/_documentation/$page" <<EOF
---
redirect_to: $WWWPATH/$2/${page%.html}
permalink: $WWWPATH/${page%.html}/
title: $manpage [latest stable]
description: RGBDS latest stable — $descr
---
EOF
fi
done
cat - >"$1/_documentation/$2/index.html" <<EOF
---
layout: doc_index
permalink: /docs/$2/
title: RGBDS online manual [$2]
description: RGBDS $2 - Online manual
---
EOF
# If making a release, add a new entry right after `master`
if [ $is_release -ne 0 ]; then
awk '{ print }
/"name": "master"/ { print "\t\t{\"name\": \"'$2'\", \"text\": \"'$2'\" }," }
' "$1/_data/doc.json" >"$1/_data/doc.json.tmp"
mv "$1/_data/doc.json"{.tmp,}
fi
# Clean up
rm "${PAGES[@]##*/}"
+18
View File
@@ -0,0 +1,18 @@
case `echo $1 | cut -d '-' -f 1` in
ubuntu)
sudo apt-get -qq update
sudo apt-get install -yq bison libpng-dev pkg-config
;;
macos)
brew install bison libpng pkg-config md5sha1sum
# For the version check below exclusively, re-do this before building
export PATH="/usr/local/opt/bison/bin:$PATH"
;;
*)
echo "WARNING: Cannot install deps for OS '$1'"
;;
esac
bison --version
make --version
cmake --version
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
source mingw-env @TRIPLE@
echo LAST IS: $last
# check if last arg is a path to configure, else use parent
for last; do true; done
if test -x "${last}/configure"; then
config_path="$last"
else
config_path=".."
fi
${config_path}/configure \
--host=@TRIPLE@ --target=@TRIPLE@ --build="$CHOST" \
--prefix=/usr/@TRIPLE@ --libdir=/usr/@TRIPLE@/lib --includedir=/usr/@TRIPLE@/include \
--enable-shared --enable-static "$@"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/sh
_arch=$1
default_mingw_pp_flags="-D_FORTIFY_SOURCE=2"
default_mingw_compiler_flags="$default_mingw_pp_flags -O2 -pipe -fno-plt -fexceptions --param=ssp-buffer-size=4"
default_mingw_linker_flags="-Wl,-O1,--sort-common,--as-needed -fstack-protector"
export CPPFLAGS="${MINGW_CPPFLAGS:-$default_mingw_pp_flags $CPPFLAGS}"
export CFLAGS="${MINGW_CFLAGS:-$default_mingw_compiler_flags $CFLAGS}"
export CXXFLAGS="${MINGW_CXXFLAGS:-$default_mingw_compiler_flags $CXXFLAGS}"
export LDFLAGS="${MINGW_LDFLAGS:-$default_mingw_linker_flags $LDFLAGS}"
mingw_prefix=/usr/${_arch}
export PKG_CONFIG_SYSROOT_DIR="${mingw_prefix}"
export PKG_CONFIG_LIBDIR="${mingw_prefix}/lib/pkgconfig:${mingw_prefix}/share/pkgconfig"
+44
View File
@@ -0,0 +1,44 @@
#!/bin/sh
# This script was written by ISSOtm while looking at Arch Linux's PKGBUILD for
# the corresponding package. (And its dependencies)
# https://aur.archlinux.org/packages/mingw-w64-libpng/
set -e
pngver=1.6.37
_apngver=$pngver
_arch="$1"
## Install mingw-configure and mingw-env (both build dependencies)
install -m 755 .github/actions/mingw-env.sh /usr/bin/mingw-env
sed "s|@TRIPLE@|${_arch}|g" .github/actions/mingw-configure.sh > ${_arch}-configure
install -m 755 ${_arch}-configure /usr/bin/
## Grab sources and check them
wget http://downloads.sourceforge.net/sourceforge/libpng/libpng-$pngver.tar.xz
wget http://downloads.sourceforge.net/project/apng/libpng/libpng16/libpng-$_apngver-apng.patch.gz
sha256sum -c .github/actions/mingw-w64-libpng-dev.sha256sums
## Extract sources
tar -xf libpng-$pngver.tar.xz
gunzip libpng-$_apngver-apng.patch.gz
## Start building!
cd libpng-$pngver
# Patch in apng support
patch -p0 ../libpng-$_apngver-apng.patch
mkdir -p build-${_arch}
cd build-${_arch}
${_arch}-configure LDFLAGS=-static-libgcc
make
make install
@@ -0,0 +1,2 @@
10d9e0cb60e2b387a79b355eb7527c0bee2ed8cbd12cf04417cabc4d6976683c libpng-1.6.37-apng.patch.gz
505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca libpng-1.6.37.tar.xz
+25
View File
@@ -0,0 +1,25 @@
name: "Code style checking"
on: pull_request
jobs:
checkpatch:
runs-on: ubuntu-latest
steps:
- name: Set up repo
run: |
git clone -b "${{ github.event.pull_request.head.ref }}" "${{ github.event.pull_request.head.repo.clone_url }}" rgbds
cd rgbds
git remote add upstream "${{ github.event.pull_request.base.repo.clone_url }}"
git fetch upstream
- name: Set up checkpatch
working-directory: rgbds
run: |
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/checkpatch.pl'
chmod +x checkpatch.pl
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/const_structs.checkpatch'
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/spelling.txt'
- name: Checkpatch
working-directory: rgbds
run: |
make checkpatch CHECKPATCH=./checkpatch.pl "BASE_REF=${{ github.event.pull_request.base.sha }}" Q= | tee log
if grep -q ERROR: log; then exit 1; else exit 0; fi
@@ -0,0 +1,52 @@
name: "Create release docs"
on:
release:
types:
- released # This avoids triggering on pre-releases
jobs:
build:
runs-on: ubuntu-18.04
steps:
- name: Checkout rgbds@release
uses: actions/checkout@v2
with:
path: rgbds
- name: Checkout rgbds-www@master
uses: actions/checkout@v2
with:
repository: ${{ github.repository_owner }}/rgbds-www
path: rgbds-www
# `-O toc` was added in 1.14.5, but the repos only have 1.14.4
- name: Build and install mandoc + install groff
run: |
sudo apt-get -qq update
sudo apt-get install -yq groff zlib1g-dev
wget 'http://mandoc.bsd.lv/snapshots/mandoc-1.14.5.tar.gz'
tar xf mandoc-1.14.5.tar.gz
cd mandoc-1.14.5
./configure
make
sudo make install
- name: Update pages
working-directory: rgbds
run: | # The ref appears to be in the format "refs/tags/<version>", so strip that
./.github/actions/get-pages.sh -r ../rgbds-www ${GITHUB_REF##*/}
- name: Push new pages
working-directory: rgbds-www
run: |
mkdir -p -m 700 ~/.ssh
cat > ~/.ssh/id_ed25519 <<<"${{ secrets.SSH_KEY_SECRET }}"
chmod 0600 ~/.ssh/id_ed25519
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_ed25519
git config --global user.name "GitHub Action"
git config --global user.email "[email protected]"
git add -A
git commit -m "Create RGBDS ${GITHUB_REF##*/} documentation"
if git remote | grep -q origin; then
git remote set-url origin [email protected]:${{ github.repository_owner }}/rgbds-www.git
else
git remote add origin [email protected]:${{ github.repository_owner }}/rgbds-www.git
fi
git push origin master
+200
View File
@@ -0,0 +1,200 @@
name: "Regression testing"
on:
- push
- pull_request
jobs:
unix-testing:
strategy:
matrix:
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-16.04, macos-10.15]
cc: [gcc, clang]
buildsys: [make, cmake]
include:
- os: ubuntu-18.04
cc: gcc
target: develop
cmakevars: -DSANITIZERS=ON -DMORE_WARNINGS=ON -DCMAKE_BUILD_TYPE=Debug
- os: ubuntu-20.04
cc: gcc
target: develop
cmakevars: -DSANITIZERS=ON -DMORE_WARNINGS=ON -DCMAKE_BUILD_TYPE=Debug
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Install deps
shell: bash
run: |
./.github/actions/install_deps.sh ${{ matrix.os }}
# The `export` lines are to allow working on macOS...
# Apple's base version is severely outdated, not even supporting -Wall,
# but it overrides Homebrew's version nonetheless...
- name: Build & install using Make
run: |
export PATH="/usr/local/opt/bison/bin:$PATH"
make ${{ matrix.target }} -j Q= CC=${{ matrix.cc }}
sudo make install -j Q=
if: matrix.buildsys == 'make'
- name: Build & install using CMake
run: |
export PATH="/usr/local/opt/bison/bin:$PATH"
cmake -S . -B build -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${{ matrix.cc }} ${{ matrix.cmakevars }}
cmake --build build
cp build/src/rgb{asm,link,fix,gfx} .
sudo cmake --install build
if: matrix.buildsys == 'cmake'
- name: Package binaries
run: |
mkdir bins
cp rgb{asm,link,fix,gfx} bins
- name: Upload binaries
uses: actions/upload-artifact@v1
with:
name: rgbds-canary-${{ matrix.os }}-${{ matrix.cc }}-${{ matrix.buildsys }}
path: bins
- name: Test
shell: bash
run: |
test/run-tests.sh
windows-testing:
strategy:
matrix:
bits: [32, 64]
include:
- bits: 32
arch: x86
platform: Win32
- bits: 64
arch: x86_x64
platform: x64
fail-fast: false
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Get zlib, libpng and bison
run: | # TODO: use an array
$wc = New-Object System.Net.WebClient
$wc.DownloadFile('https://www.zlib.net/zlib1211.zip', 'zlib.zip')
$hash = (Get-FileHash "zlib.zip" -Algorithm SHA256).Hash
if ($hash -ne 'd7510a8ee1918b7d0cad197a089c0a2cd4d6df05fee22389f67f115e738b178d') {
Write-Host "zlib SHA256 mismatch! ($hash)"
exit 1
}
$wc.DownloadFile('https://download.sourceforge.net/libpng/lpng1637.zip', 'libpng.zip')
$hash = (Get-FileHash "libpng.zip" -Algorithm SHA256).Hash
if ($hash -ne '3b4b1cbd0bae6822f749d39b1ccadd6297f05e2b85a83dd2ce6ecd7d09eabdf2') {
Write-Host "libpng SHA256 mismatch! ($hash)"
exit 1
}
$wc.DownloadFile('https://github.com/lexxmark/winflexbison/releases/download/v2.5.23/win_flex_bison-2.5.23.zip', 'winflexbison.zip')
$hash = (Get-FileHash "winflexbison.zip" -Algorithm SHA256).Hash
if ($hash -ne '6AA5C8EA662DA1550020A5804C28BE63FFAA53486DA9F6842E24C379EC422DFC') {
Write-Host "bison SHA256 mismatch! ($hash)"
}
Expand-Archive -DestinationPath . "zlib.zip"
Expand-Archive -DestinationPath . "libpng.zip"
Expand-Archive -DestinationPath install_dir "winflexbison.zip"
Move-Item zlib-1.2.11 zlib
Move-Item lpng1637 libpng
- name: Build zlib
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
cmake -S zlib -B zbuild -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
cmake --build zbuild --config Release
cmake --install zbuild
- name: Build libpng
run: |
cmake -S libpng -B pngbuild -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
cmake --build pngbuild --config Release
cmake --install pngbuild
- name: Build Windows binaries
run: |
cmake -S . -B build -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
cmake --install build
- name: Package binaries
shell: bash
run: |
mkdir bins
cp install_dir/bin/{rgbasm.exe,rgblink.exe,rgbfix.exe,rgbgfx.exe,zlib1.dll,libpng16.dll} bins
- name: Upload Windows binaries
uses: actions/upload-artifact@v1
with:
name: rgbds-canary-win${{ matrix.bits }}
path: bins
- name: Test
shell: bash
run: |
cp bins/* .
test/run-tests.sh
windows-xbuild:
strategy:
matrix:
bits: [32, 64]
os: [ubuntu-18.04]
include:
- bits: 32
arch: i686
triplet: i686-w64-mingw32
- bits: 64
arch: x86-64
triplet: x86_64-w64-mingw32
fail-fast: false
runs-on: ${{ matrix.os }}
env:
DIST_DIR: win${{ matrix.bits }}
steps:
- uses: actions/checkout@v2
- name: Install deps
shell: bash
run: |
./.github/actions/install_deps.sh ${{ matrix.os }}
- name: Install MinGW
run: |
sudo apt-get install gcc-mingw-w64-${{ matrix.arch }} mingw-w64-tools libz-mingw-w64-dev
- name: Install libpng dev headers for MinGW
run: |
sudo ./.github/actions/mingw-w64-libpng-dev.sh ${{ matrix.triplet }}
- name: Cross-build Windows binaries
run: |
make mingw${{ matrix.bits }} -j Q=
- name: Package binaries
run: |
mkdir bins
mv rgbasm bins/rgbasm.exe
mv rgblink bins/rgblink.exe
mv rgbfix bins/rgbfix.exe
mv rgbgfx bins/rgbgfx.exe
cp /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
cp /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
if [ ${{ matrix.bits }} -eq 32 ]; then cp /usr/lib/gcc/${{ matrix.triplet }}/7.3-win32/libgcc_s_sjlj-1.dll bins; fi
- name: Upload Windows binaries
uses: actions/upload-artifact@v1
with:
name: rgbds-canary-mingw-win${{ matrix.bits }}
path: bins
windows-xtesting:
needs: windows-xbuild
strategy:
matrix:
bits: [32, 64]
fail-fast: false
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Retrieve binaries
uses: actions/download-artifact@v1
with:
name: rgbds-canary-mingw-win${{ matrix.bits }}
path: bins
- name: Extract binaries
shell: bash
run: |
cp bins/* .
- name: Run tests
shell: bash
run: |
test/run-tests.sh
@@ -0,0 +1,65 @@
name: "Update master docs"
on:
push:
branches:
- master
paths:
- .github/actions/get-pages.sh
- src/gbz80.7
- src/rgbds.5
- src/rgbds.7
- src/asm/rgbasm.1
- src/asm/rgbasm.5
- src/link/rgblink.1
- src/link/rgblink.5
- src/fix/rgbfix.1
- src/gfx/rgbgfx.1
jobs:
build:
runs-on: ubuntu-18.04
steps:
- name: Checkout rgbds@master
uses: actions/checkout@v2
with:
repository: gbdev/rgbds
ref: master
path: rgbds
- name: Checkout rgbds-www@master
uses: actions/checkout@v2
with:
repository: gbdev/rgbds-www
ref: master
path: rgbds-www
- name: Build and install mandoc + install groff
run: |
sudo apt-get -qq update
sudo apt-get install -yq groff zlib1g-dev
wget 'http://mandoc.bsd.lv/snapshots/mandoc-1.14.5.tar.gz'
tar xf mandoc-1.14.5.tar.gz
cd mandoc-1.14.5
./configure
make
sudo make install
- name: Update pages
working-directory: rgbds
run: |
./.github/actions/get-pages.sh ../rgbds-www master
- name: Push new pages
working-directory: rgbds-www
run: |
mkdir -p -m 700 ~/.ssh
echo "${{ secrets.SSH_KEY_SECRET }}" > ~/.ssh/id_ed25519
chmod 0600 ~/.ssh/id_ed25519
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_ed25519
git config --global user.name "GitHub Action"
git config --global user.email "[email protected]"
git add .
git commit -m "Update RGBDS master documentation"
if git remote | grep -q origin; then
git remote set-url origin [email protected]:gbdev/rgbds-www.git
else
git remote add origin [email protected]:gbdev/rgbds-www.git
fi
git push origin master
-2
View File
@@ -1,2 +0,0 @@
open_collective: gbdev
github: gbdev
-4
View File
@@ -1,4 +0,0 @@
---
name: Update to RGBDS
about: Suggest a feature or report a bug in RGBDS.
---
-5
View File
@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: GBDev Discord
url: https://discord.gg/RjJKA8wrD4
about: If you have questions about the RGBDS code or its organization, join our Discord server!
-19
View File
@@ -1,19 +0,0 @@
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "quarterly" # We do not need *immediate* bumps, only frequent enough to avoid falling out of support range.
cooldown: # Avoid bumping deps immediately, to give time for security audits to be conducted
default-days: 15
include: [ "*" ]
groups:
actions:
patterns: [ "*" ]
ignore:
- dependency-name: "*"
update-types:
- "version-update:semver-minor"
- "version-update:semver-patch"
labels: [ builds ] # Since those are CI-related updates...
-8
View File
@@ -1,8 +0,0 @@
#!/usr/bin/env sh
set -eu
bash --version
zsh --version
find contrib -type f \( -name '*.sh' -o -name '*.bash' \) -exec bash --norc -n {} \;
find contrib/zsh_compl -type f -name '_rgb*' -exec zsh -n {} \;
-93
View File
@@ -1,93 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
declare -A FILES
while IFS= read -r -d '' file; do
FILES["$file"]=true
done < <(git diff --name-only -z "$1" HEAD)
edited () {
${FILES["$1"]:-false}
}
dependency () {
if edited "$1" && ! edited "$2"; then
echo "'$1' was modified, but not '$2'! $3"
fi
}
# Pull requests that edit the first file without the second may be correct,
# but are suspicious enough to require review.
dependency include/linkdefs.hpp man/rgbds.5 \
"Was the object file format changed?"
dependency src/asm/parser.y man/rgbasm.5 \
"Was the rgbasm grammar changed?"
dependency src/asm/actions.cpp man/rgbasm.5 \
"Was the rgbasm grammar changed?"
dependency src/link/script.y man/rgblink.5 \
"Was the linker script grammar changed?"
dependency src/link/layout.cpp man/rgblink.5 \
"Was the linker script grammar changed?"
dependency include/asm/warning.hpp man/rgbasm.1 \
"Were the rgbasm warnings changed?"
dependency include/link/warning.hpp man/rgblink.1 \
"Were the rgblink warnings changed?"
dependency include/fix/warning.hpp man/rgbfix.1 \
"Were the rgbfix warnings changed?"
dependency include/gfx/warning.hpp man/rgbgfx.1 \
"Were the rgbgfx warnings changed?"
dependency src/asm/object.cpp include/linkdefs.hpp \
"Should the object file revision be bumped?"
dependency src/link/object.cpp include/linkdefs.hpp \
"Should the object file revision be bumped?"
dependency Makefile CMakeLists.txt \
"Did the build process change?"
dependency Makefile src/CMakeLists.txt \
"Did the build process change?"
dependency src/asm/main.cpp man/rgbasm.1 \
"Did the rgbasm CLI change?"
dependency src/asm/main.cpp contrib/zsh_compl/_rgbasm \
"Did the rgbasm CLI change?"
dependency src/asm/main.cpp contrib/bash_compl/_rgbasm.bash \
"Did the rgbasm CLI change?"
dependency src/link/main.cpp man/rgblink.1 \
"Did the rgblink CLI change?"
dependency src/link/main.cpp contrib/zsh_compl/_rgblink \
"Did the rgblink CLI change?"
dependency src/link/main.cpp contrib/bash_compl/_rgblink.bash \
"Did the rgblink CLI change?"
dependency src/fix/main.cpp man/rgbfix.1 \
"Did the rgbfix CLI change?"
dependency src/fix/main.cpp contrib/zsh_compl/_rgbfix \
"Did the rgbfix CLI change?"
dependency src/fix/main.cpp contrib/bash_compl/_rgbfix.bash \
"Did the rgbfix CLI change?"
dependency src/gfx/main.cpp man/rgbgfx.1 \
"Did the rgbgfx CLI change?"
dependency src/gfx/main.cpp contrib/zsh_compl/_rgbgfx \
"Did the rgbgfx CLI change?"
dependency src/gfx/main.cpp contrib/bash_compl/_rgbgfx.bash \
"Did the rgbgfx CLI change?"
dependency test/external/fetch-repos.sh docs/CONTRIBUTING.md \
"Did the test protocol change?"
dependency test/run-tests.sh docs/CONTRIBUTING.md \
"Did the test protocol change?"
dependency test/asm/test.sh docs/CONTRIBUTING.md \
"Did the RGBASM test protocol change?"
dependency test/link/test.sh docs/CONTRIBUTING.md \
"Did the RGBLINK test protocol change?"
dependency test/fix/test.sh docs/CONTRIBUTING.md \
"Did the RGBFIX test protocol change?"
dependency test/gfx/test.sh docs/CONTRIBUTING.md \
"Did the RGBGFX test protocol change?"
-15
View File
@@ -1,15 +0,0 @@
#!/usr/bin/env sh
# SPDX-License-Identifier: MIT
clang-format --version
find . -type f -iname '*.[ch]pp' -exec clang-format -i {} +
if ! git diff-index --quiet HEAD --; then
echo 'Unformatted files:'
git diff-index --name-only HEAD --
echo
git diff HEAD --
exit 1
fi
-25
View File
@@ -1,25 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
tag=$1
[ $# -eq 1 ]
flags=(--draft --fail-on-no-commits --verify-tag)
if [[ "$tag" = v*-rc* ]]; then
flags+=(--prerelease)
fi
files=(
win64/rgbds-win64.zip
win32/rgbds-win32.zip
macos/rgbds-macos.zip
linux/rgbds-linux-x86_64.tar.xz
rgbds-source.tar.gz
)
set -x
gh release create "${flags[@]}" --notes-file - "$tag" "${files[@]}" <<"EOF"
Please ensure that the packages below work properly.
Once that's done, replace this text with the changelog, un-draft the release, and update the `release` branch.
By the way, if you forgot to update `include/version.hpp`, RGBASM's version test is going to fail in the tag's regression testing! (Use `git push --delete origin <tag>` to delete it)
EOF
-11
View File
@@ -1,11 +0,0 @@
#!/usr/bin/env sh
local_bin_dir="$PWD/.local/bin"
mkdir -p "$local_bin_dir"
# Alias `make` to `gmake` and `python` to `python3` for use by external tests.
ln -s "$(which gmake)" "$local_bin_dir/make"
ln -s "$(which python3)" "$local_bin_dir/python"
export PATH="$local_bin_dir:$PATH"
-102
View File
@@ -1,102 +0,0 @@
#!/bin/sh
# This script requires `sh` instead of `bash` because the latter is not always installed on FreeBSD.
set -eu
# Python and the Pillow library are dependencies for libbet, a repo built by our external tests.
# Other dependencies are for building rgbds itself.
case $# in
1) OS="$1"; TOOLSET= ;;
2) OS="$1"; TOOLSET="$2" ;;
*) echo >&2 "Usage: $0 <os> [<toolset>]" && exit 1 ;;
esac
case "${OS%%-*}" in
ubuntu|debian)
pkgs=bison
case "$TOOLSET" in
mingw32)
pkgs="$pkgs libz-mingw-w64-dev g++-mingw-w64-i686-win32"
TOOLSET=
;;
mingw64)
pkgs="$pkgs libz-mingw-w64-dev g++-mingw-w64-x86-64-win32"
TOOLSET=
;;
g++-10 | lcov)
pkgs="$pkgs libpng-dev pkgconf python3-pil $TOOLSET"
TOOLSET=
;;
'' | g++ | clang++)
pkgs="$pkgs libpng-dev pkgconf python3-pil"
TOOLSET=
;;
esac
sudo apt-get update -qq
# shellcheck disable=SC2086 # (This word splitting is intentional.)
sudo apt-get install -yq $pkgs
;;
macos)
pkgs="bison make pillow"
case "$TOOLSET" in
lld)
pkgs="$pkgs $TOOLSET"
TOOLSET=
;;
clang++)
TOOLSET=
;;
esac
# macOS bundles GNU Make 3.81, which doesn't support synced output.
# We leave it as the default in `PATH`, to test that our Makefile works with it.
# However, CMake automatically uses Homebrew's `gmake`, so our CI has synced output.
# shellcheck disable=SC2086 # (This word splitting is intentional.)
brew install $pkgs
# Export `bison` to allow using the version we install from Homebrew,
# instead of the outdated one preinstalled on macOS (which doesn't even support `-Wall`...).
export PATH="$(brew --prefix)/opt/bison/bin:$PATH"
printf 'PATH=%s\n' "$PATH" >>"$GITHUB_ENV" # Make it available to later CI steps too.
;;
freebsd)
# GNU `gmake` and `gcc` are dependencies for most repos built by our external tests.
pkg install -y bash bison cmake ninja git png gmake lang/gcc python3 py312-pillow
;;
windows)
# GitHub Actions' hosted runners ship CMake 3.x, but versions prior to 4.0.0 ignore `CPACK_PACKAGE_FILE_NAME`.
choco install -y winflexbison3 cmake
# The version-printing code below will invoke `bison`, not the Windows-specific name `win_bison`.
bison() { win_bison "$@"; } # An alias doesn't work, so we use a function instead.
py -3 -m pip install pillow
;;
windowsmingw)
py -3 -m pip install pillow
;;
*)
echo "Cannot install deps for OS '$1'"
exit 1
;;
esac
if [ -n "$TOOLSET" ]; then
printf >&2 'Unknown toolset `%s` for OS `%s`\n' "$TOOLSET" "$OS"
exit 1
fi
# We do not build RGBDS *in* MinGW on Windows, so skip printing build tool info.
if [ "$OS" = "windowsmingw" ]; then
exit 0
fi
# Print some system info, for easier debugging.
# https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands#grouping-log-lines
echo ::group::PATH
echo "PATH=($PATH)" | sed 's/:/\n /g'
echo ::endgroup::
for prog in bison make cmake; do
printf '::group::' # No line terminator, the next command's first line becomes the group's title.
$prog --version
type $prog
echo ::endgroup::
done
-4
View File
@@ -1,4 +0,0 @@
@rem From https://github.com/microsoft/vswhere/wiki/Start-Developer-Command-Prompt#using-batch
for /f "delims=" %%p in ('vswhere.exe -prerelease -latest -property installationPath') do set vspath=%%p
@rem From https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#developer_command_file_locations
call "%vspath%\VC\Auxiliary\Build\vcvars%1.bat"
-59
View File
@@ -1,59 +0,0 @@
name: Build container image
on:
push:
branches:
- master
tags:
- '*'
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
jobs:
publish-docker-image:
if: github.repository_owner == 'gbdev'
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push the master container image
if: github.ref == 'refs/heads/master'
run: |
COMMIT_HASH=$(git rev-parse --short HEAD)
sed -i "2i LABEL org.opencontainers.image.description=\"RGBDS container image, containing the git version master:$COMMIT_HASH\"" Dockerfile
docker build . --tag ghcr.io/gbdev/rgbds:master
docker push ghcr.io/gbdev/rgbds:master
- name: Build and push the version-tagged container image
if: startsWith(github.ref, 'refs/tags/')
run: |
TAG_NAME=${GITHUB_REF#refs/tags/}
sed -i "2i LABEL org.opencontainers.image.description=\"RGBDS container image for the release version $TAG_NAME\"" Dockerfile
docker build . --tag ghcr.io/gbdev/rgbds:$TAG_NAME
docker tag ghcr.io/gbdev/rgbds:$TAG_NAME ghcr.io/gbdev/rgbds:latest
docker push ghcr.io/gbdev/rgbds:$TAG_NAME
docker push ghcr.io/gbdev/rgbds:latest
- name: Delete untagged container images
if: github.repository_owner == 'gbdev'
uses: Chizkiyahu/delete-untagged-ghcr-action@v6
with:
# Requires a personal access token with delete:packages permissions
token: ${{ secrets.PAT_TOKEN }}
package_name: 'rgbds'
untagged_only: true
except_untagged_multiplatform: true
owner_type: 'org'
-23
View File
@@ -1,23 +0,0 @@
name: Contrib script syntax checking
on:
- push
- pull_request
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
jobs:
check-contrib:
runs-on: ubuntu-slim
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install zsh
run: |
sudo apt install -Uyq zsh
- name: Check contrib scripts
run: |
.github/scripts/check-contrib.sh
-27
View File
@@ -1,27 +0,0 @@
name: Diff completeness check
on: pull_request
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
jobs:
check-diff:
runs-on: ubuntu-slim
steps:
- name: Clone repo
uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Check diff
shell: bash # Bash is the default, but specifying it explicitly enables `-o pipefail`.
run: |
MERGE_BASE=$(gh api "/repos/{owner}/{repo}/compare/$BASE_SHA...$HEAD_SHA" --jq '.merge_base_commit.sha')
git fetch origin "$MERGE_BASE"
.github/scripts/check-diff.bash "$MERGE_BASE" | sed -E 's/^/::warning::/'
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
GH_TOKEN: ${{ github.token }}
-21
View File
@@ -1,21 +0,0 @@
name: Code format checking
on: pull_request
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
jobs:
check-format:
runs-on: ubuntu-slim
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install clang-format
run: |
sudo apt install -Uyq clang-format
- name: Check format
run: |
.github/scripts/check-format.sh
-33
View File
@@ -1,33 +0,0 @@
name: Code coverage report
on:
- push
- pull_request
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install deps
run: |
.github/scripts/install-deps.sh ubuntu-latest lcov
- name: Generate coverage report
run: |
contrib/coverage.bash --os ubuntu-latest --jobs "$(getconf _NPROCESSORS_ONLN)"
- name: Upload coverage report
uses: actions/upload-artifact@v7
with:
name: coverage-report
# Workaround for keeping the top-level coverage/ directory
# https://github.com/actions/upload-artifact/issues/174
path: |
coverage
dummy-file-to-keep-directory-structure.txt
if-no-files-found: error
@@ -0,0 +1,96 @@
name: "Create release artifacts"
on:
push:
tags:
- v[0-9]*
jobs:
windows:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Get version from tag
shell: bash
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
VERSION="${{ github.ref }}"
echo "version=${VERSION##*/v}" >> $GITHUB_ENV
- name: Get zlib, libpng and bison
run: | # TODO: use an array
$wc = New-Object System.Net.WebClient
$wc.DownloadFile('https://www.zlib.net/zlib1211.zip', 'zlib.zip')
$hash = (Get-FileHash "zlib.zip" -Algorithm SHA256).Hash
if ($hash -ne 'd7510a8ee1918b7d0cad197a089c0a2cd4d6df05fee22389f67f115e738b178d') {
Write-Host "zlib SHA256 mismatch! ($hash)"
exit 1
}
$wc.DownloadFile('https://download.sourceforge.net/libpng/lpng1637.zip', 'libpng.zip')
$hash = (Get-FileHash "libpng.zip" -Algorithm SHA256).Hash
if ($hash -ne '3b4b1cbd0bae6822f749d39b1ccadd6297f05e2b85a83dd2ce6ecd7d09eabdf2') {
Write-Host "libpng SHA256 mismatch! ($hash)"
exit 1
}
$wc.DownloadFile('https://github.com/lexxmark/winflexbison/releases/download/v2.5.23/win_flex_bison-2.5.23.zip', 'winflexbison.zip')
$hash = (Get-FileHash "winflexbison.zip" -Algorithm SHA256).Hash
if ($hash -ne '6AA5C8EA662DA1550020A5804C28BE63FFAA53486DA9F6842E24C379EC422DFC') {
Write-Host "bison SHA256 mismatch! ($hash)"
}
Expand-Archive -DestinationPath . "zlib.zip"
Expand-Archive -DestinationPath . "libpng.zip"
Expand-Archive -DestinationPath install_dir "winflexbison.zip"
Move-Item zlib-1.2.11 zlib
Move-Item lpng1637 libpng
- name: Build 32-bit zlib
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
cmake -S zlib -B zbuild32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
cmake --build zbuild32 --config Release
cmake --install zbuild32
- name: Build 32-bit libpng
run: |
cmake -S libpng -B pngbuild32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
cmake --build pngbuild32 --config Release
cmake --install pngbuild32
- name: Build 32-bit Windows binaries
run: |
cmake -S . -B build32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
cmake --build build32 --config Release
cmake --install build32
- name: Package 32-bit binaries
run: |
Compress-Archive -LiteralPath @("install_dir/bin/rgbasm.exe", "install_dir/bin/rgblink.exe", "install_dir/bin/rgbfix.exe", "install_dir/bin/rgbgfx.exe", "install_dir/bin/zlib1.dll", "install_dir/bin/libpng16.dll") "rgbds-${{ env.version }}-win32.zip"
- name: Build 64-bit zlib
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
cmake -S zlib -B zbuild64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
cmake --build zbuild64 --config Release
cmake --install zbuild64
- name: Build 64-bit libpng
run: |
cmake -S libpng -B pngbuild64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
cmake --build pngbuild64 --config Release
cmake --install pngbuild64
- name: Build 64-bit Windows binaries
run: |
cmake -S . -B build64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
cmake --build build64 --config Release
cmake --install build64
- name: Package 64-bit binaries
run: |
Compress-Archive -LiteralPath @("install_dir/bin/rgbasm.exe", "install_dir/bin/rgblink.exe", "install_dir/bin/rgbfix.exe", "install_dir/bin/rgbgfx.exe", "install_dir/bin/zlib1.dll", "install_dir/bin/libpng16.dll") "rgbds-${{ env.version }}-win64.zip"
- name: Package sources
run: |
make dist
- name: Release
uses: softprops/action-gh-release@v1
with:
body: |
Please ensure that the three assets below work properly.
Once that's done, replace this text with the changelog, un-draft the release, and update the `release` branch.
By the way, if you forgot to update `include/version.h`, RGBASM's version test is gonna fail in the tag's regression testing! (Use `git push --delete origin <tag>` to delete it)
draft: true # Don't publish the release quite yet...
prerelease: ${{ contains(github.ref, '-rc') }}
files: |
rgbds-${{ env.version }}-win32.zip
rgbds-${{ env.version }}-win64.zip
rgbds-${{ env.version }}.tar.gz
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1,125 +0,0 @@
name: Create release artifacts
on:
push:
tags:
- v[0-9]*
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
CMAKE_COLOR_DIAGNOSTICS: ON # Tells CMake-generated build systems to have colored output.
CMAKE_BUILD_TYPE: Release # `cmake -S` now implies `-DCMAKE_BUILD_TYPE=Release`.
CMAKE_CONFIG_TYPE: Release # `cmake --build` now implies `--config Release`.
# We instruct CMake to download and build third-party projects in the same place as in `testing.yml`
# to prevent divergence between testing and release workflows.
DEPS_ROOT_DIR: ~/_deps
# We use Ninja as the generator for CMake below because it provides synchronous output by default,
# and only shows full command lines when they fail.
jobs:
windows:
runs-on: windows-2022
strategy:
matrix:
bits: [32, 64]
fail-fast: false
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install deps
run: |
bash .github/scripts/install-deps.sh windows
- name: Build Windows binaries
shell: cmd
run: |
call .github\scripts\msvc-env.bat ${{ matrix.bits }}
cmake -B build -G Ninja -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}" -DCMAKE_C_FLAGS="/nologo"
cmake --build build -- -k 0
- name: Package binaries
working-directory: build
run: |
cpack -DCPACK_PACKAGE_FILE_NAME=rgbds-win${{ matrix.bits }} -G ZIP --verbose
- name: Upload Windows binaries
uses: actions/upload-artifact@v7
with:
name: win${{ matrix.bits }}
path: build/rgbds-win${{ matrix.bits }}.zip
if-no-files-found: error
macos:
runs-on: macos-26
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install deps
run: |
./.github/scripts/install-deps.sh macos lld
- name: Build binaries
run: |
cmake -B build -G Ninja --preset macos-static -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}"
cmake --build build -- -k 0
strip rgb{asm,link,fix,gfx}
env:
LDFLAGS: -fuse-ld=lld # cmake/macos-static.cmake comments explain why we use lld.
- name: Create install script
run: |
make install.sh
- name: Package binaries
run: |
zip --junk-paths rgbds-macos.zip rgb{asm,link,fix,gfx} man/* install.sh
- name: Upload macOS binaries
uses: actions/upload-artifact@v7
with:
name: macos
path: rgbds-macos.zip
if-no-files-found: error
linux:
runs-on: ubuntu-22.04 # Oldest supported, for best glibc compatibility.
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install deps
run: |
./.github/scripts/install-deps.sh ubuntu-22.04
- name: Build binaries
run: |
make -k -j "$(getconf _NPROCESSORS_ONLN)" WARNFLAGS="-Wall -Wextra -pedantic -static" PKG_CONFIG="pkg-config --static" Q=
strip rgb{asm,link,fix,gfx}
- name: Create install script
run: |
make install.sh Q=
- name: Package binaries
run: |
tar caf rgbds-linux-x86_64.tar.xz --transform='s#.*/##' rgb{asm,link,fix,gfx} man/* install.sh
- name: Upload Linux binaries
uses: actions/upload-artifact@v7
with:
name: linux
path: rgbds-linux-x86_64.tar.xz
if-no-files-found: error
release:
runs-on: ubuntu-slim
needs: [windows, macos, linux]
permissions:
contents: write
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Package sources
run: |
make dist Q=
- name: Download all binary packages
uses: actions/download-artifact@v8
- name: Draft the release
run: |
.github/scripts/draft-release.sh "${ref#refs/tags/}"
env:
ref: ${{ github.ref_name }}
GH_TOKEN: ${{ github.token }} # Required by the `gh` command.
-48
View File
@@ -1,48 +0,0 @@
name: Create release docs
on:
release:
types:
- released # This avoids triggering on pre-releases
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
jobs:
build:
if: github.repository_owner == 'gbdev'
runs-on: ubuntu-slim
steps:
- name: Checkout rgbds@release
uses: actions/checkout@v7
with:
path: rgbds
sparse-checkout: man # Avoid checking out other files, we don't use them here.
- name: Checkout rgbds-www
uses: actions/checkout@v7
with:
path: rgbds-www
repository: ${{ github.repository_owner }}/rgbds-www
ref: master # Need to check out the branch to be able to commit on and push it.
ssh-key: !!str ${{ secrets.SSH_KEY_SECRET }}
- name: Install groff and mandoc
run: |
sudo apt install -Uyq groff mandoc -o APT::Color=yes -o Acquire::Queue-Mode=access
- name: Update pages
working-directory: rgbds/man
run: | # The ref appears to be in the format "refs/tags/<version>", so strip that
../../rgbds-www/maintainer/man_to_html.sh ${GITHUB_REF##*/} *
../../rgbds-www/maintainer/new_release.sh ${GITHUB_REF##*/}
- name: Push new pages
working-directory: rgbds-www
env:
GIT_AUTHOR_NAME: !!str ${{ github.actor }}
GIT_AUTHOR_EMAIL: !!str ${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
run: |
git add -A
git commit -m "Create RGBDS ${GITHUB_REF##*/} documentation"
git push
-451
View File
@@ -1,451 +0,0 @@
name: Regression testing
on:
- push
- pull_request
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
CMAKE_COLOR_DIAGNOSTICS: ON # Tells CMake-generated build systems to have colored output.
CMAKE_CONFIG_TYPE: Debug # `cmake --build` now implies `--config Debug`.
CTEST_PARALLEL_LEVEL: "" # `ctest` now implies `--parallel` (default number of logical CPUs).
CTEST_NO_TESTS_ACTION: error # Make CTest fail if it cannot find any tests. (That should never happen.)
CTEST_OUTPUT_ON_FAILURE: ON # CTest reports test program output on failure.
GIT_CONFIG_COUNT: 1
GIT_CONFIG_KEY_0: color.ui
GIT_CONFIG_VALUE_0: always # Colorful output is helpful even though CI is not considered to be a terminal.
# We instruct CMake to download and build third-party projects outside of our source tree,
# otherwise they can trigger `-Werror=dev` (from the `develop` preset).
DEPS_ROOT_DIR: ~/_deps # Note that this needs to be used in a position where Bash will trigger tilde expansion!
# We use bash syntax across OSes for consistency unless otherwise specified
defaults:
run:
shell: bash
# We use Ninja as the generator for CMake below because it provides synchronous output by default,
# and only shows full command lines when they fail.
jobs:
unix:
strategy:
matrix:
os: [ubuntu-22.04, macos-15-intel, macos-26]
cxx: [g++, clang++]
buildsys: [make, cmake]
exclude: # Don't use `g++` on macOS; it's just an alias to `clang++`.
- { os: macos-15-intel, cxx: g++ }
- { os: macos-26, cxx: g++ }
include: # Use `g++-10`, the earliest GCC version we support, on the earliest Ubuntu runner.
- { os: ubuntu-22.04, cxx: g++-10, buildsys: make }
- { os: ubuntu-22.04, cxx: g++-10, buildsys: cmake }
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install deps
run: |
.github/scripts/install-deps.sh ${{ matrix.os }} ${{ matrix.cxx }}
- name: Build using Make
if: matrix.buildsys == 'make'
run: |
make develop -k -j "$(getconf _NPROCESSORS_ONLN)" Q= CXX=${{ matrix.cxx }}
- name: Install using Make
if: matrix.buildsys == 'make'
run: |
sudo make install Q=
type rgbasm rgblink rgbfix rgbgfx
man -w 1 rgbasm rgblink rgbfix rgbgfx
- name: Build using CMake
if: matrix.buildsys == 'cmake'
# Since GitHub's runners are basically kitchen sinks,
# the Mono framework exposes a libpng 1.4.x header, breaking everything.
# Searching frameworks last makes Homebrew's libpng be discovered first, which works.
# Note that since this is specific to our CI environment, the workaround is
# better applied here than in our CMakeLists, where it could affect and break someone else.
run: |
CXX=${{ matrix.cxx }} cmake -B build -G Ninja --preset develop -DCMAKE_FIND_FRAMEWORK=LAST
cmake --build build -- -k 0
- name: Install using CMake
if: matrix.buildsys == 'cmake'
run: |
sudo cmake --install build --verbose
type rgbasm rgblink rgbfix rgbgfx
man -w 1 rgbasm rgblink rgbfix rgbgfx
- name: Package binaries
run: |
mkdir bins
cp rgb{asm,link,fix,gfx} bins
- name: Upload binaries
uses: actions/upload-artifact@v7
with:
name: rgbds-canary-${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.buildsys }}
path: bins
if-no-files-found: error
- name: Compute test dependency cache params
id: test-deps-cache-params
run: |
paths=$(test/external/fetch-repos.sh --get-paths)
hash=$(test/external/fetch-repos.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v5
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: ${{ matrix.os }}-${{ steps.test-deps-cache-params.outputs.hash }}
- name: Fetch test dependency repositories
if: steps.test-deps-cache.outputs.cache-hit != 'true'
continue-on-error: true
run: |
test/external/fetch-repos.sh
- name: Run tests using our script
if: matrix.buildsys == 'make'
run: |
CXX=${{ matrix.cxx }} test/run-tests.sh --os ${{ matrix.os }} --jobs "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests using CTest
if: matrix.buildsys == 'cmake'
run: |
ctest --test-dir build --schedule-random
macos-static:
runs-on: macos-26
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install deps
run: |
.github/scripts/install-deps.sh macos lld
- name: Cache library deps
uses: actions/cache@v5
with:
path: ${{ env.DEPS_ROOT_DIR }}/*-tmp/
key: dep-srcs-${{ hashFiles('cmake/deps.cmake') }}
enableCrossOsArchive: true
- name: Build
run: |
cmake -B build -G Ninja --preset macos-static -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}"
cmake --build build -- -k 0
env:
LDFLAGS: -fuse-ld=lld # cmake/macos-static.cmake comments explain why we use lld.
- name: Install
run: |
sudo cmake --install build --verbose
type rgbasm rgblink rgbfix rgbgfx
man -w 1 rgbasm rgblink rgbfix rgbgfx
- name: Package binaries
run: |
mkdir bins
cp rgb{asm,link,fix,gfx} bins
- name: Upload binaries
uses: actions/upload-artifact@v7
with:
name: rgbds-canary-macos-static
path: bins
if-no-files-found: error
- name: Compute test dependency cache params
id: test-deps-cache-params
run: |
paths=$(test/external/fetch-repos.sh --get-paths)
hash=$(test/external/fetch-repos.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v5
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: macos-26-${{ steps.test-deps-cache-params.outputs.hash }}
- name: Fetch test dependency repositories
if: steps.test-deps-cache.outputs.cache-hit != 'true'
continue-on-error: true
run: |
test/external/fetch-repos.sh
- name: Run tests
run: |
ctest --test-dir build --schedule-random
windows:
strategy:
matrix:
bits: [32, 64]
os: [windows-2022, windows-2025]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install deps
run: |
bash .github/scripts/install-deps.sh ${{ matrix.os }}
- name: Cache library deps
uses: actions/cache@v5
with:
path: ${{ env.DEPS_ROOT_DIR }}/*-tmp/
key: dep-srcs-${{ hashFiles('cmake/deps.cmake') }}
enableCrossOsArchive: true
- name: Build
shell: cmd
run: | # ASan seems to be broken on Windows, so we disable it.
call .github\scripts\msvc-env.bat ${{ matrix.bits }}
cmake -B build -G Ninja --preset develop -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}" ^
-DSANITIZERS=OFF -DCMAKE_C_FLAGS="/nologo"
cmake --build build -- -k 0
- name: Install
shell: cmd
run: |
cmake --install build --verbose
where rgbasm rgblink rgbfix rgbgfx
- name: Package binaries
working-directory: build
run: |
cpack -DCPACK_PACKAGE_FILE_NAME=rgbds-win${{ matrix.bits }} -G ZIP --verbose
- name: Upload Windows binaries
uses: actions/upload-artifact@v7
with:
name: rgbds-canary-w${{ matrix.bits }}-${{ matrix.os }}
path: build/rgbds-win${{ matrix.bits }}.zip
if-no-files-found: error
- name: Compute test dependency cache params
id: test-deps-cache-params
run: |
paths=$(test/external/fetch-repos.sh --get-paths)
hash=$(test/external/fetch-repos.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v5
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: ${{ matrix.os }}-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }}
- name: Fetch test dependency repositories
if: steps.test-deps-cache.outputs.cache-hit != 'true'
continue-on-error: true
run: |
test/external/fetch-repos.sh
- name: Run tests using CTest
run: |
ctest --test-dir build --schedule-random
windows-mingw-build:
strategy:
matrix:
bits: [32, 64]
fail-fast: false
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install deps
run: |
.github/scripts/install-deps.sh ubuntu mingw${{ matrix.bits }}
- name: Cache library deps
uses: actions/cache@v5
with:
path: ${{ env.DEPS_ROOT_DIR }}/*-tmp/
key: dep-srcs-${{ hashFiles('cmake/deps.cmake') }}
enableCrossOsArchive: true
- name: Cross-build Windows binaries
run: | # MinGW doesn't support `--preset develop` sanitizers ASan or UBSan, so we disable them.
dll_search_dir=$(printf '%s\n' /usr/lib/gcc/*-w64-mingw32/*-win32 | tee -a /dev/stderr)
cmake -B build -G Ninja --preset develop -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}" \
-DSANITIZERS=OFF -DDLL_SEARCH_DIRS="$dll_search_dir" \
--toolchain cmake/toolchain-mingw${{ matrix.bits }}.cmake
cmake --build build -- -k 0
- name: Package Windows binaries
run: |
cmake --install build --prefix . --verbose --component binaries
cmake --install build --prefix . --verbose --component shared-libs
- name: Upload Windows binaries
uses: actions/upload-artifact@v7
with:
name: rgbds-canary-mingw-win${{ matrix.bits }}
path: bin
if-no-files-found: error
- name: Upload Windows test binaries
uses: actions/upload-artifact@v7
with:
name: testing-programs-mingw-win${{ matrix.bits }}
path: |
test/gfx/randtilegen.exe
test/gfx/rgbgfx_test.exe
if-no-files-found: error
windows-mingw-testing:
needs: windows-mingw-build
strategy:
matrix:
os: [windows-2022, windows-2025]
bits: [32, 64]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install test deps
run: |
.github/scripts/install-deps.sh windowsmingw
- name: Retrieve binaries
uses: actions/download-artifact@v8
with:
name: rgbds-canary-mingw-win${{ matrix.bits }}
path: bins
- name: Retrieve test binaries
uses: actions/download-artifact@v8
with:
name: testing-programs-mingw-win${{ matrix.bits }}
path: test/gfx
- name: Extract binaries
run: |
cp bins/* .
cp bins/*.dll test/gfx
- name: Compute test dependency cache params
id: test-deps-cache-params
run: |
paths=$(test/external/fetch-repos.sh --get-paths)
hash=$(test/external/fetch-repos.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v5
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: mingw-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }}
- name: Fetch test dependency repositories
if: steps.test-deps-cache.outputs.cache-hit != 'true'
continue-on-error: true
run: |
test/external/fetch-repos.sh
- name: Run tests
run: |
test/run-tests.sh --os ${{ matrix.os }} --jobs "$(getconf _NPROCESSORS_ONLN)"
cygwin:
strategy:
matrix:
arch: [x86, x86_64]
fail-fast: false
runs-on: windows-2022
timeout-minutes: 30
env:
CYGWIN_NOWINPATH: 1
CHERE_INVOKING: 1
defaults:
run:
shell: C:\cygwin\bin\bash.exe -leo igncr '{0}'
steps:
- name: Save Windows git location for the PATH
shell: pwsh
run: | # The `cygwin/cygwin-install-action` step will override the PATH with Cygwin's binaries
"ORIGINAL_GIT_DIR=$(Split-Path (Get-Command git).Source)" >> $env:GITHUB_ENV
- name: Checkout repo
uses: actions/checkout@v7
- name: Setup Cygwin
uses: cygwin/cygwin-install-action@v6
with:
platform: ${{ matrix.arch }}
packages: >-
bison
cmake
gcc-g++
git
libpng-devel
make
ninja
pkg-config
python3
python-imaging
- name: Build using Make
if: matrix.arch == 'x86'
run: | # Cygwin doesn't support `make develop` sanitizers ASan or UBSan, so we don't use it.
make -k -j "$(getconf _NPROCESSORS_ONLN)" Q=
- name: Install using Make
if: matrix.arch == 'x86'
run: |
make install Q=
type rgbasm rgblink rgbfix rgbgfx
man -w 1 rgbasm rgblink rgbfix rgbgfx
- name: Build using CMake
if: matrix.arch == 'x86_64'
run: | # Cygwin doesn't support `--preset develop` sanitizers ASan or UBSan, so we disable them.
cmake -B build -G Ninja --preset develop -DSANITIZERS=OFF
cmake --build build -- -k 0
- name: Install using CMake
if: matrix.arch == 'x86_64'
run: |
cmake --install build --verbose
type rgbasm rgblink rgbfix rgbgfx
man -w 1 rgbasm rgblink rgbfix rgbgfx
- name: Compute test dependency cache params
id: test-deps-cache-params
run: |
paths=$(test/external/fetch-repos.sh --get-paths)
hash=$(test/external/fetch-repos.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v5
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: cygwin-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }}
- name: Fetch test dependency repositories
if: steps.test-deps-cache.outputs.cache-hit != 'true'
continue-on-error: true
run: |
test/external/fetch-repos.sh
- name: Run tests using our script
if: matrix.arch == 'x86'
run: | # 32-bit Cygwin's `git` 2.38 doesn't support `git clone --revision`, so we don't fetch/run external tests.
test/run-tests.sh --os cygwin --only-internal --jobs "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests using CTest
if: matrix.arch == 'x86_64'
run: |
ctest --test-dir build --schedule-random
- name: Use Windows git location in the PATH
shell: pwsh
run: | # Prevents the `actions/checkout` post-job cleanup from using Cygwin's git binary
"$env:ORIGINAL_GIT_DIR" >> $env:GITHUB_PATH
freebsd:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Build & test using CMake on FreeBSD
uses: vmactions/freebsd-vm@v1
with:
envs: >-
TERM CLICOLOR CLICOLOR_FORCE
CMAKE_COLOR_DIAGNOSTICS CMAKE_CONFIG_TYPE
CTEST_PARALLEL_LEVEL
CTEST_NO_TESTS_ACTION CTEST_OUTPUT_ON_FAILURE
GIT_CONFIG_COUNT GIT_CONFIG_KEY_0 GIT_CONFIG_VALUE_0
release: "15.1"
usesh: true
copyback: false
prepare: |
.github/scripts/install-deps.sh freebsd
run: |
: # Build
cmake -B build -G Ninja --preset develop
cmake --build build -- -k 0
: # Install
cmake --install build --verbose
type rgbasm rgblink rgbfix rgbgfx
man -w 1 rgbasm rgblink rgbfix rgbgfx
: # Run tests
: # Leak detection is not supported on FreeBSD, so we disable it.
. .github/scripts/freebsd-env.sh
ASAN_OPTIONS=detect_leaks=0 ctest --test-dir build --schedule-random
-50
View File
@@ -1,50 +0,0 @@
name: Update master docs
on:
push:
branches:
- master
paths:
- man/*
workflow_dispatch:
env:
# Force colored output (see https://bixense.com/clicolors/ and https://force-color.org/)
TERM: xterm-256color
CLICOLOR: 1
CLICOLOR_FORCE: 1
jobs:
build:
if: github.repository_owner == 'gbdev'
runs-on: ubuntu-slim
steps:
- name: Checkout rgbds
uses: actions/checkout@v7
with:
path: rgbds
sparse-checkout: man # Avoid checking out other files, we don't use them here.
- name: Checkout rgbds-www
uses: actions/checkout@v7
with:
path: rgbds-www
repository: ${{ github.repository_owner }}/rgbds-www
ref: master # Need to check out the branch to be able to commit on and push it.
ssh-key: !!str ${{ secrets.SSH_KEY_SECRET }}
- name: Install groff and mandoc
run: |
sudo apt install -Uyq groff mandoc -o APT::Color=yes -o Acquire::Queue-Mode=access
- name: Update pages
working-directory: rgbds/man
run: |
../../rgbds-www/maintainer/man_to_html.sh master *
- name: Push new pages
working-directory: rgbds-www
env:
GIT_AUTHOR_NAME: !!str ${{ github.actor }}
GIT_AUTHOR_EMAIL: !!str ${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
run: |
git add -A
git commit -m "Update RGBDS master documentation"
git push
+11 -16
View File
@@ -1,21 +1,16 @@
/rgbasm
/rgblink
/rgbfix
/rgbgfx
/install.sh
/rgbshim.sh
/coverage/
rgbasm
rgblink
rgbfix
rgbgfx
rgbshim.sh
*.o
*.exe
*.dll
*.gcno
*.gcda
*.gcov
/compile_flags.txt
.checkpatch-camelcase.*
CMakeCache.txt
CMakeFiles/
CMakeFiles
cmake_install.cmake
CMakeUserPresets.json
build*/
*.dSYM/
callgrind.out.*
test/pokecrystal
test/pokered
test/ucity
+74 -208
View File
@@ -1,231 +1,97 @@
#
# This file is part of RGBDS.
#
# Copyright (c) 2020 RGBDS contributors.
#
# SPDX-License-Identifier: MIT
#
# - 3.24 is required for `FetchContent`'s `find_package` integration.
# Older versions *may* work, but we can't test them; compat patches are welcome.
# - 3.17 is required for `CHECK_*` messages to display properly, but is not essential.
# - 3.9 is required for LTO checks.
cmake_minimum_required(VERSION 3.24...4.3 FATAL_ERROR)
# Read the project version from the header (the canonical source of truth).
file(STRINGS "include/version.hpp" version_defines REGEX "^[ \t]*#define[ \t]+PACKAGE_VERSION_")
foreach(line IN LISTS version_defines)
# We want the `CMAKE_MATCH_n` variables, so we just need to run *some* regex op.
string(REGEX MATCH "PACKAGE_(VERSION_[^ \t]+)[ \t]+([0-9]+)" dummy "${line}")
set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}")
endforeach()
# 3.9 required for LTO checks
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
project(rgbds
VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"
LANGUAGES CXX
DESCRIPTION "Game Boy assembly toolchain"
HOMEPAGE_URL "https://rgbds.gbdev.io")
if(DEFINED VERSION_RC)
string(APPEND CMAKE_PROJECT_VERSION "-rc${VERSION_RC}")
endif()
LANGUAGES C)
# Reject in-source builds, as they may conflict with the Makefile.
# get real path of source and binary directories
get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)
# reject in-source builds, may conflict with Makefile
if(srcdir STREQUAL bindir)
message(FATAL_ERROR "RGBDS should not be built in the source directory.
Instead, create a separate build directory and specify to CMake the path to the source directory.")
message("RGBDS should not be built in the source directory.")
message("Instead, create a separate build directory and specify to CMake the path to the source directory.")
message(FATAL_ERROR "Terminating configuration")
endif()
include(CTest) # Note: CTest only functions properly if included from the top-level CMakeLists.
include(GNUInstallDirs)
include(CMakeDependentOption)
## Compiler switches that should apply to our deps too.
option(SANITIZERS "Build with sanitizers enabled" OFF)
cmake_dependent_option(MORE_WARNINGS "Turn on more warnings" OFF "NOT MSVC" OFF)
if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) # Allow this to be overridden from the CLI easily.
# We link against the Microsoft C++ runtime libs statically, except the debug-mode one.
# This is because Microsoft's license terms (through some indirection) allow us to redistribute
# the runtime lib code *except* the debug-mode libs'.
# Since we want to remain able to not think too hard about debug executables, we link against
# the debug libs dynamically, shifting the burden of obtaining them onto the recipient.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:DebugDLL>")
endif()
if(SANITIZERS)
if(MSVC)
message(STATUS "ASan enabled")
add_compile_options(/fsanitize=address) # Note that this shouldn't be passed to the linker.
else() # We assume a GNU-like compiler.
message(STATUS "ASan and UBSan enabled")
set(SAN_FLAGS -fsanitize=address -fsanitize=undefined
-fsanitize=float-divide-by-zero)
add_compile_options(${SAN_FLAGS})
add_link_options(${SAN_FLAGS})
add_definitions(-D_GLIBCXX_ASSERTIONS -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG)
# A non-zero optimization level is desired even in debug mode (especially for Clang),
# and the two codegen flags improve the sanitizers' backtraces, but we want the user to
# be able to override these easily so we put them first.
string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-Og -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
endif()
endif()
message(CHECK_START "Checking if LTO is supported")
include(CheckIPOSupported)
check_ipo_supported(RESULT enable_lto)
if(enable_lto)
message(CHECK_PASS "yes (enabled only in release modes)")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL ON)
else()
message(CHECK_FAIL "no")
endif()
# Use versioning consistent with Makefile:
# the git revision is used but uses the fallback in an archive.
message(CHECK_START "Determining RGBDS version from Git history")
list(APPEND CMAKE_MESSAGE_INDENT " ")
set(GIT_REV "") # This fallback is important!
find_package(Git)
list(POP_BACK CMAKE_MESSAGE_INDENT)
if(NOT Git_FOUND)
message(CHECK_FAIL "Git not found")
else()
execute_process(COMMAND "${GIT_EXECUTABLE}" --git-dir=.git -c safe.directory='*'
describe --tags --dirty --always --match "v[0-9]*"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE GIT_REV OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE git_err ERROR_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE result)
if(NOT result EQUAL 0)
# Note that this happens e.g. when building from a tarball, so it shouldn't fail the build!
message(CHECK_FAIL "error ${result} from Git:")
list(APPEND CMAKE_MESSAGE_INDENT " ")
message("${git_err}")
list(POP_BACK CMAKE_MESSAGE_INDENT)
else()
message(CHECK_PASS "${GIT_REV}")
if(NOT "${GIT_REV}" MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+(-rc[0-9]+)?")
# Can't find an ancestor tag! (That passes `--match`, anyway.)
message(WARNING "No `v*` Git tag reachable; falling back")
elseif(NOT CMAKE_MATCH_0 STREQUAL "v${CMAKE_PROJECT_VERSION}")
message(SEND_ERROR "\
Version mismatch! Git says ${CMAKE_MATCH_0},
version.hpp says v${CMAKE_PROJECT_VERSION}!")
endif()
endif()
endif()
## Dependencies.
include(FetchContent)
include(cmake/deps.cmake)
# Be sure to make zlib available before libpng, otherwise libpng
# will attempt to `find_package(ZLIB)` without going through `FetchContent`.
if(NOT DEFINED ZLIB_BUILD_TESTING) # Unless overridden (e.g. in the cache), we don't care about zlib's tests.
set(ZLIB_BUILD_TESTING OFF)
endif()
FetchContent_MakeAvailable(ZLIB)
if(NOT DEFINED ZLIB_INCLUDE_DIRS)
set(ZLIB_INCLUDE_DIRS "${zlib_BINARY_DIR};${zlib_SOURCE_DIR}") # libpng's `genout` script relies on this variable to be set.
endif()
# Statically building zlib (from source) generates a target named differently.
if(NOT TARGET ZLIB::ZLIB AND TARGET zlibstatic)
add_library(ZLIB::ZLIB ALIAS zlibstatic)
endif()
if(NOT DEFINED PNG_TESTS) # Unless overridden (e.g. in the cache), we don't care about libpng's tests.
set(PNG_TESTS OFF)
endif()
FetchContent_MakeAvailable(PNG)
if(NOT TARGET PNG::PNG)
if(PNG_SHARED)
add_library(PNG::PNG ALIAS png_shared)
else()
add_library(PNG::PNG ALIAS png_static)
endif()
endif()
## The actual stuff.
# Any compiler options that shouldn't apply to our dependencies go here.
include_directories("include")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
option(SANITIZERS "Build with sanitizers enabled" OFF) # Ignored on MSVC
option(MORE_WARNINGS "Turn on more warnings" OFF) # Ignored on MSVC
option(TRACE_PARSER "Trace parser execution" OFF)
option(TRACE_LEXER "Trace lexer execution" OFF)
if(MSVC)
add_compile_options(
/wd5030 # Warning C5030 is about unknown attributes (`[[gnu::ATTR]]`), none of ours being load-bearing.
/wd4996 # Warning C4996 is about using POSIX names, which we want to do for portability.
/Zc:preprocessor # Opt into the C++20-conformant preprocessor.
)
# MSVC's standard library triggers warning C5105,
# "macro expansion producing 'defined' has undefined behavior"
add_compile_options(/std:c11 /W1 /MP /wd5105)
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
else()
add_compile_options(-Wall -pedantic -Wno-unknown-warning-option -fno-exceptions -fno-rtti)
add_compile_options(-Wall -pedantic)
if(SANITIZERS)
set(SAN_FLAGS -fsanitize=shift -fsanitize=integer-divide-by-zero
-fsanitize=unreachable -fsanitize=vla-bound
-fsanitize=signed-integer-overflow -fsanitize=bounds
-fsanitize=object-size -fsanitize=bool -fsanitize=enum
-fsanitize=alignment -fsanitize=null)
add_compile_options(${SAN_FLAGS})
link_libraries(${SAN_FLAGS})
endif()
if(MORE_WARNINGS)
add_compile_options(-Wextra
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond
-Wfloat-equal -Wlogical-op -Wnull-dereference -Wold-style-cast -Wshift-overflow=2
-Wstringop-overflow=4 -Wtrampolines -Wundef -Wuninitialized -Wunused -Wshadow
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1
-Wno-format-nonliteral -Wno-strict-overflow
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare
-Wvla) # MSVC does not support VLAs
endif()
add_compile_options(-Wno-unused-but-set-variable # bison's `yynerrs_` is incremented but unused
# C++20 allows macros to take zero variadic arguments.
# Some versions of Clang don't recognize this, and treat them as a GNU extension.
-Wno-gnu-zero-variadic-macro-arguments)
if(MINGW)
# MinGW warns about format specifiers like `%z` and `%j`, which are missing on Windows XP and earlier.
# We rely on runtimes more modern than that, so we can ignore those warnings.
# If this is a problem for you: use Microsoft's equivalents, or define `__USE_MINGW_ANSI_STDIO=1`.
# https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/
add_compile_options(-Wno-error=format -Wno-error=format-extra-args)
add_compile_options(-Werror -Wextra -Wno-type-limits
-Wno-sign-compare -Wvla -Wformat -Wformat-security -Wformat-overflow=2
-Wformat-truncation=1 -Wformat-y2k -Wswitch-enum -Wunused
-Wuninitialized -Wunknown-pragmas -Wstrict-overflow=5
-Wstringop-overflow=4 -Walloc-zero -Wduplicated-cond
-Wfloat-equal -Wshadow -Wcast-qual -Wcast-align -Wlogical-op
-Wnested-externs -Wno-aggressive-loop-optimizations -Winline
-Wundef -Wstrict-prototypes -Wold-style-definition)
endif()
endif()
# Use versioning consistent with Makefile
# the git revision is used but uses the fallback in an archive
execute_process(COMMAND git describe --tags --dirty --always
OUTPUT_VARIABLE GIT_REV
ERROR_QUIET)
string(STRIP "${GIT_REV}" GIT_REV)
include_directories("${PROJECT_SOURCE_DIR}/include")
add_definitions(-DBUILD_VERSION_STRING="${GIT_REV}")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED True)
add_subdirectory(src)
if(BUILD_TESTING) # This option is defined implicitly by `include(CTest)`.
add_subdirectory(test)
# By default, build in Release mode; Debug mode must be explicitly requested
# (You may want to augment it with the options above)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
message(CHECK_START "Checking if LTO is supported")
include(CheckIPOSupported)
check_ipo_supported(RESULT enable_lto)
if(enable_lto)
message(CHECK_PASS "yes")
set_property(TARGET rgbasm rgblink rgbfix rgbgfx PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
else()
message(CHECK_FAIL "no")
endif()
endif()
set(man1 "man/rgbasm.1"
"man/rgbfix.1"
"man/rgbgfx.1"
"man/rgblink.1")
set(man5 "man/rgbasm.5"
"man/rgbasm-old.5"
"man/rgblink.5"
"man/rgbds.5")
set(man7 "man/gbz80.7"
"man/rgbds.7")
if(TRACE_PARSER)
target_compile_definitions(rgbasm PRIVATE -DYYDEBUG)
endif()
foreach(SECTION "man1" "man5" "man7")
install(FILES ${${SECTION}} DESTINATION "${CMAKE_INSTALL_MANDIR}/${SECTION}" COMPONENT man)
endforeach()
## Packaging.
# We only specify here the package-agnostic options;
# the rest is rather convention from our side, and thus more appropriate for presets or CLI flags.
## CPACK_PACKAGE_NAME: copied from `project()`
set(CPACK_PACKAGE_VENDOR "GBDev")
set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}") # The individual components are defined implicitly.
set(CPACK_PACKAGE_DESCRIPTION "An assembly toolchain for the Nintendo Game Boy and Game Boy Color") # Same as our repo's description.
## CPACK_PACKAGE_DESCRIPTION_SUMMARY: copied from `project()`
set(CPACK_PACKAGE_HOMEPAGE_URL "https://rgbds.gbdev.io")
## CPACK_PACKAGE_FILE_NAME: should be provided at runtime (`cpack -P`)
set(CPACK_PACKAGE_CHECKSUM SHA256)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
set(CPACK_STRIP_FILES ON) # Only applies to binary packages, not sources.
set(CPACK_VERBATIM_VARIABLES ON)
set(CPACK_THREADS 0) # Use all available CPU cores.
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
include(CPack)
if(TRACE_LEXER)
target_compile_definitions(rgbasm PRIVATE -DLEXER_DEBUG)
endif()
-46
View File
@@ -1,46 +0,0 @@
{
"version": 3,
"configurePresets": [
{
"name": "develop",
"description": "Debugging config for maintainers",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": true,
"CMAKE_COMPILE_WARNING_AS_ERROR": true,
"CMAKE_LINK_WARNING_AS_ERROR": true,
"MORE_WARNINGS": true,
"SANITIZERS": true
},
"warnings": { "uninitialized": true },
"errors": { "dev": true }
},
{
"name": "develop-msbuild32",
"inherits": ["develop", "msbuild32"]
},
{
"name": "develop-msbuild64",
"inherits": ["develop", "msbuild64"]
},
{
"name": "msbuild32",
"description": "Flags for building 32-bit executables with MSBuild",
"architecture": "Win32"
},
{
"name": "msbuild64",
"description": "Flags for building 64-bit executables with MSBuild",
"architecture": "x64"
},
{
"name": "macos-static",
"description": "Flags for building an executable compatible with old macOS",
"cacheVariables": {
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "cmake/macos-static.cmake"
}
}
]
}
+96
View File
@@ -0,0 +1,96 @@
Contributing
============
RGBDS was created in the late 90's and has received contributions from several
developers since then. It wouldn't have been possible to get to this point
without their work and, for that reason, it is always open to the contributions
of other people.
Reporting Bugs
--------------
Bug reports are essential to improve RGBDS and they are always welcome. If you
want to report a bug:
1. Make sure that there isn't a similar issue already reported
`here <https://github.com/rednex/rgbds/issues>`__.
2. Figure out a way of reproducing it reliably.
3. If there is a piece of code that triggers the bug, try to reduce it to the
smallest file you can.
4. Create a new `issue <https://github.com/rednex/rgbds/issues>`__.
Of course, it may not always be possible to give an accurate bug report, but it
always helps to fix it.
Requesting new features
-----------------------
If you come up with a good idea that could be implemented, you can propose it to
be done.
1. Create a new `issue <https://github.com/rednex/rgbds/issues>`__.
2. Try to be as accurate as possible. Describe what you need and why you need
it, maybe with examples.
Please understand that the contributors are doing it in their free time, so
simple requests are more likely to catch the interest of a contributor than
complicated ones. If you really need something to be done, and you think you can
implement it yourself, you can always contribute to RGBDS with your own code.
Contributing code
-----------------
If you want to contribute with your own code, whether it is to fix a current
issue or to add something that nobody had requested, you should first consider
if your change is going to be small (and likely to be accepted as-is) or big
(and will have to go through some rework).
Big changes will most likely require some discussion, so open an
`issue <https://github.com/rednex/rgbds/issues>`__ and explain what you want to
do and how you intend to do it. If you already have a prototype, it's always a
good idea to show it. Tests help, too.
If you are going to work on a specific issue that involves a lot of work, it is
always a good idea to leave a message, just in case someone else is interested
but doesn't know that there's someone working on it.
Note that you must contribute all your changes under the MIT License. If you are
just modifying a file, you don't need to do anything (maybe update the copyright
years). If you are adding new files, you need to use the correct header with the
copyright and the reference to the MIT License.
1. Fork this repository.
2. Checkout the ``master`` branch.
3. Create a new branch to work on. You could still work on ``master``, but it's
easier that way.
4. Compile your changes with ``make develop`` instead of just ``make``. This
target checks for additional warnings. Your patches shouldn't introduce any
new warning (but it may be possible to remove some warning checks if it makes
the code much easier).
5. Follow the Linux kernel coding style, which can be found in the file
``Documentation/process/coding-style.rst`` in the Linux kernel repository.
Note that the coding style isn't written in stone, if there is a good reason
to deviate from it, it should be fine.
6. Download the files ``checkpatch.pl``, ``const_structs.checkpatch`` and
``spelling.txt`` from the folder ``scripts`` in the Linux kernel repository.
7. To use ``checkpatch.pl`` you can use ``make checkpatch``, which will check
the coding style of all patches between the current one and the upstream
code. By default, the Makefile expects the script (and associate files) to be
located in ``../linux/scripts/``, but you can place them anywhere you like as
long as you specify it when executing the command:
``make checkpatch CHECKPATCH=../path/to/folder``.
8. Create a pull request against the branch ``master``.
9. Be prepared to get some comments about your code and to modify it. Tip: Use
``git rebase -i origin/master`` to modify chains of commits.
+53
View File
@@ -0,0 +1,53 @@
Contributors to RGBDS
=====================
Original author
---------------
- Carsten Elton Sørensen <[email protected]>
Main contributors
-----------------
- Justin Lloyd <[email protected]>
- Vegard Nossum <[email protected]>
- Anthony J. Bentley <[email protected]>
- stag019 <[email protected]>
- Antonio Niño Díaz <[email protected]>
Other contributors
------------------
- Ben Hetherington <[email protected]>
- Björn Höhrmann <[email protected]>
- Christophe Staïesse <[email protected]>
- David Brotz <[email protected]>
- Eldred Habert <[email protected]>
- The Musl C library <http://www.musl-libc.org>
- obskyr <[email protected]>
- The OpenBSD Project <http://www.openbsd.org>
- Quint Guvernator <[email protected]>
- Rangi <http://github.com/Rangi42>
- Sanqui <[email protected]>
- YamaArashi <[email protected]>
- yenatch <[email protected]>
- phs <[email protected]>
- jidoc01 <[email protected]>
+22 -23
View File
@@ -1,25 +1,24 @@
FROM debian:13-slim
LABEL org.opencontainers.image.source=https://github.com/gbdev/rgbds
ARG version=1.0.3
# This file is part of RGBDS.
#
# Copyright (c) 2018-2019, Phil Smith and RGBDS contributors.
#
# SPDX-License-Identifier: MIT
# docker build -t rgbds:vX.X.X-alpine
FROM alpine:latest
RUN apk add --update \
build-base \
bison \
libpng-dev
COPY . /rgbds
WORKDIR /rgbds
RUN make Q='' all
COPY . .
# Install dependencies
RUN apt-get update && \
apt-get install sudo make cmake gcc build-essential -y
RUN ./.github/scripts/install-deps.sh debian
# Build RGBDS
RUN make -j "$(getconf _NPROCESSORS_ONLN)" CXXFLAGS="-O3 -flto -DNDEBUG -static" PKG_CONFIG="pkg-config --static" Q=
# Create the install script
RUN make install.sh Q=
# Create an archive with the compiled executables, man pages, and install script,
# so it can be copied outside of the container and installed/used in another system
RUN tar caf rgbds-linux-x86_64.tar.xz --transform='s#.*/##' rgbasm rgblink rgbfix rgbgfx man/* install.sh
# Install RGBDS on the container so all the executables will be available in the PATH
RUN cp man/* .
RUN make install Q=
FROM alpine:latest
RUN apk add --update \
libpng
COPY --from=0 \
/rgbds/rgbasm \
/rgbds/rgbfix \
/rgbds/rgblink \
/rgbds/rgbgfx \
/bin/
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 1996-2025, Carsten Sørensen and RGBDS contributors.
Copyright (c) 1997-2020, Carsten Sorensen and RGBDS contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
+146 -179
View File
@@ -1,271 +1,237 @@
#
# This file is part of RGBDS.
#
# Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
#
# SPDX-License-Identifier: MIT
#
.SUFFIXES:
.SUFFIXES: .cpp .y .o
.PHONY: all clean install develop debug profile coverage format tidy iwyu wine-shim dist
.SUFFIXES: .h .y .c .o
# User-defined variables
Q := @
PREFIX := /usr/local
bindir := ${PREFIX}/bin
mandir := ${PREFIX}/share/man
SUFFIX :=
STRIP := -s
BINMODE := 755
MANMODE := 644
MANSRC := man/
Q := @
PREFIX := /usr/local
bindir := ${PREFIX}/bin
mandir := ${PREFIX}/share/man
STRIP := -s
BINMODE := 755
MANMODE := 644
CHECKPATCH := ../linux/scripts/checkpatch.pl
# Other variables
PKG_CONFIG := pkg-config
PNGCFLAGS := `${PKG_CONFIG} --cflags libpng`
PNGLDFLAGS := `${PKG_CONFIG} --libs-only-L libpng`
PNGLDLIBS := `${PKG_CONFIG} --libs-only-l libpng`
PKG_CONFIG := pkg-config
PNGCFLAGS := `${PKG_CONFIG} --cflags libpng`
PNGLDFLAGS := `${PKG_CONFIG} --libs-only-L libpng`
PNGLDLIBS := `${PKG_CONFIG} --libs-only-l libpng`
# Note: if this comes up empty, `version.cpp` will automatically fall back to last release number
VERSION_STRING := `git --git-dir=.git -c safe.directory='*' describe --tags --dirty --always 2>/dev/null`
# Note: if this comes up empty, `version.c` will automatically fall back to last release number
VERSION_STRING := `git describe --tags --dirty --always 2>/dev/null`
WARNFLAGS := -Wall -pedantic -Wno-unknown-warning-option \
-Wno-gnu-zero-variadic-macro-arguments -Wno-unused-but-set-variable
WARNFLAGS := -Wall
# Overridable CXXFLAGS
CXXFLAGS ?= -O3 -flto -DNDEBUG
# Non-overridable CXXFLAGS
REQUIREDCXXFLAGS := -std=c++20 -I include -fno-exceptions -fno-rtti
REALCXXFLAGS := ${CXXFLAGS} ${WARNFLAGS} ${REQUIREDCXXFLAGS}
# Overridable CFLAGS
CFLAGS ?= -O3 -flto -DNDEBUG
# Non-overridable CFLAGS
REALCFLAGS := ${CFLAGS} ${WARNFLAGS} -std=gnu11 -D_POSIX_C_SOURCE=200809L \
-Iinclude
# Overridable LDFLAGS
LDFLAGS ?=
LDFLAGS ?=
# Non-overridable LDFLAGS
REQUIREDLDFLAGS := -DBUILD_VERSION_STRING=\"${VERSION_STRING}\"
REALLDFLAGS := ${LDFLAGS} ${WARNFLAGS} ${REQUIREDLDFLAGS}
REALLDFLAGS := ${LDFLAGS} ${WARNFLAGS} \
-DBUILD_VERSION_STRING=\"${VERSION_STRING}\"
# Wrapper around bison that passes flags depending on what the version supports
BISON := src/bison.sh
YFLAGS ?= -Wall
RM := rm -rf
BISON := bison
RM := rm -rf
# Rules to build the RGBDS binaries
all: rgbasm rgblink rgbfix rgbgfx
common_obj := \
src/extern/getopt.o \
src/cli.o \
src/diagnostics.o \
src/style.o \
src/usage.o \
src/util.o
rgbasm_obj := \
${common_obj} \
src/asm/actions.o \
src/asm/charmap.o \
src/asm/fixpoint.o \
src/asm/format.o \
src/asm/fstack.o \
src/asm/intern.o \
src/asm/lexer.o \
src/asm/macro.o \
src/asm/main.o \
src/asm/parser.o \
src/asm/opt.o \
src/asm/output.o \
src/asm/parser.o \
src/asm/rpn.o \
src/asm/section.o \
src/asm/symbol.o \
src/asm/util.o \
src/asm/warning.o \
src/extern/err.o \
src/extern/getopt.o \
src/extern/utf8decoder.o \
src/backtrace.o \
src/hashmap.o \
src/linkdefs.o \
src/opmath.o \
src/verbosity.o
src/opmath.o
src/asm/lexer.o src/asm/main.o: src/asm/parser.hpp
src/asm/lexer.o src/asm/main.o: src/asm/parser.h
rgblink_obj := \
${common_obj} \
src/link/assign.o \
src/link/fstack.o \
src/link/lexer.o \
src/link/layout.o \
src/link/main.o \
src/link/object.o \
src/link/output.o \
src/link/patch.o \
src/link/script.o \
src/link/sdas_obj.o \
src/link/section.o \
src/link/symbol.o \
src/link/warning.o \
src/extern/utf8decoder.o \
src/backtrace.o \
src/extern/err.o \
src/extern/getopt.o \
src/hashmap.o \
src/linkdefs.o \
src/opmath.o \
src/verbosity.o
src/link/lexer.o src/link/main.o: src/link/script.hpp
src/opmath.o
rgbfix_obj := \
${common_obj} \
src/fix/fix.o \
src/fix/main.o \
src/fix/mbc.o \
src/fix/warning.o
src/extern/err.o \
src/extern/getopt.o
rgbgfx_obj := \
${common_obj} \
src/gfx/color_set.o \
src/gfx/gb.o \
src/gfx/main.o \
src/gfx/pal_packing.o \
src/gfx/pal_sorting.o \
src/gfx/pal_spec.o \
src/gfx/palette.o \
src/gfx/png.o \
src/gfx/process.o \
src/gfx/reverse.o \
src/gfx/rgba.o \
src/gfx/warning.o \
src/verbosity.o
src/gfx/makepng.o \
src/extern/err.o \
src/extern/getopt.o
rgbasm: ${rgbasm_obj}
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCXXFLAGS} src/version.cpp
$Q${CC} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCFLAGS} src/version.c -lm
rgblink: ${rgblink_obj}
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCXXFLAGS} src/version.cpp
$Q${CC} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCFLAGS} src/version.c
rgbfix: ${rgbfix_obj}
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCXXFLAGS} src/version.cpp
$Q${CC} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCFLAGS} src/version.c
rgbgfx: ${rgbgfx_obj}
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCXXFLAGS} ${PNGLDLIBS} src/version.cpp
test/gfx/randtilegen: test/gfx/randtilegen.cpp
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGCFLAGS} ${PNGLDLIBS}
test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGCFLAGS} ${PNGLDLIBS}
$Q${CC} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCFLAGS} src/version.c ${PNGLDLIBS}
# Rules to process files
# We want the Bison invocation to pass through our rules, not default ones
.y.o:
.y.cpp:
$Q${BISON} $@ $<
# Bison-generated C++ files have an accompanying header
src/asm/parser.hpp: src/asm/parser.cpp
$Qtouch $@
src/link/script.hpp: src/link/script.cpp
# Bison-generated C files have an accompanying header
src/asm/parser.h: src/asm/parser.c
$Qtouch $@
# Only RGBGFX uses libpng (POSIX make doesn't support pattern rules to cover all these)
src/gfx/color_set.o: src/gfx/color_set.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/main.o: src/gfx/main.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/pal_packing.o: src/gfx/pal_packing.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/pal_sorting.o: src/gfx/pal_sorting.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/pal_spec.o: src/gfx/pal_spec.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/png.o: src/gfx/png.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/process.o: src/gfx/process.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/reverse.o: src/gfx/reverse.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/rgba.o: src/gfx/rgba.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/asm/parser.c: src/asm/parser.y
$QDEFS=; \
add_flag(){ \
if src/check_bison_ver.sh $$1 $$2; then \
DEFS="-D$$3 $$DEFS"; \
fi \
}; \
add_flag 3 5 api.token.raw=true; \
add_flag 3 6 parse.error=detailed; \
add_flag 3 0 parse.error=verbose; \
add_flag 3 0 parse.lac=full; \
add_flag 3 0 lr.type=ielr; \
echo "DEFS=$$DEFS"; \
${BISON} $$DEFS -d ${YFLAGS} -o $@ $<
.cpp.o:
$Q${CXX} ${REALCXXFLAGS} -c -o $@ $<
install.sh:
$Qecho '#!/usr/bin/env bash' > $@
$Q${MAKE} -s -n install MANSRC= >> $@
$Qchmod +x $@
.c.o:
$Q${CC} ${REALCFLAGS} ${PNGCFLAGS} -c -o $@ $<
# Target used to remove all files generated by other Makefile targets
clean:
$Q${RM} rgbasm rgbasm.exe
$Q${RM} rgblink rgblink.exe
$Q${RM} rgbfix rgbfix.exe
$Q${RM} rgbgfx rgbgfx.exe
$Qfind src/ -name "*.o" -exec rm {} \;
$Qfind . -type f \( -name "*.gcno" -o -name "*.gcda" -o -name "*.gcov" \) -exec rm {} \;
$Q${RM} install.sh rgbshim.sh
$Q${RM} src/asm/parser.cpp src/asm/parser.hpp src/asm/stack.hh
$Q${RM} src/link/script.cpp src/link/script.hpp src/link/stack.hh
$Q${RM} test/gfx/randtilegen test/gfx/rgbgfx_test
$Q${RM} rgbshim.sh
$Q${RM} src/asm/parser.c src/asm/parser.h
# Target used to install the binaries and man pages.
install: all
$Qinstall -d ${DESTDIR}${bindir}/ ${DESTDIR}${mandir}/man1/ ${DESTDIR}${mandir}/man5/ ${DESTDIR}${mandir}/man7/
$Qinstall ${STRIP} -m ${BINMODE} rgbasm ${DESTDIR}${bindir}/rgbasm${SUFFIX}
$Qinstall ${STRIP} -m ${BINMODE} rgblink ${DESTDIR}${bindir}/rgblink${SUFFIX}
$Qinstall ${STRIP} -m ${BINMODE} rgbfix ${DESTDIR}${bindir}/rgbfix${SUFFIX}
$Qinstall ${STRIP} -m ${BINMODE} rgbgfx ${DESTDIR}${bindir}/rgbgfx${SUFFIX}
$Qinstall -m ${MANMODE} ${MANSRC}rgbasm.1 ${MANSRC}rgblink.1 ${MANSRC}rgbfix.1 ${MANSRC}rgbgfx.1 ${DESTDIR}${mandir}/man1/
$Qinstall -m ${MANMODE} ${MANSRC}rgbds.5 ${MANSRC}rgbasm.5 ${MANSRC}rgbasm-old.5 ${MANSRC}rgblink.5 ${DESTDIR}${mandir}/man5/
$Qinstall -m ${MANMODE} ${MANSRC}rgbds.7 ${MANSRC}gbz80.7 ${DESTDIR}${mandir}/man7/
$Qmkdir -p ${DESTDIR}${bindir}
$Qinstall ${STRIP} -m ${BINMODE} rgbasm ${DESTDIR}${bindir}/rgbasm
$Qinstall ${STRIP} -m ${BINMODE} rgbfix ${DESTDIR}${bindir}/rgbfix
$Qinstall ${STRIP} -m ${BINMODE} rgblink ${DESTDIR}${bindir}/rgblink
$Qinstall ${STRIP} -m ${BINMODE} rgbgfx ${DESTDIR}${bindir}/rgbgfx
$Qmkdir -p ${DESTDIR}${mandir}/man1 ${DESTDIR}${mandir}/man5 ${DESTDIR}${mandir}/man7
$Qinstall -m ${MANMODE} src/rgbds.7 ${DESTDIR}${mandir}/man7/rgbds.7
$Qinstall -m ${MANMODE} src/gbz80.7 ${DESTDIR}${mandir}/man7/gbz80.7
$Qinstall -m ${MANMODE} src/rgbds.5 ${DESTDIR}${mandir}/man5/rgbds.5
$Qinstall -m ${MANMODE} src/asm/rgbasm.1 ${DESTDIR}${mandir}/man1/rgbasm.1
$Qinstall -m ${MANMODE} src/asm/rgbasm.5 ${DESTDIR}${mandir}/man5/rgbasm.5
$Qinstall -m ${MANMODE} src/fix/rgbfix.1 ${DESTDIR}${mandir}/man1/rgbfix.1
$Qinstall -m ${MANMODE} src/link/rgblink.1 ${DESTDIR}${mandir}/man1/rgblink.1
$Qinstall -m ${MANMODE} src/link/rgblink.5 ${DESTDIR}${mandir}/man5/rgblink.5
$Qinstall -m ${MANMODE} src/gfx/rgbgfx.1 ${DESTDIR}${mandir}/man1/rgbgfx.1
# Target used to check the coding style of the whole codebase.
# `extern/` is excluded, as it contains external code that should not be patched
# to meet our coding style, so applying upstream patches is easier.
# `.y` files aren't checked, unfortunately...
checkcodebase:
$Qfor file in `git ls-files | grep -E '(\.c|\.h)$$' | grep -Ev '(src|include)/extern/'`; do \
${CHECKPATCH} -f "$$file"; \
done
# Target used to check the coding style of the patches from the upstream branch
# to the HEAD. Runs checkpatch once for each commit between the current HEAD and
# the first common commit between the HEAD and origin/master.
# `.y` files aren't checked, unfortunately...
BASE_REF:= origin/master
checkpatch:
$Qeval COMMON_COMMIT=$$(git merge-base HEAD ${BASE_REF}); \
for commit in `git rev-list $$COMMON_COMMIT..HEAD`; do \
echo "[*] Analyzing commit '$$commit'"; \
git format-patch --stdout "$$commit~..$$commit" \
-- src include '!src/extern' '!include/extern' \
| ${CHECKPATCH} - || true; \
done
# This target is used during development in order to prevent adding new issues
# to the source code. All warnings are treated as errors in order to block the
# compilation and make the continous integration infrastructure return failure.
# Target used in development to prevent adding new issues to the source code.
# All warnings are treated as errors to block the compilation and make the
# continous integration infrastructure return failure.
# The rationale for some of the flags is documented in the CMakeLists.
develop:
$Q${MAKE} WARNFLAGS="${WARNFLAGS} -Werror -Wextra \
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond \
-Wfloat-equal -Wlogical-op -Wnull-dereference -Wold-style-cast -Wshift-overflow=2 \
-Wstringop-overflow=4 -Wtrampolines -Wundef -Wuninitialized -Wunused -Wshadow \
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1 \
-Wno-format-nonliteral -Wno-strict-overflow -Wno-unused-but-set-variable \
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare -Wvla \
-D_GLIBCXX_ASSERTIONS -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG \
-fsanitize=address -fsanitize=undefined -fsanitize=float-divide-by-zero" \
CXXFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls"
$Qenv $(MAKE) -j WARNFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-type-limits \
-Wno-sign-compare -Wvla -Wformat -Wformat-security -Wformat-overflow=2 \
-Wformat-truncation=1 -Wformat-y2k -Wswitch-enum -Wunused \
-Wuninitialized -Wunknown-pragmas -Wstrict-overflow=4 \
-Wstringop-overflow=4 -Walloc-zero -Wduplicated-cond \
-Wfloat-equal -Wshadow -Wcast-qual -Wcast-align -Wlogical-op \
-Wnested-externs -Wno-aggressive-loop-optimizations -Winline \
-Wundef -Wstrict-prototypes -Wold-style-definition \
-fsanitize=shift -fsanitize=integer-divide-by-zero \
-fsanitize=unreachable -fsanitize=vla-bound \
-fsanitize=signed-integer-overflow -fsanitize=bounds \
-fsanitize=object-size -fsanitize=bool -fsanitize=enum \
-fsanitize=alignment -fsanitize=null" CFLAGS="-ggdb3 -O0"
# Target used in development to debug with gdb.
debug:
$Qenv ${MAKE} \
CXXFLAGS="-ggdb3 -O0 -fno-omit-frame-pointer -fno-optimize-sibling-calls"
# Targets for the project maintainer to easily create Windows exes.
# This is not for Windows users!
# If you're building on Windows with Cygwin or Mingw, just follow the Unix
# install instructions instead.
# Target used in development to profile with callgrind.
# Use `valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes ./rgbasm ...`.
profile:
$Qenv ${MAKE} \
CXXFLAGS="-ggdb3 -O3 -fno-omit-frame-pointer -fno-optimize-sibling-calls"
mingw32:
$Qmake CC=i686-w64-mingw32-gcc BISON=bison \
PKG_CONFIG=i686-w64-mingw32-pkg-config -j
# Target used in development to inspect code coverage with gcov.
# Use `./contrib/coverage.bash`.
coverage:
$Qenv ${MAKE} \
CXXFLAGS="-ggdb3 -Og --coverage -fno-omit-frame-pointer -fno-optimize-sibling-calls"
mingw64:
$Qmake CC=x86_64-w64-mingw32-gcc BISON=bison \
PKG_CONFIG=x86_64-w64-mingw32-pkg-config -j
# Target used in development to format source code with clang-format.
format:
$Qclang-format -i $$(git ls-files '*.[hc]pp')
# Target used in development to check code with clang-tidy.
# Requires Bison-generated header files to exist.
tidy: src/asm/parser.hpp src/link/script.hpp compile_flags.txt
$Qclang-tidy -p . $$(git ls-files '*.[hc]pp')
compile_flags.txt:
$Qprintf '%s\n' ${REQUIREDCXXFLAGS} ${REQUIREDLDFLAGS} >$@
# Target used in development to remove unused `#include` headers.
iwyu:
$Qenv ${MAKE} \
CXX="include-what-you-use" \
REALCXXFLAGS="-std=c++20 -I include"
# Target used in development to conveniently invoke RGBDS binaries with Wine.
wine-shim:
$Qecho '#!/usr/bin/env bash' > rgbshim.sh
$Qecho '#!/bin/bash' > rgbshim.sh
$Qecho 'WINEDEBUG=-all wine $$0.exe "$${@:1}"' >> rgbshim.sh
$Qchmod +x rgbshim.sh
$Qln -s rgbshim.sh rgbasm
@@ -275,6 +241,7 @@ wine-shim:
# Target for the project maintainer to produce distributable release tarballs
# of the source code.
dist:
$Qgit ls-files | sed s~^~$${PWD##*/}/~ \
| tar -czf rgbds-source.tar.gz -C .. -T -
| tar -czf rgbds-`git describe --tags | cut -c 2-`.tar.gz -C .. -T -
-63
View File
@@ -1,63 +0,0 @@
# RGBDS
[RGBDS](https://github.com/gbdev/rgbds) (Rednex Game Boy Development System) is
a free assembler/linker package for the Game Boy and Game Boy Color.
It consists of four tools:
- **RGBASM:** assembler
- **RGBLINK:** linker
- **RGBFIX:** ROM checksum/header fixer
- **RGBGFX:** PNG-to-Game Boy graphics converter
## Documentation
The [full documentation](https://rgbds.gbdev.io/docs/) is available online,
including the [development history](https://rgbds.gbdev.io/docs/rgbds.7) and
[version history](https://rgbds.gbdev.io/versions), generated from the man pages
in this repository.
The documentation website's own source code is available in the
[rgbds-www](https://github.com/gbdev/rgbds-www) repository.
## Community
If you have questions about the RGBDS code or its organization, you can contact
the maintainers on the [GBDev Discord server](https://discord.gg/RjJKA8wrD4) or
[other community channels](https://gbdev.io/chat), or via email at
`rgbds at gbdev dot io`.
If you want to help maintain RGBDS, please read [the contribution guide](/docs/CONTRIBUTING.md).
## Installing
The [platform-specific installation instructions](https://rgbds.gbdev.io/install/)
are available online. To [build from source](https://rgbds.gbdev.io/install/source)
using `make` or `cmake`, briefly:
```sh
make
sudo make install
```
```sh
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
cmake --install build
```
Both build systems support a prefix (e.g. to install into a specific directory)
and a suffix (e.g. to append the version number or commit ID):
```sh
make
sudo make install PREFIX=install_dir/ SUFFIX=-$(git rev-parse --short HEAD)
```
```sh
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DSUFFIX=-$(git rev-parse --short HEAD)
cmake --build build
cmake --install build --prefix install_dir
```
On Windows, any `SUFFIX` should include the `.exe` extension.
+115
View File
@@ -0,0 +1,115 @@
RGBDS
=====
RGBDS (Rednex Game Boy Development System) is a free assembler/linker package
for the Game Boy and Game Boy Color. It consists of:
- rgbasm (assembler)
- rgblink (linker)
- rgbfix (checksum/header fixer)
- rgbgfx (PNGtoGame Boy graphics converter)
This is a fork of the original RGBDS which aims to make the programs more like
other UNIX tools.
This toolchain is maintained on `GitHub <https://github.com/rednex/rgbds>`__.
The documentation of this toolchain can be viewed online
`here <https://rgbds.gbdev.io/docs/>`__, it is generated from the man pages
found in this repository.
1. Installing RGBDS
-------------------
The `installation procedure <https://rgbds.gbdev.io/install>`__ is available
online for various platforms. `Building from source <https://rgbds.gbdev.io/install/source>`__
is possible using ``make`` or ``cmake``; follow the link for more detailed instructions.
.. code:: sh
make
sudo make install
.. code:: sh
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
cmake --install build
2. RGBDS Folder Organization
----------------------------
The RGBDS source code file structure somewhat resembles the following:
::
.
├── .github/
│   ├── actions/
│   │   └── ...
│   └── workflows/
│      └── ...
├── contrib/
│   ├── zsh_compl/
│   │   └── ...
│   └── ...
├── include/
│   └── ...
├── src/
│   ├── asm/
│   │   └── ...
│   ├── extern/
│   │   └── ...
│   ├── fix/
│   │   └── ...
│   ├── gfx/
│   │   └── ...
│   ├── link/
│   │   └── ...
│   ├── CMakeLists.txt
│   └── ...
├── test/
│   ├── ...
│ └── run-tests.sh
├── CMakeLists.txt
├── Makefile
└── README.rst
- ``.github/`` - files and scripts related to the integration of the RGBDS codebase with
GitHub.
- ``contrib/`` - scripts and other resources which may be useful to users and developers of
RGBDS.
* ``zsh_compl`` contains tab completion scripts for use with zsh. Put them somewhere in your ``fpath``, and they should auto-load.
- ``include/`` - header files for each respective C files in `src`.
- ``src/`` - source code and manual pages for RGBDS.
* Note that the code unique to each RGBDS tool is stored in its respective subdirectory
(rgbasm -> ``src/asm/``, for example). ``src/extern/`` contains code imported from external sources.
- ``test/`` - testing framework used to verify that changes to the code don't break or modify the behavior of RGBDS.
3. History
----------
- Around 1997, Carsten Sørensen (AKA SurfSmurf) writes ASMotor as a
general-purpose assembler/linker system for DOS/Win32
- Around 1999, Justin Lloyd (AKA Otaku no Zoku) adapts ASMotor to read and
produce GBZ80 assembly/machine code, and releases this version as RGBDS.
- 2009, Vegard Nossum adapts the code to be more UNIX-like and releases
this version as rgbds-linux on
`GitHub <https://github.com/vegard/rgbds-linux>`__.
- 2010, Anthony J. Bentley forks that repository. The fork becomes the reference
implementation of rgbds.
- 2017, Bentley's repository is moved to a neutral name.
- 2018, codebase relicensed under the MIT license.
- 2020, repository is moved to the `gbdev <https://github.com/gbdev>`__ organisation. The `rgbds.gbdev.io <https://rgbds.gbdev.io>`__ website serving documentation and downloads is created.
-25
View File
@@ -1,25 +0,0 @@
# This file declares the dependencies we use, using `FetchContent`.
# https://cmake.org/cmake.help/latest/guide/using-dependencies/index.html#downloading-and-building-from-source-with-fetchcontent
# These are kept in a separate file so that it can be hashed as a key for our CI's `actions/cache`.
FetchContent_Declare(PNG
URL https://download.sourceforge.net/libpng/libpng-1.6.58.tar.xz
URL_HASH SHA256=28eb403f51f0f7405249132cecfe82ea5c0ef97f1b32c5a65828814ae0d34775
EXCLUDE_FROM_ALL # We only install the runtime dependencies, and do so separately.
FIND_PACKAGE_ARGS 1.5.4)
set(PNG_TESTS OFF CACHE INTERNAL "") # We do not need libpng's tests or tools
set(PNG_TOOLS OFF CACHE INTERNAL "") # (and they can even cause compile errors!)
set(PNG_SHARED OFF CACHE INTERNAL "")
set(PNG_STATIC ON CACHE INTERNAL "")
FetchContent_Declare(ZLIB
URL https://www.zlib.net/zlib-1.3.2.tar.xz
URL_HASH SHA256=d7a0654783a4da529d1bb793b7ad9c3318020af77667bcae35f95d0e42a792f3
EXCLUDE_FROM_ALL # We only install the runtime dependencies, and do so separately.
# libpng documents requiring "zlib 1.0.4 or later (1.2.13 or later recommended for performance and security reasons)".
# We thus enforce 1.0.4, but note that the libpng source code mentions that "it may work with versions as old as zlib 0.95".
FIND_PACKAGE_ARGS 1.0.4)
set(ZLIB_BUILD_SHARED OFF CACHE INTERNAL "")
set(ZLIB_BUILD_STATIC ON CACHE INTERNAL "")
-33
View File
@@ -1,33 +0,0 @@
# This file is meant to be included at the project level,
# in order to generate executables compatible with old macOS versions.
# See our `macos-static` CMake preset for how it's meant to be used.
# Note that targeting old enough versions of Mac OS X on recent enough versions of macOS
# triggers some poorly-tested code paths within Apple's linker, which then crashes.
# This can be worked around by using LLVM's LLD linker and passing `-fuse-ld=lld` when linking.
# The `-mmacosx-version-min=10.4` flag ensures that the binary only uses APIs available on Mac OS X 10.4 Tiger.
# The `-arch` flags build a "fat binary" that works on both Apple architectures:
# older Intel x64 Macs and newer ARM "Apple Silicon" ones.
set(secret_sauce -mmacosx-version-min=10.4 "SHELL:-arch x86_64" "SHELL:-arch arm64") # Avoid `-arch` being dedup'd.
add_compile_options(${secret_sauce})
add_link_options(${secret_sauce})
set(PNG_HARDWARE_OPTIMIZATIONS OFF) # These do not play well with a dual-arch build.
# Mac OS X has always provided zlib, so we can safely link dynamically against it.
# However, libpng is *not* provided by default, so we link it statically, which requires downloading and building it from source.
set(PNG_SHARED OFF)
set(PNG_STATIC ON)
# If libpng is already available (e.g. via Homebrew), we ignore that and still build our own.
set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE NEVER)
# But we still want to attempt linking against the system's zlib.
function(rgbds_provide_dependency method dep_name)
if(dep_name STREQUAL "ZLIB")
find_package(ZLIB)
if(ZLIB_FOUND)
FetchContent_SetPopulated(ZLIB)
endif()
endif()
endfunction(rgbds_provide_dependency)
cmake_language(SET_DEPENDENCY_PROVIDER rgbds_provide_dependency
SUPPORTED_METHODS FETCHCONTENT_MAKEAVAILABLE_SERIAL)
-22
View File
@@ -1,22 +0,0 @@
# From https://www.mingw-w64.org/build-systems/cmake/
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR i686)
# Specify the cross-compiler.
set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
# Specify the target environment.
set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
# Search for programs in the build host directories.
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Search for libraries and headers in the target directories.
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# CMake determines how to examine dependencies based on the *host* system, leading to
# a "file unknown error" unless the target platform is explicitly specified.
set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM "windows+pe")
-22
View File
@@ -1,22 +0,0 @@
# From https://www.mingw-w64.org/build-systems/cmake/
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
# Specify the cross-compiler.
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
# Specify the target environment.
set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
# Search for programs in the build host directories.
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Search for libraries and headers in the target directories.
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# CMake determines how to examine dependencies based on the *host* system, leading to
# a "file unknown error" unless the target platform is explicitly specified.
set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM "windows+pe")
-228
View File
@@ -1,228 +0,0 @@
#!/usr/bin/env bash
# Known bugs:
# - Newlines in file/directory names break this script
# This is because we rely on `compgen -A`, which is broken like this.
# A fix would require implementing it ourselves, and no thanks!
# - `rgbasm --binary-digits=a` is treated the same as `rgbasm --binary-digits=` (for example)
# This is not our fault, Bash passes both of these identically.
# Maybe it could be worked around, but such a fix would likely be involved.
# The user can work around it by typing `--binary-digits ''` instead, for example.
# - Directories are not completed as such in "coalesced" short-opt arguments. For example,
# `rgbasm -M d<tab>` can autocomplete to `rgbasm -M dir/` (no space), but
# `rgbasm -Md<tab>` would autocomplete to `rgbasm -Mdir ` (trailing space) instead.
# This is because directory handling is performed by Readline, whom we can't tell about the short
# opt kerfuffle. The user can work around by separating the argument, as shown above.
# (Also, there might be more possible bugs if `-Mdir` is actually a directory. Ugh.)
# Something to note:
# `rgbasm --binary-digits=a` gets passed to us as ('rgbasm' '--binary-digits' '=' 'a')
# Thus, we don't need to do much to handle that form of argument passing: skip '=' after long opts.
_rgbasm_completions() {
# Format: "long_opt:state_after"
# Empty long opt = it doesn't exit
# See the `state` variable below for info about `state_after`
declare -A opts=(
[h]="help:normal"
[V]="version:normal"
[W]="warning:warning"
[w]=":normal"
[B]="backtrace:unk"
[b]="binary-digits:unk"
[D]="define:unk"
[E]="export-all:normal"
[g]="gfx-chars:unk"
[I]="include:dir"
[M]="dependfile:glob-*.mk *.d"
[o]="output:glob-*.o"
[P]="preinclude:glob-*.asm *.inc"
[p]="pad-value:unk"
[Q]="q-precision:unk"
[r]="recursion-depth:unk"
[s]="state:unk"
[v]="verbose:normal"
[X]="max-errors:unk"
)
# Parse command-line up to current word
local opt_ena=true
# Possible states:
# - normal = Well, normal. Options are parsed normally.
# - unk = An argument that can't be completed, and should just be skipped.
# - warning = A warning flag.
# - dir = A directory path
# - glob-* = A glob, after the dash is a whitespace-separated list of file globs to use
local state=normal
# The length of the option, used as a return value by the function below
local optlen=0
# $1: a short option word
# `state` will be set to the parsing state after the last option character in the word. If
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
# part of the argument.
parse_short_opt() {
# These options act like a long option (= takes up the entire word), but only use a single dash
# So, they need some special handling
if [[ "$1" = "-M"[CGP] ]]; then
state=normal
optlen=${#1}
return;
elif [[ "$1" = "-M"[QT] ]]; then
state='glob-*.d *.mk *.o'
optlen=${#1}
return;
fi
for (( i = 1; i < "${#1}"; i++ )); do
# If the option is not known, assume it doesn't take an argument
local opt="${opts["${1:$i:1}"]:-":normal"}"
state="${opt#*:}"
# If the option takes an argument, record the length and exit
if [[ "$state" != 'normal' ]]; then
let optlen="$i + 1"
return
fi
done
optlen=0
}
for (( i = 1; i < COMP_CWORD; i++ )); do
local word="${COMP_WORDS[$i]}"
# If currently processing an argument, skip this word
if [[ "$state" != 'normal' ]]; then
state=normal
continue
fi
if [[ "$word" = '--' ]]; then
# Options stop being parsed after this
opt_ena=false
break
fi
# Check if it's a long option
if [[ "$word" = '--'* ]]; then
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
for long_opt in "${opts[@]}"; do
if [[ "$word" = "--${long_opt%%:*}" ]]; then
state="${long_opt#*:}"
# Check if the next word is just '='; if so, skip it, the argument must follow
# (See "known bugs" at the top of this script)
let i++
if [[ "${COMP_WORDS[$i]}" != '=' ]]; then
let i--
fi
optlen=0
break
fi
done
# Check if it's a short option
elif [[ "$word" = '-'* ]]; then
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
if [[ "$optlen" -ne "${#word}" ]]; then
# If it's contained within the word, we won't complete it, revert to "normal"
state=normal
else
# Otherwise, complete it, but start at the beginning of *that* word
optlen=0
fi
fi
fi
done
# Parse current word
# Careful that it might look like an option, so use `--` aggressively!
local cur_word="${COMP_WORDS[$i]}"
# Process options, as short ones may change the state
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
# We might want to complete to an option or an arg to that option
# Parse the option word to check
# There's no whitespace in the option names, so we can ride a little dirty...
# Is this a long option?
if [[ "$cur_word" = '--'* ]]; then
# It is, try to complete one
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
return 0
elif [[ "$cur_word" = '-M'[CGPQT] ]]; then
# These options act like long opts with no arguments, so return them and exactly them
COMPREPLY=( "$cur_word" )
return 0
else
# Short options may be grouped, parse them to determine what to complete
parse_short_opt "$cur_word"
if [[ "$state" = 'normal' ]]; then
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" ''; compgen -W '-MC -MG -MP -MQ -MT' "$cur_word")
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
# Post the option group as-is as a reply so that Readline inserts a space,
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY=( "$cur_word" )
return 0
fi
fi
fi
COMPREPLY=()
case "$state" in
unk) # Return with no replies: no idea what to complete!
;;
warning)
mapfile -t COMPREPLY < <(compgen -W "
assert
backwards-for
builtin-args
charmap-redef
div
empty-data-directive
empty-macro-arg
empty-strrpl
export-undefined
large-constant
macro-shift
nested-comment
numeric-string
obsolete
purge
shift
shift-amount
truncation
unmapped-char
unmatched-directive
unterminated-load
user
all
extra
everything
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
;;
normal) # Acts like a glob...
state="glob-*.asm *.inc *.sm83"
;&
glob-*)
while read -r word; do
COMPREPLY+=("${cur_word:0:$optlen}$word")
done < <(for glob in ${state#glob-}; do compgen -A file -X \!"$glob" -- "${cur_word:$optlen}"; done)
# Also complete directories
;&
dir)
while read -r word; do
COMPREPLY+=("${cur_word:0:$optlen}$word")
done < <(compgen -A directory -- "${cur_word:$optlen}")
compopt -o filenames
;;
*)
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
return 1
;;
esac
}
complete -F _rgbasm_completions rgbasm
-201
View File
@@ -1,201 +0,0 @@
#!/usr/bin/env bash
# Same notes as RGBASM
_rgbfix_completions() {
# Format: "long_opt:state_after"
# Empty long opt = it doesn't exit
# See the `state` variable below for info about `state_after`
declare -A opts=(
[h]="help:normal"
[V]="version:normal"
[W]="warning:warning"
[w]=":normal"
[C]="color-only:normal"
[c]="color-compatible:normal"
[f]="fix-spec:fix-spec"
[i]="game-id:unk"
[j]="non-japanese:normal"
[k]="new-licensee:unk"
[L]="custom-logo:glob-*.1bpp"
[l]="old-licensee:unk"
[m]="mbc-type:mbc"
[n]="rom-version:unk"
[o]="output:glob-*.gb *.gbc *.sgb"
[p]="pad-value:unk"
[r]="ram-size:unk"
[s]="sgb-compatible:normal"
[t]="title:unk"
[v]="validate:normal"
)
# Parse command-line up to current word
local opt_ena=true
# Possible states:
# - normal = Well, normal. Options are parsed normally.
# - unk = An argument that can't be completed, and should just be skipped.
# - warning = A warning flag.
# - dir = A directory path
# - glob-* = A glob, after the dash is a whitespace-separated list of file globs to use
local state=normal
# The length of the option, used as a return value by the function below
local optlen=0
# $1: a short option word
# `state` will be set to the parsing state after the last option character in the word. If
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
# part of the argument.
parse_short_opt() {
for (( i = 1; i < "${#1}"; i++ )); do
# If the option is not known, assume it doesn't take an argument
local opt="${opts["${1:$i:1}"]:-":normal"}"
state="${opt#*:}"
# If the option takes an argument, record the length and exit
if [[ "$state" != 'normal' ]]; then
let optlen="$i + 1"
return
fi
done
optlen=0
}
for (( i = 1; i < COMP_CWORD; i++ )); do
local word="${COMP_WORDS[$i]}"
# If currently processing an argument, skip this word
if [[ "$state" != 'normal' ]]; then
state=normal
continue
fi
if [[ "$word" = '--' ]]; then
# Options stop being parsed after this
opt_ena=false
break
fi
# Check if it's a long option
if [[ "$word" = '--'* ]]; then
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
for long_opt in "${opts[@]}"; do
if [[ "$word" = "--${long_opt%%:*}" ]]; then
state="${long_opt#*:}"
# Check if the next word is just '='; if so, skip it, the argument must follow
# (See "known bugs" at the top of this script)
let i++
if [[ "${COMP_WORDS[$i]}" != '=' ]]; then
let i--
fi
optlen=0
break
fi
done
# Check if it's a short option
elif [[ "$word" = '-'* ]]; then
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
if [[ "$optlen" -ne "${#word}" ]]; then
# If it's contained within the word, we won't complete it, revert to "normal"
state=normal
else
# Otherwise, complete it, but start at the beginning of *that* word
optlen=0
fi
fi
fi
done
# Parse current word
# Careful that it might look like an option, so use `--` aggressively!
local cur_word="${COMP_WORDS[$i]}"
# Process options, as short ones may change the state
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
# We might want to complete to an option or an arg to that option
# Parse the option word to check
# There's no whitespace in the option names, so we can ride a little dirty...
# Is this a long option?
if [[ "$cur_word" = '--'* ]]; then
# It is, try to complete one
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
return 0
else
# Short options may be grouped, parse them to determine what to complete
parse_short_opt "$cur_word"
if [[ "$state" = 'normal' ]]; then
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
# Post the option group as-is as a reply so that Readline inserts a space,
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY=( "$cur_word" )
return 0
fi
fi
fi
COMPREPLY=()
case "$state" in
unk) # Return with no replies: no idea what to complete!
;;
warning)
mapfile -t COMPREPLY < <(compgen -W "
mbc
obsolete
overwrite
sgb
truncation
all
everything
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
;;
fix-spec)
COMPREPLY=( "${cur_word}"{l,h,g,L,H,G} )
;;
mbc)
local cur_arg="${cur_word:$optlen}"
cur_arg="${cur_arg@U}"
compopt -o nosort # Keep `help` first in the list, mainly
mapfile -t COMPREPLY < <(compgen -W "help" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
mapfile -t COMPREPLY -O ${#COMPREPLY} < <(compgen -W "
ROM_ONLY
MBC1{,+RAM,+RAM+BATTERY}
MBC2{,+BATTERY}
MMM01{,+RAM}
MBC3{+TIMER+BATTERY,+TIMER+RAM+BATTERY,,+RAM,+RAM+BATTERY}
MBC5{,+RAM,+RAM+BATTERY,+RUMBLE,+RUMBLE+RAM,+RUMBLE+RAM+BATTERY}
MBC6
MBC7+SENSOR+RUMBLE+RAM+BATTERY
POCKET_CAMERA
BANDAI_TAMA5
HUC3
HUC1+RAM+BATTERY
TPP1_1.0{,+BATTERY}{,+RTC}{,+RUMBLE,+MULTIRUMBLE}" -P "${cur_word:0:$optlen}" -- "${cur_word/ /_}")
;;
normal) # Acts like a glob...
state="glob-*.gb *.gbc *.sgb"
;&
glob-*)
while read -r word; do
COMPREPLY+=("${cur_word:0:$optlen}$word")
done < <(for glob in ${state#glob-}; do compgen -A file -X \!"$glob" -- "${cur_word:$optlen}"; done)
# Also complete directories
;&
dir)
while read -r word; do
COMPREPLY+=("${cur_word:0:$optlen}$word")
done < <(compgen -A directory -- "${cur_word:$optlen}")
compopt -o filenames
;;
*)
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
return 1
;;
esac
}
complete -F _rgbfix_completions rgbfix
-188
View File
@@ -1,188 +0,0 @@
#!/usr/bin/env bash
# Same notes as RGBASM
_rgbgfx_completions() {
# Format: "long_opt:state_after"
# Empty long opt = it doesn't exit
# See the `state` variable below for info about `state_after`
declare -A opts=(
[h]="help:normal"
[V]="version:normal"
[W]="warning:warning"
[w]=":normal"
[A]="auto-attr-map:normal"
[a]="attr-map:glob-*.attrmap"
[B]="background-color:unk"
[b]="base-tiles:unk"
[C]="color-curve:normal"
[c]="colors:unk"
[d]="depth:unk"
[i]="input-tileset:glob-*.2bpp"
[L]="slice:unk"
[m]="mirror-tiles:normal"
[N]="nb-tiles:unk"
[n]="nb-palettes:unk"
[O]="group-outputs:normal"
[o]="output:glob-*.2bpp"
[P]="auto-palette:normal"
[p]="palette:glob-*.pal"
[Q]="auto-palette-map:normal"
[q]="palette-map:glob-*.palmap"
[r]="reverse:unk"
[s]="palette-size:unk"
[T]="auto-tilemap:normal"
[t]="tilemap:glob-*.tilemap"
[u]="unique-tiles:normal"
[v]="verbose:normal"
[X]="mirror-x:normal"
[x]="trim-end:unk"
[Y]="mirror-y:normal"
[Z]="columns:normal"
)
# Parse command-line up to current word
local opt_ena=true
# Possible states:
# - normal = Well, normal. Options are parsed normally.
# - unk = An argument that can't be completed, and should just be skipped.
# - warning = A warning flag.
# - dir = A directory path
# - glob-* = A glob, after the dash is a whitespace-separated list of file globs to use
local state=normal
# The length of the option, used as a return value by the function below
local optlen=0
# $1: a short option word
# `state` will be set to the parsing state after the last option character in the word. If
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
# part of the argument.
parse_short_opt() {
for (( i = 1; i < "${#1}"; i++ )); do
# If the option is not known, assume it doesn't take an argument
local opt="${opts["${1:$i:1}"]:-":normal"}"
state="${opt#*:}"
# If the option takes an argument, record the length and exit
if [[ "$state" != 'normal' ]]; then
let optlen="$i + 1"
return
fi
done
optlen=0
}
for (( i = 1; i < COMP_CWORD; i++ )); do
local word="${COMP_WORDS[$i]}"
# If currently processing an argument, skip this word
if [[ "$state" != 'normal' ]]; then
state=normal
continue
fi
if [[ "$word" = '--' ]]; then
# Options stop being parsed after this
opt_ena=false
break
fi
# Check if it's a long option
if [[ "$word" = '--'* ]]; then
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
for long_opt in "${opts[@]}"; do
if [[ "$word" = "--${long_opt%%:*}" ]]; then
state="${long_opt#*:}"
# Check if the next word is just '='; if so, skip it, the argument must follow
# (See "known bugs" at the top of this script)
let i++
if [[ "${COMP_WORDS[$i]}" != '=' ]]; then
let i--
fi
optlen=0
break
fi
done
# Check if it's a short option
elif [[ "$word" = '-'* ]]; then
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
if [[ "$optlen" -ne "${#word}" ]]; then
# If it's contained within the word, we won't complete it, revert to "normal"
state=normal
else
# Otherwise, complete it, but start at the beginning of *that* word
optlen=0
fi
fi
fi
done
# Parse current word
# Careful that it might look like an option, so use `--` aggressively!
local cur_word="${COMP_WORDS[$i]}"
# Process options, as short ones may change the state
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
# We might want to complete to an option or an arg to that option
# Parse the option word to check
# There's no whitespace in the option names, so we can ride a little dirty...
# Is this a long option?
if [[ "$cur_word" = '--'* ]]; then
# It is, try to complete one
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
return 0
else
# Short options may be grouped, parse them to determine what to complete
parse_short_opt "$cur_word"
if [[ "$state" = 'normal' ]]; then
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
# Post the option group as-is as a reply so that Readline inserts a space,
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY=( "$cur_word" )
return 0
fi
fi
fi
COMPREPLY=()
case "$state" in
unk) # Return with no replies: no idea what to complete!
;;
warning)
mapfile -t COMPREPLY < <(compgen -W "
embedded
obsolete
trim-nonempty
all
everything
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
;;
normal) # Acts like a glob...
state="glob-*.png"
;&
glob-*)
while read -r word; do
COMPREPLY+=("${cur_word:0:$optlen}$word")
done < <(for glob in ${state#glob-}; do compgen -A file -X \!"$glob" -- "${cur_word:$optlen}"; done)
# Also complete directories
;&
dir)
while read -r word; do
COMPREPLY+=("${cur_word:0:$optlen}$word")
done < <(compgen -A directory -- "${cur_word:$optlen}")
compopt -o filenames
;;
*)
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
return 1
;;
esac
}
complete -F _rgbgfx_completions rgbgfx
-176
View File
@@ -1,176 +0,0 @@
#!/usr/bin/env bash
# Same notes as RGBASM
_rgblink_completions() {
# Format: "long_opt:state_after"
# Empty long opt = it doesn't exit
# See the `state` variable below for info about `state_after`
declare -A opts=(
[h]="help:normal"
[V]="version:normal"
[W]="warning:warning"
[M]="no-sym-in-map:normal"
[d]="dmg:normal"
[B]="backtrace:unk"
[l]="linkerscript:glob-*"
[m]="map:glob-*.map"
[n]="sym:glob-*.sym"
[O]="overlay:glob-*.gb *.gbc *.sgb"
[o]="output:glob-*.gb *.gbc *.sgb"
[p]="pad:unk"
[t]="tiny:normal"
[v]="verbose:normal"
[w]="wramx:normal"
[x]="nopad:normal"
)
# Parse command-line up to current word
local opt_ena=true
# Possible states:
# - normal = Well, normal. Options are parsed normally.
# - unk = An argument that can't be completed, and should just be skipped.
# - warning = A warning flag.
# - dir = A directory path
# - glob-* = A glob, after the dash is a whitespace-separated list of file globs to use
local state=normal
# The length of the option, used as a return value by the function below
local optlen=0
# $1: a short option word
# `state` will be set to the parsing state after the last option character in the word. If
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
# part of the argument.
parse_short_opt() {
for (( i = 1; i < "${#1}"; i++ )); do
# If the option is not known, assume it doesn't take an argument
local opt="${opts["${1:$i:1}"]:-":normal"}"
state="${opt#*:}"
# If the option takes an argument, record the length and exit
if [[ "$state" != 'normal' ]]; then
let optlen="$i + 1"
return
fi
done
optlen=0
}
for (( i = 1; i < COMP_CWORD; i++ )); do
local word="${COMP_WORDS[$i]}"
# If currently processing an argument, skip this word
if [[ "$state" != 'normal' ]]; then
state=normal
continue
fi
if [[ "$word" = '--' ]]; then
# Options stop being parsed after this
opt_ena=false
break
fi
# Check if it's a long option
if [[ "$word" = '--'* ]]; then
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
for long_opt in "${opts[@]}"; do
if [[ "$word" = "--${long_opt%%:*}" ]]; then
state="${long_opt#*:}"
# Check if the next word is just '='; if so, skip it, the argument must follow
# (See "known bugs" at the top of this script)
let i++
if [[ "${COMP_WORDS[$i]}" != '=' ]]; then
let i--
fi
optlen=0
break
fi
done
# Check if it's a short option
elif [[ "$word" = '-'* ]]; then
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
if [[ "$optlen" -ne "${#word}" ]]; then
# If it's contained within the word, we won't complete it, revert to "normal"
state=normal
else
# Otherwise, complete it, but start at the beginning of *that* word
optlen=0
fi
fi
fi
done
# Parse current word
# Careful that it might look like an option, so use `--` aggressively!
local cur_word="${COMP_WORDS[$i]}"
# Process options, as short ones may change the state
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
# We might want to complete to an option or an arg to that option
# Parse the option word to check
# There's no whitespace in the option names, so we can ride a little dirty...
# Is this a long option?
if [[ "$cur_word" = '--'* ]]; then
# It is, try to complete one
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
return 0
else
# Short options may be grouped, parse them to determine what to complete
parse_short_opt "$cur_word"
if [[ "$state" = 'normal' ]]; then
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
# Post the option group as-is as a reply so that Readline inserts a space,
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY=( "$cur_word" )
return 0
fi
fi
fi
COMPREPLY=()
case "$state" in
unk) # Return with no replies: no idea what to complete!
;;
warning)
mapfile -t COMPREPLY < <(compgen -W "
assert
div
large-constant
obsolete
shift
shift-amount
truncation
all
everything
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
;;
normal) # Acts like a glob...
state="glob-*.o *.obj"
;&
glob-*)
while read -r word; do
COMPREPLY+=("${cur_word:0:$optlen}$word")
done < <(for glob in ${state#glob-}; do compgen -A file -X \!"$glob" -- "${cur_word:$optlen}"; done)
# Also complete directories
;&
dir)
while read -r word; do
COMPREPLY+=("${cur_word:0:$optlen}$word")
done < <(compgen -A directory -- "${cur_word:$optlen}")
compopt -o filenames
;;
*)
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
return 1
;;
esac
}
complete -F _rgblink_completions rgblink
-75
View File
@@ -1,75 +0,0 @@
#!/usr/bin/env bash
set -eu
usage() {
cat <<"EOF"
Generates LCOV code coverage report for RGBDS.
Options:
-h, --help show this help message
-o, --open open the HTML report in the preferred application
--jobs <n> build RGBDS and external codebases with `make -j<n>`
--os <os> skip tests known to fail on <os> (e.g. `macos-14`)
EOF
}
# Parse options in pure Bash because macOS `getopt` is stuck
# in what util-linux `getopt` calls `GETOPT_COMPATIBLE` mode
make_args=()
runtests_args=()
open_report=false
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
-o|--open)
open_report=true
;;
--jobs)
shift
make_args+=(-j "$1")
runtests_args+=(--jobs "$1")
;;
--os)
shift
runtests_args+=(--os "$1")
;;
*)
echo "$(basename "$0"): unknown option '$1'"
exit 1
;;
esac
shift
done
# Build RGBDS with gcov support
make coverage "${make_args[@]}"
# Run the tests
pushd test
external/fetch-repos.sh
./run-tests.sh "${runtests_args[@]}"
popd
# Generate coverage logs
gcov src/**/*.cpp
mkdir -p coverage
# Generate coverage report, excluding Bison-generated files
COVERAGE_INFO=coverage/coverage.info
lcov -c --no-external -d . -o "$COVERAGE_INFO"
lcov -r "$COVERAGE_INFO" src/asm/parser.{hpp,cpp} src/link/script.{hpp,cpp} -o "$COVERAGE_INFO"
genhtml --dark-mode --num-spaces 4 -f -s -o coverage/ "$COVERAGE_INFO"
if "$open_report"; then
# Open the report in the preferred web browser
if [ "$(uname)" == "Darwin" ]; then
open coverage/index.html
else
xdg-open coverage/index.html
fi
else
# Output the path to the report
echo "Generated LCOV report at $PWD/coverage/index.html"
fi
+37 -18
View File
@@ -1,54 +1,73 @@
#!/usr/bin/env bash
#!/bin/bash
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2020 Eldred Habert
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
STATE=0
diff <(xxd "$1") <(xxd "$2") | while read -r LINE; do
if [[ $STATE -eq 0 ]]; then
diff <(xxd $1) <(xxd $2) | while read -r LINE; do
if [ $STATE -eq 0 ]; then
# Discard first line (line info)
STATE=1
elif [[ "$LINE" = '---' ]]; then
elif [ "$LINE" = '---' ]; then
# Separator between files switches states
echo "$LINE"
echo $LINE
STATE=3
elif grep -Eq '^[0-9]+(,[0-9]+)?[cd][0-9]+(,[0-9]+)?' <<< "$LINE"; then
# Line info resets the whole thing
STATE=1
elif [[ $STATE -eq 1 || $STATE -eq 3 ]]; then
elif [ $STATE -eq 1 -o $STATE -eq 3 ]; then
# Compute the GB address from the ROM offset
OFS=$(cut -d ' ' -f 2 <<< "$LINE" | tr -d ':')
BANK=$((0x$OFS / 0x4000))
ADDR=$((0x$OFS % 0x4000 + (BANK != 0) * 0x4000))
ADDR=$((0x$OFS % 0x4000 + ($BANK != 0) * 0x4000))
# Try finding the preceding symbol closest to the diff
if [[ $STATE -eq 1 ]]; then
if [ $STATE -eq 1 ]; then
STATE=2
SYMFILE=${1%.*}.sym
else
STATE=4
SYMFILE=${2%.*}.sym
fi
EXTRA=$(if [[ -f "$SYMFILE" ]]; then
EXTRA=$(if [ -f "$SYMFILE" ]; then
# Read the sym file for such a symbol
# Ignore comment lines, only pick matching bank
# (The bank regex ignores comments already, make `cut` and `tr` process less lines)
grep -Ei "$(printf "^%02x:" $BANK)" "$SYMFILE" |
sed "s/$(printf "^%02x:" $BANK)/0x/g" |
grep -Ei $(printf "^%02x:" $BANK) "$SYMFILE" |
cut -d ';' -f 1 |
tr -d "\r" |
sort -g |
while read -r SYMADDR SYM; do
SYMADDR=$(($SYMADDR))
if [[ $SYMADDR -le $ADDR ]]; then
printf " (%s+0x%x)\n" "$SYM" $((ADDR - SYMADDR))
SYMADDR=$((0x${SYMADDR#*:}))
if [ $SYMADDR -le $ADDR ]; then
printf " (%s+%#x)\n" "$SYM" $(($ADDR - $SYMADDR))
fi
# TODO: assumes sorted sym files
done | tail -n 1
fi)
printf "%02x:%04x %s\n" $BANK $ADDR "$EXTRA"
printf "%02x:%04x %s\n" $BANK $ADDR $EXTRA
fi
if [[ $STATE -eq 2 || $STATE -eq 4 ]]; then
if [ $STATE -eq 2 -o $STATE -eq 4 ]; then
OFS=$(cut -d ' ' -f 2 <<< "$LINE" | tr -d ':')
BANK=$((0x$OFS / 0x4000))
ADDR=$((0x$OFS % 0x4000 + (BANK != 0) * 0x4000))
ADDR=$((0x$OFS % 0x4000 + ($BANK != 0) * 0x4000))
printf "%s %02x:%04x: %s\n" "${LINE:0:1}" $BANK $ADDR "${LINE#*: }"
fi
done
-25
View File
@@ -1,25 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -ne 2 ]]; then
cat <<EOF >&2
Usage: $0 <palettes.pal> <output.png>
EOF
exit 1
fi
TMP=$(mktemp -d)
readonly TMP
trap 'rm -rf "$TMP"' EXIT
tile() { for i in {0..7}; do printf "$1"; done }
{ tile '\x00\x00' && tile '\xFF\x00' && tile '\x00\xFF' && tile '\xFF\xFF'; } >"$TMP/tmp.2bpp"
NB_BYTES=$(wc -c <"$1")
(( NB_PALS = NB_BYTES / 8 ))
for (( i = 0; i < NB_PALS; i++ )); do
printf '\0\1\2\3' >>"$TMP/tmp.tilemap"
printf $(printf '\\x%x' $i{,,,}) >> "$TMP/tmp.palmap"
done
"${RGBGFX:-${RGBDS+$RGBDS/}rgbgfx}" -r 4 "$2" -o "$TMP/tmp.2bpp" -OTQ -p "$1" -n "$NB_PALS"
+14 -34
View File
@@ -9,61 +9,41 @@ _rgbasm_warnings() {
'everything:Enable literally everything'
'assert:Warn when WARN-type asserts fail'
'backwards-for:Warn when start and stop are backwards relative to step'
'builtin-args:Report incorrect args to built-in funcs'
'charmap-redef:Warn when redefining a charmap mapping'
'div:Warn when dividing the smallest int by -1'
'empty-data-directive:Warn on arg-less d[bwl] in ROM'
'empty-macro-arg:Warn on empty macro arg'
'empty-strrpl:Warn on calling STRRPL with empty pattern'
'export-undefined:Warn on EXPORT of an undefined symbol'
'empty-entry:Warn on empty entries in db, dw, dl args'
'large-constant:Warn on constants too large for a signed 32-bit int'
'macro-shift:Warn when shifting macro args part their limits'
'nested-comment:Warn on "/*" inside block comments'
'numeric-string:Warn when a multi-character string is treated as a number'
'long-string:Warn on strings too long'
'obsolete:Warn when using deprecated features'
'purge:Warn when purging exported symbols or labels'
'shift:Warn when shifting negative values'
'shift-amount:Warn when a shift'\''s operand is negative or \> 32'
'truncation:Warn when implicit truncation loses bits'
'unmapped-char:Warn on unmapped character'
'unmatched-directive:Warn on unmatched directive pair'
'unterminated-load:Warn on LOAD without ENDL'
'shift-amount:Warn when a shift'\''s operand it negative or \> 32'
'truncation:Warn when implicit truncations lose bits'
'user:Warn when executing the WARN built-in'
)
# TODO: handle `no-` and `error=` somehow?
_describe warning warnings
}
local args=(
# Arguments are listed here in the same order as in the manual, except for the version and help
'(- : * options)'{-V,--version}'[Print version number and exit]'
'(- : * options)'{-h,--help}'[Print help text and exit]'
# Arguments are listed here in the same order as in the manual, except for the version
'(- : * options)'{-V,--version}'[Print version number]'
'(-E --export-all)'{-E,--export-all}'[Export all symbols]'
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
'(-h --halt-without-nop)'{-h,--halt-without-nop}'[Avoid outputting a `nop` after `halt`]'
'(-L ---preserve-ld)'{-L,--preserve-ld}'[Prevent auto-optimizing `ld` into `ldh`]'
'(-v --verbose)'{-v,--verbose}'[Print additional messages regarding progression]'
-w'[Disable all warnings]'
'(-B --backtrace)'{-B,--backtrace}'+[Set backtrace depth or style]:param:'
'(-b --binary-digits)'{-b,--binary-digits}'+[Change chars for binary constants]:digit spec:'
--color'[Whether to use color in output]:color:(auto always never)'
'*'{-D,--define}'+[Define a string symbol]:name + value (default 1):'
'(-D --define)'{-D,--define}'+[Define a string symbol]:name + value (default 1):'
'(-g --gfx-chars)'{-g,--gfx-chars}'+[Change chars for gfx constants]:chars spec:'
'(-I --include)'{-I,--include}'+[Add an include directory]:include path:_files -/'
'(-M --dependfile)'{-M,--dependfile}"+[Write dependencies in Makefile format]:output file:_files -g '*.{d,mk}'"
-MC'[Continue after missing dependencies]'
-MG'[Assume missing dependencies should be generated]'
-MP'[Add phony targets to all dependencies]'
'*'-MT"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
'*'-MQ"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
'(-i --include)'{-i,--include}'+[Add an include directory]:include path:_files -/'
'(-M --dependfile)'{-M,--dependfile}"+[List deps in make format]:output file:_files -g '*.{d,mk}"
'(-o --output)'{-o,--output}'+[Output file]:output file:_files'
'(-P --preinclude)'{-P,--preinclude}"+[Pre-include a file]:include file:_files -g '*.{asm,inc}'"
'(-p --pad-value)'{-p,--pad-value}'+[Set padding byte]:padding byte:'
'(-Q --q-precision)'{-Q,--q-precision}'+[Set fixed-point precision]:precision:'
'(-r --recursion-depth)'{-r,--recursion-depth}'+[Set maximum recursion depth]:depth:'
'(-s --state)'{-s,--state}"+[Write features of final state]:state file:_files -g '*.dump.asm'"
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgbasm_warnings'
'(-X --max-errors)'{-X,--max-errors}'+[Set maximum errors before aborting]:maximum errors:'
":assembly sources:_files -g '*.asm'"
'*'":assembly sources:_files -g '*.asm'"
)
_arguments -s -S : $args
+5 -62
View File
@@ -1,81 +1,24 @@
#compdef rgbfix
_mbc_names() {
local mbc_names=(
'ROM:$00'
'MBC1:$01'
'MBC1+RAM:$02'
'MBC1+RAM+BATTERY:$03'
'MBC2:$05'
'MBC2+BATTERY:$06'
'ROM+RAM:$08'
'ROM+RAM+BATTERY:$09'
'MMM01:$0B'
'MMM01+RAM:$0C'
'MMM01+RAM+BATTERY:$0D'
'MBC3+TIMER+BATTERY:$0F'
'MBC3+TIMER+RAM+BATTERY:$10'
'MBC3:$11'
'MBC3+RAM:$12'
'MBC3+RAM+BATTERY:$13'
'MBC5:$19'
'MBC5+RAM:$1A'
'MBC5+RAM+BATTERY:$1B'
'MBC5+RUMBLE:$1C'
'MBC5+RUMBLE+RAM:$1D'
'MBC5+RUMBLE+RAM+BATTERY:$1E'
'MBC6:$20'
'MBC7+SENSOR+RUMBLE+RAM+BATTERY:$22'
'POCKET_CAMERA:$FC'
'BANDAI_TAMA5:$FD'
'HUC3:$FE'
'HUC1+RAM+BATTERY:$FF'
)
_describe "MBC name" mbc_names
}
_rgbfix_warnings() {
local warnings=(
'error:Turn all warnings into errors'
'all:Enable most warning messages'
'everything:Enable literally everything'
'mbc:Warn about issues with MBC specs'
'obsolete:Warn when using deprecated features'
'overwrite:Warn when overwriting non-zero bytes'
'sgb:Warn when SGB flag conflicts with old licensee code'
'truncation:Warn when values are truncated to fit'
)
_describe warning warnings
}
local args=(
# Arguments are listed here in the same order as in the manual, except for the version and help
'(- : * options)'{-V,--version}'[Print version number and exit]'
'(- : * options)'{-h,--help}'[Print help text and exit]'
# Arguments are listed here in the same order as in the manual, except for the version
'(- : * options)'{-V,--version}'[Print version number]'
'(-C --color-only -c --color-compatible)'{-C,--color-only}'[Mark ROM as GBC-only]'
'(-C --color-only -c --color-compatible)'{-c,--color-compatible}'[Mark ROM as GBC-compatible]'
'(-C --color-only)'{-C,--color-only}'[Mark ROM as GBC-only]'
'(-c --color-compatible)'{-c,--color-compatible}'[Mark ROM as GBC-compatible]'
'(-j --non-japanese)'{-j,--non-japanese}'[Set the non-Japanese region flag]'
'(-O --overwrite)'{-O,--overwrite}'[Allow overwriting non-zero bytes]'
'(-s --sgb-compatible)'{-s,--sgb-compatible}'[Set the SGB flag]'
'(-f --fix-spec -v --validate)'{-v,--validate}'[Shorthand for -f lhg]'
-w'[Disable all warnings]'
--color'[Whether to use color in output]:color:(auto always never)'
'(-f --fix-spec -v --validate)'{-f,--fix-spec}'+[Fix or trash some header values]:fix spec:'
'(-i --game-id)'{-i,--game-id}'+[Set game ID string]:4-char game ID:'
'(-k --new-licensee)'{-k,--new-licensee}'+[Set new licensee string]:2-char licensee ID:'
'(-l --old-licensee)'{-l,--old-licensee}'+[Set old licensee ID]:licensee number:'
'(-L --logo)'{-L,--logo}'+[Set custom logo]:1bpp image:'
'(-m --mbc-type)'{-m,--mbc-type}"+[Set MBC flags]:mbc name:_mbc_names"
'(-m --mbc-type)'{-m,--mbc-type}'+[Set MBC flags]:mbc flags byte:'
'(-n --rom-version)'{-n,--rom-version}'+[Set ROM version]:rom version byte:'
'(-o --output)'{-o,--output}"+[Output file]:output file:_files -g '*.{gb,sgb,gbc}'"
'(-p --pad-value)'{-p,--pad-value}'+[Pad to next valid size using this byte as padding]:padding byte:'
'(-r --ram-size)'{-r,--ram-size}'+[Set RAM size]:ram size byte:'
'(-t --title)'{-t,--title}'+[Set title string]:11-char title string:'
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgbfix_warnings'
'*'":ROM files:_files -g '*.{gb,sgb,gbc}'"
)
+13 -42
View File
@@ -9,58 +9,29 @@ _depths() {
_describe 'bit depth' depths
}
_rgbgfx_warnings() {
local warnings=(
'error:Turn all warnings into errors'
'all:Enable most warning messages'
'everything:Enable literally everything'
'embedded:Warn when using embedded PLTE without "-c embedded"'
'obsolete:Warn when using deprecated features'
'trim-nonempty:Warn when "-x" trims nonempty tiles'
)
_describe warning warnings
}
local args=(
# Arguments are listed here in the same order as in the manual, except for the version and help
'(- : * options)'{-V,--version}'[Print version number and exit]'
'(- : * options)'{-h,--help}'[Print help text and exit]'
# Arguments are listed here in the same order as in the manual, except for the version
'(- : * options)'{-V,--version}'[Print version number]'
'(-a --attr-map -A --auto-attr-map)'{-A,--auto-attr-map}'[Shortcut for -a <file>.attrmap]'
'(-a --attr-map -A --output-attr-map)'{-A,--output-attr-map}'[Shortcut for -a <file>.attrmap]'
'(-C --color-curve)'{-C,--color-curve}'[Generate palettes using GBC color curve]'
'(-D --debug)'{-D,--debug}'[Enable debug features]'
'(-f --fix -F --fix-and-save)'{-f,--fix}'[Fix input PNG into an indexed image]'
'(-f --fix -F --fix-and-save)'{-F,--fix-and-save}'[Like -f but also save CLI params within the PNG]'
'(-h --horizontal)'{-h,--horizontal}'[Lay out tiles horizontally instead of vertically]'
'(-m --mirror-tiles)'{-m,--mirror-tiles}'[Eliminate mirrored tiles from output]'
'(-O --group-outputs)'{-O,--group-outputs}'[Base "shortcut" options on the output path, not input]'
'(-p --palette -P --auto-palette)'{-P,--auto-palette}'[Shortcut for -p <file>.pal]'
'(-q --palette-map -Q --auto-palette-map)'{-Q,--auto-palette-map}'[Shortcut for -p <file>.palmap]'
'(-t --tilemap -T --auto-tilemap)'{-T,--auto-tilemap}'[Shortcut for -t <file>.tilemap]'
'(-p --palette -P --output-palette)'{-P,--output-palette}'[Shortcut for -p <file>.pal]'
'(-t --tilemap -T --output-tilemap)'{-T,--output-tilemap}'[Shortcut for -t <file>.tilemap]'
'(-u --unique-tiles)'{-u,--unique-tiles}'[Eliminate redundant tiles]'
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
-w'[Disable all warnings]'
'(-X --mirror-x)'{-X,--mirror-x}'[Eliminate horizontally mirrored tiles from output]'
'(-Y --mirror-y)'{-Y,--mirror-y}'[Eliminate vertically mirrored tiles from output]'
'(-Z --columns)'{-Z,--columns}'[Read the image in column-major order]'
'(-a --attr-map -A --auto-attr-map)'{-a,--attr-map}'+[Generate a map of tile attributes (mirroring)]:attrmap file:_files'
'(-B --background-color)'{-B,--background-color}'+[Ignore tiles containing only specified color]:color:'
'(-b --base-tiles)'{-b,--base-tiles}'+[Base tile IDs for tile map output]:base tile IDs:'
--color'[Whether to use color in output]:color:(auto always never)'
'(-c --colors)'{-c,--colors}'+[Specify color palettes]:palette spec:'
'(-a --attr-map -A --output-attr-map)'{-a,--attr-map}'+[Generate a map of tile attributes (mirroring)]:attrmap file:_files'
'(-d --depth)'{-d,--depth}'+[Set bit depth]:bit depth:_depths'
'(-i --input-tileset)'{-i,--input-tileset}'+[Use specific tiles]:tileset file:_files -g "*.2bpp"'
'(-L --slice)'{-L,--slice}'+[Only process a portion of the image]:input slice:'
'(-N --nb-tiles)'{-N,--nb-tiles}'+[Limit number of tiles]:tile count:'
'(-n --nb-palettes)'{-n,--nb-palettes}'+[Limit number of palettes]:palette count:'
'(-o --output)'{-o,--output}'+[Set output file]:output file:_files'
'(-p --palette -P --auto-palette)'{-p,--palette}"+[Output the image's palette in little-endian native RGB555 format]:palette file:_files"
'(-q --palette-map -Q --auto-palette-map)'{-q,--palette-map}"+[Output the image's palette map]:palette map file:_files"
'(-r --reverse)'{-r,--reverse}'+[Yield an image from binary data]:image width (in tiles):'
'(-s --palette-size)'{-s,--palette-size}'+[Limit palette size]:palette size:'
'(-t --tilemap -T --auto-tilemap)'{-t,--tilemap}'+[Generate a map of tile indices]:tilemap file:_files'
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgbgfx_warnings'
'(-p --palette -P --output-palette)'{-p,--palette}"+[Output the image's palette in little-endian native RGB555 format]:palette file:_files"
'(-t --tilemap -T --output-tilemap)'{-t,--tilemap}'+[Generate a map of tile indices]:tilemap file:_files'
'(-x --trim-end)'{-x,--trim-end}'+[Trim end of output by this many tiles]:tile count:'
":input png file:_files -g '*.png'"
'*'":input png files:_files -g '*.png'"
)
_arguments -s -S : $args
+3 -27
View File
@@ -1,45 +1,21 @@
#compdef rgblink
_rgblink_warnings() {
local warnings=(
'error:Turn all warnings into errors'
'all:Enable most warning messages'
'everything:Enable literally everything'
'assert:Warn when WARN-type asserts fail'
'div:Warn when dividing the smallest int by -1'
'large-constant:Warn on constants too large for a signed 32-bit int'
'obsolete:Warn when using deprecated features'
'shift:Warn when shifting negative values'
'shift-amount:Warn when a shift'\''s operand is negative or \> 32'
'truncation:Warn when implicit truncation loses bits'
)
_describe warning warnings
}
local args=(
# Arguments are listed here in the same order as in the manual, except for the version and help
'(- : * options)'{-V,--version}'[Print version number and exit]'
'(- : * options)'{-h,--help}'[Print help text and exit]'
# Arguments are listed here in the same order as in the manual, except for the version
'(- : * options)'{-V,--version}'[Print version number]'
'(-d --dmg)'{-d,--dmg}'[Enable DMG mode (-w + no VRAM banking)]'
'(-t --tiny)'{-t,--tiny}'[Enable tiny mode, disabling ROM banking]'
'(-v --verbose)'{-v,--verbose}'[Enable verbose output]'
'(-w --wramx)'{-w,--wramx}'[Disable WRAM banking]'
'(-x --nopad)'{-x,--nopad}'[Disable padding the end of the final file]'
'(-B --backtrace)'{-B,--backtrace}'+[Set backtrace depth or style]:param:'
--color'[Whether to use color in output]:color:(auto always never)'
'(-l --linkerscript)'{-l,--linkerscript}"+[Use a linker script]:linker script:_files -g '*.link'"
'(-M --no-sym-in-map)'{-M,--no-sym-in-map}'[Do not output symbol names in map file]'
'(-m --map)'{-m,--map}"+[Produce a map file]:map file:_files -g '*.map'"
'(-n --sym)'(-n,--sym)"+[Produce a symbol file]:sym file:_files -g '*.sym'"
'(-O --overlay)'{-O,--overlay}'+[Overlay sections over on top of bin file]:base overlay:_files'
'(-o --output)'{-o,--output}"+[Write ROM image to this file]:rom file:_files -g '*.{gb,sgb,gbc}'"
'(-p --pad-value)'{-p,--pad-value}'+[Set padding byte]:padding byte:'
'(-S --scramble)'{-s,--scramble}'+[Activate scrambling]:scramble spec'
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgblink_warnings'
'(-s --smart)'{-s,--smart}'+[!BROKEN! Perform smart linking from this symbol]:symbol name:'
'*'":object files:_files -g '*.o'"
)
-301
View File
@@ -1,301 +0,0 @@
# RGBDS Architecture
The RGBDS package consists of four programs: RGBASM, RGBLINK, RGBFIX, and RGBGFX.
- RGBASM is the assembler. It takes assembly code as input, and produces an RGB object file as output (and optionally a state file, logging the final state of variables and constants).
- RGBLINK is the linker. It takes object files as input, and produces a ROM file as output (and optionally a symbol and/or map file, logging where the assembly declarations got placed in the ROM).
- RGBFIX is the checksum/header fixer. It takes a ROM file as input, and outputs the same ROM file (or modifies it in-place) with the cartridge header's checksum and other metadata fixed for consistency.
- RGBGFX is the graphics converter. It takes a PNG image file as input, and outputs the tile data, palettes, tilemap, attribute map, and/or palette map in formats that the Game Boy can use.
In the simplest case, a single pipeline can turn an assembly file into a ROM:
```console
(rgbasm -o - - | rgblink -o - - | rgbfix -v -p 0) < game.asm > game.gb
```
This document describes how these four programs are structured. It goes over each source code file, noting which data is *global* (and thus scoped in all files), *owned* by that file (i.e. that is where the data's memory is managed, via [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)) or *referenced* by that file (i.e. there are non-owning pointers to some data, and care must be taken to not dereference those pointers after the data's owner has moved or deleted the data).
We assume that the programs are single-threaded; data structures and operations may not be thread-safe.
## Folder Organization
The RGBDS source code file structure is as follows:
```
rgbds/
├── .github/
│ ├── scripts/
│ │ └── ...
│ └── workflows/
│ └── ...
├── cmake/
│ └── ...
├── contrib/
│ ├── bash_compl/
│ ├── zsh_compl/
│ │ └── ...
│ └── ...
├── docs/
│ └── ...
├── include/
│ └── ...
├── man/
│ └── ...
├── src/
│ ├── asm/
│ │ └── ...
│ ├── extern/
│ │ └── ...
│ ├── fix/
│ │ └── ...
│ ├── gfx/
│ │ └── ...
│ ├── link/
│ │ └── ...
│ ├── CMakeLists.txt
│ ├── bison.sh
│ └── ...
├── test/
│ ├── run-tests.sh
│ ├── external/
│ │ ├── fetch-repos.sh
│ │ └── ...
│ └── ...
├── .clang-format
├── .clang-tidy
├── CMakeLists.txt
├── CMakePresets.json
├── Dockerfile
└── Makefile
```
- **`.github/`:**
Files related to the integration of the RGBDS codebase with GitHub features.
* **`scripts/`:**
Scripts used by GitHub Actions workflow files.
* **`workflows/`:**
GitHub Actions CI workflow description files. Used for automated testing, deployment, etc.
- **`cmake/`**:
Files relevant to our CMake build system that are not required to be somewhere else (e.g. `CMakePresets.json` *has* to be at the root).
- **`contrib/`:**
Scripts and other resources which may be useful to RGBDS users and developers.
* **`bash_compl/`:**
Tab completion scripts for use with `bash`. Run them with `source` somewhere in your `.bashrc`, and they should auto-load when you open a shell.
* **`zsh_compl/`:**
Tab completion scripts for use with `zsh`. Put them somewhere in your `fpath`, and they should auto-load when you open a shell.
- **`docs/`:**
Documentation related to the development and maintenance of RGBDS itself.
(The directory's name, as well as some of its file's names, are
[recognized by GitHub](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/setting-guidelines-for-repository-contributors)
and linked to in parts of its UI.)
Documentation for RGBDS itself exists as manual pages in `man/`.
- **`include/`:**
Header files for the respective source files in `src`.
- **`man/`:**
Manual pages to be read with `man`, written in the [`mandoc`](https://mandoc.bsd.lv) dialect.
- **`src/`:**
Source code of RGBDS.
* **`asm/`:**
Source code of RGBASM.
* **`extern/`:**
Source code copied from external sources.
* **`fix/`:**
Source code of RGBFIX.
* **`gfx/`:**
Source code of RGBGFX.
* **`link/`:**
Source code of RGBLINK.
* **`CMakeLists.txt`:**
Defines how to build individual RGBDS programs with CMake, including the source files that each program depends on.
* **`bison.sh`:**
Script used to run the Bison parser generator with the latest flags that the user's version supports.
- **`test/`:**
Testing framework used to verify that changes to the code don't break or modify the behavior of RGBDS.
The `test.sh` scripts inside each of the subdirectories are the individual test drivers.
* **`run-tests.sh`:**
Script used to run tests, including internal test cases and external repositories. `run-tests.sh --help` describes its options.
* **`external/`:**
Directory for third-party repos making use of RGBDS, which get cloned here and built during testing.
- **`fetch-repos.sh`:**
Script used to clone the external repositories. `fetch-repos.sh --help` describes its options.
- **`*.cfg`:**
Each `.cfg` file defines the parameters to clone, build, and verify an external repository.
- **`.clang-format`:**
Code style for automated C++ formatting with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) (for which we define the shortcut `make format`).
- **`.clang-tidy`:**
Configuration for C++ static analysis with [`clang-tidy`](https://clang.llvm.org/extra/clang-tidy/) (for which we define the shortcut `make tidy`).
- **`CMakeLists.txt`:**
Defines how to build RGBDS with CMake.
- **`CMakePresets.json`:**
Defines some [presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) useful for working with our CMake.
- **`Dockerfile`:**
Defines how to build RGBDS with Docker (which we do in CI to provide a [container image](https://github.com/gbdev/rgbds/pkgs/container/rgbds)).
- **`Makefile`:**
Defines how to build RGBDS with `make`, including the source files that each program depends on.
## RGBDS
These files in the `src/` directory are shared across multiple programs: often all four (RGBASM, RGBLINK, RGBFIX, and RGBGFX), sometimes only RGBASM and RGBLINK.
- **`backtrace.cpp`:**
Generic printing of location backtraces for RGBASM and RGBLINK. Allows configuring backtrace styles with a command-line flag (conventionally `-B/--backtrace`). Renders warnings in yellow, errors in red, and locations in cyan.
- **`cli.cpp`:**
A function for parsing command-line options, including RGBDS-specific "at-files" (a filename containing more options, prepended with an "`@`").
This is the only file to use the extern/getopt.cpp variables and functions.
- **`diagnostics.cpp`:**
Generic warning/error diagnostic support for all programs. Allows command-line flags (conventionally `-W`) to have `no-`, `error=`, or `no-error=` prefixes, and `=` level suffixes; allows "meta" flags to affect groups of individual flags; and counts how many total errors there have been. Every program has its own `warning.cpp` file that uses this.
- **`linkdefs.cpp`:**
Constants, data, and functions related to RGBDS object files, which are used for RGBASM output and RGBLINK input.
This file defines two *global* variables, `sectionTypeInfo` (metadata about each section type) and `sectionModNames` (names of section modifiers, for error reporting). RGBLINK may change some values in `sectionTypeInfo` depending on its command-line options (this only affects RGBLINK; `sectionTypeInfo` is immutable in RGBASM).
- **`opmath.cpp`:**
Functions for mathematical operations in RGBASM and RGBLINK that aren't trivially equivalent to built-in C++ ones, such as division and modulo with well-defined results for negative values.
- **`style.cpp`:**
Generic printing of cross-platform colored or bold text. Obeys the [`FORCE_COLOR`](https://force-color.org/) and [`NO_COLOR`](https://no-color.org/) environment variables, and allows configuring with a command-line flag (conventionally `--color`).
- **`usage.cpp`:**
Generic printing of usage information. Renders headings in green, flags in cyan, and URLs in blue. Every program has its own `main.cpp` file that uses this.
- **`util.cpp`:**
Utility functions applicable to most programs, mostly dealing with text strings, such as locale-independent character checks.
- **`verbosity.cpp`:**
Generic printing of messages conditionally at different verbosity levels. Allows configuring with a command-line flag (conventionally `-v/--verbose`).
- **`version.cpp`:**
RGBDS version number and string for all the programs.
## External
These files have been copied ("vendored") from external authors and adapted for use with RGBDS. Both of our vendored dependencies use the same MIT license as RGBDS.
- **`getopt.cpp`:**
Functions for parsing command-line options, including conventional single-dash and double-dash options.
This file defines some *global* `musl_opt*` variables, including `musl_optarg` (the argument given after an option flag) and `musl_optind` (the index of the next option in `argv`). Copied from [musl libc](https://musl.libc.org/).
- **`utf8decoder.cpp`:**
Function for decoding UTF-8 bytes into Unicode code points. Copied from [Björn Höhrmann](https://bjoern.hoehrmann.de/utf-8/decoder/dfa/).
## RGBASM
- **`actions.cpp`:**
Actions taken by the assembly language parser, to avoid large amounts of code going in the parser.y file.
- **`charmap.cpp`:**
Functions and data related to charmaps.
This file *owns* the `Charmap`s in its `charmaps` collection. It also maintains a static `currentCharmap` pointer, and a `charmapStack` stack of pointers to `Charmap`s within `charmaps` (which is affected by `PUSHC` and `POPC` directives).
- **`fixpoint.cpp`:**
Functions for fixed-point math, with configurable [Q*m*.*n*](https://en.wikipedia.org/wiki/Q_(number_format)) precision.
- **`format.cpp`:**
`FormatSpec` methods for parsing and applying format specs, as used by `{interpolations}` and `STRFMT`.
- **`fstack.cpp`:**
Functions and data related to "fstack" nodes (the contents of top-level or `INCLUDE`d files, macro expansions, or `REPT`/`FOR` loop iterations) and their "contexts" (metadata that is only relevant while a node's content is being lexed and parsed).
This file *owns* the `Context`s in its `contextStack` collection. Each of those `Context`s *owns* its `LexerState`, and *refers* to its `FileStackNode`, `uniqueIDStr`, and `macroArgs`. Each `FileStackNode` also *references* its `parent`.
- **`intern.cpp`:**
[Interned strings](https://en.wikipedia.org/wiki/String_interning), which are used for the names of keywords, symbols (labels, constants, variables, string constants, macros, etc), and charmaps.
This file *owns* the strings in its `internedStrings` collection, which its `internedIndexes` collection *references* by view and index.
- **`lexer.cpp`:**
Functions and data related to [lexing](https://en.wikipedia.org/wiki/Lexical_analysis) assembly source code into tokens, which can then be parsed.
This file maintains static `lexerState` and `lexerStateEOL` pointers to `LexerState`s from the `Context`s in `fstack.cpp`.
Each `LexerState` *owns* its `content` and its `expansionStack`'s content. Each `Expansion` (the contents of an `{interpolation}` or macro argument) in turn *owns* its `contents`.
The lexer and parser are interdependent: when the parser reaches certain tokens, it changes the lexer's mode, which affects how characters get lexed into tokens. For example, when the parser reaches a macro name, it changes the lexer to "raw" mode, which lexes the rest of the line as a sequence of string arguments to the macro.
- **`macro.cpp`:**
`MacroArgs` methods related to macro arguments. Each `MacroArgs` *references* its arguments' contents.
- **`main.cpp`:**
The `main` function for running RGBASM, including the initial handling of command-line options.
This file defines a *global* `options` variable with the parsed CLI options.
- **`opt.cpp`:**
Functions for parsing options specified by `OPT` or by certain command-line options.
This file *owns* the `OptStackEntry`s in its `stack` collection (which is affected by `PUSHO` and `POPO` directives).
- **`output.cpp`:**
Functions and data related to outputting object files (with `-o/--output`) and state files (with `-s/--state`).
This file *owns* its `assertions` (created by `ASSERT` and `STATIC_ASSERT` directives). Every assertion gets output in the object file.
This file also *references* some `fileStackNodes`, and maintains static pointers to `Symbol`s in `objectSymbols`. Only the "registered" symbols and fstack nodes get output in the object file. The `fileStackNodes` and `objectSymbols` collections keep track of which nodes and symbols have been registered for output.
- **`parser.y`:**
Grammar for the RGBASM assembly language, which Bison preprocesses into a [LALR(1) parser](https://en.wikipedia.org/wiki/LALR_parser).
The Bison-generated parser calls `yylex` (defined in `lexer.cpp`) to get the next token, and calls `yywrap` (defined in `fstack.cpp`) when the current context is out of tokens and returns `EOF`.
- **`rpn.cpp`:**
`Expression` methods and data related to "[RPN](https://en.wikipedia.org/wiki/Reverse_Polish_notation)" expressions. When a numeric expression is parsed, if its value cannot be calculated at assembly time, it is built up into a buffer of RPN-encoded operations to do so at link time by RGBLINK. The valid RPN operations are defined in [man/rgbds.5](/man/rgbds.5).
- **`section.cpp`:**
Functions and data related to `SECTION`s.
This file *owns* the `Section`s in its `sections` collection. It also maintains various static pointers to those sections, including the `currentSection`, `currentLoadSection`, and `sectionStack` (which is affected by `PUSHS` and `POPS` directives). (Note that sections cannot be deleted.)
- **`symbol.cpp`:**
Functions and data related to symbols (labels, constants, variables, string constants, macros, etc).
This file *owns* the `Symbol`s in its `symbols` collection, and the various built-in ones outside that collection (`PCSymbol` for "`@`", `NARGSymbol` for "`_NARG`", etc). It also maintains a static `purgedSymbols` collection to remember which symbol names have been `PURGE`d from `symbols`, for error reporting purposes.
- **`warning.cpp`:**
Functions and data for warning and error output.
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBASM-specific warning flags.
## RGBFIX
- **`fix.cpp`:**
Functions for fixing the ROM header.
- **`main.cpp`:**
The `main` function for running RGBFIX, including the initial handling of command-line options.
This file defines a *global* `options` variable with the parsed CLI options.
- **`mbc.cpp`:**
Functions and data related to [MBCs](https://gbdev.io/pandocs/MBCs.html), including the names of known MBC values.
- **`warning.cpp`:**
Functions and data for warning and error output.
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBFIX-specific warning flags.
## RGBGFX
- **`color_set.cpp`:**
`ColorSet` methods for creating and comparing sets of colors. A color set includes the unique colors used by a single tile, and these sets are then packed into palettes.
- **`main.cpp`:**
The `main` function for running RGBGFX, including the initial handling of command-line options.
This file defines a *global* `options` variable with the parsed CLI options.
- **`pal_packing.cpp`:**
Functions for packing color sets into palettes. This is done with an ["overload-and-remove" heuristic](https://arxiv.org/abs/1605.00558) for a pagination algorithm.
- **`pal_sorting.cpp`:**
Functions for sorting colors within palettes, which works differently for grayscale, RGB, or indexed-color palettes.
- **`pal_spec.cpp`:**
Functions for parsing various formats of palette specifications (from `-c/--colors`).
- **`palette.cpp`:**
`Palette` methods for working with up to four GBC-native (RGB555) colors.
- **`png.cpp`:**
`Png` methods for reading PNG image files, standardizing them to 8-bit RGBA pixels while also reading their indexed palette if there is one.
- **`process.cpp`:**
Functions related to generating and outputting files (tile data, palettes, tilemap, attribute map, and/or palette map).
- **`reverse.cpp`:**
Functions related to reverse-generating RGBGFX outputs into a PNG file (for `-r/--reverse`).
- **`rgba.cpp`:**
`Rgba` methods related to RGBA colors and their 8-bit or 5-bit representations.
- **`warning.cpp`:**
Functions and data for warning and error output.
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBGFX-specific warning flags.
## RGBLINK
- **`assign.cpp`:**
Functions and data for assigning `SECTION`s to specific banks and addresses.
This file *owns* the `memory` table of free space: each section type is associated with a list of each bank's free address ranges, which are allocated to sections using a [first-fit decreasing](https://en.wikipedia.org/wiki/Bin_packing_problem#First-fit_algorithm) bin-packing algorithm.
- **`fstack.cpp`:**
Functions related to "fstack" nodes (the contents of top-level or `INCLUDE`d files, macro expansions, or `REPT`/`FOR` loop iterations) read from the object files. At link time, these nodes are only needed for printing of location backtraces.
- **`layout.cpp`:**
Actions taken by the linker script parser, to avoid large amounts of code going in the script.y file.
This file maintains some static data about the current bank and address layout, which get checked and updated for consistency as the linker script is parsed.
- **`lexer.cpp`:**
Functions and data related to [lexing](https://en.wikipedia.org/wiki/Lexical_analysis) linker script files into tokens, which can then be parsed.
This file *owns* the `LexerStackEntry`s in its `lexerStack` collection. Each of those `LexerStackEntry`s *owns* its `file`. The stack is updated as linker scripts can `INCLUDE` other linker script pieces.
The linker script lexer is simpler than the RGBASM one, and does not have modes.
- **`main.cpp`:**
The `main` function for running RGBLINK, including the initial handling of command-line options.
This file defines a *global* `options` variable with the parsed CLI options.
- **`object.cpp`:**
Functions and data for reading object files generated by RGBASM.
This file *owns* the `Symbol`s in its `symbolLists` collection, and the `FileStackNode`s in its `nodes` collection.
- **`output.cpp`:**
Functions and data related to outputting ROM files (with `-o/--output`), symbol files (with `-n/--sym`), and map files (with `-m/--map`).
This file *references* some `Symbol`s and `Section`s, in collections that keep them sorted by address and name, which allows the symbol and map output to be in order.
- **`patch.cpp`:**
Functions and data related to "[RPN](https://en.wikipedia.org/wiki/Reverse_Polish_notation)" expression patches read from the object files, including the ones for `ASSERT` conditions. After sections have been assigned specific locations, the RPN patches can have their values calculated and applied to the ROM. The valid RPN operations are defined in [man/rgbds.5](/man/rgbds.5).
This file *owns* the `Assertion`s in its `assertions` collection, and the `RPNStackEntry`s in its `rpnStack` collection.
- **`script.y`:**
Grammar for the linker script language, which Bison preprocesses into a [LALR(1) parser](https://en.wikipedia.org/wiki/LALR_parser).
The Bison-generated parser calls `yylex` (defined in `lexer.cpp`) to get the next token, and calls `yywrap` (also defined in `lexer.cpp`) when the current context is out of tokens and returns `EOF`.
- **`sdas_obj.cpp`:**
Functions and data for reading object files generated by [GBDK with SDCC](https://gbdk.org/). RGBLINK support for these object files is incomplete.
- **`section.cpp`:**
Functions and data related to `SECTION`s read from the object files.
This file *owns* the `Section`s in its `sections` collection.
- **`symbol.cpp`:**
Functions and data related to symbols read from the object files.
This file *references* the `Symbol`s in its `symbols` and `localSymbols` collections, which allow accessing symbols by name.
- **`warning.cpp`:**
Functions and data for warning and error output.
This file defines a *global* `warnings` variable using the `diagnostics.cpp` code for RGBLINK-specific warning flags.
-271
View File
@@ -1,271 +0,0 @@
# Contributing
RGBDS was created in the late '90s and has received contributions from several
developers since then. It wouldn't have been possible to get to this point
without their work, and it is always open to the contributions of other people.
## Reporting bugs
Bug reports are essential to improve RGBDS and they are always welcome. If you
want to report a bug:
1. Make sure that there isn't a similar issue
[already reported](https://github.com/gbdev/rgbds/issues).
2. Figure out a way of reproducing it reliably.
3. If there is a piece of code that triggers the bug, try to reduce it to the
smallest file you can.
4. Create a new [issue](https://github.com/gbdev/rgbds/issues).
Of course, it may not always be possible to give an accurate bug report, but it
always helps to fix it.
## Requesting new features
If you come up with a good idea that could be implemented, you can propose it to
be done.
1. Create a new [issue](https://github.com/gbdev/rgbds/issues).
2. Try to be as accurate as possible. Describe what you need and why you need
it, maybe with examples.
Please understand that the contributors are doing it in their free time, so
simple requests are more likely to catch the interest of a contributor than
complicated ones. If you really need something to be done, and you think you can
implement it yourself, you can always contribute to RGBDS with your own code.
## Contributing code
Thank you! Code contributions are the most appreciated.
You can find a description of the project's layout in [`ARCHITECTURE.md`](/ARCHITECTURE.md).
If you want to contribute with your own code, whether it is to fix a current
issue or to add something that nobody had requested, you should first consider
if your change is going to be small (and likely to be accepted as-is) or big
(and will have to go through some rework).
Big changes will most likely require some discussion, so open an
[issue](https://github.com/gbdev/rgbds/issues) and explain what you want to
do and how you intend to do it. If you already have a prototype, it's always a
good idea to show it. Tests help, too.
If you are going to work on a specific issue that involves a lot of work, it is
always a good idea to leave a message, just in case someone else is interested
but doesn't know that there's someone working on it.
Note that you must contribute all your changes under the MIT License. If you are
just modifying a file, you don't need to do anything (maybe update the copyright
years). If you are adding new files, you need to use the
`SPDX-License-Identifier: MIT` header.
1. Fork this repository.
2. Checkout the `master` branch.
3. Create a new branch to work on. You could still work on `master`, but it's
easier that way.
4. Compile your changes with `make develop` instead of just `make`. This
target checks for additional warnings. Your patches shouldn't introduce any
new warning (but it may be possible to remove some warning checks if it makes
the code much easier).
You can also use `cmake --preset develop` if you prefer.
5. Test your changes by running `./run-tests.sh` in the `test` directory.
`./run-tests.sh --help` will print its available options. (You must run
`external/fetch-repos.sh` first; if you forget to, the test suite will fail and
remind you mid-way.)
You can also use `ctest --test-dir build` if you prefer.
`ctest --test-dir build --print-labels` will print its available
[test labels](https://cmake.org/cmake/help/latest/manual/ctest.1.html#label-matching).
6. Format your changes according to `clang-format`, which will reformat the
coding style according to our standards defined in `.clang-format`. You can
use `make format` to format all the C++ files.
7. Create a pull request against the branch `master`.
8. Check the results of the GitHub Actions CI jobs for your pull request. The
"Code format checking" and "Regression testing" jobs should all succeed.
The "Diff completeness check" job should be manually checked, as it may
output warnings which do not count as failure errors. The "Code coverage
report" provides an [LCOV](https://github.com/linux-test-project/lcov)-generated
report which can be downloaded and checked to see if your new code has full
test coverage.
9. Be prepared to get some comments about your code and to modify it. Tip: Use
`git rebase -i origin/master` to modify chains of commits.
## Adding a test
The test suite is a little ad-hoc, so the way tests work is different for each
program being tested.
Feel free to modify how the test scripts work, if the thing you want to test
doesn't fit the existing scheme(s).
### RGBASM
There are two kinds of test.
#### Simple tests
Each `.asm` file corresponds to one test.
RGBASM will be invoked on the `.asm` file with all warnings enabled.
If a `.flags` file exists, its first line contains flags to pass to RGBASM.
(There may be more lines, which will be ignored; they can serve as comments to
explain what the test is about.)
If a `.out` file exists, RGBASM's output (`print`, `println`, etc.) must match
its contents.
If a `.err` file exists, RGBASM's error output (`warn`, errors, etc.) must match
its contents.
If a `.out.bin` file exists, the object file will be linked, and the generated
ROM truncated to the length of the `.out.bin` file.
After that, the ROM must match the `.out.bin` file.
#### CLI tests
Each `.flags` file in `cli/` corresponds to one test.
RGBASM will be invoked, passing it the first line of the `.flags` file.
(There may be more lines, which will be ignored; they can serve as comments to
explain what the test is about.)
If a `.out` file exists, RGBASM's output (`print`, `println`, etc.) must match
its contents.
If a `.err` file exists, RGBASM's error output (`warn`, errors, etc.) must match
its contents.
### RGBLINK
Each `.asm` file corresponds to one test, or one *set* of tests.
All tests begin by assembling the `.asm` file into an object file, which will be
linked in various ways depending on the test.
#### Simple tests
These simply check that RGBLINK's output matches some expected output.
If a `.flags` file exists, its first line contains flags to pass to RGBLINK.
(There may be more lines, which will be ignored; they can serve as comments to
explain what the test is about.)
A `.out` file **must** exist, and RGBLINK's total output must match that file's
contents.
Additionally, if a `.out.bin` file exists, the `.gb` file generated by RGBLINK
must match it.
#### Linker script tests
These allow applying various linker scripts to the same object file.
If one or more `.link` files exist, whose names start the same as the `.asm`
file, then each of those files correspond to one test.
Each `.link` linker script **must** be accompanied by a `.out` file, and
RGBLINK's total output must match that file's contents when passed the
corresponding linker script.
#### Variant tests
These allow testing RGBLINK's `-d`, `-t`, and `-w` flags.
If one or more
<code>-<var>&lt;flag&gt;</var>.out</code> or <code>-no-<var>&lt;flag&gt;</var>.out</code>
files exist, then each of them corresponds to one test.
The object file will be linked with and without said flag, respectively; and in
each case, RGBLINK's total output must match the `.out` file's contents.
### RGBFIX
Each `.flags` file corresponds to one test.
Each one is a text file whose first line contains flags to pass to RGBFIX.
(There may be more lines, which will be ignored; they can serve as comments to
explain what the test is about.)
RGBFIX will be invoked on the `.bin` file if it exists, or else on
default-input.bin.
If no `.out` file exist, RGBFIX is not expected to output anything.
If one *does* exist, RGBFIX's output **must** match the `.out` file's contents.
If no `.err` file exists, RGBFIX is simply expected to be able to process the
file normally.
If one *does* exist, RGBFIX's return status is ignored, but its error output
**must** match the `.err` file's contents.
Additionally, if a `.gb` file exists, the output of RGBFIX must match the `.gb`.
### RGBGFX
There are three kinds of test.
#### Simple tests
Each `.png` file corresponds to one test.
RGBGFX will be invoked on the file.
If a `.flags` file exists, it will be used as part of the RGBGFX invocation
(<code>@<var>&lt;file&gt;</var>.flags</code>).
If `.out.1bpp`, `.out.2bpp`, `.out.pal`, `.out.tilemap`, `.out.attrmap`, or
`.out.palmap` files exist, RGBGFX will create the corresponding kind of output,
which must match the file's contents.
Multiple kinds of output may be tested for the same input.
If no `.err` file exists, RGBGFX is simply expected to be able to process the
file normally.
If one *does* exist, RGBGFX's return status is ignored, but its output **must**
match the `.err` file's contents.
#### Reverse tests
Each `.1bpp` or `.2bpp` file corresponds to one test.
RGBGFX will be invoked on the file with `-r 1` for reverse mode, then invoked on
the output without `-r 1`.
The round-trip output must match the input file's contents.
If a `.flags` file exists, it will be used as part of the RGBGFX invocation
(<code>@<var>&lt;file&gt;</var>.flags</code>).
#### Random seed tests
Each `seed*.bin` file corresponds to one test.
Each one is a binary RNG file which is passed to the `rgbgfx_test` program.
### External projects
Each `.cfg` file corresponds to one test.
Each one defines the parameters for a real external project that builds using RGBDS.
1. Ensure that the downstream project supports a `RGBDS` variable to build with
a non-system copy of RGBDS in some directory, i.e.
<code>make <var>&lt;target&gt;</var> RGBDS=<var>&lt;path/to/rgbds/&gt;</var></code>.
Only [GNU Make](https://www.gnu.org/software/make/) is currently supported.
2. Create the new `.cfg` file, following the existing ones.
If an external project does not support `make RGBDS=`, or otherwise fails to
build with current RGBDS, then you can edit the project to build correctly, and
create a patch with `git diff` to be committed as
<code>test/external/patches/<var>&lt;project&gt;</var>.patch</code>.
## Container images
The CI will
[take care](https://github.com/gbdev/rgbds/blob/master/.github/workflows/build-container.yml)
of updating the
[rgbds container](https://github.com/gbdev/rgbds/pkgs/container/rgbds) image
tagged `master`.
When a git tag is pushed, the image is also tagged with that tag.
The image can be built locally and pushed to the GitHub container registry by
manually running:
```bash
# e.g. to build and tag as 'master'
docker build . --tag ghcr.io/gbdev/rgbds:master
docker push ghcr.io/gbdev/rgbds:master
```
## Publishing a new release
Please refer to [`RELEASE.md`](/RELEASE.md).
## Closing remarks
Feel free to add yourself to `CREDITS.md`!
-48
View File
@@ -1,48 +0,0 @@
# Contributors to RGBDS
## Original author
- Carsten Elton Sørensen &lt;csoren@gmail.com&gt;
## Main contributors
- Justin Lloyd &lt;jlloyd@imf.la&gt;
- Vegard Nossum &lt;vegard.nossum@gmail.com&gt;
- Anthony J. Bentley &lt;anthony@anjbe.name&gt;
- stag019 &lt;stag019@gmail.com&gt;
- Antonio Niño Díaz &lt;antonio_nd@outlook.com&gt;
- Eldred "ISSOtm" Habert &lt;me@eldred.fr&gt;
- Sylvie "Rangi" Oukaour &lt;https://github.com/Rangi42&gt;
## Other contributors
- Ben Hetherington &lt;dev@ben-h.uk&gt;
- Björn Höhrmann &lt;bjoern@hoehrmann.de&gt;
- Christophe Staïesse &lt;chastai@skynet.be&gt;
- David Brotz &lt;dbrotz007@gmail.com&gt;
- Evie &lt;https://evie.gbdev.io&gt;
- James "JL2210" Larrowe &lt;https://github.com/JL2210&gt;
- Maja Kądziołka &lt;github@compilercrim.es&gt;
- The Musl C library &lt;https://musl.libc.org/&gt;
- obskyr &lt;powpowd@gmail.com&gt;
- The OpenBSD Project &lt;http://www.openbsd.org&gt;
- Quint Guvernator &lt;quint@guvernator.net&gt;
- Sanqui &lt;gsanky@gmail.com&gt;
- YamaArashi &lt;shadow962@live.com&gt;
- yenatch &lt;yenatch@gmail.com&gt;
- phs &lt;phil@philhsmith.com&gt;
- jidoc01 &lt;jidoc01@naver.com&gt;
[<img src="https://contrib.rocks/image?repo=gbdev/rgbds">](https://github.com/gbdev/rgbds/graphs/contributors)
Contributor image made with [contrib.rocks](https://contrib.rocks).
## Acknowledgements
RGBGFX generates palettes using algorithms found in the paper
["Algorithms for the Pagination Problem, a Bin Packing with Overlapping Items"](https://arxiv.org/abs/1605.00558)
([GitHub](https://github.com/pagination-problem/pagination), MIT license),
by Aristide Grange, Imed Kacem, and Sébastien Martin.
RGBGFX's color palette was taken from [SameBoy](https://sameboy.github.io), with
permission and help by [LIJI](https://github.com/LIJI32).
-84
View File
@@ -1,84 +0,0 @@
# Releasing
This describes for the maintainers of RGBDS how to publish a new release on
GitHub.
1. Update the following files, then commit and push.
You can use <code>git commit -m "Release <i>&lt;version&gt;</i>"</code> and `git push origin master`.
- [include/version.hpp](/include/version.hpp): set appropriate values for `PACKAGE_VERSION_MAJOR`,
`PACKAGE_VERSION_MINOR`, `PACKAGE_VERSION_PATCH`, and `PACKAGE_VERSION_RC`.
**Only** define `PACKAGE_VERSION_RC` if you are publishing a release candidate!
- [Dockerfile](/Dockerfile): update `ARG version`.
- [test/external/\*.cfg](/test/external): update test dependency commits
(preferably, use the latest available).
- [man/\*](/man/): update dates and authors.
2. Create a Git tag formatted as <code>v<i>&lt;MAJOR&gt;</i>.<i>&lt;MINOR&gt;</i>.<i>&lt;PATCH&gt;</i></code>,
or <code>v<i>&lt;MAJOR&gt;</i>.<i>&lt;MINOR&gt;</i>.<i>&lt;PATCH&gt;</i>-rc<i>&lt;RC&gt;</i></code>
for a release candidate. <code><i>MAJOR</i></code>, <code><i>MINOR</i></code>,
<code><i>PATCH</i></code>, and <code><i>RC</i></code> should match their values from
[include/version.hpp](/include/version.hpp). You can use <code>git tag <i>&lt;tag&gt;</i></code>.
3. Push the tag to GitHub. You can use <code>git push origin <i>&lt;tag&gt;</i></code>.
GitHub Actions will run the
[create-release-artifacts.yml](/.github/workflows/create-release-artifacts.yml)
workflow to detect the tag starting with "`v[0-9]`" and automatically do the following:
1. Build 32-bit and 64-bit RGBDS binaries for Windows with `cmake`.
2. Package the binaries into zip files.
3. Package the source code into a tar.gz file with `make dist`.
4. Create a draft GitHub release for the tag, attaching the three
packaged files. It will be a prerelease if the tag contains "`-rc`".
If an error occurred in the above steps, delete the tag and restart the
procedure. You can use <code>git push --delete origin <i>&lt;tag&gt;</i></code> and
<code>git tag --delete <i>&lt;tag&gt;</i></code>.
4. GitHub Actions will run the [create-release-docs.yml](/.github/workflows/create-release-docs.yml)
workflow to add the release documentation to [rgbds-www](https://github.com/gbdev/rgbds-www).
This is not done automatically for prereleases, since we do not normally publish documentation
for them. If you want to manually publish prerelease documentation, such as for an April Fools
joke prerelease,
1. Clone [rgbds-www](https://github.com/gbdev/rgbds-www). You can use
`git clone https://github.com/gbdev/rgbds-www.git`.
2. Make sure that you have installed `groff` and `mandoc`. You will
need `mandoc` 1.14.5 or later to support `-O toc`.
3. Inside of the `man` directory, run <code><i>&lt;path/to/rgbds-www&gt;</i>/maintainer/man_to_html.sh <i>&lt;tag&gt;</i> *</code> then <code><i>&lt;path/to/rgbds-www&gt;</i>/maintainer/new_release.sh <i>&lt;tag&gt;</i></code>.
This will render the RGBDS documentation as HTML and PDF and copy it to
`rgbds-www`.
If you do not have `groff` installed, you can change
`groff -Tpdf -mdoc -wall` to `mandoc -Tpdf -I os=Linux` in
[maintainer/man_to_html.sh](https://github.com/gbdev/rgbds-www/blob/master/maintainer/man_to_html.sh)
and it will suffice.
4. Commit and push the documentation. You can use <code>git commit -m
"Create RGBDS <i>&lt;tag&gt;</i> documentation"</code> and `git push origin master`
(within the `rgbds-www` directory, not RGBDS).
5. Write a changelog in the GitHub draft release.
6. Click the "Publish release" button to publish it!
7. Update the `release` branch. You can use `git push origin master:release`.
8. Update the following related projects.
1. [rgbds-www](https://github.com/gbdev/rgbds-www): update
[src/pages/versions.mdx](https://github.com/gbdev/rgbds-www/blob/master/src/pages/versions.mdx)
to list the new release.
2. [rgbds-live](https://github.com/gbdev/rgbds-live): update the `rgbds` submodule (and
[patches/rgbds.patch](https://github.com/gbdev/rgbds-live/blob/master/patches/rgbds.patch)
if necessary) to use the new release.
3. [rgbobj](https://github.com/gbdev/rgbobj) and [rgbds-obj](https://github.com/gbdev/rgbds-obj):
make sure that object files created by the latest RGBASM can be parsed and displayed.
If the object file revision has been updated, `rgbobj` will need a corresponding release.
-62
View File
@@ -1,62 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_ACTIONS_HPP
#define RGBDS_ASM_ACTIONS_HPP
#include <optional>
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <string_view>
#include <variant>
#include <vector>
#include "linkdefs.hpp" // AssertionType, RPNCommand
#include "asm/intern.hpp" // InternedStr
#include "asm/rpn.hpp" // Expression
struct AlignmentSpec {
uint8_t alignment;
uint16_t alignOfs;
};
void act_If(int32_t condition);
void act_Elif(int32_t condition);
void act_Else();
void act_Endc();
AlignmentSpec act_Alignment(int32_t alignment, int32_t alignOfs);
void act_Assert(AssertionType type, Expression const &expr, std::string const &message);
void act_StaticAssert(AssertionType type, int32_t condition, std::string const &message);
std::optional<std::string> act_ReadFile(std::string const &name, uint32_t maxLen);
uint32_t act_CharToNum(std::string const &str);
uint32_t act_StringToNum(std::string const &str);
int32_t act_CharVal(std::string const &str);
int32_t act_CharVal(std::string const &str, int32_t negIdx);
uint8_t act_StringByte(std::string const &str, int32_t negIdx);
size_t act_StringLen(std::string const &str, bool printErrors);
std::string
act_StringSlice(std::string const &str, int32_t negStart, std::optional<int32_t> negStop);
std::string act_StringSub(std::string const &str, int32_t negPos, std::optional<uint32_t> optLen);
size_t act_CharLen(std::string const &str);
std::string act_StringChar(std::string const &str, int32_t negIdx);
std::string act_CharSub(std::string const &str, int32_t negPos);
int32_t act_CharCmp(std::string_view str1, std::string_view str2);
std::string act_StringReplace(std::string_view str, std::string const &old, std::string const &rep);
std::string act_StringFormat(
std::string const &spec, std::vector<std::variant<uint32_t, std::string>> const &args
);
std::string act_SectionName(InternedStr symName);
void act_CompoundAssignment(InternedStr symName, RPNCommand op, int32_t constValue);
#endif // RGBDS_ASM_ACTIONS_HPP
+22
View File
@@ -0,0 +1,22 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_CHARMAP_H
#define RGBDS_ASM_CHARMAP_H
#include <stdint.h>
struct Charmap *charmap_New(const char *name, const char *baseName);
void charmap_Delete(struct Charmap *charmap);
void charmap_Set(const char *name);
void charmap_Push(void);
void charmap_Pop(void);
void charmap_Add(char *mapping, uint8_t value);
size_t charmap_Convert(char const *input, uint8_t *output);
#endif /* RGBDS_ASM_CHARMAP_H */
-32
View File
@@ -1,32 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_CHARMAP_HPP
#define RGBDS_ASM_CHARMAP_HPP
#include <optional>
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <string_view>
#include <vector>
#include "asm/intern.hpp"
void charmap_Init();
bool charmap_ForEach(
void (*mapFunc)(InternedStr), void (*charFunc)(std::string const &, std::vector<int32_t>)
);
void charmap_New(InternedStr name, InternedStr const *baseName);
void charmap_Set(InternedStr name);
void charmap_Push();
void charmap_Pop();
void charmap_CheckStack();
void charmap_Add(std::string const &mapping, std::vector<int32_t> &&value);
bool charmap_HasChar(std::string const &mapping);
size_t charmap_CharSize(std::string const &mapping);
std::optional<int32_t> charmap_CharValue(std::string const &mapping, size_t idx);
std::vector<int32_t> charmap_Convert(std::string const &input);
size_t charmap_ConvertNext(std::string_view &input, std::vector<int32_t> *output);
std::string charmap_Reverse(std::vector<int32_t> const &value, bool &unique);
#endif // RGBDS_ASM_CHARMAP_HPP
+31
View File
@@ -0,0 +1,31 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2021, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_FIXPOINT_H
#define RGBDS_ASM_FIXPOINT_H
#include <stdint.h>
int32_t fix_Callback_PI(void);
void fix_Print(int32_t i);
int32_t fix_Sin(int32_t i);
int32_t fix_Cos(int32_t i);
int32_t fix_Tan(int32_t i);
int32_t fix_ASin(int32_t i);
int32_t fix_ACos(int32_t i);
int32_t fix_ATan(int32_t i);
int32_t fix_ATan2(int32_t i, int32_t j);
int32_t fix_Mul(int32_t i, int32_t j);
int32_t fix_Div(int32_t i, int32_t j);
int32_t fix_Pow(int32_t i, int32_t j);
int32_t fix_Log(int32_t i, int32_t j);
int32_t fix_Round(int32_t i);
int32_t fix_Ceil(int32_t i);
int32_t fix_Floor(int32_t i);
#endif /* RGBDS_ASM_FIXPOINT_H */
-24
View File
@@ -1,24 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_FIXPOINT_HPP
#define RGBDS_ASM_FIXPOINT_HPP
#include <stdint.h>
int32_t fix_Sin(int32_t i, int32_t q);
int32_t fix_Cos(int32_t i, int32_t q);
int32_t fix_Tan(int32_t i, int32_t q);
int32_t fix_ASin(int32_t i, int32_t q);
int32_t fix_ACos(int32_t i, int32_t q);
int32_t fix_ATan(int32_t i, int32_t q);
int32_t fix_ATan2(int32_t i, int32_t j, int32_t q);
int32_t fix_Mul(int32_t i, int32_t j, int32_t q);
int32_t fix_Mod(int32_t i, int32_t j, int32_t q);
int32_t fix_Div(int32_t i, int32_t j, int32_t q);
int32_t fix_Pow(int32_t i, int32_t j, int32_t q);
int32_t fix_Log(int32_t i, int32_t j, int32_t q);
int32_t fix_Round(int32_t i, int32_t q);
int32_t fix_Ceil(int32_t i, int32_t q);
int32_t fix_Floor(int32_t i, int32_t q);
#endif // RGBDS_ASM_FIXPOINT_HPP
+63
View File
@@ -0,0 +1,63 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2020, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_FORMAT_SPEC_H
#define RGBDS_FORMAT_SPEC_H
#include <stdint.h>
#include <stdbool.h>
enum FormatState {
FORMAT_SIGN, // expects '+' or ' ' (optional)
FORMAT_PREFIX, // expects '#' (optional)
FORMAT_ALIGN, // expects '-' (optional)
FORMAT_WIDTH, // expects '0'-'9', max 255 (optional) (leading '0' indicates pad)
FORMAT_FRAC, // got '.', expects '0'-'9', max 255 (optional)
FORMAT_DONE, // got [duXxbofs] (required)
FORMAT_INVALID, // got unexpected character
};
struct FormatSpec {
enum FormatState state;
int sign;
bool prefix;
bool alignLeft;
bool padZero;
uint8_t width;
bool hasFrac;
uint8_t fracWidth;
int type;
bool valid;
};
struct StrFmtArg {
union {
uint32_t number;
char *string;
};
bool isNumeric;
};
#define INITIAL_STRFMT_ARG_SIZE 4
struct StrFmtArgList {
char *format;
size_t nbArgs;
size_t capacity;
struct StrFmtArg *args;
};
struct FormatSpec fmt_NewSpec(void);
bool fmt_IsEmpty(struct FormatSpec const *fmt);
bool fmt_IsValid(struct FormatSpec const *fmt);
bool fmt_IsFinished(struct FormatSpec const *fmt);
void fmt_UseCharacter(struct FormatSpec *fmt, int c);
void fmt_FinishCharacters(struct FormatSpec *fmt);
void fmt_PrintString(char *buf, size_t bufLen, struct FormatSpec const *fmt, char const *value);
void fmt_PrintNumber(char *buf, size_t bufLen, struct FormatSpec const *fmt, uint32_t value);
#endif /* RGBDS_FORMAT_SPEC_H */
-33
View File
@@ -1,33 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_FORMAT_HPP
#define RGBDS_ASM_FORMAT_HPP
#include <stddef.h>
#include <stdint.h>
#include <string>
class FormatSpec {
int sign;
bool exact;
bool alignLeft;
bool padZero;
size_t width;
bool hasFrac;
size_t fracWidth;
bool hasPrec;
size_t precision;
int type;
bool parsed;
public:
bool isValid() const { return !!type; }
bool isParsed() const { return parsed; }
size_t parseSpec(char const *spec);
void appendString(std::string &str, std::string const &value) const;
void appendNumber(std::string &str, uint32_t value) const;
};
#endif // RGBDS_ASM_FORMAT_HPP
+83
View File
@@ -0,0 +1,83 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* Contains some assembler-wide defines and externs
*/
#ifndef RGBDS_ASM_FSTACK_H
#define RGBDS_ASM_FSTACK_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "asm/lexer.h"
#include "types.h"
struct FileStackNode {
struct FileStackNode *parent; /* Pointer to parent node, for error reporting */
/* Line at which the parent context was exited; meaningless for the root level */
uint32_t lineNo;
struct FileStackNode *next; /* Next node in the output linked list */
bool referenced; /* If referenced, don't free! */
uint32_t ID; /* Set only if referenced: ID within the object file, -1 if not output yet */
enum {
NODE_REPT,
NODE_FILE,
NODE_MACRO,
} type;
};
struct FileStackReptNode { /* NODE_REPT */
struct FileStackNode node;
uint32_t reptDepth;
/* WARNING: if changing this type, change overflow check in `fstk_Init` */
uint32_t iters[]; /* REPT iteration counts since last named node, in reverse depth order */
};
struct FileStackNamedNode { /* NODE_FILE, NODE_MACRO */
struct FileStackNode node;
char name[]; /* File name for files, file::macro name for macros */
};
extern size_t nMaxRecursionDepth;
struct MacroArgs;
void fstk_Dump(struct FileStackNode const *node, uint32_t lineNo);
void fstk_DumpCurrent(void);
struct FileStackNode *fstk_GetFileStack(void);
/* The lifetime of the returned chars is until reaching the end of that file */
char const *fstk_GetFileName(void);
void fstk_AddIncludePath(char const *s);
/**
* @param path The user-provided file name
* @param fullPath The address of a pointer, which will be made to point at the full path
* The pointer's value must be a valid argument to `realloc`, including NULL
* @param size Current size of the buffer, or 0 if the pointer is NULL
* @return True if the file was found, false if no path worked
*/
bool fstk_FindFile(char const *path, char **fullPath, size_t *size);
bool yywrap(void);
void fstk_RunInclude(char const *path);
void fstk_RunMacro(char const *macroName, struct MacroArgs *args);
void fstk_RunRept(uint32_t count, int32_t nReptLineNo, char *body, size_t size);
void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
int32_t reptLineNo, char *body, size_t size);
void fstk_StopRept(void);
bool fstk_Break(void);
void fstk_Init(char const *mainPath, size_t maxRecursionDepth);
#endif /* RGBDS_ASM_FSTACK_H */
-88
View File
@@ -1,88 +0,0 @@
// SPDX-License-Identifier: MIT
// Contains some assembler-wide defines and externs
#ifndef RGBDS_ASM_FSTACK_HPP
#define RGBDS_ASM_FSTACK_HPP
#include <memory>
#include <optional>
#include <stdint.h>
#include <stdio.h>
#include <string>
#include <variant>
#include <vector>
#include "linkdefs.hpp"
#include "asm/intern.hpp"
#include "asm/lexer.hpp"
struct FileStackNode {
FileStackNodeType type;
std::variant<
std::vector<uint32_t>, // NODE_REPT
std::string // NODE_FILE, NODE_MACRO
>
data;
bool isQuiet; // Whether to omit this node from error reporting
std::shared_ptr<FileStackNode> parent; // Pointer to parent node, for error reporting
// Line at which the parent context was exited
// Meaningless at the root level, but gets written to the object file anyway, so init it
uint32_t lineNo = 0;
// Set only if referenced: ID within the object file, `UINT32_MAX` if not output yet
uint32_t ID = UINT32_MAX;
// REPT iteration counts since last named node, in reverse depth order
std::vector<uint32_t> &iters() { return std::get<std::vector<uint32_t>>(data); }
std::vector<uint32_t> const &iters() const { return std::get<std::vector<uint32_t>>(data); }
// File name for files, file::macro name for macros
std::string &name() { return std::get<std::string>(data); }
std::string const &name() const { return std::get<std::string>(data); }
FileStackNode(
FileStackNodeType type_,
std::variant<std::vector<uint32_t>, std::string> data_,
bool isQuiet_
)
: type(type_), data(data_), isQuiet(isQuiet_) {}
void printBacktrace(uint32_t curLineNo) const;
};
struct MacroArgs;
void fstk_VerboseOutputConfig();
void fstk_TraceCurrent();
std::shared_ptr<FileStackNode> fstk_GetFileStack();
std::shared_ptr<std::string> fstk_GetUniqueIDStr();
MacroArgs *fstk_GetCurrentMacroArgs();
void fstk_AddIncludePath(std::string const &path);
void fstk_AddPreIncludeFile(std::string const &path);
std::optional<std::string> fstk_FindFile(std::string const &path);
bool fstk_FileError(std::string const &path, char const *description);
bool fstk_FailedOnMissingInclude();
bool yywrap();
bool fstk_RunInclude(std::string const &path, bool isQuiet);
void fstk_RunMacro(InternedStr macroName, std::shared_ptr<MacroArgs> macroArgs, bool isQuiet);
void fstk_RunRept(uint32_t count, int32_t reptLineNo, ContentSpan const &span, bool isQuiet);
void fstk_RunFor(
InternedStr symName,
int32_t start,
int32_t stop,
int32_t step,
int32_t reptLineNo,
ContentSpan const &span,
bool isQuiet
);
bool fstk_Break();
void fstk_NewRecursionDepth(size_t newDepth);
bool fstk_Init(std::string const &mainPath);
#endif // RGBDS_ASM_FSTACK_HPP
-34
View File
@@ -1,34 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_INTERN_HPP
#define RGBDS_ASM_INTERN_HPP
#include <stddef.h>
#include <string>
#include <string_view>
#include <utility> // hash
class InternedStr {
size_t index;
public:
constexpr InternedStr() : index(static_cast<size_t>(-1)) {}
explicit constexpr InternedStr(size_t index_) : index(index_) {}
std::string const &str() const;
char const *c_str() const { return str().c_str(); }
bool operator==(InternedStr const &rhs) const { return index == rhs.index; }
template<typename T>
friend struct std::hash;
};
template<>
struct std::hash<InternedStr> {
size_t operator()(InternedStr const &str) const { return std::hash<size_t>{}(str.index); }
};
InternedStr intern(std::string_view str);
#endif // RGBDS_ASM_INTERN_HPP
+101
View File
@@ -0,0 +1,101 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_LEXER_H
#define RGBDS_ASM_LEXER_H
#include <stdbool.h>
#define MAXSTRLEN 255
struct LexerState;
extern struct LexerState *lexerState;
extern struct LexerState *lexerStateEOL;
static inline struct LexerState *lexer_GetState(void)
{
return lexerState;
}
static inline void lexer_SetState(struct LexerState *state)
{
lexerState = state;
}
static inline void lexer_SetStateAtEOL(struct LexerState *state)
{
lexerStateEOL = state;
}
extern char binDigits[2];
extern char gfxDigits[4];
static inline void lexer_SetBinDigits(char const digits[2])
{
binDigits[0] = digits[0];
binDigits[1] = digits[1];
}
static inline void lexer_SetGfxDigits(char const digits[4])
{
gfxDigits[0] = digits[0];
gfxDigits[1] = digits[1];
gfxDigits[2] = digits[2];
gfxDigits[3] = digits[3];
}
/*
* `path` is referenced, but not held onto..!
*/
struct LexerState *lexer_OpenFile(char const *path);
struct LexerState *lexer_OpenFileView(char *buf, size_t size, uint32_t lineNo);
void lexer_RestartRept(uint32_t lineNo);
void lexer_DeleteState(struct LexerState *state);
void lexer_Init(void);
enum LexerMode {
LEXER_NORMAL,
LEXER_RAW,
LEXER_SKIP_TO_ELIF,
LEXER_SKIP_TO_ENDC,
LEXER_SKIP_TO_ENDR
};
void lexer_SetMode(enum LexerMode mode);
void lexer_ToggleStringExpansion(bool enable);
uint32_t lexer_GetIFDepth(void);
void lexer_IncIFDepth(void);
void lexer_DecIFDepth(void);
bool lexer_RanIFBlock(void);
bool lexer_ReachedELSEBlock(void);
void lexer_RunIFBlock(void);
void lexer_ReachELSEBlock(void);
struct CaptureBody {
uint32_t lineNo;
char *body;
size_t size;
};
char const *lexer_GetFileName(void);
uint32_t lexer_GetLineNo(void);
uint32_t lexer_GetColNo(void);
void lexer_DumpStringExpansions(void);
int yylex(void);
void lexer_CaptureRept(struct CaptureBody *capture);
void lexer_CaptureMacroBody(struct CaptureBody *capture);
#define INITIAL_DS_ARG_SIZE 2
struct DsArgList {
size_t nbArgs;
size_t capacity;
struct Expression *args;
};
#endif /* RGBDS_ASM_LEXER_H */
-107
View File
@@ -1,107 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_LEXER_HPP
#define RGBDS_ASM_LEXER_HPP
#include <deque>
#include <memory>
#include <optional>
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "asm/intern.hpp"
enum LexerMode {
LEXER_NORMAL,
LEXER_RAW,
LEXER_SKIP_TO_ELIF,
LEXER_SKIP_TO_ENDC,
LEXER_SKIP_TO_ENDR,
NB_LEXER_MODES
};
struct Expansion {
std::optional<InternedStr> name;
std::shared_ptr<std::string> contents;
size_t offset; // Cursor into `contents`
size_t size() const { return contents->size(); }
bool advance(); // Increment `offset`; return whether it then exceeds `contents`
};
struct ContentSpan {
std::shared_ptr<char[]> ptr;
size_t size;
};
struct IfStackEntry {
bool ranIfBlock; // Whether an IF/ELIF/ELSE block ran already
bool reachedElseBlock; // Whether an ELSE block ran already
};
struct LexerState {
std::string path;
LexerMode mode;
bool atLineStart;
uint32_t lineNo;
int lastToken;
int nextToken;
std::deque<IfStackEntry> ifStack; // Front is the innermost `IF` block
bool capturing; // Whether the text being lexed should be captured
size_t captureSize; // Amount of text captured
std::shared_ptr<std::vector<char>> captureBuf; // Buffer to send the captured text to if set
bool enableExpansions;
bool enableStringExpansions;
size_t expansionScanDistance; // Max distance already scanned for expansions
std::deque<Expansion> expansionStack; // Front is the innermost current expansion
ContentSpan content; // Span of chars
size_t offset = 0; // Cursor into `content.ptr`
~LexerState();
int peekChar();
int peekCharAhead();
void setAsCurrentState();
void setFileAsNextState(std::string const &filePath, bool updateStateNow);
void setViewAsNextState(char const *name, ContentSpan const &content_, uint32_t lineNo_);
void clear(uint32_t lineNo_);
};
void lexer_SetBinDigits(char const digits[2]);
void lexer_SetGfxDigits(char const digits[4]);
bool lexer_AtTopLevel();
void lexer_RestartRept(uint32_t lineNo);
void lexer_SetMode(LexerMode mode);
void lexer_ToggleStringExpansion(bool enable);
uint32_t lexer_GetIFDepth();
void lexer_IncIFDepth();
void lexer_DecIFDepth();
bool lexer_RanIFBlock();
bool lexer_ReachedELSEBlock();
void lexer_RunIFBlock();
void lexer_ReachELSEBlock();
void lexer_CheckRecursionDepth();
uint32_t lexer_GetLineNo();
void lexer_TraceStringExpansions();
struct Capture {
uint32_t lineNo;
ContentSpan span;
};
Capture lexer_CaptureRept();
Capture lexer_CaptureMacro();
#endif // RGBDS_ASM_LEXER_HPP
+37
View File
@@ -0,0 +1,37 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2020, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_MACRO_H
#define RGBDS_MACRO_H
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "asm/warning.h"
#include "helpers.h"
struct MacroArgs;
struct MacroArgs *macro_GetCurrentArgs(void);
struct MacroArgs *macro_NewArgs(void);
void macro_AppendArg(struct MacroArgs **args, char *s);
void macro_UseNewArgs(struct MacroArgs *args);
void macro_FreeArgs(struct MacroArgs *args);
char const *macro_GetArg(uint32_t i);
char *macro_GetAllArgs(void);
uint32_t macro_GetUniqueID(void);
char const *macro_GetUniqueIDStr(void);
void macro_SetUniqueID(uint32_t id);
uint32_t macro_UseNewUniqueID(void);
void macro_ShiftCurrentArgs(int32_t count);
uint32_t macro_NbArgs(void);
#endif
-23
View File
@@ -1,23 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_MACRO_HPP
#define RGBDS_ASM_MACRO_HPP
#include <memory>
#include <stdint.h>
#include <string>
#include <vector>
struct MacroArgs {
uint32_t shift;
std::vector<std::shared_ptr<std::string>> args;
uint32_t nbArgs() const { return args.size() - shift; }
std::shared_ptr<std::string> getArg(int32_t num) const;
std::shared_ptr<std::string> getAllArgs() const;
void appendArg(std::shared_ptr<std::string> arg);
void shiftArgs(int32_t count);
};
#endif // RGBDS_ASM_MACRO_HPP
+37
View File
@@ -0,0 +1,37 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2021, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_MAIN_H
#define RGBDS_MAIN_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "helpers.h"
extern bool haltnop;
extern bool optimizeloads;
extern bool verbose;
extern bool warnings; /* True to enable warnings, false to disable them. */
extern FILE *dependfile;
extern char *tzTargetFileName;
extern bool oGeneratedMissingIncludes;
extern bool oFailedOnMissingInclude;
extern bool oGeneratePhonyDeps;
/* TODO: are these really needed? */
#define YY_FATAL_ERROR fatalerror
#ifdef YYLMAX
#undef YYLMAX
#endif
#define YYLMAX 65536
#endif /* RGBDS_MAIN_H */
-50
View File
@@ -1,50 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_MAIN_HPP
#define RGBDS_ASM_MAIN_HPP
#include <optional>
#include <stdint.h>
#include <stdio.h>
#include <string>
#include "helpers.hpp" // assume
#include "util.hpp" // xfclose
enum MissingInclude {
INC_ERROR, // A missing included file is an error that halts assembly
GEN_EXIT, // A missing included file is assumed to be generated; exit normally
GEN_CONTINUE, // A missing included file is assumed to be generated; continue assembling
};
struct Options {
bool exportAll = false; // -E
uint8_t fixPrecision = 16; // -Q
size_t maxRecursionDepth = 64; // -r
char binDigits[2] = {'0', '1'}; // -b
char gfxDigits[4] = {'0', '1', '2', '3'}; // -g
FILE *dependFile = nullptr; // -M
std::optional<std::string> targetFileName{}; // -MQ, -MT
MissingInclude missingIncludeState = INC_ERROR; // -MC, -MG
bool generatePhonyDeps = false; // -MP
std::optional<std::string> objectFileName{}; // -o
uint8_t padByte = 0; // -p
uint64_t maxErrors = 0; // -X
~Options() {
if (dependFile) {
xfclose(dependFile);
}
}
void printDep(std::string const &depName) {
if (dependFile) {
assume(targetFileName.has_value());
fprintf(dependFile, "%s: %s\n", targetFileName->c_str(), depName.c_str());
}
}
};
extern Options options;
#endif // RGBDS_ASM_MAIN_HPP
+22
View File
@@ -0,0 +1,22 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2021, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_OPT_H
#define RGBDS_OPT_H
void opt_B(char chars[2]);
void opt_G(char chars[4]);
void opt_P(uint8_t fill);
void opt_Parse(char const *option);
void opt_Push(void);
void opt_Pop(void);
#endif
-19
View File
@@ -1,19 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_OPT_HPP
#define RGBDS_ASM_OPT_HPP
#include <stdint.h>
void opt_B(char const binDigits[2]);
void opt_G(char const gfxDigits[4]);
void opt_P(uint8_t padByte);
void opt_Q(uint8_t fixPrecision);
void opt_W(char const *flag);
void opt_Parse(char const *option);
void opt_Push();
void opt_Pop();
void opt_CheckStack();
#endif // RGBDS_ASM_OPT_HPP
+30
View File
@@ -0,0 +1,30 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_OUTPUT_H
#define RGBDS_ASM_OUTPUT_H
#include <stdint.h>
#include "linkdefs.h"
struct Expression;
struct FileStackNode;
extern char *tzObjectname;
extern struct Section *pSectionList, *pCurrentSection;
void out_RegisterNode(struct FileStackNode *node);
void out_ReplaceNode(struct FileStackNode *node);
void out_SetFileName(char *s);
void out_CreatePatch(uint32_t type, struct Expression const *expr, uint32_t ofs, uint32_t pcShift);
bool out_CreateAssert(enum AssertionType type, struct Expression const *expr,
char const *message, uint32_t ofs);
void out_WriteObject(void);
#endif /* RGBDS_ASM_OUTPUT_H */
-28
View File
@@ -1,28 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_OUTPUT_HPP
#define RGBDS_ASM_OUTPUT_HPP
#include <memory>
#include <stdint.h>
#include <string>
#include <vector>
#include "linkdefs.hpp"
struct Expression;
struct FileStackNode;
struct Symbol;
enum StateFeature { STATE_EQU, STATE_VAR, STATE_EQUS, STATE_CHAR, STATE_MACRO, NB_STATE_FEATURES };
void out_RegisterNode(std::shared_ptr<FileStackNode> node);
void out_RegisterSymbol(Symbol &sym);
void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32_t pcShift);
void out_CreateAssert(
AssertionType type, Expression const &expr, std::string const &message, uint32_t ofs
);
void out_WriteObject();
void out_WriteState(std::string name, std::vector<StateFeature> const &features);
#endif // RGBDS_ASM_OUTPUT_HPP
+66
View File
@@ -0,0 +1,66 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_RPN_H
#define RGBDS_ASM_RPN_H
#include <stdint.h>
#include <stdbool.h>
#include "linkdefs.h"
#define MAXRPNLEN 1048576
struct Expression {
int32_t nVal; // If the expression's value is known, it's here
char *reason; // Why the expression is not known, if it isn't
bool isKnown; // Whether the expression's value is known
bool isSymbol; // Whether the expression represents a symbol
uint8_t *tRPN; // Array of bytes serializing the RPN expression
uint32_t nRPNCapacity; // Size of the `tRPN` buffer
uint32_t nRPNLength; // Used size of the `tRPN` buffer
uint32_t nRPNPatchSize; // Size the expression will take in the obj file
};
/*
* Determines if an expression is known at assembly time
*/
static inline bool rpn_isKnown(const struct Expression *expr)
{
return expr->isKnown;
}
/*
* Determines if an expression is a symbol suitable for const diffing
*/
static inline bool rpn_isSymbol(const struct Expression *expr)
{
return expr->isSymbol;
}
void rpn_Symbol(struct Expression *expr, char const *tzSym);
void rpn_Number(struct Expression *expr, uint32_t i);
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
struct Symbol const *rpn_SymbolOf(struct Expression const *expr);
bool rpn_IsDiffConstant(struct Expression const *src, struct Symbol const *sym);
void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
const struct Expression *src1,
const struct Expression *src2);
void rpn_HIGH(struct Expression *expr, const struct Expression *src);
void rpn_LOW(struct Expression *expr, const struct Expression *src);
void rpn_ISCONST(struct Expression *expr, const struct Expression *src);
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
void rpn_BankSymbol(struct Expression *expr, char const *tzSym);
void rpn_BankSection(struct Expression *expr, char const *tzSectionName);
void rpn_BankSelf(struct Expression *expr);
void rpn_Free(struct Expression *expr);
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
void rpn_CheckRST(struct Expression *expr, const struct Expression *src);
#endif /* RGBDS_ASM_RPN_H */
-66
View File
@@ -1,66 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_RPN_HPP
#define RGBDS_ASM_RPN_HPP
#include <stdint.h>
#include <string>
#include <variant>
#include <vector>
#include "linkdefs.hpp"
#include "asm/intern.hpp"
struct Symbol;
struct RPNValue {
RPNCommand command; // The RPN_* command ID
std::variant<std::monostate, uint8_t, uint32_t, InternedStr> data; // Data after the ID, if any
RPNValue(RPNCommand cmd);
RPNValue(RPNCommand cmd, uint8_t val);
RPNValue(RPNCommand cmd, uint32_t val);
RPNValue(RPNCommand cmd, InternedStr name);
void appendEncoded(std::vector<uint8_t> &buffer) const;
};
struct Expression {
std::variant<
int32_t, // If the expression's value is known, it's here
std::string // Why the expression is not known, if it isn't
>
data = 0;
std::vector<RPNValue> rpn{}; // Values to be serialized into the RPN expression
bool isKnown() const { return std::holds_alternative<int32_t>(data); }
int32_t value() const { return std::get<int32_t>(data); }
int32_t getConstVal() const;
Symbol const *symbolOf() const;
bool isDiffConstant(Symbol const *symName) const;
void makeNumber(uint32_t value);
void makeSymbol(InternedStr symName);
void makeBankSymbol(InternedStr symName);
void makeBankSection(std::string const &sectName);
void makeSizeOfSection(std::string const &sectName);
void makeStartOfSection(std::string const &sectName);
void makeSizeOfSectionType(SectionType type);
void makeStartOfSectionType(SectionType type);
void makeUnaryOp(RPNCommand op, Expression &&src);
void makeBinaryOp(RPNCommand op, Expression &&src1, Expression const &src2);
void addCheckHRAM();
void addCheckRST();
void addCheckBitIndex(uint8_t mask);
void checkNBit(uint8_t n) const;
void encode(std::vector<uint8_t> &buffer) const;
};
bool checkNBit(int32_t v, uint8_t n, char const *name);
#endif // RGBDS_ASM_RPN_HPP
+79
View File
@@ -0,0 +1,79 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2020, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_SECTION_H
#define RGBDS_SECTION_H
#include <stdint.h>
#include <stdbool.h>
#include "linkdefs.h"
extern uint8_t fillByte;
struct Expression;
struct Section {
char *name;
enum SectionType type;
enum SectionModifier modifier;
struct FileStackNode *src; /* Where the section was defined */
uint32_t fileLine; /* Line where the section was defined */
uint32_t size;
uint32_t org;
uint32_t bank;
uint8_t align;
uint16_t alignOfs;
struct Section *next;
struct Patch *patches;
uint8_t *data;
};
struct SectionSpec {
uint32_t bank;
uint8_t alignment;
uint16_t alignOfs;
};
struct Section *out_FindSectionByName(const char *name);
void out_NewSection(char const *name, uint32_t secttype, uint32_t org,
struct SectionSpec const *attributes,
enum SectionModifier mod);
void out_SetLoadSection(char const *name, uint32_t secttype, uint32_t org,
struct SectionSpec const *attributes,
enum SectionModifier mod);
void out_EndLoadSection(void);
struct Section *sect_GetSymbolSection(void);
uint32_t sect_GetSymbolOffset(void);
uint32_t sect_GetOutputOffset(void);
void sect_AlignPC(uint8_t alignment, uint16_t offset);
void sect_StartUnion(void);
void sect_NextUnionMember(void);
void sect_EndUnion(void);
void sect_CheckUnionClosed(void);
void out_AbsByte(uint8_t b);
void out_AbsByteGroup(uint8_t const *s, int32_t length);
void out_AbsWordGroup(uint8_t const *s, int32_t length);
void out_AbsLongGroup(uint8_t const *s, int32_t length);
void out_Skip(int32_t skip, bool ds);
void out_String(char const *s);
void out_RelByte(struct Expression *expr, uint32_t pcShift);
void out_RelBytes(uint32_t n, struct Expression *exprs, size_t size);
void out_RelWord(struct Expression *expr, uint32_t pcShift);
void out_RelLong(struct Expression *expr, uint32_t pcShift);
void out_PCRelByte(struct Expression *expr, uint32_t pcShift);
void out_BinaryFile(char const *s, int32_t startPos);
void out_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length);
void out_PushSection(void);
void out_PopSection(void);
#endif
-113
View File
@@ -1,113 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_SECTION_HPP
#define RGBDS_ASM_SECTION_HPP
#include <deque>
#include <memory>
#include <optional>
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "intern.hpp"
#include "linkdefs.hpp"
struct Expression;
struct FileStackNode;
struct Section;
struct Patch {
std::shared_ptr<FileStackNode> src;
uint32_t lineNo;
uint32_t offset;
Section *pcSection;
uint32_t pcOffset;
uint8_t type;
std::vector<uint8_t> rpn;
};
struct Section {
std::string name;
SectionType type;
SectionModifier modifier;
std::shared_ptr<FileStackNode> src; // Where the section was defined
uint32_t fileLine; // Line where the section was defined
uint32_t size;
uint32_t org;
uint32_t bank;
uint8_t align; // Exactly as specified in `ALIGN[]`
uint16_t alignOfs;
std::deque<Patch> patches;
std::vector<uint8_t> data;
uint32_t getID() const; // ID of the section in the object file (`UINT32_MAX` if none)
bool isSizeKnown() const;
};
struct SectionSpec {
uint32_t bank;
uint8_t alignment;
uint16_t alignOfs;
};
size_t sect_CountSections();
void sect_ForEach(void (*callback)(Section &));
Section *sect_FindSectionByName(std::string const &name);
void sect_NewSection(
std::string const &name,
SectionType type,
uint32_t org,
SectionSpec const &attrs,
SectionModifier mod
);
void sect_SetLoadSection(
std::string const &name,
SectionType type,
uint32_t org,
SectionSpec const &attrs,
SectionModifier mod
);
void sect_EndLoadSection(char const *cause);
void sect_CheckLoadClosed();
Section *sect_GetSymbolSection();
uint32_t sect_GetSymbolOffset();
uint32_t sect_GetOutputOffset();
std::optional<uint32_t> sect_GetOutputBank();
Patch *sect_AddOutputPatch();
uint32_t sect_GetAlignBytes(uint8_t alignment, uint16_t offset);
void sect_AlignPC(uint8_t alignment, uint16_t offset);
void sect_CheckSizes();
void sect_StartUnion();
void sect_NextUnionMember();
void sect_EndUnion();
void sect_CheckUnionClosed();
void sect_ConstByte(uint8_t byte);
void sect_ByteString(std::vector<int32_t> const &str);
void sect_WordString(std::vector<int32_t> const &str);
void sect_LongString(std::vector<int32_t> const &str);
void sect_Skip(uint32_t skip, bool ds);
void sect_RelByte(Expression const &expr, uint32_t pcShift);
void sect_RelBytes(uint32_t n, std::vector<Expression> const &exprs);
void sect_RelWord(Expression const &expr, uint32_t pcShift);
void sect_RelLong(Expression const &expr, uint32_t pcShift);
void sect_PCRelByte(Expression const &expr, uint32_t pcShift);
bool sect_BinaryFile(std::string const &name, uint32_t startPos);
bool sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t length);
void sect_EndSection();
void sect_PushSection();
void sect_PopSection();
void sect_CheckStack();
InternedStr sect_PushSectionFragmentLiteral();
#endif // RGBDS_ASM_SECTION_HPP
+152
View File
@@ -0,0 +1,152 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2020, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_SYMBOL_H
#define RGBDS_SYMBOL_H
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include "asm/section.h"
#include "platform.h" // MIN_NB_ELMS
#include "types.h"
#define HASHSIZE (1 << 16)
#define MAXSYMLEN 256
enum SymbolType {
SYM_LABEL,
SYM_EQU,
SYM_SET,
SYM_MACRO,
SYM_EQUS,
SYM_REF // Forward reference to a label
};
struct Symbol {
char name[MAXSYMLEN + 1];
enum SymbolType type;
bool isExported; /* Whether the symbol is to be exported */
bool isBuiltin; /* Whether the symbol is a built-in */
struct Section *section;
struct FileStackNode *src; /* Where the symbol was defined */
uint32_t fileLine; /* Line where the symbol was defined */
bool hasCallback;
union {
/* If sym_IsNumeric */
int32_t value;
int32_t (*numCallback)(void);
/* For SYM_MACRO */
struct {
size_t macroSize;
char *macro;
};
/* For SYM_EQUS, TODO: separate "base" fields from SYM_MACRO */
char const *(*strCallback)(void); /* For SYM_EQUS */
};
uint32_t ID; /* ID of the symbol in the object file (-1 if none) */
struct Symbol *next; /* Next object to output in the object file */
};
bool sym_IsPC(struct Symbol const *sym);
static inline bool sym_IsDefined(struct Symbol const *sym)
{
return sym->type != SYM_REF;
}
static inline struct Section *sym_GetSection(struct Symbol const *sym)
{
return sym_IsPC(sym) ? sect_GetSymbolSection() : sym->section;
}
static inline bool sym_IsConstant(struct Symbol const *sym)
{
if (sym->type == SYM_LABEL) {
struct Section const *sect = sym_GetSection(sym);
return sect && sect->org != (uint32_t)-1;
}
return sym->type == SYM_EQU || sym->type == SYM_SET;
}
static inline bool sym_IsNumeric(struct Symbol const *sym)
{
return sym->type == SYM_LABEL || sym->type == SYM_EQU
|| sym->type == SYM_SET;
}
static inline bool sym_IsLabel(struct Symbol const *sym)
{
return sym->type == SYM_LABEL || sym->type == SYM_REF;
}
static inline bool sym_IsLocal(struct Symbol const *sym)
{
return sym_IsLabel(sym) && strchr(sym->name, '.');
}
static inline bool sym_IsExported(struct Symbol const *sym)
{
return sym->isExported;
}
/*
* Get a string equate's value
*/
static inline char const *sym_GetStringValue(struct Symbol const *sym)
{
if (sym->hasCallback)
return sym->strCallback();
return sym->macro;
}
void sym_ForEach(void (*func)(struct Symbol *, void *), void *arg);
int32_t sym_GetValue(struct Symbol const *sym);
void sym_SetExportAll(bool set);
struct Symbol *sym_AddLocalLabel(char const *symName);
struct Symbol *sym_AddLabel(char const *symName);
struct Symbol *sym_AddAnonLabel(void);
void sym_WriteAnonLabelName(char buf[MIN_NB_ELMS(MAXSYMLEN + 1)], uint32_t ofs, bool neg);
void sym_Export(char const *symName);
struct Symbol *sym_AddEqu(char const *symName, int32_t value);
struct Symbol *sym_AddSet(char const *symName, int32_t value);
uint32_t sym_GetPCValue(void);
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);
uint32_t sym_GetConstantValue(char const *s);
/*
* Find a symbol by exact name, bypassing expansion checks
*/
struct Symbol *sym_FindExactSymbol(char const *name);
/*
* Find a symbol by exact name; may not be scoped, produces an error if it is
*/
struct Symbol *sym_FindUnscopedSymbol(char const *name);
/*
* Find a symbol, possibly scoped, by name
*/
struct Symbol *sym_FindScopedSymbol(char const *name);
struct Symbol const *sym_GetPC(void);
struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char *body, size_t size);
struct Symbol *sym_Ref(char const *symName);
struct Symbol *sym_AddString(char const *symName, char const *value);
struct Symbol *sym_RedefString(char const *symName, char const *value);
void sym_Purge(char const *symName);
void sym_Init(time_t now);
/* Functions to save and restore the current symbol scope. */
char const *sym_GetCurrentSymbolScope(void);
void sym_SetCurrentSymbolScope(char const *newScope);
#endif /* RGBDS_SYMBOL_H */
-107
View File
@@ -1,107 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_SYMBOL_HPP
#define RGBDS_ASM_SYMBOL_HPP
#include <memory>
#include <stdint.h>
#include <string>
#include <time.h>
#include <utility>
#include <variant>
#include "asm/intern.hpp"
#include "asm/lexer.hpp"
#include "asm/section.hpp"
enum SymbolType {
SYM_LABEL,
SYM_EQU,
SYM_VAR,
SYM_MACRO,
SYM_EQUS,
SYM_REF // Forward reference to a label
};
struct Symbol; // Forward declaration for `sym_IsPC`
bool sym_IsPC(Symbol const *sym); // Forward declaration for `getSection`
struct Symbol {
InternedStr name;
SymbolType type;
bool isBuiltin;
bool isExported; // Not relevant for SYM_MACRO or SYM_EQUS
bool isQuiet; // Only relevant for SYM_MACRO
Section *section;
std::shared_ptr<FileStackNode> src; // Where the symbol was defined
uint32_t fileLine; // Line where the symbol was defined
std::variant<
int32_t, // If isNumeric()
int32_t (*)(), // If isNumeric() via a callback
ContentSpan, // For SYM_MACRO
std::shared_ptr<std::string>, // For SYM_EQUS
std::shared_ptr<std::string> (*)() // For SYM_EQUS via a callback
>
data;
uint32_t ID; // ID of the symbol in the object file (`UINT32_MAX` if none)
uint32_t defIndex; // Ordering of the symbol in the state file
bool isDefined() const { return type != SYM_REF; }
bool isNumeric() const { return type == SYM_LABEL || type == SYM_EQU || type == SYM_VAR; }
bool isLabel() const { return type == SYM_LABEL || type == SYM_REF; }
bool isConstant() const {
if (type == SYM_LABEL) {
Section const *sect = getSection();
return sect && sect->org != UINT32_MAX;
}
return type == SYM_EQU || type == SYM_VAR;
}
Section *getSection() const { return sym_IsPC(this) ? sect_GetSymbolSection() : section; }
int32_t getValue() const;
int32_t getOutputValue() const;
ContentSpan const &getMacro() const;
std::shared_ptr<std::string> getEqus() const;
uint32_t getConstantValue() const;
};
bool sym_IsDotScope(InternedStr symName);
void sym_ForEach(void (*callback)(Symbol &));
Symbol *sym_AddLocalLabel(InternedStr symName);
Symbol *sym_AddLabel(InternedStr symName);
Symbol *sym_AddAnonLabel();
InternedStr sym_MakeAnonLabelName(uint32_t ofs, bool neg);
void sym_Export(InternedStr symName);
Symbol *sym_AddEqu(InternedStr symName, int32_t value);
Symbol *sym_RedefEqu(InternedStr symName, int32_t value);
Symbol *sym_AddVar(InternedStr symName, int32_t value);
int32_t sym_GetRSValue();
void sym_SetRSValue(int32_t value);
// Find a symbol by exact name, bypassing expansion checks
Symbol *sym_FindExactSymbol(InternedStr symName);
// Find a symbol, possibly scoped, by name
Symbol *sym_FindScopedSymbol(InternedStr symName);
// Find a scoped symbol by name; do not return `@` or `_NARG` when they have no value
Symbol *sym_FindScopedValidSymbol(InternedStr symName);
Symbol const *sym_GetPC();
Symbol *sym_AddMacro(InternedStr symName, int32_t defLineNo, ContentSpan const &span, bool isQuiet);
Symbol *sym_Ref(InternedStr symName);
Symbol *sym_AddString(InternedStr symName, std::shared_ptr<std::string> value);
Symbol *sym_RedefString(InternedStr symName, std::shared_ptr<std::string> value);
void sym_Purge(InternedStr symName);
bool sym_IsPurgedExact(InternedStr symName);
bool sym_IsPurgedScoped(InternedStr symName);
void sym_Init(time_t now);
// Functions to save and restore the current label scopes.
std::pair<Symbol const *, Symbol const *> sym_GetCurrentLabelScopes();
void sym_SetCurrentLabelScopes(std::pair<Symbol const *, Symbol const *> newScopes);
void sym_ResetCurrentLabelScopes();
#endif // RGBDS_ASM_SYMBOL_HPP
+21
View File
@@ -0,0 +1,21 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_UTIL_H
#define RGBDS_UTIL_H
#include <stdint.h>
uint32_t calchash(const char *s);
char const *print(int c);
/*
* @return The number of bytes read, or 0 if invalid data was found
*/
size_t readUTF8Char(uint8_t *dest, char const *src);
#endif /* RGBDS_UTIL_H */
+70
View File
@@ -0,0 +1,70 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2019, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef WARNING_H
#define WARNING_H
#include "helpers.h"
extern unsigned int nbErrors;
enum WarningID {
WARNING_ASSERT, /* Assertions */
WARNING_BUILTIN_ARG, /* Invalid args to builtins */
WARNING_CHARMAP_REDEF, /* Charmap entry re-definition */
WARNING_DIV, /* Division undefined behavior */
WARNING_EMPTY_DATA_DIRECTIVE, /* `db`, `dw` or `dl` directive without data in ROM */
WARNING_EMPTY_MACRO_ARG, /* Empty macro argument */
WARNING_EMPTY_STRRPL, /* Empty second argument in `STRRPL` */
WARNING_LARGE_CONSTANT, /* Constants too large */
WARNING_LONG_STR, /* String too long for internal buffers */
WARNING_MACRO_SHIFT, /* Shift past available arguments in macro */
WARNING_NESTED_COMMENT, /* Comment-start delimiter in a block comment */
WARNING_OBSOLETE, /* Obsolete things */
WARNING_SHIFT, /* Shifting undefined behavior */
WARNING_SHIFT_AMOUNT, /* Strange shift amount */
WARNING_TRUNCATION, /* Implicit truncation loses some bits */
WARNING_USER, /* User warnings */
NB_WARNINGS,
/* Warnings past this point are "meta" warnings */
WARNING_ALL = NB_WARNINGS,
WARNING_EXTRA,
WARNING_EVERYTHING,
NB_WARNINGS_ALL
#define NB_META_WARNINGS (NB_WARNINGS_ALL - NB_WARNINGS)
};
void processWarningFlag(char const *flag);
/*
* Used to warn the user about problems that don't prevent the generation of
* valid code.
*/
void warning(enum WarningID id, const char *fmt, ...) format_(printf, 2, 3);
/*
* Used for errors that compromise the whole assembly process by affecting the
* following code, potencially making the assembler generate errors caused by
* the first one and unrelated to the code that the assembler complains about.
* It is also used when the assembler goes into an invalid state (for example,
* when it fails to allocate memory).
*/
_Noreturn void fatalerror(const char *fmt, ...) format_(printf, 1, 2);
/*
* Used for errors that make it impossible to assemble correctly, but don't
* affect the following code. The code will fail to assemble but the user will
* get a list of all errors at the end, making it easier to fix all of them at
* once.
*/
void error(const char *fmt, ...) format_(printf, 1, 2);
#endif
-89
View File
@@ -1,89 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_ASM_WARNING_HPP
#define RGBDS_ASM_WARNING_HPP
#include <functional>
#include "diagnostics.hpp"
enum WarningLevel {
LEVEL_DEFAULT, // Warnings that are enabled by default
LEVEL_ALL, // Warnings that probably indicate an error
LEVEL_EXTRA, // Warnings that are less likely to indicate an error
LEVEL_EVERYTHING, // Literally every warning
};
enum WarningID {
WARNING_ASSERT, // Assertions
WARNING_BACKWARDS_FOR, // `FOR` loop with backwards range
WARNING_BUILTIN_ARG, // Invalid args to builtins
WARNING_CHARMAP_REDEF, // Charmap entry re-definition
WARNING_DIV, // Undefined division behavior
WARNING_EMPTY_DATA_DIRECTIVE, // `db`, `dw` or `dl` directive without data in ROM
WARNING_EMPTY_MACRO_ARG, // Empty macro argument
WARNING_EMPTY_STRRPL, // Empty second argument in `STRRPL`
WARNING_EXPORT_UNDEFINED, // `EXPORT` of an undefined symbol
WARNING_LARGE_CONSTANT, // Constants too large
WARNING_MACRO_SHIFT, // `SHIFT` past available arguments in macro
WARNING_NESTED_COMMENT, // Comment-start delimiter in a block comment
WARNING_OBSOLETE, // Obsolete/deprecated things
WARNING_SHIFT, // Undefined `SHIFT` behavior
WARNING_SHIFT_AMOUNT, // Strange `SHIFT` amount
WARNING_UNMATCHED_DIRECTIVE, // `PUSH[C|O|S]` without `POP[C|O|S]`
WARNING_UNTERMINATED_LOAD, // `LOAD` without `ENDL`
WARNING_USER, // User-defined `WARN`ings
NB_PLAIN_WARNINGS,
// Warnings past this point are "parametric" warnings, only mapping to a single flag
// Treating string as number may lose some bits
WARNING_NUMERIC_STRING_1 = NB_PLAIN_WARNINGS,
WARNING_NUMERIC_STRING_2,
// Purging an exported symbol or label
WARNING_PURGE_1,
WARNING_PURGE_2,
// Implicit truncation loses some bits
WARNING_TRUNCATION_1,
WARNING_TRUNCATION_2,
// Character without charmap entry
WARNING_UNMAPPED_CHAR_1,
WARNING_UNMAPPED_CHAR_2,
NB_WARNINGS,
};
extern Diagnostics<WarningLevel, WarningID> warnings;
// Used to warn the user about problems that don't prevent the generation of
// valid code.
[[gnu::format(printf, 2, 3)]]
void warning(WarningID id, char const *fmt, ...);
// Used for errors that compromise the whole assembly process by affecting the
// following code, potentially making the assembler generate errors caused by
// the first one and unrelated to the code that the assembler complains about.
// It is also used when the assembler goes into an invalid state (for example,
// when it fails to allocate memory).
[[gnu::format(printf, 1, 2), noreturn]]
void fatal(char const *fmt, ...);
// Used for fatal errors that handle their own backtrace output.
[[noreturn]]
void fatalNoTrace(std::function<void()> callback);
// Used for errors that make it impossible to assemble correctly, but don't
// affect the following code. The code will fail to assemble but the user will
// get a list of all errors at the end, making it easier to fix all of them at
// once.
[[gnu::format(printf, 1, 2)]]
void error(char const *fmt, ...);
// Used for errors that handle their own backtrace output. The code will fail
// to assemble but the user will get a list of all errors at the end, making it
// easier to fix all of them at once.
void errorNoTrace(std::function<void()> callback);
void requireZeroErrors();
#endif // RGBDS_ASM_WARNING_HPP
-94
View File
@@ -1,94 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_BACKTRACE_HPP
#define RGBDS_BACKTRACE_HPP
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <vector>
#include "helpers.hpp" // InvocableR
#include "style.hpp"
#define TRACE_SEPARATOR "<-"
#define NODE_SEPARATOR "::"
#define REPT_NODE_PREFIX "REPT~"
struct Tracing {
uint64_t depth = 0;
bool collapse = false;
bool loud = false;
};
extern Tracing tracing;
bool trace_ParseTraceDepth(char const *arg);
template<typename NodeT>
void trace_PrintBacktrace(
std::vector<NodeT> const &stack,
InvocableR<char const *, NodeT const &> auto getName,
InvocableR<uint32_t, NodeT const &> auto getLineNo
) {
size_t n = stack.size();
if (n == 0) {
return; // LCOV_EXCL_LINE
}
auto printLocation = [&](size_t i) {
NodeT const &item = stack[n - i - 1];
style_Reset(stderr);
if (!tracing.collapse) {
fputs(" ", stderr); // Just three spaces; the fourth will be printed next
}
fprintf(stderr, " %s ", i == 0 ? "at" : TRACE_SEPARATOR);
style_Set(stderr, STYLE_CYAN, true);
fputs(getName(item), stderr);
style_Set(stderr, STYLE_CYAN, false);
fprintf(stderr, "(%" PRIu32 ")", getLineNo(item));
if (!tracing.collapse) {
putc('\n', stderr);
}
};
if (tracing.collapse) {
fputs(" ", stderr); // Just three spaces; the fourth will be handled by the loop
}
if (tracing.depth == 0 || static_cast<size_t>(tracing.depth) >= n) {
for (size_t i = 0; i < n; ++i) {
printLocation(i);
}
} else {
size_t last = tracing.depth / 2;
size_t first = tracing.depth - last;
size_t skipped = n - tracing.depth;
for (size_t i = 0; i < first; ++i) {
printLocation(i);
}
style_Reset(stderr);
if (tracing.collapse) {
fputs(" " TRACE_SEPARATOR, stderr);
} else {
fputs(" ", stderr); // Just three spaces; the fourth will be printed next
}
fprintf(stderr, " ...%zu more%s", skipped, last ? "..." : "");
if (!tracing.collapse) {
putc('\n', stderr);
}
for (size_t i = n - last; i < n; ++i) {
printLocation(i);
}
}
if (tracing.collapse) {
putc('\n', stderr);
}
style_Reset(stderr);
}
#endif // RGBDS_BACKTRACE_HPP
-21
View File
@@ -1,21 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef RGBDS_CLI_HPP
#define RGBDS_CLI_HPP
#include <stdarg.h>
#include <string>
#include "extern/getopt.hpp" // option
#include "usage.hpp"
void cli_ParseArgs(
int argc,
char *argv[],
char const *shortOpts,
option const *longOpts,
void (*parseArg)(int, char *),
Usage usage
);
#endif // RGBDS_CLI_HPP

Some files were not shown because too many files have changed in this diff Show More