This adds an extra check in plungequalifiedfile() that ensures that
the file being includes is not a directory. It seems to be the only
place where we need to check that, in other places files are opened
by exact name.
The bug appears to be specific to the Linux compiler. On Windows
fopen() will return NULL if trying to open a directory.
Fixes#41.
#emit directives inside #if ... #endif blocks were processed by the
compiler regardless of the condition.
--------- test code --------
main() {
#if 0
#emit halt 1
#endif
}
----- end of test code -----
Stop find_symbol() from exiting too early when have multiple matching
symbols (static and non-static). Ignore non-static symbols (those with
fnumber == -1) unless found nothing else.
Fixes#20.
This reverts commit a1d0fe39d488f2376b76b6b2d0a81f29b1b61dcc.
It's a total mess! I can't understand their logic on choosing signed vs.
unsigned char. I guess I'd better off not touching this at all.
The compiler now has a new command-line option (-Z) that toggles
between normal mode and "compatibility" mode.
When this mode is on the compiler attempts to be compatible with
the current SA-MP compiler, which allows compiling old SA-MP scripts
that would not compile otherwise and at the same time benefiting
from new features and bug fixes.
In particular, this allows compiling code that relies on the auto
generated #include guard symbols (_inc_filename).
And in case you're wondering, the Z in "-Z" does not stand for "Zeex",
it just means "a letter that is unlikely to be ever taken by another
option".
This closes#23.
They are useful most of the time but also a pain in the ass if you have
multiple files with the same name but in different directories (e.g. YSI).
Even worse, they didn't work with non-native directory separators in
#include directives, but that actually turned out to be useful and helped
defeat the first bug!
See issue #6.
This fixes a bug where if you use '/' in an #include directive on Windows
the _inc_XXX symbol will contain not only the file name but also its path
as the compiler didn't count '/' as a path separator.
This patch introduces a new built-in constant called "__line" that is set
to the current line number during compile time. I've taken the code from
Pawn 4.0 though I'm pretty sure it was implemented prior to 4.0 as I've
seen __line mentioned in the language documentation for 3.x.
Make it possible to specify multiple warning numbers in #pragma warning
enable/disable. The values must be separated with commas (possibly with
whitespace in between).
This pragma lets you to enable or disable a specific warning by its
unique number (same as in error messages).
Syntax: #pragma warning (push|pop|enable XXX|disable XXX)
#pragma warning push - save current warnings
#pragma warning pop - restore warnings
#pragma warning enable XXX - enable warning XXX
#pragma warning disable XXX - disable warning XXX
When applied to a function #pragma naked merely disables the "should return
a value" warning for the function. It's intended to be used with functions
that return a value via #emit instead of the normal return statement.
This pragma works only on function definitions, not declarations. It's also
pretty stupid - the function may be defined way after this directive and it
won't stop on things coming in between.
For example, here all declarations between #pragma naked and f() are
effectively ignored:
#pragma naked
new x; // ignored
forward g(); // ignored
native n(); // ignored
f() {
// f() becomes naked
}
Note that #pragma naked does not affect generated code in any way, unlike
e.g. __declspec(naked) or __attribute__((naked)) in C/C++ where the compiler
omits the code for the prolog and epilog.
This fixes a bug where the compiler generated incorrect addresses for
functions in #emit code if they were defined after the point of use.
For example, you couldn't reliably get the address of a function with
"#emit CONST.pri XXX" unless you make sure that XXX is defined before
the function in which you have you are referencing it.
Now the resolution of the function's address is deferred until assembling
phase (as with CALL), and the assembler is guaranteed to see all symbols
with their final addresses. To distinguish between functions and numeric
operands I added a '.' (period) in front of function names for both #emit
and normal calls.
See also 5) here: http://forum.sa-mp.com/showthread.php?t=355877
--------- test code --------
#include <a_samp> // DO NOT REMOVE THIS
main() {
#emit const.pri foo
}
stock foo() {
printf("Hello, World!");
}
----- end of test code -----
It is possible to use natives in any instructions and their name should
evaluate to a native table index. But the patch in the previous commit
(bb4163ea456fab54385f7310b4e20949cda0aaa6) affected only SYSREQ.C
instructions, thus using natives with other instructions (for example,
with CONST.pri) would still result in an incorrect index.
This commit fixes a bug where the compiler generated incorrect native
index in assembly code for natives invoked via #emit sysreq.c and not
called elsewhere with the normal syntax.
See 4) here: http://forum.sa-mp.com/showthread.php?t=355877
--------- test code --------
native print(const s[]);
native printf(const format[], ...);
main() {
new string[] = "hi there!";
printf(string);
#emit push.adr string
#emit push.c 4
#emit sysreq.c print
#emit sysreq.c printf
#emit stack 8
}
----- end of test code -----
This fixes a crash when calling a function with the CALL instruction in #emit.
Instead of merely writing a symbol's address to the .asm file we check
if we are in a CALL instruction, and if so we output the function's name
rather than its address.
See 7) here: http://forum.sa-mp.com/showthread.php?t=355877
--------- test code --------
foo() {}
main() {
#emit call foo
}
----- end of test code -----
The ':' symbol was not recognized as a separator in stringize mode
so you always got a weird compile error with a code like this:
(condition) ? "yes : "no"
error 001: expected token: "-string end-", but found "-identifier-"
See 2) here: http://forum.sa-mp.com/showthread.php?t=355877
Test code:
native print(const s[]);
main() {
new a = 5;
print((a == 5) ? "is five" : !"is not five");
print((a != 5) ? !"is not five" : "is five");
}
This fixes the "possibly non-terminated string" error when declaring an
array of packed strings (unpacked strings worked OK).
Test code:
new x[][] = {
!"hello",
!"world"
};
main() {
printf("%s", x[0]);
}