Introduce compatibility mode

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.
This commit is contained in:
Zeex 2014-03-29 19:51:01 +07:00
parent ed8175dab5
commit 7ee5e98e30
4 changed files with 26 additions and 14 deletions

View File

@ -815,6 +815,7 @@ SC_VDECL int sc_curstates; /* ID of the current state list */
SC_VDECL int pc_optimize; /* (peephole) optimization level */ SC_VDECL int pc_optimize; /* (peephole) optimization level */
SC_VDECL int pc_memflags; /* special flags for the stack/heap usage */ SC_VDECL int pc_memflags; /* special flags for the stack/heap usage */
SC_VDECL int pc_naked; /* if true mark following function as naked */ SC_VDECL int pc_naked; /* if true mark following function as naked */
SC_VDECL int pc_compat; /* running in compatibility mode? */
SC_VDECL constvalue sc_automaton_tab; /* automaton table */ SC_VDECL constvalue sc_automaton_tab; /* automaton table */
SC_VDECL constvalue sc_state_tab; /* state table */ SC_VDECL constvalue sc_state_tab; /* state table */

View File

@ -66,6 +66,7 @@
#include "svnrev.h" #include "svnrev.h"
#define VERSION_STR "3.2." SVN_REVSTR #define VERSION_STR "3.2." SVN_REVSTR
#define VERSION_INT 0x030A #define VERSION_INT 0x030A
#define VERSION_INT_COMPAT 0x0302
static void resetglobals(void); static void resetglobals(void);
static void initglobals(void); static void initglobals(void);
@ -1128,6 +1129,9 @@ static void parseoptions(int argc,char **argv,char *oname,char *ename,char *pnam
about(); about();
} /* if */ } /* if */
break; break;
case 'Z':
pc_compat=toggle_option(ptr,pc_compat);
break;
case '\\': /* use \ instead for escape characters */ case '\\': /* use \ instead for escape characters */
sc_ctrlchar='\\'; sc_ctrlchar='\\';
break; break;
@ -1391,6 +1395,7 @@ static void about(void)
pc_printf(" -w<num> disable a specific warning by its number\n"); pc_printf(" -w<num> disable a specific warning by its number\n");
pc_printf(" -X<num> abstract machine size limit in bytes\n"); pc_printf(" -X<num> abstract machine size limit in bytes\n");
pc_printf(" -XD<num> abstract machine data/stack size limit in bytes\n"); pc_printf(" -XD<num> abstract machine data/stack size limit in bytes\n");
pc_printf(" -Z[+/-] run in compatibility mode (default=%c)\n",pc_compat ? '+' : '-');
pc_printf(" -\\ use '\\' for escape characters\n"); pc_printf(" -\\ use '\\' for escape characters\n");
pc_printf(" -^ use '^' for escape characters\n"); pc_printf(" -^ use '^' for escape characters\n");
pc_printf(" -;[+/-] require a semicolon to end each statement (default=%c)\n", sc_needsemicolon ? '+' : '-'); pc_printf(" -;[+/-] require a semicolon to end each statement (default=%c)\n", sc_needsemicolon ? '+' : '-');
@ -1453,7 +1458,7 @@ static void setconstants(void)
add_constant("charmax",~(-1 << sCHARBITS) - 1,sGLOBAL,0); add_constant("charmax",~(-1 << sCHARBITS) - 1,sGLOBAL,0);
add_constant("ucharmax",(1 << (sizeof(cell)-1)*8)-1,sGLOBAL,0); add_constant("ucharmax",(1 << (sizeof(cell)-1)*8)-1,sGLOBAL,0);
add_constant("__Pawn",VERSION_INT,sGLOBAL,0); add_constant("__Pawn",pc_compat ? VERSION_INT_COMPAT : VERSION_INT,sGLOBAL,0);
add_constant("__line",0,sGLOBAL,0); add_constant("__line",0,sGLOBAL,0);
debug=0; debug=0;

View File

@ -235,6 +235,7 @@ static void doinclude(int silent)
char *ptr; char *ptr;
char c; char c;
int i, result; int i, result;
int included=FALSE;
while (*lptr<=' ' && *lptr!='\0') /* skip leading whitespace */ while (*lptr<=' ' && *lptr!='\0') /* skip leading whitespace */
lptr++; lptr++;
@ -262,6 +263,7 @@ static void doinclude(int silent)
if (c!='\0') if (c!='\0')
check_empty(lptr+1); /* verify that the rest of the line is whitespace */ check_empty(lptr+1); /* verify that the rest of the line is whitespace */
if (pc_compat) {
/* create a symbol from the name of the include file; this allows the system /* create a symbol from the name of the include file; this allows the system
* to test for multiple inclusions * to test for multiple inclusions
*/ */
@ -270,7 +272,10 @@ static void doinclude(int silent)
strlcat(symname,ptr+1,sizeof symname); strlcat(symname,ptr+1,sizeof symname);
else else
strlcat(symname,name,sizeof symname); strlcat(symname,name,sizeof symname);
if (find_symbol(&glbtab,symname,fcurrent,-1,NULL)==NULL) { included=find_symbol(&glbtab,symname,fcurrent,-1,NULL)!=NULL;
} /* if */
if (!included) {
/* constant is not present, so this file has not been included yet */ /* constant is not present, so this file has not been included yet */
/* Include files between "..." or without quotes are read from the current /* Include files between "..." or without quotes are read from the current
@ -278,9 +283,9 @@ static void doinclude(int silent)
* between <...> are only read from the list of include directories. * between <...> are only read from the list of include directories.
*/ */
result=plungefile(name,(c!='>'),TRUE); result=plungefile(name,(c!='>'),TRUE);
if (result) if (result && pc_compat)
add_constant(symname,1,sGLOBAL,0); add_constant(symname,1,sGLOBAL,0);
else if (!silent) else if (!result && !silent)
error(100,name); /* cannot read from ... (fatal error) */ error(100,name); /* cannot read from ... (fatal error) */
} /* if */ } /* if */
} }

View File

@ -91,6 +91,7 @@ SC_VDEFINE int sc_curstates=0; /* ID of the current state list */
SC_VDEFINE int pc_optimize=sOPTIMIZE_NOMACRO; /* (peephole) optimization level */ SC_VDEFINE int pc_optimize=sOPTIMIZE_NOMACRO; /* (peephole) optimization level */
SC_VDEFINE int pc_memflags=0; /* special flags for the stack/heap usage */ SC_VDEFINE int pc_memflags=0; /* special flags for the stack/heap usage */
SC_VDEFINE int pc_naked=FALSE; /* if true mark following function as naked */ SC_VDEFINE int pc_naked=FALSE; /* if true mark following function as naked */
SC_VDEFINE int pc_compat=FALSE; /* running in compatibility mode? */
SC_VDEFINE constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */ SC_VDEFINE constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */
SC_VDEFINE constvalue sc_state_tab = { NULL, "", 0, 0}; /* state table */ SC_VDEFINE constvalue sc_state_tab = { NULL, "", 0, 0}; /* state table */