Skip to content

Commit 271a8ee

Browse files
committed
Merge branch 'asar_19'
2 parents a1f1f21 + 7e1d78a commit 271a8ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+514
-403
lines changed

README.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,18 @@ If you'd rather not build from source, check out the [Releases](https://github.c
1414
Asar can also be built as a DLL. This makes it easier and faster to use in other programs (such as a sprite insertion tool). You can find documentation on the DLL API in the respective bindings (asardll.h, asar.cs, asar.py).
1515

1616
## Asar as a static library
17-
Asar can also be build as a static library. All "out-facing" functions are in interface-lib.h. This is useful for embedding Asar in other programs which don't want to use DLLs. The easiest way to add asar as a static library to your project, assuming you are using CMake (at least 3.11), is to use [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) to fetch the source code, then add the following to your CMakeLists.txt:
17+
Asar can also be built as a static library. All "out-facing" functions are in interface-lib.h. This is useful for embedding Asar in other programs which don't want to use DLLs. The easiest way to add asar as a static library to your project is to add it as a git submodule
18+
19+
`git submodule add https://github.com/RPGHacker/asar <path-to-subdir>`
20+
21+
then add the following to your CMakeLists.txt:
1822
```CMake
19-
target_include_directories(YourTarget PUBLIC ${asar_SOURCE_DIR}/src)
23+
add_subdirectory(<path-to-subdir>/src)
24+
get_target_property(ASAR_INCLUDE_DIR asar-static INCLUDE_DIRECTORIES)
25+
include_directories(${ASAR_INCLUDE_DIR})
26+
target_link_libraries(YourTarget PUBLIC asar-static)
2027
```
21-
to be able to include the header files. It is also recommended to add `set(ASAR_TESTING_DISABLED TRUE)` to your CMakeLists.txt to disable building tests.
28+
to be able to include the header files. It is also recommended to turn off every build in target in asar except the static one using the appropriate CMake options. You will need to make sure that your project has an Asar compatible license.
2229

2330
## Folder layout
2431
* `docs` contains the source of the manual and changelog.
@@ -46,7 +53,7 @@ These two characters should precede each test line, so that Asar sees them as co
4653
* 2 hex digits - a byte for it to check for
4754
* You can specify more than one, like in the examples below, and it will automatically increment the offset.
4855
* A line starting with `+` tells the testing app to patch the SMW ROM instead of creating a new ROM
49-
* `errEXXXX` and `warnWXXXX` (where `XXXX` is an ID number) means that the test is expected to throw that specific error or warning while patching. The test will succeed only if the number and order of errors and warnings thrown exactly matches what's specified here. Be wary that Asar uses multiple passes and throws errors and warnings across multiple of them. This can make the actual order in which errors and warnings are thrown a bit unintuitive.
56+
* `errE{name}` and `warnW{name}` (where `{name}` is the name of an error or warning) means that the test is expected to throw that specific error or warning while patching. The test will succeed only if the number and order of errors and warnings thrown exactly matches what's specified here. Be wary that Asar uses multiple passes and throws errors and warnings across multiple of them. This can make the actual order in which errors and warnings are thrown a bit unintuitive.
5057

5158
In addition to the format mentioned above, it's also possible to check for user prints a patch is expected to output (by `print`, `error`, `warn` or `assert` commands). This is done by starting the line with one of the following sequences:
5259
```
@@ -68,17 +75,17 @@ This line tests that `22`, `20`, `80` and `90` were written to the ROM offset `0
6875
;`007606 22 20 80 90
6976
```
7077

71-
This line tests that assembling the patch throws error `5117` twice and warning `1030` once.
78+
This line tests that assembling the patch throws error `Eunknown_command` twice and warning `Wfeature_deprecated` once.
7279
```
73-
;`errE5117
74-
;`errE5117
75-
;`warnW1030
80+
;`errEunknown_command
81+
;`errEunknown_command
82+
;`warnWfeature_deprecated
7683
```
7784

78-
This line tests that the byte `FF` was written to the start of the ROM, that the string `This is a print.` was printed and that the string `This is a user error.` was output via the error command (which itself also causes error `E5159`to be thrown once).
85+
This line tests that the byte `FF` was written to the start of the ROM, that the string `This is a print.` was printed and that the string `This is a user error.` was output via the error command (which itself also causes error `Eerror_command` to be thrown once).
7986
```
8087
;`FF
8188
;P>This is a print.
8289
;E>This is a user error.
83-
;`errE5159
90+
;`errEerror_command
8491
```

docs/changelog/index.html

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,23 @@ <h3>Contributors:</h3>
4545
<ul>
4646
<li>RPG Hacker</li>
4747
<li>randomdude999</li>
48+
<li>p4plus2</li>
49+
<li>Atari2</li>
4850
</ul>
4951

52+
<h3>Notes:</h3>
53+
<ul>
54+
<li>The primary purpose of this release is to be a stepping stone towards Asar 2.0. For this purpose, a lot of features have been deprecated and will now throw warnings. Please fix any of those warnings you come across in your patches to assure they will still assemble in Asar 2.0.</li>
55+
</ul></div>
56+
5057
<h3>New features:</h3>
5158
<ul>
5259
<li>The Asar test suite can now verify user-printable strings. (RPG Hacker)</li>
5360
<li>The <code>error</code>, <code>warn</code> and <code>assert</code> commands now support the same functions as the print command. (RPG Hacker)</li>
5461
<li>Static labels (i.e. labels that don't move between passes) can now be used in more places, including if statements. (RPG Hacker)</li>
62+
<li>Asar can be built as a static library. (Atari2)</li>
63+
<li>Asar now uses named warnings and errors instead of magic numbers as identifiers. (p4plus2, RPG Hacker)</li>
64+
<li>Variadic macro parameters now use the syntax <code class="65c816_asar">&lt;...[math]&gt;</code>, which makes them less ambiguous and helps prevent syntax parsing bugs. (RPG Hacker)</li>
5565
</ul>
5666

5767
<h3>Bug fixes:</h3>
@@ -62,6 +72,32 @@ <h3>Bug fixes:</h3>
6272
<li>For invalid table files, Asar now prints the line number of the first invalid entry. (RPG Hacker)</li>
6373
<li>When Asar generates addr-to-line mappings, it now includes multiple addresses for pseudo opcodes like &quot;asl #4&quot;. (RPG Hacker)</li>
6474
<li><code>'''</code> and <code>';'</code> are now valid can now be used without causing errors. (randomdude999, RPG Hacker)</li>
75+
<li>Fixed some edge case bugs in Asar's virtual filesystem (usable via the DLL) on Windows. (Atari2)</li>
76+
</ul></div>
77+
78+
<h3>Deprecated features:</h3>
79+
<ul>
80+
<li>Warning and error IDs: Use new name strings instead.</li>
81+
<li><code>JMP.l</code>: Use <code>JML</code> instead.</li>
82+
<li>Quoted symbolic arguments to functions (e.g. <code>sizeof("my_struct")</code>): Remove the quotes (<code>sizeof(my_struct)</code>).</li>
83+
<li>Redefining previously defined functions.</li>
84+
<li><code>math round</code> and <code>math pri</code>: Use parentheses and explicit rounding where xkas-style math emulation is needed instead.</li>
85+
<li><code>.d</code> length specifier on opcodes.</li>
86+
<li><code>if !condition</code> to negate conditions: Use <code>if not(condition)</code> instead.</li>
87+
<li>While blocks ending with <code>endif</code>: Use <code>endwhile</code> instead.</li>
88+
<li><code>bankcheck on</code>: Use <code>bankcheck full</code> or <code>bankcheck half</code> instead.</li>
89+
<li><code>rep</code> to repeat commands: Use while loops or unrolled loops instead.</li>
90+
<li>Windows-specific paths (e.g. <code>incsrc dir\file.asm</code>): Use cross-platform paths instead (<code>incsrc dir/file.asm</code>).</li>
91+
<li><code>table</code> command: Assign characters directly instead, like <code>'a' = $00</code>.</li>
92+
<li>Labels in <code>padbyte</code> or <code>fillbyte</code> commands.</li>
93+
<li><code>spc700-raw</code> architecture: Use <code>spc700</code> with <code>norom</code> instead.</li>
94+
<li><code>fastrom</code>: Has never actually worked and can be removed.</li>
95+
<li><code>header</code>: Doesn't do anything and can be removed.</li>
96+
<li>Non-UTF-8 source files: Re-save your source files as UTF-8 in a text editor of choice.</li>
97+
<li><code>;@command</code> and <code>@command</code> notation: Use <code>command</code> instead.</li>
98+
<li>Wrapping defines to resolve in quotes (e.g. <code>db "!define"</code>): The quotes aren't needed (<code>db !define</code>).</li>
99+
<li>Single-line/inline if statements: Use full if blocks with an <code>if</code>/<code>endif</code> pair instead.</li>
100+
<li><code class="65c816_asar">&lt;math&gt;</code> syntax for variadic macro parameters: Use <code class="65c816_asar">&lt;...[math]&gt;</code> insread.</li>
65101
</ul></div>
66102

67103
<hr />

docs/manual/index.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,26 +2439,26 @@ <h4 id="built-in-defines">Built-in Defines</h4>
24392439
</code></pre>
24402440

24412441
In addition to named substitutions if the variadic token <code class="65c816_asar">...</code> is specified as the last parameter asar will allow an arbitrary number of parameters after all prior parameters have been satisfied.
2442-
To access unnamed arguments of a variadic function they are declared numerically starting from 0 up to the number of provided parameters. To access the number of provided variadic arguments one may use <code class="65c816_asar">sizeof(...)</code>.
2442+
To access unnamed parameters of a variadic macro, use the syntax <code class="65c816_asar">&lt;...[{math}]&gt;</code>, where <code class="65c816_asar">math</code> is any math expression evaluating to the index of a variadic parameter. These are declared numerically starting from 0 up to the number of provided parameters. To access the number of provided variadic arguments one may use <code class="65c816_asar">sizeof(...)</code>.
24432443
Lastly, it is important to note that while traditionally macros do not parse defines at their creation variadic macros will. This is to allow iteration of arguments by using defines.
24442444

24452445
<pre><code class="65c816_asar">
24462446
macro example0(...)
2447-
db sizeof(...), &lt;0&gt; ;04 01
2447+
db sizeof(...), &lt;...[0]&gt; ;04 01
24482448
endmacro
24492449

24502450
macro example1(...)
24512451
!a #= 0
24522452
while !a &lt; sizeof(...)
2453-
db &lt;!a&gt; ;01 02 03
2453+
db &lt;...[!a]&gt; ;01 02 03
24542454
!a #= !a+1
24552455
endif
24562456
endmacro
24572457

24582458
macro example2(named_parameter, ...)
24592459
!a #= 0
24602460
while !a &lt; sizeof(...)
2461-
db &lt;!a&gt; ;02 03 04 05 06 07
2461+
db &lt;...[!a]&gt; ;02 03 04 05 06 07
24622462
!a #= !a+1
24632463
endif
24642464
db &lt;named_parameter&gt; ;01
@@ -2467,7 +2467,7 @@ <h4 id="built-in-defines">Built-in Defines</h4>
24672467
macro macro_with_optional_arguments(required, ...)
24682468
db &lt;required&gt;
24692469
if sizeof(...) &gt; 0
2470-
db &lt;0&gt;
2470+
db &lt;...[0]&gt;
24712471
end
24722472
end
24732473

src/asar-tests/test.cpp

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,8 @@ int main(int argc, char * argv[])
534534

535535
int numiter = 1;
536536

537-
std::vector<int> expected_errors;
538-
std::vector<int> expected_warnings;
537+
std::vector<std::string> expected_errors;
538+
std::vector<std::string> expected_warnings;
539539
std::vector<std::string> expected_prints;
540540
std::vector<std::string> expected_error_prints;
541541
std::vector<std::string> expected_warn_prints;
@@ -604,30 +604,16 @@ int main(int argc, char * argv[])
604604
if (strncmp(cur_word.c_str(), token, strlen(token)) == 0)
605605
{
606606
const char* idstr = cur_word.c_str() + strlen(token);
607-
char* endpos = nullptr;
608-
long int id = strtol(idstr, &endpos, 10);
609607

610-
if (endpos == nullptr || *endpos != '\0')
611-
{
612-
dief("Error: Invalid %s declaration!\n", token);
613-
}
614-
615-
expected_errors.push_back((int)id);
608+
expected_errors.push_back(idstr-1);
616609
}
617610

618611
token = "warnW";
619612
if (strncmp(cur_word.c_str(), token, strlen(token)) == 0)
620613
{
621614
const char* idstr = cur_word.c_str() + strlen(token);
622-
char* endpos = nullptr;
623-
long int id = strtol(idstr, &endpos, 10);
624615

625-
if (endpos == nullptr || *endpos != '\0')
626-
{
627-
dief("Error: Invalid %s declaration!\n", token);
628-
}
629-
630-
expected_warnings.push_back((int)id);
616+
expected_warnings.push_back(idstr-1);
631617
}
632618

633619
if (pos > len) len = pos;
@@ -824,8 +810,8 @@ int main(int argc, char * argv[])
824810
FILE * out = nullptr;
825811
#endif
826812

827-
std::vector<int> actual_errors;
828-
std::vector<int> actual_warnings;
813+
std::vector<std::string> actual_errors;
814+
std::vector<std::string> actual_warnings;
829815
std::vector<std::string> actual_prints;
830816
std::vector<std::string> actual_error_prints;
831817
std::vector<std::string> actual_warn_prints;
@@ -851,20 +837,20 @@ int main(int argc, char * argv[])
851837
size_t found = log_line.find(token);
852838
if (found != std::string::npos)
853839
{
854-
char* endpos = nullptr;
855-
long int num = strtol(log_line.c_str() + found + strlen(token), &endpos, 10);
840+
size_t found_end = log_line.find(')', found + 1);
856841

857-
if (endpos == nullptr || *endpos != ')')
842+
if (found_end == std::string::npos)
858843
{
859-
dief("Error: Failed parsing error code from Asar output!\n");
844+
dief("Error: Failed parsing error name from Asar output!\n");
860845
}
861846

862-
actual_errors.push_back(num);
847+
size_t start_pos = found + strlen(token) - 1;
848+
actual_errors.push_back(log_line.substr(start_pos, found_end - start_pos));
863849

864850
// RPG Hacker: Check if it's the error command. If so, we also need to add a print as well.
865851
{
866852
std::string command_token = ": error command: ";
867-
std::string remainder = endpos;
853+
std::string remainder = log_line.substr(found_end+1);
868854
size_t command_found = remainder.find(command_token);
869855

870856
if (command_found != std::string::npos)
@@ -877,7 +863,7 @@ int main(int argc, char * argv[])
877863
{
878864
std::string command_token_1 = ": Assertion failed: ";
879865
std::string command_token_2 = " [assert ";
880-
std::string remainder = endpos;
866+
std::string remainder = log_line.substr(found_end + 1);
881867
size_t command_found_1 = remainder.find(command_token_1);
882868
size_t command_found_2 = remainder.find(command_token_2);
883869

@@ -895,20 +881,20 @@ int main(int argc, char * argv[])
895881
found = log_line.find(token);
896882
if (found != std::string::npos)
897883
{
898-
char* endpos = nullptr;
899-
long int num = strtol(log_line.c_str() + found + strlen(token), &endpos, 10);
884+
size_t found_end = log_line.find(')', found + 1);
900885

901-
if (endpos == nullptr || *endpos != ')')
886+
if (found_end == std::string::npos)
902887
{
903888
dief("Error: Failed parsing warning code from Asar output!\n");
904889
}
905890

906-
actual_warnings.push_back(num);
891+
size_t start_pos = found + strlen(token) - 1;
892+
actual_warnings.push_back(log_line.substr(start_pos, found_end - start_pos));
907893

908894
// RPG Hacker: Check if it's the warn command. If so, we also need to add a print as well.
909895
{
910896
std::string command_token = ": warn command: ";
911-
std::string remainder = endpos;
897+
std::string remainder = log_line.substr(found_end + 1);
912898
size_t command_found = remainder.find(command_token);
913899

914900
if (command_found != std::string::npos)
@@ -1000,28 +986,28 @@ int main(int argc, char * argv[])
1000986
printf("\nExpected errors: ");
1001987
for (auto it = expected_errors.begin(); it != expected_errors.end(); ++it)
1002988
{
1003-
printf("%sE%d", (it != expected_errors.begin() ? "," : ""), *it);
989+
printf("%s%s", (it != expected_errors.begin() ? "," : ""), it->c_str());
1004990
}
1005991
printf("\n");
1006992

1007993
printf("Actual errors: ");
1008994
for (auto it = actual_errors.begin(); it != actual_errors.end(); ++it)
1009995
{
1010-
printf("%sE%d", (it != actual_errors.begin() ? "," : ""), *it);
996+
printf("%s%s", (it != actual_errors.begin() ? "," : ""), it->c_str());
1011997
}
1012998
printf("\n");
1013999

10141000
printf("\nExpected warnings: ");
10151001
for (auto it = expected_warnings.begin(); it != expected_warnings.end(); ++it)
10161002
{
1017-
printf("%sW%d", (it != expected_warnings.begin() ? "," : ""), *it);
1003+
printf("%s%s", (it != expected_warnings.begin() ? "," : ""), it->c_str());
10181004
}
10191005
printf("\n");
10201006

10211007
printf("Actual warnings: ");
10221008
for (auto it = actual_warnings.begin(); it != actual_warnings.end(); ++it)
10231009
{
1024-
printf("%sW%d", (it != actual_warnings.begin() ? "," : ""), *it);
1010+
printf("%s%s", (it != actual_warnings.begin() ? "," : ""), it->c_str());
10251011
}
10261012
printf("\n");
10271013

@@ -1068,7 +1054,7 @@ int main(int argc, char * argv[])
10681054
fclose(rom);
10691055
#endif
10701056
bool fail = false;
1071-
for (int i = 0;i < min(len, truelen);i++)
1057+
for (int i = 0;i < min(len, truelen); i++)
10721058
{
10731059
if (truerom[i] != expectedrom[i] && !(i >= 0x07FDC && i <= 0x07FDF && (expectedrom[i] == 0x00 || expectedrom[i] == smwrom[i])))
10741060
{
@@ -1087,6 +1073,10 @@ int main(int argc, char * argv[])
10871073

10881074
free(smwrom);
10891075

1076+
#if defined(ASAR_TEST_DLL)
1077+
asar_close();
1078+
#endif
1079+
10901080
printf("%u out of %u performed tests succeeded.\n", (unsigned int)(input_files.size() - (size_t)numfailed), (unsigned int)input_files.size());
10911081

10921082
if (numfailed > 0)
@@ -1095,9 +1085,5 @@ int main(int argc, char * argv[])
10951085
return 1;
10961086
}
10971087

1098-
#if defined(ASAR_TEST_DLL)
1099-
asar_close();
1100-
#endif
1101-
11021088
return 0;
11031089
}

0 commit comments

Comments
 (0)