mirror of
https://github.com/gbdev/rgbds.git
synced 2026-06-25 18:48:04 +00:00
Ensure CRLF line endings are preserved when necessary
Some test cases need CRLF line endings checked out even on Unix. Also some source files had inadvertently contained CR bytes.
This commit is contained in:
+21
-21
@@ -1,21 +1,21 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
#ifndef RGBDS_CLI_HPP
|
#ifndef RGBDS_CLI_HPP
|
||||||
#define RGBDS_CLI_HPP
|
#define RGBDS_CLI_HPP
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "extern/getopt.hpp" // option
|
#include "extern/getopt.hpp" // option
|
||||||
#include "usage.hpp"
|
#include "usage.hpp"
|
||||||
|
|
||||||
void cli_ParseArgs(
|
void cli_ParseArgs(
|
||||||
int argc,
|
int argc,
|
||||||
char *argv[],
|
char *argv[],
|
||||||
char const *shortOpts,
|
char const *shortOpts,
|
||||||
option const *longOpts,
|
option const *longOpts,
|
||||||
void (*parseArg)(int, char *),
|
void (*parseArg)(int, char *),
|
||||||
Usage usage
|
Usage usage
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif // RGBDS_CLI_HPP
|
#endif // RGBDS_CLI_HPP
|
||||||
|
|||||||
+23
-23
@@ -1,23 +1,23 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
#ifndef RGBDS_GFX_FLIP_HPP
|
#ifndef RGBDS_GFX_FLIP_HPP
|
||||||
#define RGBDS_GFX_FLIP_HPP
|
#define RGBDS_GFX_FLIP_HPP
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// Flipping tends to happen fairly often, so take a bite out of dcache to speed it up
|
// Flipping tends to happen fairly often, so take a bite out of dcache to speed it up
|
||||||
static std::array<uint16_t, 256> flipTable = ([]() constexpr {
|
static std::array<uint16_t, 256> flipTable = ([]() constexpr {
|
||||||
std::array<uint16_t, 256> table{};
|
std::array<uint16_t, 256> table{};
|
||||||
for (uint16_t i = 0; i < table.size(); ++i) {
|
for (uint16_t i = 0; i < table.size(); ++i) {
|
||||||
// To flip all the bits, we'll flip both nibbles, then each nibble half, etc.
|
// To flip all the bits, we'll flip both nibbles, then each nibble half, etc.
|
||||||
uint16_t byte = i;
|
uint16_t byte = i;
|
||||||
byte = (byte & 0b0000'1111) << 4 | (byte & 0b1111'0000) >> 4;
|
byte = (byte & 0b0000'1111) << 4 | (byte & 0b1111'0000) >> 4;
|
||||||
byte = (byte & 0b0011'0011) << 2 | (byte & 0b1100'1100) >> 2;
|
byte = (byte & 0b0011'0011) << 2 | (byte & 0b1100'1100) >> 2;
|
||||||
byte = (byte & 0b0101'0101) << 1 | (byte & 0b1010'1010) >> 1;
|
byte = (byte & 0b0101'0101) << 1 | (byte & 0b1010'1010) >> 1;
|
||||||
table[i] = byte;
|
table[i] = byte;
|
||||||
}
|
}
|
||||||
return table;
|
return table;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
#endif // RGBDS_GFX_FLIP_HPP
|
#endif // RGBDS_GFX_FLIP_HPP
|
||||||
|
|||||||
+27
-27
@@ -1,27 +1,27 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
#ifndef RGBDS_GFX_PALETTE_HPP
|
#ifndef RGBDS_GFX_PALETTE_HPP
|
||||||
#define RGBDS_GFX_PALETTE_HPP
|
#define RGBDS_GFX_PALETTE_HPP
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct Palette {
|
struct Palette {
|
||||||
// An array of 4 GBC-native (RGB555) colors
|
// An array of 4 GBC-native (RGB555) colors
|
||||||
std::array<uint16_t, 4> colors{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
std::array<uint16_t, 4> colors{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
||||||
|
|
||||||
void addColor(uint16_t color);
|
void addColor(uint16_t color);
|
||||||
uint8_t indexOf(uint16_t color) const;
|
uint8_t indexOf(uint16_t color) const;
|
||||||
uint16_t &operator[](size_t index) { return colors[index]; }
|
uint16_t &operator[](size_t index) { return colors[index]; }
|
||||||
uint16_t const &operator[](size_t index) const { return colors[index]; }
|
uint16_t const &operator[](size_t index) const { return colors[index]; }
|
||||||
|
|
||||||
decltype(colors)::iterator begin();
|
decltype(colors)::iterator begin();
|
||||||
decltype(colors)::iterator end();
|
decltype(colors)::iterator end();
|
||||||
decltype(colors)::const_iterator begin() const;
|
decltype(colors)::const_iterator begin() const;
|
||||||
decltype(colors)::const_iterator end() const;
|
decltype(colors)::const_iterator end() const;
|
||||||
|
|
||||||
uint8_t size() const;
|
uint8_t size() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RGBDS_GFX_PALETTE_HPP
|
#endif // RGBDS_GFX_PALETTE_HPP
|
||||||
|
|||||||
+159
-159
@@ -1,159 +1,159 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
#include "cli.hpp"
|
#include "cli.hpp"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "extern/getopt.hpp"
|
#include "extern/getopt.hpp"
|
||||||
#include "style.hpp"
|
#include "style.hpp"
|
||||||
#include "usage.hpp"
|
#include "usage.hpp"
|
||||||
#include "util.hpp" // isBlankSpace
|
#include "util.hpp" // isBlankSpace
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
// Turn an at-file's contents into an argv that `getopt` can handle, appending them to `argPool`.
|
// Turn an at-file's contents into an argv that `getopt` can handle, appending them to `argPool`.
|
||||||
static std::vector<size_t>
|
static std::vector<size_t>
|
||||||
readAtFile(std::string const &path, std::vector<char> &argPool, Usage usage) {
|
readAtFile(std::string const &path, std::vector<char> &argPool, Usage usage) {
|
||||||
std::vector<size_t> argvOfs;
|
std::vector<size_t> argvOfs;
|
||||||
|
|
||||||
std::filebuf file;
|
std::filebuf file;
|
||||||
if (!file.open(path, std::ios_base::in)) {
|
if (!file.open(path, std::ios_base::in)) {
|
||||||
int errnum = errno;
|
int errnum = errno;
|
||||||
style_Set(stderr, STYLE_RED, true);
|
style_Set(stderr, STYLE_RED, true);
|
||||||
fputs("FATAL: ", stderr);
|
fputs("FATAL: ", stderr);
|
||||||
style_Reset(stderr);
|
style_Reset(stderr);
|
||||||
fprintf(stderr, "Failed to open at-file \"%s\": %s\n", path.c_str(), strerror(errnum));
|
fprintf(stderr, "Failed to open at-file \"%s\": %s\n", path.c_str(), strerror(errnum));
|
||||||
usage.printAndExit(1);
|
usage.printAndExit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = file.sbumpc();
|
int c = file.sbumpc();
|
||||||
|
|
||||||
// First, discard any leading blank space
|
// First, discard any leading blank space
|
||||||
while (isBlankSpace(c)) {
|
while (isBlankSpace(c)) {
|
||||||
c = file.sbumpc();
|
c = file.sbumpc();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's a comment, discard everything until EOL
|
// If it's a comment, discard everything until EOL
|
||||||
if (c == '#') {
|
if (c == '#') {
|
||||||
c = file.sbumpc();
|
c = file.sbumpc();
|
||||||
while (c != EOF && !isNewline(c)) {
|
while (c != EOF && !isNewline(c)) {
|
||||||
c = file.sbumpc();
|
c = file.sbumpc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
return argvOfs;
|
return argvOfs;
|
||||||
} else if (isNewline(c)) {
|
} else if (isNewline(c)) {
|
||||||
continue; // Start processing the next line
|
continue; // Start processing the next line
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alright, now we can parse the line
|
// Alright, now we can parse the line
|
||||||
do {
|
do {
|
||||||
argvOfs.push_back(argPool.size());
|
argvOfs.push_back(argPool.size());
|
||||||
|
|
||||||
// Read one argument (until the next whitespace char).
|
// Read one argument (until the next whitespace char).
|
||||||
// We know there is one because we already have its first character in `c`.
|
// We know there is one because we already have its first character in `c`.
|
||||||
for (; c != EOF && !isWhitespace(c); c = file.sbumpc()) {
|
for (; c != EOF && !isWhitespace(c); c = file.sbumpc()) {
|
||||||
argPool.push_back(c);
|
argPool.push_back(c);
|
||||||
}
|
}
|
||||||
argPool.push_back('\0');
|
argPool.push_back('\0');
|
||||||
|
|
||||||
// Discard blank space until the next argument (candidate)
|
// Discard blank space until the next argument (candidate)
|
||||||
while (isBlankSpace(c)) {
|
while (isBlankSpace(c)) {
|
||||||
c = file.sbumpc();
|
c = file.sbumpc();
|
||||||
}
|
}
|
||||||
} while (c != EOF && !isNewline(c)); // End if we reached EOL
|
} while (c != EOF && !isNewline(c)); // End if we reached EOL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cli_ParseArgs(
|
void cli_ParseArgs(
|
||||||
int argc,
|
int argc,
|
||||||
char *argv[],
|
char *argv[],
|
||||||
char const *shortOpts,
|
char const *shortOpts,
|
||||||
option const *longOpts,
|
option const *longOpts,
|
||||||
void (*parseArg)(int, char *),
|
void (*parseArg)(int, char *),
|
||||||
Usage usage
|
Usage usage
|
||||||
) {
|
) {
|
||||||
struct AtFileStackEntry {
|
struct AtFileStackEntry {
|
||||||
int parentInd; // Saved offset into parent argv
|
int parentInd; // Saved offset into parent argv
|
||||||
std::vector<char *> argv; // This context's arg pointer vec
|
std::vector<char *> argv; // This context's arg pointer vec
|
||||||
|
|
||||||
AtFileStackEntry(int parentInd_, std::vector<char *> argv_)
|
AtFileStackEntry(int parentInd_, std::vector<char *> argv_)
|
||||||
: parentInd(parentInd_), argv(argv_) {}
|
: parentInd(parentInd_), argv(argv_) {}
|
||||||
};
|
};
|
||||||
std::vector<AtFileStackEntry> atFileStack;
|
std::vector<AtFileStackEntry> atFileStack;
|
||||||
|
|
||||||
int curArgc = argc;
|
int curArgc = argc;
|
||||||
char **curArgv = argv;
|
char **curArgv = argv;
|
||||||
std::string optString = "-"s + shortOpts; // Request position arguments with a leading '-'
|
std::string optString = "-"s + shortOpts; // Request position arguments with a leading '-'
|
||||||
std::vector<std::vector<char>> argPools;
|
std::vector<std::vector<char>> argPools;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char *atFileName = nullptr;
|
char *atFileName = nullptr;
|
||||||
for (int ch;
|
for (int ch;
|
||||||
(ch = musl_getopt_long_only(curArgc, curArgv, optString.c_str(), longOpts)) != -1;) {
|
(ch = musl_getopt_long_only(curArgc, curArgv, optString.c_str(), longOpts)) != -1;) {
|
||||||
if (ch == 1 && musl_optarg[0] == '@') {
|
if (ch == 1 && musl_optarg[0] == '@') {
|
||||||
atFileName = &musl_optarg[1];
|
atFileName = &musl_optarg[1];
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
parseArg(ch, musl_optarg);
|
parseArg(ch, musl_optarg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atFileName) {
|
if (atFileName) {
|
||||||
// We need to allocate a new arg pool for each at-file, so as not to invalidate pointers
|
// We need to allocate a new arg pool for each at-file, so as not to invalidate pointers
|
||||||
// previous at-files may have generated to their own arg pools.
|
// previous at-files may have generated to their own arg pools.
|
||||||
// But for the same reason, the arg pool must also outlive the at-file's stack entry!
|
// But for the same reason, the arg pool must also outlive the at-file's stack entry!
|
||||||
std::vector<char> &argPool = argPools.emplace_back();
|
std::vector<char> &argPool = argPools.emplace_back();
|
||||||
|
|
||||||
// Copy `argv[0]` for error reporting, and because option parsing skips it
|
// Copy `argv[0]` for error reporting, and because option parsing skips it
|
||||||
AtFileStackEntry &stackEntry =
|
AtFileStackEntry &stackEntry =
|
||||||
atFileStack.emplace_back(musl_optind, std::vector{atFileName});
|
atFileStack.emplace_back(musl_optind, std::vector{atFileName});
|
||||||
|
|
||||||
// It would be nice to compute the char pointers on the fly, but reallocs don't allow
|
// It would be nice to compute the char pointers on the fly, but reallocs don't allow
|
||||||
// that; so we must compute the offsets after the pool is fixed
|
// that; so we must compute the offsets after the pool is fixed
|
||||||
std::vector<size_t> offsets = readAtFile(&musl_optarg[1], argPool, usage);
|
std::vector<size_t> offsets = readAtFile(&musl_optarg[1], argPool, usage);
|
||||||
stackEntry.argv.reserve(offsets.size() + 2); // Avoid a bunch of reallocs
|
stackEntry.argv.reserve(offsets.size() + 2); // Avoid a bunch of reallocs
|
||||||
for (size_t ofs : offsets) {
|
for (size_t ofs : offsets) {
|
||||||
stackEntry.argv.push_back(&argPool.data()[ofs]);
|
stackEntry.argv.push_back(&argPool.data()[ofs]);
|
||||||
}
|
}
|
||||||
stackEntry.argv.push_back(nullptr); // Don't forget the arg vector terminator!
|
stackEntry.argv.push_back(nullptr); // Don't forget the arg vector terminator!
|
||||||
|
|
||||||
curArgc = stackEntry.argv.size() - 1;
|
curArgc = stackEntry.argv.size() - 1;
|
||||||
curArgv = stackEntry.argv.data();
|
curArgv = stackEntry.argv.data();
|
||||||
musl_optind = 1; // Don't use 0 because we're not scanning a different argv per se
|
musl_optind = 1; // Don't use 0 because we're not scanning a different argv per se
|
||||||
} else {
|
} else {
|
||||||
if (musl_optind != curArgc) {
|
if (musl_optind != curArgc) {
|
||||||
// This happens if `--` is passed, process the remaining arg(s) as positional
|
// This happens if `--` is passed, process the remaining arg(s) as positional
|
||||||
assume(musl_optind < curArgc);
|
assume(musl_optind < curArgc);
|
||||||
for (int i = musl_optind; i < curArgc; ++i) {
|
for (int i = musl_optind; i < curArgc; ++i) {
|
||||||
parseArg(1, argv[i]); // Positional argument
|
parseArg(1, argv[i]); // Positional argument
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop off the top stack entry, or end parsing if none
|
// Pop off the top stack entry, or end parsing if none
|
||||||
if (atFileStack.empty()) {
|
if (atFileStack.empty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK to restore `optind` directly, because `optpos` must be 0 right now.
|
// OK to restore `optind` directly, because `optpos` must be 0 right now.
|
||||||
// (Providing 0 would be a "proper" reset, but we want to resume parsing)
|
// (Providing 0 would be a "proper" reset, but we want to resume parsing)
|
||||||
musl_optind = atFileStack.back().parentInd;
|
musl_optind = atFileStack.back().parentInd;
|
||||||
atFileStack.pop_back();
|
atFileStack.pop_back();
|
||||||
if (atFileStack.empty()) {
|
if (atFileStack.empty()) {
|
||||||
curArgc = argc;
|
curArgc = argc;
|
||||||
curArgv = argv;
|
curArgv = argv;
|
||||||
} else {
|
} else {
|
||||||
std::vector<char *> &vec = atFileStack.back().argv;
|
std::vector<char *> &vec = atFileStack.back().argv;
|
||||||
curArgc = vec.size();
|
curArgc = vec.size();
|
||||||
curArgv = vec.data();
|
curArgv = vec.data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-55
@@ -1,55 +1,55 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
#include "gfx/palette.hpp"
|
#include "gfx/palette.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
#include "gfx/main.hpp"
|
#include "gfx/main.hpp"
|
||||||
#include "gfx/rgba.hpp"
|
#include "gfx/rgba.hpp"
|
||||||
|
|
||||||
void Palette::addColor(uint16_t color) {
|
void Palette::addColor(uint16_t color) {
|
||||||
for (size_t i = 0; true; ++i) {
|
for (size_t i = 0; true; ++i) {
|
||||||
assume(i < colors.size()); // The packing should guarantee this
|
assume(i < colors.size()); // The packing should guarantee this
|
||||||
if (colors[i] == color) { // The color is already present
|
if (colors[i] == color) { // The color is already present
|
||||||
break;
|
break;
|
||||||
} else if (colors[i] == UINT16_MAX) { // Empty slot
|
} else if (colors[i] == UINT16_MAX) { // Empty slot
|
||||||
colors[i] = color;
|
colors[i] = color;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the ID of the color in the palette, or `size()` if the color is not in
|
// Returns the ID of the color in the palette, or `size()` if the color is not in
|
||||||
uint8_t Palette::indexOf(uint16_t color) const {
|
uint8_t Palette::indexOf(uint16_t color) const {
|
||||||
return color == Rgba::transparent
|
return color == Rgba::transparent
|
||||||
? 0
|
? 0
|
||||||
: std::find(begin(), colors.end(), color) - begin() + options.hasTransparentPixels;
|
: std::find(begin(), colors.end(), color) - begin() + options.hasTransparentPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Palette::begin() -> decltype(colors)::iterator {
|
auto Palette::begin() -> decltype(colors)::iterator {
|
||||||
// Skip the first slot if reserved for transparency
|
// Skip the first slot if reserved for transparency
|
||||||
return colors.begin() + options.hasTransparentPixels;
|
return colors.begin() + options.hasTransparentPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Palette::end() -> decltype(colors)::iterator {
|
auto Palette::end() -> decltype(colors)::iterator {
|
||||||
// Return an iterator pointing past the last non-empty element.
|
// Return an iterator pointing past the last non-empty element.
|
||||||
// Since the palette may contain gaps, we must scan from the end.
|
// Since the palette may contain gaps, we must scan from the end.
|
||||||
return std::find_if(RRANGE(colors), [](uint16_t c) { return c != UINT16_MAX; }).base();
|
return std::find_if(RRANGE(colors), [](uint16_t c) { return c != UINT16_MAX; }).base();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Palette::begin() const -> decltype(colors)::const_iterator {
|
auto Palette::begin() const -> decltype(colors)::const_iterator {
|
||||||
// Same as the non-const begin().
|
// Same as the non-const begin().
|
||||||
return colors.begin() + options.hasTransparentPixels;
|
return colors.begin() + options.hasTransparentPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Palette::end() const -> decltype(colors)::const_iterator {
|
auto Palette::end() const -> decltype(colors)::const_iterator {
|
||||||
// Same as the non-const end().
|
// Same as the non-const end().
|
||||||
return std::find_if(RRANGE(colors), [](uint16_t c) { return c != UINT16_MAX; }).base();
|
return std::find_if(RRANGE(colors), [](uint16_t c) { return c != UINT16_MAX; }).base();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Palette::size() const {
|
uint8_t Palette::size() const {
|
||||||
return end() - colors.begin();
|
return end() - colors.begin();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Some files test CRLF line endings
|
||||||
|
character-escapes.out -text diff
|
||||||
|
crlf.asm text eol=crlf
|
||||||
|
string-literal-macro-arg.out -text diff
|
||||||
+11
-2
@@ -8,6 +8,15 @@ assert !strcmp("{s}", "Hello, world!")
|
|||||||
* block comment
|
* block comment
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEF t EQUS """Hello,
|
REPT 2
|
||||||
|
REDEF t EQUS """Hello,
|
||||||
world!"""
|
world!"""
|
||||||
assert !strcmp("{t}", "Hello,\nworld!")
|
assert !strcmp("{t}", "Hello,\nworld!")
|
||||||
|
ENDR
|
||||||
|
|
||||||
|
MACRO m
|
||||||
|
assert "\1" === "Hello, world!"
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
m Hello\, \
|
||||||
|
world!
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
MACRO compare
|
MACRO compare
|
||||||
print "\3: "
|
print "\3: "
|
||||||
if _NARG == 4
|
if _NARG == 4
|
||||||
def v1 = \3(\4q\1, \1)
|
def v1 = \3(\4q\1, \1)
|
||||||
def v2 = \3(\4q\2, \2)
|
def v2 = \3(\4q\2, \2)
|
||||||
elif _NARG == 5
|
elif _NARG == 5
|
||||||
def v1 = \3(\4q\1, \5q\1, \1)
|
def v1 = \3(\4q\1, \5q\1, \1)
|
||||||
def v2 = \3(\4q\2, \5q\2, \2)
|
def v2 = \3(\4q\2, \5q\2, \2)
|
||||||
endc
|
endc
|
||||||
println "{.4q\1f:v1} == {.4q\2f:v2}"
|
println "{.4q\1f:v1} == {.4q\2f:v2}"
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
compare 8, 16, mul, 6.0, 7.0
|
compare 8, 16, mul, 6.0, 7.0
|
||||||
compare 12, 24, div, 115.625, 9.25
|
compare 12, 24, div, 115.625, 9.25
|
||||||
compare 7, 14, pow, 3.5, 5.5
|
compare 7, 14, pow, 3.5, 5.5
|
||||||
|
|
||||||
compare 4, 8, sin, 0.25
|
compare 4, 8, sin, 0.25
|
||||||
compare 5, 9, cos, 0.75
|
compare 5, 9, cos, 0.75
|
||||||
compare 6, 10, asin, 1.0
|
compare 6, 10, asin, 1.0
|
||||||
compare 7, 11, acos, 0.0
|
compare 7, 11, acos, 0.0
|
||||||
|
|
||||||
compare 3, 6, round, 1.75
|
compare 3, 6, round, 1.75
|
||||||
compare 10, 20, ceil, 123.4
|
compare 10, 20, ceil, 123.4
|
||||||
compare 13, 17, floor, 567.8
|
compare 13, 17, floor, 567.8
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
SECTION UNION "wat", ROM0
|
SECTION UNION "wat", ROM0
|
||||||
db 42
|
db 42
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# Some files test CRLF line endings
|
||||||
|
linkerscript-escapes-test.link -text diff
|
||||||
Reference in New Issue
Block a user