Merge pull request #116 from Arkshine/update-compiler-safe-fix-feature
Update compiler
This commit is contained in:
commit
1463103cd7
@ -130,6 +130,8 @@ class AMXXConfig(object):
|
|||||||
'-Wno-uninitialized',
|
'-Wno-uninitialized',
|
||||||
'-Wno-unused',
|
'-Wno-unused',
|
||||||
'-Wno-switch',
|
'-Wno-switch',
|
||||||
|
'-Wno-format',
|
||||||
|
'-Wno-format-security',
|
||||||
'-m32',
|
'-m32',
|
||||||
]
|
]
|
||||||
cfg.cxxflags += [
|
cfg.cxxflags += [
|
||||||
|
@ -1,9 +1,50 @@
|
|||||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||||
import os.path
|
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 = 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']:
|
if builder.target_platform in ['mac', 'linux']:
|
||||||
binary.compiler.defines += ['ENABLE_BINRELOC']
|
binary.compiler.defines += ['ENABLE_BINRELOC']
|
||||||
@ -34,6 +75,7 @@ binary.sources = [
|
|||||||
'libpawnc.c',
|
'libpawnc.c',
|
||||||
'prefix.c',
|
'prefix.c',
|
||||||
'memfile.c',
|
'memfile.c',
|
||||||
|
'sp_symhash.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
if builder.target_platform == 'windows':
|
if builder.target_platform == 'windows':
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "sc.h"
|
#include "sc.h"
|
||||||
@ -55,6 +56,10 @@
|
|||||||
}
|
}
|
||||||
#endif /* PAWNC_DLL */
|
#endif /* PAWNC_DLL */
|
||||||
|
|
||||||
|
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* pc_printf()
|
/* pc_printf()
|
||||||
* Called for general purpose "console" output. This function prints general
|
* Called for general purpose "console" output. This function prints general
|
||||||
@ -119,6 +124,14 @@ static char *prefix[3]={ "error", "fatal error", "warning" };
|
|||||||
return 0;
|
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()
|
/* pc_opensrc()
|
||||||
* Opens a source file (or include file) for reading. The "file" does not have
|
* Opens a source file (or include file) for reading. The "file" does not have
|
||||||
* to be a physical file, one might compile from memory.
|
* 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)
|
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()
|
/* pc_createsrc()
|
||||||
@ -150,7 +202,23 @@ void *pc_opensrc(char *filename)
|
|||||||
*/
|
*/
|
||||||
void *pc_createsrc(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()
|
/* pc_closesrc()
|
||||||
@ -159,8 +227,15 @@ void *pc_createsrc(char *filename)
|
|||||||
*/
|
*/
|
||||||
void pc_closesrc(void *handle)
|
void pc_closesrc(void *handle)
|
||||||
{
|
{
|
||||||
assert(handle!=NULL);
|
src_file_t *src = (src_file_t *)handle;
|
||||||
fclose((FILE*)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()
|
/* pc_resetsrc()
|
||||||
@ -169,8 +244,12 @@ void pc_closesrc(void *handle)
|
|||||||
*/
|
*/
|
||||||
void pc_resetsrc(void *handle,void *position)
|
void pc_resetsrc(void *handle,void *position)
|
||||||
{
|
{
|
||||||
assert(handle!=NULL);
|
src_file_t *src = (src_file_t *)handle;
|
||||||
fsetpos((FILE*)handle,(fpos_t *)position);
|
ptrdiff_t pos = (ptrdiff_t)position;
|
||||||
|
|
||||||
|
assert(!src->fp);
|
||||||
|
assert(pos >= 0 && src->buffer + pos <= src->end);
|
||||||
|
src->pos = src->buffer + pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pc_readsrc()
|
/* pc_readsrc()
|
||||||
@ -179,7 +258,35 @@ void pc_resetsrc(void *handle,void *position)
|
|||||||
*/
|
*/
|
||||||
char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
|
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()
|
/* pc_writesrc()
|
||||||
@ -188,20 +295,51 @@ char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
|
|||||||
*/
|
*/
|
||||||
int pc_writesrc(void *handle,unsigned char *source)
|
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)
|
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);
|
assert(!src->fp);
|
||||||
return &lastpos;
|
return (void *)(ptrdiff_t)(src->pos - src->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pc_eofsrc(void *handle)
|
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
|
/* should return a pointer, which is used as a "magic cookie" to all I/O
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<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>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>
|
||||||
@ -71,7 +71,7 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<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>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
|
<BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
@ -105,11 +105,13 @@
|
|||||||
<ClCompile Include="scmemfil.c" />
|
<ClCompile Include="scmemfil.c" />
|
||||||
<ClCompile Include="scstate.c" />
|
<ClCompile Include="scstate.c" />
|
||||||
<ClCompile Include="scvars.c" />
|
<ClCompile Include="scvars.c" />
|
||||||
|
<ClCompile Include="sp_symhash.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="amx.h" />
|
<ClInclude Include="amx.h" />
|
||||||
<ClInclude Include="memfile.h" />
|
<ClInclude Include="memfile.h" />
|
||||||
<ClInclude Include="sc.h" />
|
<ClInclude Include="sc.h" />
|
||||||
|
<ClInclude Include="sp_symhash.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="libpawnc.rc" />
|
<ResourceCompile Include="libpawnc.rc" />
|
||||||
|
@ -60,6 +60,9 @@
|
|||||||
<ClCompile Include="scvars.c">
|
<ClCompile Include="scvars.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="sp_symhash.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="amx.h">
|
<ClInclude Include="amx.h">
|
||||||
@ -71,6 +74,9 @@
|
|||||||
<ClInclude Include="sc.h">
|
<ClInclude Include="sc.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="sp_symhash.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="libpawnc.rc">
|
<ResourceCompile Include="libpawnc.rc">
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
#define sCHARBITS 8 /* size of a packed character */
|
#define sCHARBITS 8 /* size of a packed character */
|
||||||
|
|
||||||
#define sDIMEN_MAX 3 /* maximum number of array dimensions */
|
#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 sCOMP_STACK 32 /* maximum nesting of #if .. #endif sections */
|
||||||
#define sDEF_LITMAX 500 /* initial size of the literal pool, in "cells" */
|
#define sDEF_LITMAX 500 /* initial size of the literal pool, in "cells" */
|
||||||
#define sDEF_AMXSTACK 4096 /* default stack size for AMX files */
|
#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 vclass; /* sLOCAL if "addr" refers to a local symbol */
|
||||||
char ident; /* see below for possible values */
|
char ident; /* see below for possible values */
|
||||||
char usage; /* 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 compound; /* compound level (braces nesting level) */
|
||||||
int tag; /* tagname id */
|
int tag; /* tagname id */
|
||||||
int fieldtag; /* enumeration fields, where a size is attached to the field */
|
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 */
|
} dim; /* for 'dimension', both functions and arrays */
|
||||||
constvalue *states; /* list of state function addresses */
|
constvalue *states; /* list of state function addresses */
|
||||||
int fnumber; /* static global variables: file number in which the declaration is visible */
|
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 */
|
struct s_symbol **refer; /* referrer list, functions that "use" this symbol */
|
||||||
int numrefers; /* number of entries in the referrer list */
|
int numrefers; /* number of entries in the referrer list */
|
||||||
char *documentation; /* optional documentation string */
|
char *documentation; /* optional documentation string */
|
||||||
@ -221,6 +223,8 @@ typedef struct s_symbol {
|
|||||||
*/
|
*/
|
||||||
#define uRETNONE 0x10
|
#define uRETNONE 0x10
|
||||||
|
|
||||||
|
#define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */
|
||||||
|
|
||||||
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
|
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
|
||||||
#define uSIZEOF 0x80 /* 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 *first;
|
||||||
char *second;
|
char *second;
|
||||||
int matchlength;
|
int matchlength;
|
||||||
|
char flags;
|
||||||
|
char *documentation;
|
||||||
} stringpair;
|
} stringpair;
|
||||||
|
|
||||||
/* macros for code generation */
|
/* macros for code generation */
|
||||||
@ -365,6 +371,7 @@ typedef struct s_stringpair {
|
|||||||
#define tLABEL 331
|
#define tLABEL 331
|
||||||
#define tSTRING 332
|
#define tSTRING 332
|
||||||
#define tEXPR 333 /* for assigment to "lastst" only */
|
#define tEXPR 333 /* for assigment to "lastst" only */
|
||||||
|
#define tEMPTYBLOCK 334 /* empty blocks for AM bug 4825 */
|
||||||
|
|
||||||
/* (reversed) evaluation of staging buffer */
|
/* (reversed) evaluation of staging buffer */
|
||||||
#define sSTARTREORDER 0x01
|
#define sSTARTREORDER 0x01
|
||||||
@ -400,6 +407,8 @@ typedef struct s_stringpair {
|
|||||||
#define sFORCESET 1 /* force error flag on */
|
#define sFORCESET 1 /* force error flag on */
|
||||||
#define sEXPRMARK 2 /* mark start of expression */
|
#define sEXPRMARK 2 /* mark start of expression */
|
||||||
#define sEXPRRELEASE 3 /* mark end 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 {
|
typedef enum s_regid {
|
||||||
sPRI, /* indicates the primary register */
|
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 symbol *add_constant(char *name,cell val,int vclass,int tag);
|
||||||
SC_FUNC void exporttag(int tag);
|
SC_FUNC void exporttag(int tag);
|
||||||
SC_FUNC void sc_attachdocumentation(symbol *sym);
|
SC_FUNC void sc_attachdocumentation(symbol *sym);
|
||||||
|
SC_FUNC int get_actual_compound(symbol *sym);
|
||||||
|
|
||||||
/* function prototypes in SC2.C */
|
/* function prototypes in SC2.C */
|
||||||
#define PUSHSTK_P(v) { stkitem s_; s_.pv=(v); pushstk(s_); }
|
#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 void delete_symbols(symbol *root,int level,int del_labels,int delete_functions);
|
||||||
SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom);
|
SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom);
|
||||||
SC_FUNC void markusage(symbol *sym,int usage);
|
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 *findglb(const char *name);
|
||||||
SC_FUNC symbol *findloc(const char *name);
|
SC_FUNC symbol *findloc(const char *name);
|
||||||
SC_FUNC symbol *findconst(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 */
|
/* function prototypes in SC5.C */
|
||||||
SC_FUNC int error(int number,...) INVISIBLE;
|
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 */
|
/* function prototypes in SC6.C */
|
||||||
SC_FUNC int assemble(FILE *fout,FILE *fin);
|
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 stringlist *insert_sourcefile(char *string);
|
||||||
SC_FUNC char *get_sourcefile(int index);
|
SC_FUNC char *get_sourcefile(int index);
|
||||||
SC_FUNC void delete_sourcefiletable(void);
|
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 stringlist *insert_docstring(char *string);
|
||||||
SC_FUNC char *get_docstring(int index);
|
SC_FUNC char *get_docstring(int index);
|
||||||
SC_FUNC void delete_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) */
|
/* external variables (defined in scvars.c) */
|
||||||
#if !defined SC_SKIP_VDECL
|
#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 loctab; /* local symbol table */
|
||||||
SC_VDECL symbol glbtab; /* global symbol table */
|
SC_VDECL symbol glbtab; /* global symbol table */
|
||||||
SC_VDECL cell *litq; /* the literal queue */
|
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 cell sc_amxlimit; /* abstract machine size limit */
|
||||||
SC_VDECL int freading; /* is there an input file ready for reading? */
|
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 int fline; /* the line number in the current file */
|
||||||
SC_VDECL short fnumber; /* number of files in the file table (debugging) */
|
SC_VDECL short fnumber; /* number of files in the input file table */
|
||||||
SC_VDECL short fcurrent; /* current file being processed (debugging) */
|
SC_VDECL short fcurrent; /* current file being processed */
|
||||||
SC_VDECL short sc_intest; /* true if inside a test */
|
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 sideeffect; /* true if an expression causes a side-effect */
|
||||||
SC_VDECL int stmtindent; /* current indent of the statement */
|
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 rational_digits; /* number of fractional digits */
|
||||||
SC_VDECL int sc_allowproccall;/* allow/detect tagnames in lex() */
|
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 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_automaton_tab; /* automaton table */
|
||||||
SC_VDECL constvalue sc_state_tab; /* state table */
|
SC_VDECL constvalue sc_state_tab; /* state table */
|
||||||
|
11352
compiler/libpc300/sc1.c
11352
compiler/libpc300/sc1.c
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,7 @@
|
|||||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
||||||
#include <sclinux.h>
|
#include <sclinux.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "sp_symhash.h"
|
||||||
|
|
||||||
#if defined FORTIFY
|
#if defined FORTIFY
|
||||||
#include "fortify.h"
|
#include "fortify.h"
|
||||||
@ -120,18 +121,18 @@ SC_FUNC void clearstk(void)
|
|||||||
SC_FUNC int plungequalifiedfile(char *name)
|
SC_FUNC int plungequalifiedfile(char *name)
|
||||||
{
|
{
|
||||||
static char *extensions[] = { ".inc", ".p", ".pawn" };
|
static char *extensions[] = { ".inc", ".p", ".pawn" };
|
||||||
FILE *fp;
|
void *fp;
|
||||||
char *ext;
|
char *ext;
|
||||||
int ext_idx;
|
int ext_idx;
|
||||||
|
|
||||||
ext_idx=0;
|
ext_idx=0;
|
||||||
do {
|
do {
|
||||||
fp=(FILE*)pc_opensrc(name);
|
fp=(void*)pc_opensrc(name);
|
||||||
ext=strchr(name,'\0'); /* save position */
|
ext=strchr(name,'\0'); /* save position */
|
||||||
if (fp==NULL) {
|
if (fp==NULL) {
|
||||||
/* try to append an extension */
|
/* try to append an extension */
|
||||||
strcpy(ext,extensions[ext_idx]);
|
strcpy(ext,extensions[ext_idx]);
|
||||||
fp=(FILE*)pc_opensrc(name);
|
fp=(void*)pc_opensrc(name);
|
||||||
if (fp==NULL)
|
if (fp==NULL)
|
||||||
*ext='\0'; /* on failure, restore filename */
|
*ext='\0'; /* on failure, restore filename */
|
||||||
} /* if */
|
} /* if */
|
||||||
@ -156,15 +157,17 @@ static char *extensions[] = { ".inc", ".p", ".pawn" };
|
|||||||
PUSHSTK_I(fline);
|
PUSHSTK_I(fline);
|
||||||
inpfname=duplicatestring(name);/* set name of include file */
|
inpfname=duplicatestring(name);/* set name of include file */
|
||||||
if (inpfname==NULL)
|
if (inpfname==NULL)
|
||||||
error(103); /* insufficient memory */
|
error(103); /* insufficient memory */
|
||||||
inpf=fp; /* set input file pointer to include file */
|
inpf=fp; /* set input file pointer to include file */
|
||||||
fnumber++;
|
fnumber++;
|
||||||
fline=0; /* set current line number to 0 */
|
fline=0; /* set current line number to 0 */
|
||||||
fcurrent=fnumber;
|
fcurrent=fnumber;
|
||||||
icomment=0; /* not in a comment */
|
icomment=0; /* not in a comment */
|
||||||
insert_dbgfile(inpfname);
|
insert_dbgfile(inpfname); /* attach to debug information */
|
||||||
setfiledirect(inpfname);
|
insert_inputfile(inpfname); /* save for the error system */
|
||||||
listline=-1; /* force a #line directive when changing the file */
|
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);
|
sc_is_utf8=(short)scan_utf8(inpf,name);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -281,6 +284,7 @@ static void readline(unsigned char *line)
|
|||||||
{
|
{
|
||||||
int i,num,cont;
|
int i,num,cont;
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
|
symbol *sym;
|
||||||
|
|
||||||
if (lptr==term_expr)
|
if (lptr==term_expr)
|
||||||
return;
|
return;
|
||||||
@ -319,6 +323,7 @@ static void readline(unsigned char *line)
|
|||||||
inpf=(FILE *)POPSTK_P();
|
inpf=(FILE *)POPSTK_P();
|
||||||
insert_dbgfile(inpfname);
|
insert_dbgfile(inpfname);
|
||||||
setfiledirect(inpfname);
|
setfiledirect(inpfname);
|
||||||
|
assert(sc_status==statFIRST || strcmp(get_inputfile(fcurrent),inpfname)==0);
|
||||||
listline=-1; /* force a #line directive when changing the file */
|
listline=-1; /* force a #line directive when changing the file */
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
@ -358,6 +363,9 @@ static void readline(unsigned char *line)
|
|||||||
line+=strlen((char*)line);
|
line+=strlen((char*)line);
|
||||||
} /* if */
|
} /* if */
|
||||||
fline+=1;
|
fline+=1;
|
||||||
|
sym=findconst("__LINE__");
|
||||||
|
assert(sym!=NULL);
|
||||||
|
sym->addr=fline;
|
||||||
} while (num>=0 && cont);
|
} while (num>=0 && cont);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,7 +597,7 @@ static int htoi(cell *val,const unsigned char *curptr)
|
|||||||
#if defined __APPLE__
|
#if defined __APPLE__
|
||||||
static double pow10(double d)
|
static double pow10(double d)
|
||||||
{
|
{
|
||||||
return pow(10, d);
|
return pow(10, d);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -850,6 +858,7 @@ static int command(void)
|
|||||||
char *str;
|
char *str;
|
||||||
int index;
|
int index;
|
||||||
cell code_index;
|
cell code_index;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
while (*lptr<=' ' && *lptr!='\0')
|
while (*lptr<=' ' && *lptr!='\0')
|
||||||
lptr+=1;
|
lptr+=1;
|
||||||
@ -889,7 +898,7 @@ static int command(void)
|
|||||||
assert(iflevel>=0);
|
assert(iflevel>=0);
|
||||||
if (iflevel==0) {
|
if (iflevel==0) {
|
||||||
error(26); /* no matching #if */
|
error(26); /* no matching #if */
|
||||||
errorset(sRESET);
|
errorset(sRESET,0);
|
||||||
} else {
|
} else {
|
||||||
/* check for earlier #else */
|
/* check for earlier #else */
|
||||||
if ((ifstack[iflevel-1] & HANDLED_ELSE)==HANDLED_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 */
|
error(61); /* #elseif directive may not follow an #else */
|
||||||
else
|
else
|
||||||
error(60); /* multiple #else directives between #if ... #endif */
|
error(60); /* multiple #else directives between #if ... #endif */
|
||||||
errorset(sRESET);
|
errorset(sRESET,0);
|
||||||
} else {
|
} else {
|
||||||
assert(iflevel>0);
|
assert(iflevel>0);
|
||||||
/* if there has been a "parse mode" on this level, set "skip mode",
|
/* 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) {
|
if ((ifstack[iflevel-1] & PARSEMODE)==PARSEMODE) {
|
||||||
/* there has been a parse mode already on this level, so skip the rest */
|
/* there has been a parse mode already on this level, so skip the rest */
|
||||||
ifstack[iflevel-1] |= (char)SKIPMODE;
|
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 {
|
} else {
|
||||||
/* previous conditions were all FALSE */
|
/* previous conditions were all FALSE */
|
||||||
if (tok==tpELSEIF) {
|
if (tok==tpELSEIF) {
|
||||||
/* get new expression */
|
/* if we were already skipping this section, allow expressions with
|
||||||
preproc_expr(&val,NULL); /* get value (or 0 on error) */
|
* 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);
|
ifstack[iflevel-1]=(char)(val ? PARSEMODE : SKIPMODE);
|
||||||
} else {
|
} else {
|
||||||
/* a simple #else, clear skip mode */
|
/* a simple #else, clear skip mode */
|
||||||
@ -925,7 +950,7 @@ static int command(void)
|
|||||||
ret=CMD_IF;
|
ret=CMD_IF;
|
||||||
if (iflevel==0){
|
if (iflevel==0){
|
||||||
error(26); /* no matching "#if" */
|
error(26); /* no matching "#if" */
|
||||||
errorset(sRESET);
|
errorset(sRESET,0);
|
||||||
} else {
|
} else {
|
||||||
iflevel--;
|
iflevel--;
|
||||||
if (iflevel<skiplevel)
|
if (iflevel<skiplevel)
|
||||||
@ -1003,14 +1028,27 @@ static int command(void)
|
|||||||
error(27); /* invalid character constant */
|
error(27); /* invalid character constant */
|
||||||
sc_ctrlchar=(char)val;
|
sc_ctrlchar=(char)val;
|
||||||
} /* if */
|
} /* 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) {
|
} else if (strcmp(str,"dynamic")==0) {
|
||||||
preproc_expr(&sc_stksize,NULL);
|
preproc_expr(&sc_stksize,NULL);
|
||||||
} else if ( !strcmp(str,"library") ||
|
} else if ( !strcmp(str,"library") ||
|
||||||
!strcmp(str, "reqlib") ||
|
!strcmp(str, "reqlib") ||
|
||||||
!strcmp(str, "reqclass") ||
|
!strcmp(str, "reqclass") ||
|
||||||
!strcmp(str, "loadlib") ||
|
!strcmp(str, "loadlib") ||
|
||||||
!strcmp(str, "explib") ||
|
!strcmp(str, "explib") ||
|
||||||
!strcmp(str, "expclass") ||
|
!strcmp(str, "expclass") ||
|
||||||
!strcmp(str, "defclasslib") ) {
|
!strcmp(str, "defclasslib") ) {
|
||||||
char name[sNAMEMAX+1],sname[sNAMEMAX+1];
|
char name[sNAMEMAX+1],sname[sNAMEMAX+1];
|
||||||
const char *prefix = "";
|
const char *prefix = "";
|
||||||
@ -1050,7 +1088,7 @@ static int command(void)
|
|||||||
} else {
|
} else {
|
||||||
sname[0] = '_';
|
sname[0] = '_';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* if */
|
} /* if */
|
||||||
if (strlen(name)==0) {
|
if (strlen(name)==0) {
|
||||||
curlibrary=NULL;
|
curlibrary=NULL;
|
||||||
@ -1060,20 +1098,20 @@ static int command(void)
|
|||||||
/* add the name if it does not yet exist in the table */
|
/* add the name if it does not yet exist in the table */
|
||||||
char newname[sNAMEMAX+1];
|
char newname[sNAMEMAX+1];
|
||||||
if (strlen(name) + strlen(prefix) + strlen(sname) <= sNAMEMAX)
|
if (strlen(name) + strlen(prefix) + strlen(sname) <= sNAMEMAX)
|
||||||
{
|
{
|
||||||
strcpy(newname, prefix);
|
strcpy(newname, prefix);
|
||||||
strcat(newname, name);
|
strcat(newname, name);
|
||||||
strcat(newname, sname);
|
strcat(newname, sname);
|
||||||
if (newname[0] != '?')
|
if (newname[0] != '?')
|
||||||
{
|
{
|
||||||
if (find_constval(&libname_tab,newname,0)==NULL)
|
if (find_constval(&libname_tab,newname,0)==NULL)
|
||||||
{
|
{
|
||||||
curlibrary=append_constval(&libname_tab,newname,0,0);
|
curlibrary=append_constval(&libname_tab,newname,0,0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exporttag(pc_addtag(newname));
|
exporttag(pc_addtag(newname));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* if */
|
} /* if */
|
||||||
} else if (strcmp(str,"pack")==0) {
|
} else if (strcmp(str,"pack")==0) {
|
||||||
cell val;
|
cell val;
|
||||||
@ -1117,7 +1155,8 @@ static int command(void)
|
|||||||
} else if (strcmp(str,"tabsize")==0) {
|
} else if (strcmp(str,"tabsize")==0) {
|
||||||
cell val;
|
cell val;
|
||||||
preproc_expr(&val,NULL);
|
preproc_expr(&val,NULL);
|
||||||
sc_tabsize=(int)val;
|
if (val>0)
|
||||||
|
sc_tabsize=(int)val;
|
||||||
} else if (strcmp(str,"align")==0) {
|
} else if (strcmp(str,"align")==0) {
|
||||||
sc_alignnext=TRUE;
|
sc_alignnext=TRUE;
|
||||||
} else if (strcmp(str,"unused")==0) {
|
} else if (strcmp(str,"unused")==0) {
|
||||||
@ -1251,7 +1290,7 @@ static int command(void)
|
|||||||
} /* while */
|
} /* while */
|
||||||
end=lptr;
|
end=lptr;
|
||||||
/* check pattern to match */
|
/* check pattern to match */
|
||||||
if (!isalpha(*start) && *start!='_') {
|
if (!alpha(*start)) {
|
||||||
error(74); /* pattern must start with an alphabetic character */
|
error(74); /* pattern must start with an alphabetic character */
|
||||||
break;
|
break;
|
||||||
} /* if */
|
} /* if */
|
||||||
@ -1302,7 +1341,7 @@ static int command(void)
|
|||||||
} /* while */
|
} /* while */
|
||||||
substitution[count]='\0';
|
substitution[count]='\0';
|
||||||
/* check whether the definition already exists */
|
/* 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 */;
|
/* nothing */;
|
||||||
assert(prefixlen>0);
|
assert(prefixlen>0);
|
||||||
if ((def=find_subst(pattern,prefixlen))!=NULL) {
|
if ((def=find_subst(pattern,prefixlen))!=NULL) {
|
||||||
@ -1333,7 +1372,7 @@ static int command(void)
|
|||||||
case tpERROR:
|
case tpERROR:
|
||||||
while (*lptr<=' ' && *lptr!='\0')
|
while (*lptr<=' ' && *lptr!='\0')
|
||||||
lptr++;
|
lptr++;
|
||||||
if (!SKIPPING)
|
if (!SKIPPING)
|
||||||
error(111,lptr); /* user error */
|
error(111,lptr); /* user error */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1412,7 +1451,7 @@ static const unsigned char *skippgroup(const unsigned char *string)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
close='\0'; /* only to avoid a compiler warning */
|
close='\0'; /* only to avoid a compiler warning */
|
||||||
}/* switch */
|
}/* switch */
|
||||||
|
|
||||||
string++;
|
string++;
|
||||||
@ -1458,7 +1497,7 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
|
|||||||
memset(args,0,sizeof args);
|
memset(args,0,sizeof args);
|
||||||
|
|
||||||
/* check the length of the prefix */
|
/* 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 */;
|
/* nothing */;
|
||||||
assert(prefixlen>0);
|
assert(prefixlen>0);
|
||||||
assert(strncmp((char*)line,pattern,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) */
|
/* store the parameter (overrule any earlier) */
|
||||||
if (args[arg]!=NULL)
|
if (args[arg]!=NULL)
|
||||||
free(args[arg]);
|
free(args[arg]);
|
||||||
else
|
else
|
||||||
argsnum++;
|
argsnum++;
|
||||||
len=(int)(e-s);
|
len=(int)(e-s);
|
||||||
args[arg]=(unsigned char*)malloc(len+1);
|
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),
|
/* find the start of a prefix (skip all non-alphabetic characters),
|
||||||
* also skip strings
|
* also skip strings
|
||||||
*/
|
*/
|
||||||
while (!isalpha(*start) && *start!='_' && *start!='\0') {
|
while (!alpha(*start) && *start!='\0') {
|
||||||
/* skip strings */
|
/* skip strings */
|
||||||
if (is_startstring(start)) {
|
if (is_startstring(start)) {
|
||||||
start=(unsigned char *)skipstring(start);
|
start=(unsigned char *)skipstring(start);
|
||||||
@ -1636,7 +1675,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
|
|||||||
while ((*start<=' ' && *start!='\0') || *start=='(')
|
while ((*start<=' ' && *start!='\0') || *start=='(')
|
||||||
start++;
|
start++;
|
||||||
/* skip the symbol behind it */
|
/* skip the symbol behind it */
|
||||||
while (isalpha(*start) || isdigit(*start) || *start=='_')
|
while (alphanum(*start))
|
||||||
start++;
|
start++;
|
||||||
/* drop back into the main loop */
|
/* drop back into the main loop */
|
||||||
continue;
|
continue;
|
||||||
@ -1644,7 +1683,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
|
|||||||
/* get the prefix (length), look for a matching definition */
|
/* get the prefix (length), look for a matching definition */
|
||||||
prefixlen=0;
|
prefixlen=0;
|
||||||
end=start;
|
end=start;
|
||||||
while (isalpha(*end) || isdigit(*end) || *end=='_') {
|
while (alphanum(*end)) {
|
||||||
prefixlen++;
|
prefixlen++;
|
||||||
end++;
|
end++;
|
||||||
} /* while */
|
} /* while */
|
||||||
@ -1688,7 +1727,7 @@ SC_FUNC void preprocess(void)
|
|||||||
lptr=pline; /* set "line pointer" to start of the parsing buffer */
|
lptr=pline; /* set "line pointer" to start of the parsing buffer */
|
||||||
iscommand=command();
|
iscommand=command();
|
||||||
if (iscommand!=CMD_NONE)
|
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 !defined NO_DEFINE
|
||||||
if (iscommand==CMD_NONE) {
|
if (iscommand==CMD_NONE) {
|
||||||
assert(lptr!=term_expr);
|
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 */
|
while (i<=tLAST) { /* match reserved words and compiler directives */
|
||||||
if (*lptr==**tokptr && match(*tokptr,TRUE)) {
|
if (*lptr==**tokptr && match(*tokptr,TRUE)) {
|
||||||
_lextok=i;
|
_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 */
|
if (pc_docexpr) /* optionally concatenate to documentation string */
|
||||||
insert_autolist(*tokptr);
|
insert_autolist(*tokptr);
|
||||||
return _lextok;
|
return _lextok;
|
||||||
@ -1974,7 +2013,7 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
|
|||||||
} else if (*lptr==';') { /* semicolumn resets "error" flag */
|
} else if (*lptr==';') { /* semicolumn resets "error" flag */
|
||||||
_lextok=';';
|
_lextok=';';
|
||||||
lptr+=1;
|
lptr+=1;
|
||||||
errorset(sRESET); /* reset error flag (clear the "panic mode")*/
|
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
|
||||||
} else {
|
} else {
|
||||||
_lextok=*lptr; /* if every match fails, return the character */
|
_lextok=*lptr; /* if every match fails, return the character */
|
||||||
lptr+=1; /* increase the "lptr" pointer */
|
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)
|
static symbol *add_symbol(symbol *root,symbol *entry,int sort)
|
||||||
{
|
{
|
||||||
symbol *newsym;
|
symbol *newsym;
|
||||||
|
int global = root==&glbtab;
|
||||||
|
|
||||||
if (sort)
|
if (sort)
|
||||||
while (root->next!=NULL && strcmp(entry->name,root->next->name)>0)
|
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));
|
memcpy(newsym,entry,sizeof(symbol));
|
||||||
newsym->next=root->next;
|
newsym->next=root->next;
|
||||||
root->next=newsym;
|
root->next=newsym;
|
||||||
|
if (global)
|
||||||
|
AddToHashTable(sp_Globals, newsym);
|
||||||
return newsym;
|
return newsym;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2388,6 +2430,7 @@ static void free_symbol(symbol *sym)
|
|||||||
|
|
||||||
SC_FUNC void delete_symbol(symbol *root,symbol *sym)
|
SC_FUNC void delete_symbol(symbol *root,symbol *sym)
|
||||||
{
|
{
|
||||||
|
symbol *origRoot = root;
|
||||||
/* find the symbol and its predecessor
|
/* find the symbol and its predecessor
|
||||||
* (this function assumes that you will never delete a symbol that is not
|
* (this function assumes that you will never delete a symbol that is not
|
||||||
* in the table pointed at by "root")
|
* in the table pointed at by "root")
|
||||||
@ -2398,13 +2441,27 @@ SC_FUNC void delete_symbol(symbol *root,symbol *sym)
|
|||||||
assert(root!=NULL);
|
assert(root!=NULL);
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
if (origRoot==&glbtab)
|
||||||
|
RemoveFromHashTable(sp_Globals, sym);
|
||||||
|
|
||||||
/* unlink it, then free it */
|
/* unlink it, then free it */
|
||||||
root->next=sym->next;
|
root->next=sym->next;
|
||||||
free_symbol(sym);
|
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)
|
SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_functions)
|
||||||
{
|
{
|
||||||
|
symbol *origRoot=root;
|
||||||
symbol *sym,*parent_sym;
|
symbol *sym,*parent_sym;
|
||||||
constvalue *stateptr;
|
constvalue *stateptr;
|
||||||
int mustdelete=0;
|
int mustdelete=0;
|
||||||
@ -2413,7 +2470,7 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
|
|||||||
* specified nesting level */
|
* specified nesting level */
|
||||||
while (root->next!=NULL) {
|
while (root->next!=NULL) {
|
||||||
sym=root->next;
|
sym=root->next;
|
||||||
if (sym->compound<level)
|
if (get_actual_compound(sym)<level)
|
||||||
break;
|
break;
|
||||||
switch (sym->ident) {
|
switch (sym->ident) {
|
||||||
case iLABEL:
|
case iLABEL:
|
||||||
@ -2458,6 +2515,8 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
|
|||||||
break;
|
break;
|
||||||
} /* switch */
|
} /* switch */
|
||||||
if (mustdelete) {
|
if (mustdelete) {
|
||||||
|
if (origRoot == &glbtab)
|
||||||
|
RemoveFromHashTable(sp_Globals, sym);
|
||||||
root->next=sym->next;
|
root->next=sym->next;
|
||||||
free_symbol(sym);
|
free_symbol(sym);
|
||||||
} else {
|
} 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
|
/* for user defined operators, also remove the "prototyped" flag, as
|
||||||
* user-defined operators *must* be declared before use
|
* 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;
|
sym->usage &= ~uPROTOTYPED;
|
||||||
root=sym; /* skip the symbol */
|
root=sym; /* skip the symbol */
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* 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)
|
static symbol *find_symbol(const symbol *root,const char *name,int fnumber,int includechildren)
|
||||||
{
|
{
|
||||||
symbol *ptr=root->next;
|
symbol *ptr=root->next;
|
||||||
unsigned long hash=namehash(name);
|
unsigned long hash=NameHash(name);
|
||||||
while (ptr!=NULL) {
|
while (ptr!=NULL) {
|
||||||
if (hash==ptr->hash && strcmp(name,ptr->name)==0
|
if (hash==ptr->hash && strcmp(name,ptr->name)==0
|
||||||
&& (ptr->parent==NULL || includechildren)
|
&& (ptr->parent==NULL || includechildren)
|
||||||
&& (fnumber<0 || (ptr->fnumber<0 || ptr->fnumber==fnumber)))
|
&& (fnumber<0 || (ptr->fnumber<0 || ptr->fnumber==fnumber)))
|
||||||
return ptr;
|
return ptr;
|
||||||
ptr=ptr->next;
|
ptr=ptr->next;
|
||||||
} /* while */
|
} /* while */
|
||||||
@ -2569,7 +2614,10 @@ SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom)
|
|||||||
|
|
||||||
SC_FUNC void markusage(symbol *sym,int usage)
|
SC_FUNC void markusage(symbol *sym,int usage)
|
||||||
{
|
{
|
||||||
|
assert(sym!=NULL);
|
||||||
sym->usage |= (char)usage;
|
sym->usage |= (char)usage;
|
||||||
|
if ((usage & uWRITTEN) != 0)
|
||||||
|
sym->lnumber=fline;
|
||||||
/* check if (global) reference must be added to the symbol */
|
/* check if (global) reference must be added to the symbol */
|
||||||
if ((usage & (uREAD | uWRITTEN))!=0) {
|
if ((usage & (uREAD | uWRITTEN))!=0) {
|
||||||
/* only do this for global symbols */
|
/* 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 */
|
sym=find_symbol(&loctab,name,-1,TRUE); /* try local symbols first */
|
||||||
if (sym==NULL || sym->ident!=iCONSTEXPR) /* not found, or not a constant */
|
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)
|
if (sym==NULL || sym->ident!=iCONSTEXPR)
|
||||||
return NULL;
|
return NULL;
|
||||||
assert(sym->parent==NULL || (sym->usage & uENUMFIELD)!=0);
|
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 */
|
/* first fill in the entry */
|
||||||
strcpy(entry.name,name);
|
strcpy(entry.name,name);
|
||||||
entry.hash=namehash(name);
|
entry.hash=NameHash(name);
|
||||||
entry.addr=addr;
|
entry.addr=addr;
|
||||||
entry.codeaddr=code_idx;
|
entry.codeaddr=code_idx;
|
||||||
entry.vclass=(char)vclass;
|
entry.vclass=(char)vclass;
|
||||||
entry.ident=(char)ident;
|
entry.ident=(char)ident;
|
||||||
entry.tag=tag;
|
entry.tag=tag;
|
||||||
entry.usage=(char)usage;
|
entry.usage=(char)usage;
|
||||||
|
entry.flags=0;
|
||||||
entry.compound=0; /* may be overridden later */
|
entry.compound=0; /* may be overridden later */
|
||||||
entry.states=NULL;
|
entry.states=NULL;
|
||||||
entry.fnumber=-1; /* assume global visibility (ignored for local symbols) */
|
entry.fnumber=-1; /* assume global visibility (ignored for local symbols) */
|
||||||
|
entry.lnumber=fline;
|
||||||
entry.numrefers=1;
|
entry.numrefers=1;
|
||||||
entry.refer=refer;
|
entry.refer=refer;
|
||||||
entry.parent=NULL;
|
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 */
|
/* then insert it in the list */
|
||||||
if (vclass==sGLOBAL)
|
if (vclass==sGLOBAL)
|
||||||
return add_symbol(&glbtab,&entry,TRUE);
|
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,
|
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.
|
* this special case.
|
||||||
*/
|
*/
|
||||||
assert(vclass!=sGLOBAL || (sym=findglb(name))==NULL || (sym->usage & uDEFINE)==0
|
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) {
|
if (ident==iARRAY || ident==iREFARRAY) {
|
||||||
symbol *parent=NULL,*top;
|
symbol *parent=NULL,*top;
|
||||||
|
@ -288,8 +288,7 @@ SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce)
|
|||||||
* tag is "coerced" to zero
|
* tag is "coerced" to zero
|
||||||
*/
|
*/
|
||||||
if (!allowcoerce || formaltag!=0 || (actualtag & FIXEDTAG)!=0)
|
if (!allowcoerce || formaltag!=0 || (actualtag & FIXEDTAG)!=0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
} /* if */
|
} /* if */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -488,6 +487,7 @@ static int plnge_rel(int *opstr,int opoff,int (*hier)(value *lval),value *lval)
|
|||||||
int lvalue,opidx;
|
int lvalue,opidx;
|
||||||
value lval2 = {0}; /* intialize, to avoid a compiler warning */
|
value lval2 = {0}; /* intialize, to avoid a compiler warning */
|
||||||
int count;
|
int count;
|
||||||
|
char boolresult;
|
||||||
|
|
||||||
/* this function should only be called for relational operators */
|
/* this function should only be called for relational operators */
|
||||||
assert(op1[opoff]==os_le);
|
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);
|
error(212);
|
||||||
if (count>0) {
|
if (count>0) {
|
||||||
relop_prefix();
|
relop_prefix();
|
||||||
|
boolresult = lval->boolresult;
|
||||||
*lval=lval2; /* copy right hand expression of the previous iteration */
|
*lval=lval2; /* copy right hand expression of the previous iteration */
|
||||||
|
lval->boolresult = boolresult;
|
||||||
} /* if */
|
} /* if */
|
||||||
opidx+=opoff;
|
opidx+=opoff;
|
||||||
plnge2(op1[opidx],hier,lval,&lval2);
|
plnge2(op1[opidx],hier,lval,&lval2);
|
||||||
@ -1037,13 +1039,13 @@ static int hier13(value *lval)
|
|||||||
lval->ident=iREFARRAY; /* iARRAY becomes iREFARRAY */
|
lval->ident=iREFARRAY; /* iARRAY becomes iREFARRAY */
|
||||||
else if (lval->ident!=iREFARRAY)
|
else if (lval->ident!=iREFARRAY)
|
||||||
lval->ident=iEXPRESSION; /* iREFARRAY stays iREFARRAY, rest becomes iEXPRESSION */
|
lval->ident=iEXPRESSION; /* iREFARRAY stays iREFARRAY, rest becomes iEXPRESSION */
|
||||||
if (orig_heap!=decl_heap) {
|
if (orig_heap!=decl_heap) {
|
||||||
diff2=abs(decl_heap-orig_heap);
|
diff2=abs(decl_heap-orig_heap);
|
||||||
decl_heap=orig_heap;
|
decl_heap=orig_heap;
|
||||||
}
|
}
|
||||||
if (diff1==diff2) {
|
if (diff1==diff2) {
|
||||||
decl_heap+=(diff1/2);
|
decl_heap+=(diff1/2);
|
||||||
} else {
|
} else {
|
||||||
decl_heap+=(diff1+diff2);
|
decl_heap+=(diff1+diff2);
|
||||||
}
|
}
|
||||||
return FALSE; /* conditional expression is no lvalue */
|
return FALSE; /* conditional expression is no lvalue */
|
||||||
@ -1126,6 +1128,7 @@ static int hier2(value *lval)
|
|||||||
symbol *sym=NULL;
|
symbol *sym=NULL;
|
||||||
int saveresult;
|
int saveresult;
|
||||||
|
|
||||||
|
sym = NULL;
|
||||||
tok=lex(&val,&st);
|
tok=lex(&val,&st);
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case tINC: /* ++lval */
|
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) */
|
return error(17,st); /* undefined symbol (symbol is in the table, but it is "used" only) */
|
||||||
tag=sym->tag;
|
tag=sym->tag;
|
||||||
} /* if */
|
} /* if */
|
||||||
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
|
if (sym!=NULL && (sym->ident==iARRAY || sym->ident==iREFARRAY)) {
|
||||||
int level;
|
int level;
|
||||||
symbol *idxsym=NULL;
|
symbol *idxsym=NULL;
|
||||||
for (level=0; matchtoken('['); level++) {
|
for (level=0; matchtoken('['); level++) {
|
||||||
@ -1862,6 +1865,11 @@ static int nesting=0;
|
|||||||
assert(nest_stkusage==0);
|
assert(nest_stkusage==0);
|
||||||
#endif
|
#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 */
|
/* run through the arguments */
|
||||||
arg=sym->dim.arglist;
|
arg=sym->dim.arglist;
|
||||||
assert(arg!=NULL);
|
assert(arg!=NULL);
|
||||||
@ -2039,7 +2047,7 @@ static int nesting=0;
|
|||||||
error(47); /* array sizes must match */
|
error(47); /* array sizes must match */
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
if (lval.ident!=iARRAYCELL) {
|
if (lval.ident!=iARRAYCELL|| lval.constval>0) {
|
||||||
/* save array size, for default values with uSIZEOF flag */
|
/* save array size, for default values with uSIZEOF flag */
|
||||||
cell array_sz=lval.constval;
|
cell array_sz=lval.constval;
|
||||||
assert(array_sz!=0);/* literal array must have a size */
|
assert(array_sz!=0);/* literal array must have a size */
|
||||||
|
@ -829,7 +829,7 @@ SC_FUNC void defstorage(void)
|
|||||||
stgwrite("dump ");
|
stgwrite("dump ");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Inclrement/decrement stack pointer. Note that this routine does
|
* Inclrement/decrement stack pointer. Note that this routine does
|
||||||
* nothing if the delta is zero.
|
* nothing if the delta is zero.
|
||||||
*/
|
*/
|
||||||
|
1
compiler/libpc300/sc5.scp → compiler/libpc300/sc5-in.scp
Executable file → Normal file
1
compiler/libpc300/sc5.scp → compiler/libpc300/sc5-in.scp
Executable file → Normal file
@ -290,6 +290,7 @@ static char *warnmsg[] = {
|
|||||||
/*230*/ "no implementation for state \"%s\" / function \"%s\", no fall-back\n",
|
/*230*/ "no implementation for state \"%s\" / function \"%s\", no fall-back\n",
|
||||||
/*231*/ "state specification on forward declaration is ignored\n",
|
/*231*/ "state specification on forward declaration is ignored\n",
|
||||||
/*232*/ "output file is written, but with compact encoding disabled\n"
|
/*232*/ "output file is written, but with compact encoding disabled\n"
|
||||||
|
/*233*/ "symbol \"%s\" is marked as deprecated: %s\n",
|
||||||
#else
|
#else
|
||||||
"\345 \274tr\240\226\233\277 %\206\273\337c\367\305",
|
"\345 \274tr\240\226\233\277 %\206\273\337c\367\305",
|
||||||
"\222\323i\231\300\344\224t/\314cr\375\364",
|
"\222\323i\231\300\344\224t/\314cr\375\364",
|
@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
|
#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined LINUX || defined __APPLE__ || defined __GNUC__
|
#if defined LINUX || defined __APPLE__ || defined __GNUC__
|
||||||
@ -41,7 +41,7 @@
|
|||||||
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
|
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sc5.scp"
|
#include <sc5.scp>
|
||||||
|
|
||||||
#if defined _MSC_VER
|
#if defined _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
@ -51,7 +51,9 @@
|
|||||||
static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */
|
static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */
|
||||||
|
|
||||||
static int errflag;
|
static int errflag;
|
||||||
|
static int errfile;
|
||||||
static int errstart; /* line number at which the instruction started */
|
static int errstart; /* line number at which the instruction started */
|
||||||
|
static int errline; /* forced line number for the error message */
|
||||||
|
|
||||||
/* error
|
/* error
|
||||||
*
|
*
|
||||||
@ -70,7 +72,7 @@ SC_FUNC int error(int number,...)
|
|||||||
static char *prefix[3]={ "error", "fatal error", "warning" };
|
static char *prefix[3]={ "error", "fatal error", "warning" };
|
||||||
static int lastline,errorcount;
|
static int lastline,errorcount;
|
||||||
static short lastfile;
|
static short lastfile;
|
||||||
char *msg,*pre;
|
char *msg,*pre,*filename;
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
char string[128];
|
char string[128];
|
||||||
|
|
||||||
@ -107,11 +109,22 @@ static short lastfile;
|
|||||||
|
|
||||||
strexpand(string,(unsigned char *)msg,sizeof string,SCPACK_TABLE);
|
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);
|
va_start(argptr,number);
|
||||||
if (strlen(errfname)==0) {
|
if (strlen(errfname)==0) {
|
||||||
int start= (errstart==fline) ? -1 : errstart;
|
int start= (errstart==errline) ? -1 : errstart;
|
||||||
if (pc_error(number,string,inpfname,start,fline,argptr)) {
|
if (pc_error((int)number,string,filename,start,errline,argptr)) {
|
||||||
if (outf!=NULL) {
|
if (outf!=NULL) {
|
||||||
pc_closeasm(outf,TRUE);
|
pc_closeasm(outf,TRUE);
|
||||||
outf=NULL;
|
outf=NULL;
|
||||||
@ -121,10 +134,10 @@ static short lastfile;
|
|||||||
} else {
|
} else {
|
||||||
FILE *fp=fopen(errfname,"a");
|
FILE *fp=fopen(errfname,"a");
|
||||||
if (fp!=NULL) {
|
if (fp!=NULL) {
|
||||||
if (errstart>=0 && errstart!=fline)
|
if (errstart>=0 && errstart!=errline)
|
||||||
fprintf(fp,"%s(%d -- %d) : %s %03d: ",inpfname,errstart,fline,pre,number);
|
fprintf(fp,"%s(%d -- %d) : %s %03d: ",filename,errstart,errline,pre,number);
|
||||||
else
|
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);
|
vfprintf(fp,string,argptr);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
} /* if */
|
} /* if */
|
||||||
@ -144,6 +157,8 @@ static short lastfile;
|
|||||||
longjmp(errbuf,2); /* fatal error, quit */
|
longjmp(errbuf,2); /* fatal error, quit */
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
|
errline=-1;
|
||||||
|
errfile=-1;
|
||||||
/* check whether we are seeing many errors on the same line */
|
/* check whether we are seeing many errors on the same line */
|
||||||
if ((errstart<0 && lastline!=fline) || lastline<errstart || lastline>fline || fcurrent!=lastfile)
|
if ((errstart<0 && lastline!=fline) || lastline<errstart || lastline>fline || fcurrent!=lastfile)
|
||||||
errorcount=0;
|
errorcount=0;
|
||||||
@ -157,7 +172,7 @@ static short lastfile;
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC void errorset(int code)
|
SC_FUNC void errorset(int code,int line)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case sRESET:
|
case sRESET:
|
||||||
@ -171,6 +186,15 @@ SC_FUNC void errorset(int code)
|
|||||||
break;
|
break;
|
||||||
case sEXPRRELEASE:
|
case sEXPRRELEASE:
|
||||||
errstart=-1; /* forget start line number */
|
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;
|
break;
|
||||||
} /* switch */
|
} /* switch */
|
||||||
}
|
}
|
||||||
|
0
compiler/libpc300/sc7.scp → compiler/libpc300/sc7-in.scp
Executable file → Normal file
0
compiler/libpc300/sc7.scp → compiler/libpc300/sc7-in.scp
Executable file → Normal file
@ -51,7 +51,7 @@
|
|||||||
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
|
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sc7.scp"
|
#include <sc7.scp>
|
||||||
|
|
||||||
#if defined _MSC_VER
|
#if defined _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
@ -255,16 +255,16 @@ SC_FUNC void delete_pathtable(void)
|
|||||||
|
|
||||||
static stringpair substpair = { NULL, NULL, NULL}; /* list of substitution pairs */
|
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)
|
static void adjustindex(char c)
|
||||||
{
|
{
|
||||||
stringpair *cur;
|
stringpair *cur;
|
||||||
assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_');
|
assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_' || c==PUBLIC_CHAR);
|
||||||
assert('A'<'_' && '_'<'z');
|
assert(PUBLIC_CHAR<'A' && 'A'<'_' && '_'<'z');
|
||||||
|
|
||||||
for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next)
|
for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next)
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
substindex[(int)c-'A']=cur;
|
substindex[(int)c-PUBLIC_CHAR]=cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen)
|
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)
|
if ((cur=insert_stringpair(&substpair,pattern,substitution,prefixlen))==NULL)
|
||||||
error(103); /* insufficient memory (fatal error) */
|
error(103); /* insufficient memory (fatal error) */
|
||||||
adjustindex(*pattern);
|
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;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,10 +304,26 @@ SC_FUNC stringpair *find_subst(char *name,int length)
|
|||||||
stringpair *item;
|
stringpair *item;
|
||||||
assert(name!=NULL);
|
assert(name!=NULL);
|
||||||
assert(length>0);
|
assert(length>0);
|
||||||
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_');
|
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
|
||||||
item=substindex[(int)*name-'A'];
|
item=substindex[(int)*name-PUBLIC_CHAR];
|
||||||
if (item!=NULL)
|
if (item!=NULL)
|
||||||
item=find_stringpair(item,name,length);
|
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;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,8 +332,8 @@ SC_FUNC int delete_subst(char *name,int length)
|
|||||||
stringpair *item;
|
stringpair *item;
|
||||||
assert(name!=NULL);
|
assert(name!=NULL);
|
||||||
assert(length>0);
|
assert(length>0);
|
||||||
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_');
|
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
|
||||||
item=substindex[(int)*name-'A'];
|
item=substindex[(int)*name-PUBLIC_CHAR];
|
||||||
if (item!=NULL)
|
if (item!=NULL)
|
||||||
item=find_stringpair(item,name,length);
|
item=find_stringpair(item,name,length);
|
||||||
if (item==NULL)
|
if (item==NULL)
|
||||||
@ -318,7 +354,7 @@ SC_FUNC void delete_substtable(void)
|
|||||||
#endif /* !defined NO_SUBST */
|
#endif /* !defined NO_SUBST */
|
||||||
|
|
||||||
|
|
||||||
/* ----- input file list ----------------------------------------- */
|
/* ----- input file list (explicit files)------------------------- */
|
||||||
static stringlist sourcefiles = {NULL, NULL};
|
static stringlist sourcefiles = {NULL, NULL};
|
||||||
|
|
||||||
SC_FUNC stringlist *insert_sourcefile(char *string)
|
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 -------------------------------------- */
|
/* ----- documentation tags -------------------------------------- */
|
||||||
#if !defined SC_LIGHT
|
#if !defined SC_LIGHT
|
||||||
static stringlist docstrings = {NULL, NULL};
|
static stringlist docstrings = {NULL, NULL};
|
||||||
@ -415,9 +473,9 @@ SC_FUNC stringlist *insert_dbgline(int linenr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define LONGCAST long
|
#define LONGCAST long
|
||||||
#else
|
#else
|
||||||
#define LONGCAST cell
|
#define LONGCAST cell
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
|
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) {
|
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
|
||||||
symbol *sub;
|
symbol *sub;
|
||||||
#if !defined NDEBUG
|
#if !defined NDEBUG
|
||||||
count = sym->dim.array.level;
|
count = sym->dim.array.level;
|
||||||
#endif
|
#endif
|
||||||
strcat(string," [ ");
|
strcat(string," [ ");
|
||||||
for (sub=sym; sub!=NULL; sub=finddepend(sub)) {
|
for (sub=sym; sub!=NULL; sub=finddepend(sub)) {
|
||||||
|
450
compiler/libpc300/scpack.c
Normal file
450
compiler/libpc300/scpack.c
Normal 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;
|
||||||
|
}
|
@ -24,6 +24,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h> /* for _MAX_PATH */
|
#include <stdlib.h> /* for _MAX_PATH */
|
||||||
#include "sc.h"
|
#include "sc.h"
|
||||||
|
#include "sp_symhash.h"
|
||||||
|
|
||||||
/* global variables
|
/* 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 rational_digits=0; /* number of fractional digits */
|
||||||
SC_VDEFINE int sc_allowproccall=0; /* allow/detect tagnames in lex() */
|
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 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 int sc_showincludes=0; /* show include files */
|
||||||
|
|
||||||
SC_VDEFINE constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */
|
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 jmp_buf errbuf;
|
||||||
|
|
||||||
|
SC_VDEFINE HashTable *sp_Globals = NULL;
|
||||||
|
|
||||||
#if !defined SC_LIGHT
|
#if !defined SC_LIGHT
|
||||||
SC_VDEFINE int sc_makereport=FALSE; /* generate a cross-reference report */
|
SC_VDEFINE int sc_makereport=FALSE; /* generate a cross-reference report */
|
||||||
#endif
|
#endif
|
||||||
|
229
compiler/libpc300/sp_symhash.c
Normal file
229
compiler/libpc300/sp_symhash.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
28
compiler/libpc300/sp_symhash.h
Normal file
28
compiler/libpc300/sp_symhash.h
Normal 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_ */
|
||||||
|
|
@ -2535,6 +2535,7 @@ native plugin_flags(hdr=0, plid=-1);
|
|||||||
*
|
*
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
|
#pragma deprecated Module dependency is now automatically handled by the compiler. This forward is no longer called.
|
||||||
forward plugin_modules();
|
forward plugin_modules();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2545,6 +2546,7 @@ forward plugin_modules();
|
|||||||
*
|
*
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
|
#pragma deprecated Module dependency is now automatically handled by the compiler. This native has no effect.
|
||||||
native require_module(const module[]);
|
native require_module(const module[]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2556,6 +2558,7 @@ native require_module(const module[]);
|
|||||||
*
|
*
|
||||||
* @return 1 if the server is 64 bit, 0 otherwise
|
* @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();
|
native is_amd64_server();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +62,7 @@ native bool:geoip_code3_ex(const ip[], result[4]);
|
|||||||
*
|
*
|
||||||
* @return 1 on a successful lookup, 0 otherwise.
|
* @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]);
|
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.
|
* @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]);
|
native geoip_code3(const ip[], result[4]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -543,6 +543,7 @@ forward client_spawn(id);
|
|||||||
* @param Damage The amount of damage being done.
|
* @param Damage The amount of damage being done.
|
||||||
* @param DamageType The damage type being done (bitmask).
|
* @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);
|
native ns_takedamage(IDVictim, IDInflictor, IDAttacker, Float:Damage, DamageType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -711,7 +711,7 @@ native strncmp(const string1[], const string2[], num, bool:ignorecase=false);
|
|||||||
* Backwards compatibility stock - use argbreak or argparse.
|
* Backwards compatibility stock - use argbreak or argparse.
|
||||||
* @deprecated this function does not work properly.
|
* @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)
|
stock strbreak(const text[], Left[], leftLen, Right[], rightLen)
|
||||||
{
|
{
|
||||||
return argbreak(text, Left, leftLen, Right, rightLen);
|
return argbreak(text, Left, leftLen, Right, rightLen);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include <amxmodx>
|
#include <amxmodx>
|
||||||
#include <amxmisc>
|
#include <amxmisc>
|
||||||
|
|
||||||
#pragma tabsize 0
|
#pragma tabsize 4
|
||||||
|
|
||||||
new g_TeamOneAck[12];
|
new g_TeamOneAck[12];
|
||||||
new g_TeamTwoAck[12];
|
new g_TeamTwoAck[12];
|
||||||
|
Loading…
Reference in New Issue
Block a user