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_memflags; /* special flags for the stack/heap usage */
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_state_tab; /* state table */

View File

@ -65,7 +65,8 @@
#include "sc.h"
#include "svnrev.h"
#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 initglobals(void);
@ -1128,6 +1129,9 @@ static void parseoptions(int argc,char **argv,char *oname,char *ename,char *pnam
about();
} /* if */
break;
case 'Z':
pc_compat=toggle_option(ptr,pc_compat);
break;
case '\\': /* use \ instead for escape characters */
sc_ctrlchar='\\';
break;
@ -1391,6 +1395,7 @@ static void about(void)
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(" -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(" -;[+/-] 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("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);
debug=0;

View File

@ -235,6 +235,7 @@ static void doinclude(int silent)
char *ptr;
char c;
int i, result;
int included=FALSE;
while (*lptr<=' ' && *lptr!='\0') /* skip leading whitespace */
lptr++;
@ -262,15 +263,19 @@ static void doinclude(int silent)
if (c!='\0')
check_empty(lptr+1); /* verify that the rest of the line is whitespace */
/* create a symbol from the name of the include file; this allows the system
* to test for multiple inclusions
*/
strcpy(symname,"_inc_");
if ((ptr=strrchr(name,DIRSEP_CHAR))!=NULL)
strlcat(symname,ptr+1,sizeof symname);
else
strlcat(symname,name,sizeof symname);
if (find_symbol(&glbtab,symname,fcurrent,-1,NULL)==NULL) {
if (pc_compat) {
/* create a symbol from the name of the include file; this allows the system
* to test for multiple inclusions
*/
strcpy(symname,"_inc_");
if ((ptr=strrchr(name,DIRSEP_CHAR))!=NULL)
strlcat(symname,ptr+1,sizeof symname);
else
strlcat(symname,name,sizeof symname);
included=find_symbol(&glbtab,symname,fcurrent,-1,NULL)!=NULL;
} /* if */
if (!included) {
/* constant is not present, so this file has not been included yet */
/* Include files between "..." or without quotes are read from the current
@ -278,10 +283,10 @@ static void doinclude(int silent)
* between <...> are only read from the list of include directories.
*/
result=plungefile(name,(c!='>'),TRUE);
if (result)
if (result && pc_compat)
add_constant(symname,1,sGLOBAL,0);
else if (!silent)
error(100,name); /* cannot read from ... (fatal error) */
else if (!result && !silent)
error(100,name); /* cannot read from ... (fatal error) */
} /* 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_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_compat=FALSE; /* running in compatibility mode? */
SC_VDEFINE constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */
SC_VDEFINE constvalue sc_state_tab = { NULL, "", 0, 0}; /* state table */