Merge pull request #116 from Arkshine/update-compiler-safe-fix-feature

Update compiler
This commit is contained in:
Vincent Herbet 2014-08-26 09:07:45 +02:00
commit 1463103cd7
24 changed files with 6922 additions and 5730 deletions

View File

@ -130,6 +130,8 @@ class AMXXConfig(object):
'-Wno-uninitialized',
'-Wno-unused',
'-Wno-switch',
'-Wno-format',
'-Wno-format-security',
'-m32',
]
cfg.cxxflags += [

View File

@ -1,9 +1,50 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os.path
# Build the packing binary garbage.
scpack = AMXX.Program(builder, 'scpack')
if builder.target_platform == 'windows':
scpack.compiler.linkflags.remove('/SUBSYSTEM:WINDOWS')
scpack.compiler.linkflags.append('/SUBSYSTEM:CONSOLE')
scpack.sources = ['scpack.c']
scpack = builder.Add(scpack)
# Generate pack files.
packed_files = ['sc5', 'sc7']
packed_includes = []
for packed_file in packed_files:
# The absolute path to sc5-in.scp etc.
in_path = os.path.join(builder.currentSourcePath, '{0}-in.scp'.format(packed_file))
# The output file relative to the output folder, i.e. sourcepawn/compiler/sc5.scp.
out_path = os.path.join(builder.buildFolder, '{0}.scp'.format(packed_file))
# The absolute path to the build folder, i.e. /Users/.../sourcepawn/compiler.
build_folder = os.path.join(builder.buildPath, builder.buildFolder)
# scpack runs in ./sourcepawn/compiler/scpack/ so we build relative paths
# from there.
scpack_argv = [
os.path.join(builder.buildPath, scpack.binary.path),
os.path.relpath(in_path, build_folder),
os.path.relpath(os.path.join(builder.buildPath, out_path), build_folder),
]
_, (entry,) = builder.AddCommand(
inputs = [scpack.binary, in_path],
argv = scpack_argv,
outputs = ['{0}.scp'.format(packed_file)],
)
packed_includes += [entry]
binary = AMXX.Library(builder, 'amxxpc32')
binary.compiler.includes += [builder.currentSourcePath]
binary.compiler.includes += [
builder.currentSourcePath,
os.path.join(builder.buildPath, builder.buildFolder),
]
binary.compiler.sourcedeps += packed_includes
if builder.target_platform in ['mac', 'linux']:
binary.compiler.defines += ['ENABLE_BINRELOC']
@ -34,6 +75,7 @@ binary.sources = [
'libpawnc.c',
'prefix.c',
'memfile.c',
'sp_symhash.c',
]
if builder.target_platform == 'windows':

View File

@ -23,6 +23,7 @@
#include <assert.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "sc.h"
@ -55,6 +56,10 @@
}
#endif /* PAWNC_DLL */
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
#include <sys/types.h>
#include <sys/stat.h>
#endif
/* pc_printf()
* Called for general purpose "console" output. This function prints general
@ -119,6 +124,14 @@ static char *prefix[3]={ "error", "fatal error", "warning" };
return 0;
}
typedef struct src_file_s {
FILE *fp; // Set if writing.
char *buffer; // IO buffer.
char *pos; // IO position.
char *end; // End of buffer.
size_t maxlength; // Maximum length of the writable buffer.
} src_file_t;
/* pc_opensrc()
* Opens a source file (or include file) for reading. The "file" does not have
* to be a physical file, one might compile from memory.
@ -133,7 +146,46 @@ static char *prefix[3]={ "error", "fatal error", "warning" };
*/
void *pc_opensrc(char *filename)
{
return fopen(filename,"rt");
FILE *fp = NULL;
long length;
src_file_t *src = NULL;
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined DARWIN
struct stat fileInfo;
if (stat(filename, &fileInfo) != 0) {
return NULL;
}
if (S_ISDIR(fileInfo.st_mode)) {
return NULL;
}
#endif
if ((fp = fopen(filename, "rb")) == NULL)
return NULL;
if (fseek(fp, 0, SEEK_END) == -1)
goto err;
if ((length = ftell(fp)) == -1)
goto err;
if (fseek(fp, 0, SEEK_SET) == -1)
goto err;
if ((src = (src_file_t *)calloc(1, sizeof(src_file_t))) == NULL)
goto err;
if ((src->buffer = (char *)calloc(length, sizeof(char))) == NULL)
goto err;
if (fread(src->buffer, length, 1, fp) != 1)
goto err;
src->pos = src->buffer;
src->end = src->buffer + length;
fclose(fp);
return src;
err:
pc_closesrc(src);
fclose(fp);
return NULL;
}
/* pc_createsrc()
@ -150,7 +202,23 @@ void *pc_opensrc(char *filename)
*/
void *pc_createsrc(char *filename)
{
return fopen(filename,"wt");
src_file_t *src = (src_file_t *)calloc(1, sizeof(src_file_t));
if (!src)
return NULL;
if ((src->fp = fopen(filename, "wt")) == NULL) {
pc_closesrc(src);
return NULL;
}
src->maxlength = 1024;
if ((src->buffer = (char *)calloc(1, src->maxlength)) == NULL) {
pc_closesrc(src);
return NULL;
}
src->pos = src->buffer;
src->end = src->buffer;
return src;
}
/* pc_closesrc()
@ -159,8 +227,15 @@ void *pc_createsrc(char *filename)
*/
void pc_closesrc(void *handle)
{
assert(handle!=NULL);
fclose((FILE*)handle);
src_file_t *src = (src_file_t *)handle;
if (!src)
return;
if (src->fp) {
fwrite(src->buffer, src->pos - src->buffer, 1, src->fp);
fclose(src->fp);
}
free(src->buffer);
free(src);
}
/* pc_resetsrc()
@ -169,8 +244,12 @@ void pc_closesrc(void *handle)
*/
void pc_resetsrc(void *handle,void *position)
{
assert(handle!=NULL);
fsetpos((FILE*)handle,(fpos_t *)position);
src_file_t *src = (src_file_t *)handle;
ptrdiff_t pos = (ptrdiff_t)position;
assert(!src->fp);
assert(pos >= 0 && src->buffer + pos <= src->end);
src->pos = src->buffer + pos;
}
/* pc_readsrc()
@ -179,7 +258,35 @@ void pc_resetsrc(void *handle,void *position)
*/
char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
{
return fgets((char*)target,maxchars,(FILE*)handle);
src_file_t *src = (src_file_t *)handle;
char *outptr = (char *)target;
char *outend = outptr + maxchars;
assert(!src->fp);
if (src->pos == src->end)
return NULL;
while (outptr < outend && src->pos < src->end) {
char c = *src->pos++;
*outptr++ = c;
if (c == '\n')
break;
if (c == '\r') {
// Handle CRLF.
if (src->pos < src->end && *src->pos == '\n') {
src->pos++;
if (outptr < outend)
*outptr++ = '\n';
}
break;
}
}
// Caller passes in a buffer of size >= maxchars+1.
*outptr = '\0';
return (char *)target;
}
/* pc_writesrc()
@ -188,20 +295,51 @@ char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
*/
int pc_writesrc(void *handle,unsigned char *source)
{
return fputs((char*)source,(FILE*)handle) >= 0;
char *str = (char *)source;
size_t len = strlen(str);
src_file_t *src = (src_file_t *)handle;
assert(src->fp && src->maxlength);
if (src->pos + len > src->end) {
char *newbuf;
size_t newmax = src->maxlength;
size_t newlen = (src->pos - src->buffer) + len;
while (newmax < newlen) {
// Grow by 1.5X
newmax += newmax + newmax / 2;
if (newmax < src->maxlength)
abort();
}
newbuf = (char *)realloc(src->buffer, newmax);
if (!newbuf)
abort();
src->pos = newbuf + (src->pos - src->buffer);
src->end = newbuf + newmax;
src->buffer = newbuf;
src->maxlength = newmax;
}
strcpy(src->pos, str);
src->pos += len;
return 0;
}
void *pc_getpossrc(void *handle)
{
static fpos_t lastpos; /* may need to have a LIFO stack of such positions */
src_file_t *src = (src_file_t *)handle;
fgetpos((FILE*)handle,&lastpos);
return &lastpos;
assert(!src->fp);
return (void *)(ptrdiff_t)(src->pos - src->buffer);
}
int pc_eofsrc(void *handle)
{
return feof((FILE*)handle);
src_file_t *src = (src_file_t *)handle;
assert(!src->fp);
return src->pos == src->end;
}
/* should return a pointer, which is used as a "magic cookie" to all I/O

View File

@ -51,7 +51,7 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=32;NO_MAIN;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=32;NO_MAIN;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
@ -71,7 +71,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=32;NO_MAIN;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=32;NO_MAIN;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@ -105,11 +105,13 @@
<ClCompile Include="scmemfil.c" />
<ClCompile Include="scstate.c" />
<ClCompile Include="scvars.c" />
<ClCompile Include="sp_symhash.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="amx.h" />
<ClInclude Include="memfile.h" />
<ClInclude Include="sc.h" />
<ClInclude Include="sp_symhash.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="libpawnc.rc" />

View File

@ -60,6 +60,9 @@
<ClCompile Include="scvars.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sp_symhash.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="amx.h">
@ -71,6 +74,9 @@
<ClInclude Include="sc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sp_symhash.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="libpawnc.rc">

View File

@ -55,7 +55,7 @@
#define sCHARBITS 8 /* size of a packed character */
#define sDIMEN_MAX 3 /* maximum number of array dimensions */
#define sLINEMAX 1023 /* input line length (in characters) */
#define sLINEMAX 4095 /* input line length (in characters) */
#define sCOMP_STACK 32 /* maximum nesting of #if .. #endif sections */
#define sDEF_LITMAX 500 /* initial size of the literal pool, in "cells" */
#define sDEF_AMXSTACK 4096 /* default stack size for AMX files */
@ -128,6 +128,7 @@ typedef struct s_symbol {
char vclass; /* sLOCAL if "addr" refers to a local symbol */
char ident; /* see below for possible values */
char usage; /* see below for possible values */
char flags; /* see below for possible values */
int compound; /* compound level (braces nesting level) */
int tag; /* tagname id */
int fieldtag; /* enumeration fields, where a size is attached to the field */
@ -147,6 +148,7 @@ typedef struct s_symbol {
} dim; /* for 'dimension', both functions and arrays */
constvalue *states; /* list of state function addresses */
int fnumber; /* static global variables: file number in which the declaration is visible */
int lnumber; /* line number (in the current source file) for the declaration */
struct s_symbol **refer; /* referrer list, functions that "use" this symbol */
int numrefers; /* number of entries in the referrer list */
char *documentation; /* optional documentation string */
@ -221,6 +223,8 @@ typedef struct s_symbol {
*/
#define uRETNONE 0x10
#define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
@ -270,6 +274,8 @@ typedef struct s_stringpair {
char *first;
char *second;
int matchlength;
char flags;
char *documentation;
} stringpair;
/* macros for code generation */
@ -365,6 +371,7 @@ typedef struct s_stringpair {
#define tLABEL 331
#define tSTRING 332
#define tEXPR 333 /* for assigment to "lastst" only */
#define tEMPTYBLOCK 334 /* empty blocks for AM bug 4825 */
/* (reversed) evaluation of staging buffer */
#define sSTARTREORDER 0x01
@ -400,6 +407,8 @@ typedef struct s_stringpair {
#define sFORCESET 1 /* force error flag on */
#define sEXPRMARK 2 /* mark start of expression */
#define sEXPRRELEASE 3 /* mark end of expression */
#define sSETLINE 4 /* set line number for the error */
#define sSETFILE 5 /* set file number for the error */
typedef enum s_regid {
sPRI, /* indicates the primary register */
@ -508,6 +517,7 @@ SC_FUNC void delete_consttable(constvalue *table);
SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag);
SC_FUNC void exporttag(int tag);
SC_FUNC void sc_attachdocumentation(symbol *sym);
SC_FUNC int get_actual_compound(symbol *sym);
/* function prototypes in SC2.C */
#define PUSHSTK_P(v) { stkitem s_; s_.pv=(v); pushstk(s_); }
@ -535,7 +545,6 @@ SC_FUNC void delete_symbol(symbol *root,symbol *sym);
SC_FUNC void delete_symbols(symbol *root,int level,int del_labels,int delete_functions);
SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom);
SC_FUNC void markusage(symbol *sym,int usage);
SC_FUNC uint32_t namehash(const char *name);
SC_FUNC symbol *findglb(const char *name);
SC_FUNC symbol *findloc(const char *name);
SC_FUNC symbol *findconst(const char *name);
@ -641,7 +650,7 @@ SC_FUNC void outval(cell val,int newline);
/* function prototypes in SC5.C */
SC_FUNC int error(int number,...) INVISIBLE;
SC_FUNC void errorset(int code);
SC_FUNC void errorset(int code, int line);
/* function prototypes in SC6.C */
SC_FUNC int assemble(FILE *fout,FILE *fin);
@ -674,6 +683,9 @@ SC_FUNC void delete_substtable(void);
SC_FUNC stringlist *insert_sourcefile(char *string);
SC_FUNC char *get_sourcefile(int index);
SC_FUNC void delete_sourcefiletable(void);
SC_FUNC stringlist *insert_inputfile(char *string);
SC_FUNC char *get_inputfile(int index);
SC_FUNC void delete_inputfiletable(void);
SC_FUNC stringlist *insert_docstring(char *string);
SC_FUNC char *get_docstring(int index);
SC_FUNC void delete_docstring(int index);
@ -728,6 +740,8 @@ SC_FUNC void state_conflict(symbol *root);
/* external variables (defined in scvars.c) */
#if !defined SC_SKIP_VDECL
typedef struct HashTable HashTable;
SC_VDECL struct HashTable *sp_Globals;
SC_VDECL symbol loctab; /* local symbol table */
SC_VDECL symbol glbtab; /* global symbol table */
SC_VDECL cell *litq; /* the literal queue */
@ -770,8 +784,8 @@ SC_VDECL cell sc_stksize; /* stack size */
SC_VDECL cell sc_amxlimit; /* abstract machine size limit */
SC_VDECL int freading; /* is there an input file ready for reading? */
SC_VDECL int fline; /* the line number in the current file */
SC_VDECL short fnumber; /* number of files in the file table (debugging) */
SC_VDECL short fcurrent; /* current file being processed (debugging) */
SC_VDECL short fnumber; /* number of files in the input file table */
SC_VDECL short fcurrent; /* current file being processed */
SC_VDECL short sc_intest; /* true if inside a test */
SC_VDECL int sideeffect; /* true if an expression causes a side-effect */
SC_VDECL int stmtindent; /* current indent of the statement */
@ -783,6 +797,7 @@ SC_VDECL int sc_rationaltag; /* tag for rational numbers */
SC_VDECL int rational_digits; /* number of fractional digits */
SC_VDECL int sc_allowproccall;/* allow/detect tagnames in lex() */
SC_VDECL short sc_is_utf8; /* is this source file in UTF-8 encoding */
SC_VDECL char *pc_deprecate; /* if non-NULL, mark next declaration as deprecated */
SC_VDECL constvalue sc_automaton_tab; /* automaton table */
SC_VDECL constvalue sc_state_tab; /* state table */

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
#include <sclinux.h>
#endif
#include "sp_symhash.h"
#if defined FORTIFY
#include "fortify.h"
@ -120,18 +121,18 @@ SC_FUNC void clearstk(void)
SC_FUNC int plungequalifiedfile(char *name)
{
static char *extensions[] = { ".inc", ".p", ".pawn" };
FILE *fp;
void *fp;
char *ext;
int ext_idx;
ext_idx=0;
do {
fp=(FILE*)pc_opensrc(name);
fp=(void*)pc_opensrc(name);
ext=strchr(name,'\0'); /* save position */
if (fp==NULL) {
/* try to append an extension */
strcpy(ext,extensions[ext_idx]);
fp=(FILE*)pc_opensrc(name);
fp=(void*)pc_opensrc(name);
if (fp==NULL)
*ext='\0'; /* on failure, restore filename */
} /* if */
@ -156,15 +157,17 @@ static char *extensions[] = { ".inc", ".p", ".pawn" };
PUSHSTK_I(fline);
inpfname=duplicatestring(name);/* set name of include file */
if (inpfname==NULL)
error(103); /* insufficient memory */
inpf=fp; /* set input file pointer to include file */
error(103); /* insufficient memory */
inpf=fp; /* set input file pointer to include file */
fnumber++;
fline=0; /* set current line number to 0 */
fline=0; /* set current line number to 0 */
fcurrent=fnumber;
icomment=0; /* not in a comment */
insert_dbgfile(inpfname);
setfiledirect(inpfname);
listline=-1; /* force a #line directive when changing the file */
icomment=0; /* not in a comment */
insert_dbgfile(inpfname); /* attach to debug information */
insert_inputfile(inpfname); /* save for the error system */
assert(sc_status == statFIRST || strcmp(get_inputfile(fcurrent), inpfname) == 0);
setfiledirect(inpfname); /* (optionally) set in the list file */
listline=-1; /* force a #line directive when changing the file */
sc_is_utf8=(short)scan_utf8(inpf,name);
return TRUE;
}
@ -281,6 +284,7 @@ static void readline(unsigned char *line)
{
int i,num,cont;
unsigned char *ptr;
symbol *sym;
if (lptr==term_expr)
return;
@ -319,6 +323,7 @@ static void readline(unsigned char *line)
inpf=(FILE *)POPSTK_P();
insert_dbgfile(inpfname);
setfiledirect(inpfname);
assert(sc_status==statFIRST || strcmp(get_inputfile(fcurrent),inpfname)==0);
listline=-1; /* force a #line directive when changing the file */
} /* if */
@ -358,6 +363,9 @@ static void readline(unsigned char *line)
line+=strlen((char*)line);
} /* if */
fline+=1;
sym=findconst("__LINE__");
assert(sym!=NULL);
sym->addr=fline;
} while (num>=0 && cont);
}
@ -589,7 +597,7 @@ static int htoi(cell *val,const unsigned char *curptr)
#if defined __APPLE__
static double pow10(double d)
{
return pow(10, d);
return pow(10, d);
}
#endif
@ -850,6 +858,7 @@ static int command(void)
char *str;
int index;
cell code_index;
size_t len;
while (*lptr<=' ' && *lptr!='\0')
lptr+=1;
@ -889,7 +898,7 @@ static int command(void)
assert(iflevel>=0);
if (iflevel==0) {
error(26); /* no matching #if */
errorset(sRESET);
errorset(sRESET,0);
} else {
/* check for earlier #else */
if ((ifstack[iflevel-1] & HANDLED_ELSE)==HANDLED_ELSE) {
@ -897,7 +906,7 @@ static int command(void)
error(61); /* #elseif directive may not follow an #else */
else
error(60); /* multiple #else directives between #if ... #endif */
errorset(sRESET);
errorset(sRESET,0);
} else {
assert(iflevel>0);
/* if there has been a "parse mode" on this level, set "skip mode",
@ -906,11 +915,27 @@ static int command(void)
if ((ifstack[iflevel-1] & PARSEMODE)==PARSEMODE) {
/* there has been a parse mode already on this level, so skip the rest */
ifstack[iflevel-1] |= (char)SKIPMODE;
/* if we were already skipping this section, allow expressions with
* undefined symbols; otherwise check the expression to catch errors
*/
if (tok==tpELSEIF) {
if (skiplevel==iflevel)
preproc_expr(&val,NULL); /* get, but ignore the expression */
else
lptr=(unsigned char*)strchr((char*)lptr,'\0');
} /* if */
} else {
/* previous conditions were all FALSE */
if (tok==tpELSEIF) {
/* get new expression */
preproc_expr(&val,NULL); /* get value (or 0 on error) */
/* if we were already skipping this section, allow expressions with
* undefined symbols; otherwise check the expression to catch errors
*/
if (skiplevel==iflevel) {
preproc_expr(&val,NULL); /* get value (or 0 on error) */
} else {
lptr=(unsigned char*)strchr((char*)lptr,'\0');
val=0;
} /* if */
ifstack[iflevel-1]=(char)(val ? PARSEMODE : SKIPMODE);
} else {
/* a simple #else, clear skip mode */
@ -925,7 +950,7 @@ static int command(void)
ret=CMD_IF;
if (iflevel==0){
error(26); /* no matching "#if" */
errorset(sRESET);
errorset(sRESET,0);
} else {
iflevel--;
if (iflevel<skiplevel)
@ -1003,14 +1028,27 @@ static int command(void)
error(27); /* invalid character constant */
sc_ctrlchar=(char)val;
} /* if */
}
else if (strcmp(str, "deprecated") == 0) {
while (*lptr <= ' ' && *lptr != '\0')
lptr++;
len = strlen((char*)lptr);
pc_deprecate = (char*)malloc(len + 1);
if (pc_deprecate != NULL)
{
strcpy(pc_deprecate, (char*)lptr);
if (pc_deprecate[len - 1] == '\n') /* remove extra \n as already appended in .scp file */
pc_deprecate[len-1] = '\0';
}
lptr = (unsigned char*)strchr((char*)lptr, '\0'); /* skip to end (ignore "extra characters on line") */
} else if (strcmp(str,"dynamic")==0) {
preproc_expr(&sc_stksize,NULL);
} else if ( !strcmp(str,"library") ||
} else if ( !strcmp(str,"library") ||
!strcmp(str, "reqlib") ||
!strcmp(str, "reqclass") ||
!strcmp(str, "loadlib") ||
!strcmp(str, "explib") ||
!strcmp(str, "expclass") ||
!strcmp(str, "explib") ||
!strcmp(str, "expclass") ||
!strcmp(str, "defclasslib") ) {
char name[sNAMEMAX+1],sname[sNAMEMAX+1];
const char *prefix = "";
@ -1050,7 +1088,7 @@ static int command(void)
} else {
sname[0] = '_';
}
}
}
} /* if */
if (strlen(name)==0) {
curlibrary=NULL;
@ -1060,20 +1098,20 @@ static int command(void)
/* add the name if it does not yet exist in the table */
char newname[sNAMEMAX+1];
if (strlen(name) + strlen(prefix) + strlen(sname) <= sNAMEMAX)
{
{
strcpy(newname, prefix);
strcat(newname, name);
strcat(newname, sname);
if (newname[0] != '?')
{
{
if (find_constval(&libname_tab,newname,0)==NULL)
{
{
curlibrary=append_constval(&libname_tab,newname,0,0);
}
} else {
}
} else {
exporttag(pc_addtag(newname));
}
}
}
}
} /* if */
} else if (strcmp(str,"pack")==0) {
cell val;
@ -1117,7 +1155,8 @@ static int command(void)
} else if (strcmp(str,"tabsize")==0) {
cell val;
preproc_expr(&val,NULL);
sc_tabsize=(int)val;
if (val>0)
sc_tabsize=(int)val;
} else if (strcmp(str,"align")==0) {
sc_alignnext=TRUE;
} else if (strcmp(str,"unused")==0) {
@ -1251,7 +1290,7 @@ static int command(void)
} /* while */
end=lptr;
/* check pattern to match */
if (!isalpha(*start) && *start!='_') {
if (!alpha(*start)) {
error(74); /* pattern must start with an alphabetic character */
break;
} /* if */
@ -1302,7 +1341,7 @@ static int command(void)
} /* while */
substitution[count]='\0';
/* check whether the definition already exists */
for (prefixlen=0,start=(unsigned char*)pattern; isalpha(*start) || isdigit(*start) || *start=='_'; prefixlen++,start++)
for (prefixlen=0,start=(unsigned char*)pattern; alphanum(*start); prefixlen++,start++)
/* nothing */;
assert(prefixlen>0);
if ((def=find_subst(pattern,prefixlen))!=NULL) {
@ -1333,7 +1372,7 @@ static int command(void)
case tpERROR:
while (*lptr<=' ' && *lptr!='\0')
lptr++;
if (!SKIPPING)
if (!SKIPPING)
error(111,lptr); /* user error */
break;
default:
@ -1412,7 +1451,7 @@ static const unsigned char *skippgroup(const unsigned char *string)
break;
default:
assert(0);
close='\0'; /* only to avoid a compiler warning */
close='\0'; /* only to avoid a compiler warning */
}/* switch */
string++;
@ -1458,7 +1497,7 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
memset(args,0,sizeof args);
/* check the length of the prefix */
for (prefixlen=0,s=(unsigned char*)pattern; isalpha(*s) || isdigit(*s) || *s=='_'; prefixlen++,s++)
for (prefixlen=0,s=(unsigned char*)pattern; alphanum(*s); prefixlen++,s++)
/* nothing */;
assert(prefixlen>0);
assert(strncmp((char*)line,pattern,prefixlen)==0);
@ -1493,7 +1532,7 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
/* store the parameter (overrule any earlier) */
if (args[arg]!=NULL)
free(args[arg]);
else
else
argsnum++;
len=(int)(e-s);
args[arg]=(unsigned char*)malloc(len+1);
@ -1618,7 +1657,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
/* find the start of a prefix (skip all non-alphabetic characters),
* also skip strings
*/
while (!isalpha(*start) && *start!='_' && *start!='\0') {
while (!alpha(*start) && *start!='\0') {
/* skip strings */
if (is_startstring(start)) {
start=(unsigned char *)skipstring(start);
@ -1636,7 +1675,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
while ((*start<=' ' && *start!='\0') || *start=='(')
start++;
/* skip the symbol behind it */
while (isalpha(*start) || isdigit(*start) || *start=='_')
while (alphanum(*start))
start++;
/* drop back into the main loop */
continue;
@ -1644,7 +1683,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
/* get the prefix (length), look for a matching definition */
prefixlen=0;
end=start;
while (isalpha(*end) || isdigit(*end) || *end=='_') {
while (alphanum(*end)) {
prefixlen++;
end++;
} /* while */
@ -1688,7 +1727,7 @@ SC_FUNC void preprocess(void)
lptr=pline; /* set "line pointer" to start of the parsing buffer */
iscommand=command();
if (iscommand!=CMD_NONE)
errorset(sRESET); /* reset error flag ("panic mode") on empty line or directive */
errorset(sRESET,0); /* reset error flag ("panic mode") on empty line or directive */
#if !defined NO_DEFINE
if (iscommand==CMD_NONE) {
assert(lptr!=term_expr);
@ -1882,7 +1921,7 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
while (i<=tLAST) { /* match reserved words and compiler directives */
if (*lptr==**tokptr && match(*tokptr,TRUE)) {
_lextok=i;
errorset(sRESET); /* reset error flag (clear the "panic mode")*/
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
if (pc_docexpr) /* optionally concatenate to documentation string */
insert_autolist(*tokptr);
return _lextok;
@ -1974,7 +2013,7 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
} else if (*lptr==';') { /* semicolumn resets "error" flag */
_lextok=';';
lptr+=1;
errorset(sRESET); /* reset error flag (clear the "panic mode")*/
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
} else {
_lextok=*lptr; /* if every match fails, return the character */
lptr+=1; /* increase the "lptr" pointer */
@ -2332,6 +2371,7 @@ SC_FUNC int ishex(char c)
static symbol *add_symbol(symbol *root,symbol *entry,int sort)
{
symbol *newsym;
int global = root==&glbtab;
if (sort)
while (root->next!=NULL && strcmp(entry->name,root->next->name)>0)
@ -2344,6 +2384,8 @@ static symbol *add_symbol(symbol *root,symbol *entry,int sort)
memcpy(newsym,entry,sizeof(symbol));
newsym->next=root->next;
root->next=newsym;
if (global)
AddToHashTable(sp_Globals, newsym);
return newsym;
}
@ -2388,6 +2430,7 @@ static void free_symbol(symbol *sym)
SC_FUNC void delete_symbol(symbol *root,symbol *sym)
{
symbol *origRoot = root;
/* find the symbol and its predecessor
* (this function assumes that you will never delete a symbol that is not
* in the table pointed at by "root")
@ -2398,13 +2441,27 @@ SC_FUNC void delete_symbol(symbol *root,symbol *sym)
assert(root!=NULL);
} /* while */
if (origRoot==&glbtab)
RemoveFromHashTable(sp_Globals, sym);
/* unlink it, then free it */
root->next=sym->next;
free_symbol(sym);
}
SC_FUNC int get_actual_compound(symbol *sym)
{
if (sym->ident == iARRAY || sym->ident == iREFARRAY) {
while (sym->parent)
sym = sym->parent;
}
return sym->compound;
}
SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_functions)
{
symbol *origRoot=root;
symbol *sym,*parent_sym;
constvalue *stateptr;
int mustdelete=0;
@ -2413,7 +2470,7 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
* specified nesting level */
while (root->next!=NULL) {
sym=root->next;
if (sym->compound<level)
if (get_actual_compound(sym)<level)
break;
switch (sym->ident) {
case iLABEL:
@ -2458,6 +2515,8 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
break;
} /* switch */
if (mustdelete) {
if (origRoot == &glbtab)
RemoveFromHashTable(sp_Globals, sym);
root->next=sym->next;
free_symbol(sym);
} else {
@ -2475,35 +2534,21 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
/* for user defined operators, also remove the "prototyped" flag, as
* user-defined operators *must* be declared before use
*/
if (sym->ident==iFUNCTN && !isalpha(*sym->name) && *sym->name!='_' && *sym->name!=PUBLIC_CHAR)
if (sym->ident==iFUNCTN && !alpha(*sym->name))
sym->usage &= ~uPROTOTYPED;
root=sym; /* skip the symbol */
} /* if */
} /* if */
}
/* The purpose of the hash is to reduce the frequency of a "name"
* comparison (which is costly). There is little interest in avoiding
* clusters in similar names, which is why this function is plain simple.
*/
SC_FUNC uint32_t namehash(const char *name)
{
const unsigned char *ptr=(const unsigned char *)name;
int len=strlen(name);
if (len==0)
return 0L;
assert(len<256);
return (len<<24Lu) + (ptr[0]<<16Lu) + (ptr[len-1]<<8Lu) + (ptr[len>>1Lu]);
}
static symbol *find_symbol(const symbol *root,const char *name,int fnumber,int includechildren)
{
symbol *ptr=root->next;
unsigned long hash=namehash(name);
unsigned long hash=NameHash(name);
while (ptr!=NULL) {
if (hash==ptr->hash && strcmp(name,ptr->name)==0
&& (ptr->parent==NULL || includechildren)
&& (fnumber<0 || (ptr->fnumber<0 || ptr->fnumber==fnumber)))
&& (fnumber<0 || (ptr->fnumber<0 || ptr->fnumber==fnumber)))
return ptr;
ptr=ptr->next;
} /* while */
@ -2569,7 +2614,10 @@ SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom)
SC_FUNC void markusage(symbol *sym,int usage)
{
assert(sym!=NULL);
sym->usage |= (char)usage;
if ((usage & uWRITTEN) != 0)
sym->lnumber=fline;
/* check if (global) reference must be added to the symbol */
if ((usage & (uREAD | uWRITTEN))!=0) {
/* only do this for global symbols */
@ -2610,7 +2658,7 @@ SC_FUNC symbol *findconst(const char *name)
sym=find_symbol(&loctab,name,-1,TRUE); /* try local symbols first */
if (sym==NULL || sym->ident!=iCONSTEXPR) /* not found, or not a constant */
sym=find_symbol(&glbtab,name,fcurrent,TRUE);
sym=FindInHashTable(sp_Globals,name,fcurrent);
if (sym==NULL || sym->ident!=iCONSTEXPR)
return NULL;
assert(sym->parent==NULL || (sym->usage & uENUMFIELD)!=0);
@ -2651,16 +2699,18 @@ SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,i
/* first fill in the entry */
strcpy(entry.name,name);
entry.hash=namehash(name);
entry.hash=NameHash(name);
entry.addr=addr;
entry.codeaddr=code_idx;
entry.vclass=(char)vclass;
entry.ident=(char)ident;
entry.tag=tag;
entry.usage=(char)usage;
entry.flags=0;
entry.compound=0; /* may be overridden later */
entry.states=NULL;
entry.fnumber=-1; /* assume global visibility (ignored for local symbols) */
entry.lnumber=fline;
entry.numrefers=1;
entry.refer=refer;
entry.parent=NULL;
@ -2670,8 +2720,7 @@ SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,i
/* then insert it in the list */
if (vclass==sGLOBAL)
return add_symbol(&glbtab,&entry,TRUE);
else
return add_symbol(&loctab,&entry,FALSE);
return add_symbol(&loctab, &entry, FALSE);
}
SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
@ -2685,7 +2734,7 @@ SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int
* this special case.
*/
assert(vclass!=sGLOBAL || (sym=findglb(name))==NULL || (sym->usage & uDEFINE)==0
|| sym->ident==iFUNCTN && sym==curfunc);
|| (sym->ident==iFUNCTN && sym==curfunc));
if (ident==iARRAY || ident==iREFARRAY) {
symbol *parent=NULL,*top;

View File

@ -288,8 +288,7 @@ SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce)
* tag is "coerced" to zero
*/
if (!allowcoerce || formaltag!=0 || (actualtag & FIXEDTAG)!=0)
return FALSE;
return FALSE;
} /* if */
return TRUE;
}
@ -488,6 +487,7 @@ static int plnge_rel(int *opstr,int opoff,int (*hier)(value *lval),value *lval)
int lvalue,opidx;
value lval2 = {0}; /* intialize, to avoid a compiler warning */
int count;
char boolresult;
/* this function should only be called for relational operators */
assert(op1[opoff]==os_le);
@ -504,7 +504,9 @@ static int plnge_rel(int *opstr,int opoff,int (*hier)(value *lval),value *lval)
error(212);
if (count>0) {
relop_prefix();
boolresult = lval->boolresult;
*lval=lval2; /* copy right hand expression of the previous iteration */
lval->boolresult = boolresult;
} /* if */
opidx+=opoff;
plnge2(op1[opidx],hier,lval,&lval2);
@ -1037,13 +1039,13 @@ static int hier13(value *lval)
lval->ident=iREFARRAY; /* iARRAY becomes iREFARRAY */
else if (lval->ident!=iREFARRAY)
lval->ident=iEXPRESSION; /* iREFARRAY stays iREFARRAY, rest becomes iEXPRESSION */
if (orig_heap!=decl_heap) {
diff2=abs(decl_heap-orig_heap);
decl_heap=orig_heap;
}
if (orig_heap!=decl_heap) {
diff2=abs(decl_heap-orig_heap);
decl_heap=orig_heap;
}
if (diff1==diff2) {
decl_heap+=(diff1/2);
} else {
} else {
decl_heap+=(diff1+diff2);
}
return FALSE; /* conditional expression is no lvalue */
@ -1126,6 +1128,7 @@ static int hier2(value *lval)
symbol *sym=NULL;
int saveresult;
sym = NULL;
tok=lex(&val,&st);
switch (tok) {
case tINC: /* ++lval */
@ -1290,7 +1293,7 @@ static int hier2(value *lval)
return error(17,st); /* undefined symbol (symbol is in the table, but it is "used" only) */
tag=sym->tag;
} /* if */
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
if (sym!=NULL && (sym->ident==iARRAY || sym->ident==iREFARRAY)) {
int level;
symbol *idxsym=NULL;
for (level=0; matchtoken('['); level++) {
@ -1862,6 +1865,11 @@ static int nesting=0;
assert(nest_stkusage==0);
#endif
if ((sym->flags & flgDEPRECATED)!=0) {
char *ptr= (sym->documentation!=NULL) ? sym->documentation : "";
error(233,sym->name,ptr); /* deprecated (probably a native function) */
} /* if */
/* run through the arguments */
arg=sym->dim.arglist;
assert(arg!=NULL);
@ -2039,7 +2047,7 @@ static int nesting=0;
error(47); /* array sizes must match */
} /* if */
} /* if */
if (lval.ident!=iARRAYCELL) {
if (lval.ident!=iARRAYCELL|| lval.constval>0) {
/* save array size, for default values with uSIZEOF flag */
cell array_sz=lval.constval;
assert(array_sz!=0);/* literal array must have a size */

View File

@ -829,7 +829,7 @@ SC_FUNC void defstorage(void)
stgwrite("dump ");
}
/*
/**
* Inclrement/decrement stack pointer. Note that this routine does
* nothing if the delta is zero.
*/

View File

@ -290,6 +290,7 @@ static char *warnmsg[] = {
/*230*/ "no implementation for state \"%s\" / function \"%s\", no fall-back\n",
/*231*/ "state specification on forward declaration is ignored\n",
/*232*/ "output file is written, but with compact encoding disabled\n"
/*233*/ "symbol \"%s\" is marked as deprecated: %s\n",
#else
"\345 \274tr\240\226\233\277 %\206\273\337c\367\305",
"\222\323i\231\300\344\224t/\314cr\375\364",

View File

@ -21,7 +21,7 @@
*/
#include <assert.h>
#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
#include <io.h>
#endif
#if defined LINUX || defined __APPLE__ || defined __GNUC__
@ -41,7 +41,7 @@
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
#endif
#include "sc5.scp"
#include <sc5.scp>
#if defined _MSC_VER
#pragma warning(pop)
@ -51,7 +51,9 @@
static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */
static int errflag;
static int errfile;
static int errstart; /* line number at which the instruction started */
static int errline; /* forced line number for the error message */
/* error
*
@ -70,7 +72,7 @@ SC_FUNC int error(int number,...)
static char *prefix[3]={ "error", "fatal error", "warning" };
static int lastline,errorcount;
static short lastfile;
char *msg,*pre;
char *msg,*pre,*filename;
va_list argptr;
char string[128];
@ -107,11 +109,22 @@ static short lastfile;
strexpand(string,(unsigned char *)msg,sizeof string,SCPACK_TABLE);
assert(errstart<=fline);
if (errline>0)
errstart=errline; /* forced error position, set single line destination */
else
errline=fline; /* normal error, errstart may (or may not) have been marked, endpoint is current line */
if (errstart>errline)
errstart=errline; /* special case: error found at end of included file */
if (errfile>=0)
filename=get_inputfile(errfile);/* forced filename */
else
filename=inpfname; /* current file */
assert(filename!=NULL);
va_start(argptr,number);
if (strlen(errfname)==0) {
int start= (errstart==fline) ? -1 : errstart;
if (pc_error(number,string,inpfname,start,fline,argptr)) {
int start= (errstart==errline) ? -1 : errstart;
if (pc_error((int)number,string,filename,start,errline,argptr)) {
if (outf!=NULL) {
pc_closeasm(outf,TRUE);
outf=NULL;
@ -121,10 +134,10 @@ static short lastfile;
} else {
FILE *fp=fopen(errfname,"a");
if (fp!=NULL) {
if (errstart>=0 && errstart!=fline)
fprintf(fp,"%s(%d -- %d) : %s %03d: ",inpfname,errstart,fline,pre,number);
if (errstart>=0 && errstart!=errline)
fprintf(fp,"%s(%d -- %d) : %s %03d: ",filename,errstart,errline,pre,number);
else
fprintf(fp,"%s(%d) : %s %03d: ",inpfname,fline,pre,number);
fprintf(fp,"%s(%d) : %s %03d: ",filename,errline,pre,number);
vfprintf(fp,string,argptr);
fclose(fp);
} /* if */
@ -144,6 +157,8 @@ static short lastfile;
longjmp(errbuf,2); /* fatal error, quit */
} /* if */
errline=-1;
errfile=-1;
/* check whether we are seeing many errors on the same line */
if ((errstart<0 && lastline!=fline) || lastline<errstart || lastline>fline || fcurrent!=lastfile)
errorcount=0;
@ -157,7 +172,7 @@ static short lastfile;
return 0;
}
SC_FUNC void errorset(int code)
SC_FUNC void errorset(int code,int line)
{
switch (code) {
case sRESET:
@ -171,6 +186,15 @@ SC_FUNC void errorset(int code)
break;
case sEXPRRELEASE:
errstart=-1; /* forget start line number */
errline=-1;
errfile=-1;
break;
case sSETLINE:
errstart=-1; /* force error line number, forget start line */
errline=line;
break;
case sSETFILE:
errfile=line;
break;
} /* switch */
}

View File

View File

@ -51,7 +51,7 @@
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
#endif
#include "sc7.scp"
#include <sc7.scp>
#if defined _MSC_VER
#pragma warning(pop)

View File

@ -255,16 +255,16 @@ SC_FUNC void delete_pathtable(void)
static stringpair substpair = { NULL, NULL, NULL}; /* list of substitution pairs */
static stringpair *substindex['z'-'A'+1]; /* quick index to first character */
static stringpair *substindex['z'-PUBLIC_CHAR+1]; /* quick index to first character */
static void adjustindex(char c)
{
stringpair *cur;
assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_');
assert('A'<'_' && '_'<'z');
assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_' || c==PUBLIC_CHAR);
assert(PUBLIC_CHAR<'A' && 'A'<'_' && '_'<'z');
for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next)
/* nothing */;
substindex[(int)c-'A']=cur;
substindex[(int)c-PUBLIC_CHAR]=cur;
}
SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen)
@ -276,6 +276,26 @@ SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen)
if ((cur=insert_stringpair(&substpair,pattern,substitution,prefixlen))==NULL)
error(103); /* insufficient memory (fatal error) */
adjustindex(*pattern);
if (pc_deprecate != NULL) {
assert(cur != NULL);
cur->flags |= flgDEPRECATED;
if (sc_status == statWRITE) {
if (cur->documentation != NULL) {
free(cur->documentation);
cur->documentation = NULL;
} /* if */
cur->documentation = pc_deprecate;
}
else {
free(pc_deprecate);
} /* if */
pc_deprecate = NULL;
}
else {
cur->flags = 0;
cur->documentation = NULL;
} /* if */
return cur;
}
@ -284,10 +304,26 @@ SC_FUNC stringpair *find_subst(char *name,int length)
stringpair *item;
assert(name!=NULL);
assert(length>0);
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_');
item=substindex[(int)*name-'A'];
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
item=substindex[(int)*name-PUBLIC_CHAR];
if (item!=NULL)
item=find_stringpair(item,name,length);
if (item && (item->flags & flgDEPRECATED) != 0) {
static char macro[128];
char *rem, *msg = (item->documentation != NULL) ? item->documentation : "";
strncpy(macro, item->first, sizeof(macro));
macro[sizeof(macro) - 1] = '\0';
/* If macro contains an opening parentheses and a percent sign, then assume that
* it takes arguments and remove them from the warning message.
*/
if ((rem = strchr(macro, '(')) != NULL && strchr(macro, '%') > rem) {
*rem = '\0';
}
error(233, macro, msg); /* deprecated (macro/constant) */
}
return item;
}
@ -296,8 +332,8 @@ SC_FUNC int delete_subst(char *name,int length)
stringpair *item;
assert(name!=NULL);
assert(length>0);
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_');
item=substindex[(int)*name-'A'];
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
item=substindex[(int)*name-PUBLIC_CHAR];
if (item!=NULL)
item=find_stringpair(item,name,length);
if (item==NULL)
@ -318,7 +354,7 @@ SC_FUNC void delete_substtable(void)
#endif /* !defined NO_SUBST */
/* ----- input file list ----------------------------------------- */
/* ----- input file list (explicit files)------------------------- */
static stringlist sourcefiles = {NULL, NULL};
SC_FUNC stringlist *insert_sourcefile(char *string)
@ -338,6 +374,28 @@ SC_FUNC void delete_sourcefiletable(void)
}
/* ----- parsed file list (explicit + included files) ------------ */
static stringlist inputfiles = {NULL, NULL};
SC_FUNC stringlist *insert_inputfile(char *string)
{
if (sc_status!=statFIRST)
return insert_string(&inputfiles,string);
return NULL;
}
SC_FUNC char *get_inputfile(int index)
{
return get_string(&inputfiles,index);
}
SC_FUNC void delete_inputfiletable(void)
{
delete_stringtable(&inputfiles);
assert(inputfiles.next==NULL);
}
/* ----- documentation tags -------------------------------------- */
#if !defined SC_LIGHT
static stringlist docstrings = {NULL, NULL};
@ -415,9 +473,9 @@ SC_FUNC stringlist *insert_dbgline(int linenr)
}
#ifdef WIN32
#define LONGCAST long
#define LONGCAST long
#else
#define LONGCAST cell
#define LONGCAST cell
#endif
SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
@ -450,7 +508,7 @@ SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
symbol *sub;
#if !defined NDEBUG
count = sym->dim.array.level;
count = sym->dim.array.level;
#endif
strcat(string," [ ");
for (sub=sym; sub!=NULL; sub=finddepend(sub)) {

450
compiler/libpc300/scpack.c Normal file
View File

@ -0,0 +1,450 @@
/* compress.c -- Byte Pair Encoding compression */
/* Copyright 1996 Philip Gage */
/* This program appeared in the September 1997 issue of
* C/C++ Users Journal. The original source code may still
* be found at the web site of the magazine (www.cuj.com).
*
* It has been modified by me (Thiadmer Riemersma) to
* compress only a section of the input file and to store
* the compressed output along with the input as "C" strings.
*
* Compiling instructions:
* Borland C++ 16-bit (large memory model is required):
* bcc -ml scpack.c
*
* Watcom C/C++ 32-bit:
* wcl386 scpack.c
*
* GNU C (Linux), 32-bit:
* gcc scpack.c -o scpack
*/
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if UINT_MAX > 0xFFFFU
#define MAXSIZE 1024*1024L
#else
#define MAXSIZE UINT_MAX /* Input file buffer size */
#endif
#define HASHSIZE 8192 /* Hash table size, power of 2 */
#define THRESHOLD 3 /* Increase for speed, min 3 */
#define START_TOKEN "#ifdef SCPACK" /* start reading the buffer here */
#define NAME_TOKEN "#define SCPACK_TABLE"
#define SEP_TOKEN "#define SCPACK_SEPARATOR"
#define TERM_TOKEN "#define SCPACK_TERMINATOR"
#define TEMPFILE "~SCPACK.TMP"
static char tablename[32+1] = "scpack_table";
static char separator[16]=",";
static char terminator[16]="";
int compress(unsigned char *buffer, unsigned buffersize, unsigned char pairtable[128][2])
{
unsigned char *left, *right, *count;
unsigned char a, b, bestcount;
unsigned i, j, index, bestindex, code=128;
/* Dynamically allocate buffers and check for errors */
left = (unsigned char *)malloc(HASHSIZE);
right = (unsigned char *)malloc(HASHSIZE);
count = (unsigned char *)malloc(HASHSIZE);
if (left==NULL || right==NULL || count==NULL) {
printf("Error allocating memory\n");
exit(1);
}
/* Check for errors */
for (i=0; i<buffersize; i++)
if (buffer[i] > 127) {
printf("This program works only on text files (7-bit ASCII)\n");
exit(1);
}
memset(pairtable, 0, 128*2*sizeof(char));
do { /* Replace frequent pairs with bytes 128..255 */
/* Enter counts of all byte pairs into hash table */
memset(count,0,HASHSIZE);
for (i=0; i<buffersize-1; i++) {
a = buffer[i];
b = buffer[i+1];
/* ignore any pair with a '\0' */
if (a == 0 || b == 0)
continue;
index = (a ^ (b << 6)) & (HASHSIZE-1);
while ((left[index] != a || right[index] != b) &&
count[index] != 0)
index = (index + 1) & (HASHSIZE-1);
left[index] = a;
right[index] = b;
if (count[index] < 255)
count[index] += (unsigned char)1;
}
/* Search hash table for most frequent pair */
bestcount = THRESHOLD - 1;
for (i=0; i<HASHSIZE; i++) {
if (count[i] > bestcount) {
bestcount = count[i];
bestindex = i;
}
}
/* Compress if enough occurrences of pair */
if (bestcount >= THRESHOLD) {
/* Add pair to table using code as index */
a = pairtable[code-128][0] = left[bestindex];
b = pairtable[code-128][1] = right[bestindex];
/* Replace all pair occurrences with unused byte */
for (i=0, j=0; i<buffersize; i++, j++)
if (a == buffer[i] && b == buffer[i+1]) {
buffer[j] = (unsigned char)code;
++i;
}
else
buffer[j] = buffer[i];
buffersize = j;
}
else
break;
} while (++code < 255);
/* done */
free(left); free(right); free(count);
return buffersize; /* return adjusted buffersize */
}
static int strmatch(char *str, char *token, int *indent)
{
int i = 0;
/* skip whitespace */
while (*str==' ' || *str=='\t') {
str++;
i++;
} /* while */
if (strncmp(str,token,strlen(token))!=0)
return 0;
if (indent != NULL)
*indent = i;
return 1;
}
static void check_if(char *str,int linenr)
{
if (strmatch(str,"#if",NULL)) {
printf("Error: \"#if...\" preprocessor statement should not be in SCPACK section "
"(line %d)\n", linenr);
exit(1);
} /* if */
}
static int check_tablename(char *str)
{
int i;
if (strmatch(str,NAME_TOKEN,NULL)) {
str += strlen(NAME_TOKEN);
while (*str==' ' || *str=='\t')
str++;
for (i=0; i<(sizeof tablename - 1) && *str!='\0' && strchr(" \t\n",*str)==NULL; i++, str++)
tablename[i] = *str;
tablename[i] = '\0';
return 1;
} /* if */
return 0;
}
static int check_separator(char *str)
{
int i;
if (strmatch(str,SEP_TOKEN,NULL)) {
str += strlen(SEP_TOKEN);
while (*str==' ' || *str=='\t')
str++;
for (i=0; i<(sizeof separator - 1) && *str!='\0' && strchr(" \t\n",*str)==NULL; i++, str++)
separator[i] = *str;
separator[i] = '\0';
return 1;
} /* if */
if (strmatch(str,TERM_TOKEN,NULL)) {
str += strlen(TERM_TOKEN);
while (*str==' ' || *str=='\t')
str++;
for (i=0; i<(sizeof terminator - 1) && *str!='\0' && strchr(" \t\n",*str)==NULL; i++, str++)
terminator[i] = *str;
terminator[i] = '\0';
return 1;
} /* if */
return 0;
}
/* readbuffer
* Reads in the input file and stores all strings in the
* section between "#ifdef SCPACK" and "#else" in a buffer.
* Only text that is between double quotes is added to the
* buffer; the \" escape code is handled. Multiple strings
* on one line are handled.
*/
unsigned readbuffer(FILE *input, unsigned char *buffer)
{
char str[256];
unsigned buffersize;
int i,linenr;
linenr=0;
buffersize=0;
rewind(input);
while (!feof(input)) {
while (fgets(str,sizeof str,input)!=NULL) {
linenr++;
check_tablename(str);
check_separator(str);
if (strmatch(str,START_TOKEN,NULL))
break;
} /* while */
if (!strmatch(str,START_TOKEN,NULL))
return buffersize; /* no (more) section found, quit */
while (fgets(str,sizeof str,input)!=NULL) {
linenr++;
check_if(str,linenr);
if (check_tablename(str))
printf("Error: table name definition should not be in SCPACK section (line %d)\n", linenr);
check_separator(str);
if (strmatch(str,"#else",NULL))
break; /* done */
/* add to the buffer only what is between double quotes */
i=0;
do {
while (str[i]!='\0' && str[i]!='"')
i++;
if (str[i]=='"') {
/* we are in a string */
i++;
while (str[i]!='\0' && str[i]!='"') {
/* handle escape sequences */
if (str[i]=='\\') {
i++;
switch (str[i]) {
case 'a': /* alarm */
buffer[buffersize++]='\a';
i++;
break;
case 'b': /* backspace */
buffer[buffersize++]='\b';
i++;
break;
case 'f': /* form feed */
buffer[buffersize++]='\f';
i++;
break;
case 'n': /* newline */
buffer[buffersize++]='\n';
i++;
break;
case 'r': /* carriage return */
buffer[buffersize++]='\n';
i++;
break;
case 't': /* tab */
buffer[buffersize++]='\t';
i++;
break;
case '\'':
buffer[buffersize++]='\'';
i++;
break;
case '"':
buffer[buffersize++]='"';
i++;
break;
default:
// ??? octal character code escapes and hexadecimal escapes
// not supported
printf("Unknown escape sequence '\\%c' on line %d\n",
str[i], linenr);
} /* switch */
} else {
buffer[buffersize++]=str[i++];
} /* if */
} /* while */
if (str[i]=='"') {
buffer[buffersize++]='\0'; /* terminate each string */
i++;
} else {
printf("Error: unterminated string on line %d\n",linenr);
} /* if */
} /* if */
} while (str[i]!='\0');
} /* while - in SCPACK section */
/* put in another '\0' to terminate the section */
buffer[buffersize++]='\0';
} /* while - !feof(input) */
return buffersize;
}
static void write_pairtable(FILE *output, unsigned char pairtable[128][2], char *tablename)
{
int i;
/* dump the pair table */
fprintf(output, "/*-*SCPACK start of pair table, do not change or remove this line */\n");
fprintf(output, "unsigned char %s[][2] = {", tablename);
for (i=0; i<128 && pairtable[i][0]!=0 && pairtable[i][1]!=0; i++) {
if ((i % 16)==0)
fprintf(output, "\n ");
else
fprintf(output, " ");
fprintf(output, "{%d,%d}", pairtable[i][0], pairtable[i][1]);
/* check if something follows this pair */
if (i+1<128 && pairtable[i+1][0]!=0 && pairtable[i+1][1]!=0)
fprintf(output, ",");
} /* for */
fprintf(output, "\n};\n");
fprintf(output, "/*-*SCPACK end of pair table, do not change or remove this line */\n");
}
void writefile(FILE *input, FILE *output, unsigned char *buffer, unsigned buffersize, unsigned char pairtable[128][2])
{
char str[256];
int insection, indent, needseparator;
unsigned char *bufptr;
bufptr = buffer;
insection = 0;
rewind(input);
while (!feof(input)) {
while (fgets(str,sizeof str,input)!=NULL) {
fprintf(output,"%s",str);
if (check_tablename(str)) {
write_pairtable(output, pairtable, tablename);
/* strip an existing pair table from the file */
if (fgets(str,sizeof str,input)!=NULL) {
if (strmatch(str,"/*-*SCPACK",NULL)) {
while (fgets(str,sizeof str,input)!=NULL)
if (strmatch(str,"/*-*SCPACK",NULL))
break;
} else {
fprintf(output,"%s",str);
} /* if */
} /* if */
} /* if */
if (strmatch(str,START_TOKEN,NULL))
insection = 1;
if (insection && strmatch(str,"#else",NULL))
break;
} /* while */
if (!strmatch(str,"#else",&indent))
return; /* no (more) section found, quit */
insection=0;
/* dump the buffer as strings, separated with commas */
needseparator = 0;
while (*bufptr != '\0') {
assert((unsigned)(bufptr-buffer) < buffersize);
if (needseparator)
fprintf(output, "%s\n",separator);
fprintf(output, "%*c\"",indent+2,' ');
/* loop over string */
while (*bufptr != '\0') {
if (*bufptr<' ' || *bufptr >= 128 || *bufptr == '"' || *bufptr == '\\')
fprintf(output, "\\%03o", *bufptr);
else
fprintf(output, "%c", *bufptr);
bufptr++;
} /* while */
fprintf(output, "\"");
needseparator = 1;
bufptr++; /* skip '\0' */
} /* while */
fprintf(output, "%s\n",terminator);
bufptr++;
/* skip the input file until the #endif section */
while (fgets(str,sizeof str,input)!=NULL) {
if (strmatch(str,"#endif",NULL)) {
fprintf(output,"%s",str);
break; /* done */
} /* if */
} /* while */
} /* while - !feof(input) */
}
static void usage(void)
{
printf("Usage: scpack <filename> [output file]\n");
exit(1);
}
int main(int argc, char **argv)
{
FILE *in, *out;
unsigned char *buffer;
unsigned buffersize, orgbuffersize;
unsigned char pairtable[128][2];
if (argc < 2 || argc > 3)
usage();
if ((in=fopen(argv[1],"rt"))==NULL) {
printf("SCPACK: error opening input %s\n",argv[1]);
usage();
} /* if */
if (argc == 2) {
if ((out=fopen(TEMPFILE,"wt"))==NULL) {
printf("SCPACK: error opening temporary file %s\n",TEMPFILE);
usage();
} /* if */
} else {
if ((out=fopen(argv[2],"wt"))==NULL) {
printf("SCPACK: error opening output file %s\n",argv[2]);
usage();
} /* if */
} /* if */
buffer = (unsigned char *)malloc(MAXSIZE);
if (buffer == NULL) {
printf("SCPACK: error allocating memory\n");
return 1;
} /* if */
/* 1. read the buffer
* 2. compress the buffer
* 3. copy the file, insert the compressed buffer
*/
buffersize = readbuffer(in, buffer);
orgbuffersize = buffersize;
if (buffersize > 0) {
buffersize = compress(buffer, buffersize, pairtable);
writefile(in, out, buffer, buffersize, pairtable);
printf("SCPACK: compression ratio: %ld%% (%d -> %d)\n",
100L-(100L*buffersize)/orgbuffersize, orgbuffersize, buffersize);
} else {
printf("SCPACK: no SCPACK section found, nothing to do\n");
} /* if */
fclose(out);
fclose(in);
/* let the new file replace the old file */
if (buffersize == 0) {
if (argc == 2)
remove(TEMPFILE);
else
remove(argv[2]);
} else if (argc == 2) {
remove(argv[1]);
rename(TEMPFILE,argv[1]);
} /* if */
return 0;
}

View File

@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h> /* for _MAX_PATH */
#include "sc.h"
#include "sp_symhash.h"
/* global variables
*
@ -84,6 +85,7 @@ SC_VDEFINE int sc_rationaltag=0; /* tag for rational numbers */
SC_VDEFINE int rational_digits=0; /* number of fractional digits */
SC_VDEFINE int sc_allowproccall=0; /* allow/detect tagnames in lex() */
SC_VDEFINE short sc_is_utf8=FALSE; /* is this source file in UTF-8 encoding */
SC_VDEFINE char *pc_deprecate = NULL;/* if non-null, mark next declaration as deprecated */
SC_VDEFINE int sc_showincludes=0; /* show include files */
SC_VDEFINE constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */
@ -95,6 +97,8 @@ SC_VDEFINE FILE *outf = NULL; /* (intermediate) text file written to */
SC_VDEFINE jmp_buf errbuf;
SC_VDEFINE HashTable *sp_Globals = NULL;
#if !defined SC_LIGHT
SC_VDEFINE int sc_makereport=FALSE; /* generate a cross-reference report */
#endif

View File

@ -0,0 +1,229 @@
/* vim: set ts=4 sw=4 tw=99 et: */
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sc.h"
#include "sp_symhash.h"
SC_FUNC uint32_t
NameHash(const char *str)
{
size_t len = strlen(str);
const uint8_t *data = (uint8_t *)str;
#undef get16bits
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
#define get16bits(d) (*((const uint16_t *) (d)))
#endif
#if !defined (get16bits)
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
+(uint32_t)(((const uint8_t *)(d))[0]) )
#endif
uint32_t hash = len, tmp;
int rem;
if (len <= 0 || data == NULL) return 0;
rem = len & 3;
len >>= 2;
/* Main loop */
for (;len > 0; len--) {
hash += get16bits (data);
tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2*sizeof (uint16_t);
hash += hash >> 11;
}
/* Handle end cases */
switch (rem) {
case 3: hash += get16bits (data);
hash ^= hash << 16;
hash ^= data[sizeof (uint16_t)] << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits (data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
#undef get16bits
}
SC_FUNC HashTable *NewHashTable()
{
HashTable *ht = (HashTable*)malloc(sizeof(HashTable));
if (!ht)
return ht;
ht->buckets = (HashEntry **)calloc(32, sizeof(HashEntry *));
if (!ht->buckets) {
free(ht);
return NULL;
}
ht->nbuckets = 32;
ht->nused = 0;
ht->bucketmask = 32 - 1;
return ht;
}
SC_FUNC void
DestroyHashTable(HashTable *ht)
{
uint32_t i;
if (!ht)
return;
for (i = 0; i < ht->nbuckets; i++) {
HashEntry *he = ht->buckets[i];
while (he != NULL) {
HashEntry *next = he->next;
free(he);
he = next;
}
}
free(ht->buckets);
free(ht);
}
SC_FUNC symbol *
FindTaggedInHashTable(HashTable *ht, const char *name, int fnumber,
int *cmptag)
{
int count=0;
symbol *firstmatch=NULL;
uint32_t hash = NameHash(name);
uint32_t bucket = hash & ht->bucketmask;
HashEntry *he = ht->buckets[bucket];
assert(cmptag!=NULL);
while (he != NULL) {
symbol *sym = he->sym;
if ((sym->parent==NULL || sym->ident==iCONSTEXPR) &&
(sym->fnumber<0 || sym->fnumber==fnumber) &&
(strcmp(sym->name, name) == 0))
{
/* return closest match or first match; count number of matches */
if (firstmatch==NULL)
firstmatch=sym;
if (*cmptag==0)
count++;
if (*cmptag==sym->tag) {
*cmptag=1; /* good match found, set number of matches to 1 */
return sym;
}
}
he = he->next;
}
if (firstmatch!=NULL)
*cmptag=count;
return firstmatch;
}
SC_FUNC symbol *
FindInHashTable(HashTable *ht, const char *name, int fnumber)
{
uint32_t hash = NameHash(name);
uint32_t bucket = hash & ht->bucketmask;
HashEntry *he = ht->buckets[bucket];
while (he != NULL) {
symbol *sym = he->sym;
if ((sym->parent==NULL || sym->ident==iCONSTEXPR) &&
(sym->fnumber<0 || sym->fnumber==fnumber) &&
(strcmp(sym->name, name) == 0))
{
return sym;
}
he = he->next;
}
return NULL;
}
static void
ResizeHashTable(HashTable *ht)
{
uint32_t i;
uint32_t xnbuckets = ht->nbuckets * 2;
uint32_t xbucketmask = xnbuckets - 1;
HashEntry **xbuckets = (HashEntry **)calloc(xnbuckets, sizeof(HashEntry*));
if (!xbuckets)
return;
for (i = 0; i < ht->nbuckets; i++) {
HashEntry *he = ht->buckets[i];
while (he != NULL) {
HashEntry *next = he->next;
uint32_t bucket = he->sym->hash & xbucketmask;
he->next = xbuckets[bucket];
xbuckets[bucket] = he;
he = next;
}
}
free(ht->buckets);
ht->buckets = xbuckets;
ht->nbuckets = xnbuckets;
ht->bucketmask = xbucketmask;
}
SC_FUNC void
AddToHashTable(HashTable *ht, symbol *sym)
{
uint32_t bucket = sym->hash & ht->bucketmask;
HashEntry **hep, *he;
hep = &ht->buckets[bucket];
while (*hep) {
assert((*hep)->sym != sym);
hep = &(*hep)->next;
}
he = (HashEntry *)malloc(sizeof(HashEntry));
if (!he)
error(163);
he->sym = sym;
he->next = NULL;
*hep = he;
ht->nused++;
if (ht->nused > ht->nbuckets && ht->nbuckets <= INT_MAX / 2)
ResizeHashTable(ht);
}
SC_FUNC void
RemoveFromHashTable(HashTable *ht, symbol *sym)
{
uint32_t bucket = sym->hash & ht->bucketmask;
HashEntry **hep = &ht->buckets[bucket];
HashEntry *he = *hep;
while (he != NULL) {
if (he->sym == sym) {
*hep = he->next;
free(he);
ht->nused--;
return;
}
hep = &he->next;
he = *hep;
}
assert(0);
}

View File

@ -0,0 +1,28 @@
/* vim: set ts=4 sw=4 tw=99 et: */
#ifndef _INCLUDE_SPCOMP_SYMHASH_H_
#define _INCLUDE_SPCOMP_SYMHASH_H_
SC_FUNC uint32_t NameHash(const char *str);
typedef struct HashEntry {
symbol *sym;
struct HashEntry *next;
} HashEntry;
struct HashTable {
uint32_t nbuckets;
uint32_t nused;
uint32_t bucketmask;
HashEntry **buckets;
};
SC_FUNC HashTable *NewHashTable();
SC_FUNC void DestroyHashTable(HashTable *ht);
SC_FUNC void AddToHashTable(HashTable *ht, symbol *sym);
SC_FUNC void RemoveFromHashTable(HashTable *ht, symbol *sym);
SC_FUNC symbol *FindInHashTable(HashTable *ht, const char *name, int fnumber);
SC_FUNC symbol *FindTaggedInHashTable(HashTable *ht, const char *name, int fnumber,
int *cmptag);
#endif /* _INCLUDE_SPCOMP_SYMHASH_H_ */

View File

@ -2535,6 +2535,7 @@ native plugin_flags(hdr=0, plid=-1);
*
* @noreturn
*/
#pragma deprecated Module dependency is now automatically handled by the compiler. This forward is no longer called.
forward plugin_modules();
/**
@ -2545,6 +2546,7 @@ forward plugin_modules();
*
* @noreturn
*/
#pragma deprecated Module dependency is now automatically handled by the compiler. This native has no effect.
native require_module(const module[]);
/**
@ -2556,6 +2558,7 @@ native require_module(const module[]);
*
* @return 1 if the server is 64 bit, 0 otherwise
*/
#pragma deprecated AMXX is not shipping 64bits builds anymore. This native is basically guaranteed to return 0.
native is_amd64_server();
/**

View File

@ -62,7 +62,7 @@ native bool:geoip_code3_ex(const ip[], result[4]);
*
* @return 1 on a successful lookup, 0 otherwise.
*/
//#pragma deprecated Use geoip_code2_ex() instead.
#pragma deprecated Use geoip_code2_ex() instead.
native geoip_code2(const ip[], ccode[3]);
/**
@ -76,7 +76,7 @@ native geoip_code2(const ip[], ccode[3]);
*
* @return 1 on a successful lookup, 0 otherwise.
*/
//#pragma deprecated Use geoip_code3() instead.
#pragma deprecated Use geoip_code3() instead.
native geoip_code3(const ip[], result[4]);
/**

View File

@ -543,6 +543,7 @@ forward client_spawn(id);
* @param Damage The amount of damage being done.
* @param DamageType The damage type being done (bitmask).
*/
#pragma deprecated It is suggested to use hamsandwich for this action instead.
native ns_takedamage(IDVictim, IDInflictor, IDAttacker, Float:Damage, DamageType);
/**

View File

@ -711,7 +711,7 @@ native strncmp(const string1[], const string2[], num, bool:ignorecase=false);
* Backwards compatibility stock - use argbreak or argparse.
* @deprecated this function does not work properly.
*/
//#pragma deprecated Use argbreak() instead
#pragma deprecated Use argbreak() instead
stock strbreak(const text[], Left[], leftLen, Right[], rightLen)
{
return argbreak(text, Left, leftLen, Right, rightLen);

View File

@ -14,7 +14,7 @@
#include <amxmodx>
#include <amxmisc>
#pragma tabsize 0
#pragma tabsize 4
new g_TeamOneAck[12];
new g_TeamTwoAck[12];