whoa svn is hard, sente will implode now
--HG-- branch : faluco extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/faluco%407
This commit is contained in:
parent
8064f22b72
commit
5ebf4942b4
462
compiler-init/amx.h
Normal file
462
compiler-init/amx.h
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
/* Pawn Abstract Machine (for the Pawn language)
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 1997-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: amx.h 3579 2006-06-06 13:35:29Z thiadmer $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AMX_H_INCLUDED
|
||||||
|
#define AMX_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stdlib.h> /* for size_t */
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#if defined FREEBSD && !defined __FreeBSD__
|
||||||
|
#define __FreeBSD__
|
||||||
|
#endif
|
||||||
|
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
|
#include <sclinux.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_STDINT_H
|
||||||
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#if defined __LCC__ || defined __DMC__ || defined LINUX || (defined __WATCOMC__ && __WATCOMC__ >= 1200)
|
||||||
|
#if defined HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||||
|
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||||
|
* here, these types are probably undefined.
|
||||||
|
*/
|
||||||
|
#if defined __MACH__
|
||||||
|
#include <ppc/types.h>
|
||||||
|
typedef unsigned short int uint16_t;
|
||||||
|
typedef unsigned long int uint32_t;
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
#include <inttypes.h>
|
||||||
|
#else
|
||||||
|
typedef short int int16_t;
|
||||||
|
typedef unsigned short int uint16_t;
|
||||||
|
#if defined SN_TARGET_PS2
|
||||||
|
typedef int int32_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
#else
|
||||||
|
typedef long int int32_t;
|
||||||
|
typedef unsigned long int uint32_t;
|
||||||
|
#endif
|
||||||
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||||
|
typedef __int64 int64_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
#define HAVE_I64
|
||||||
|
#elif defined __GNUC__
|
||||||
|
typedef long long int64_t;
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
#define HAVE_I64
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#define HAVE_STDINT_H
|
||||||
|
#endif
|
||||||
|
#if defined _LP64 || defined WIN64 || defined _WIN64
|
||||||
|
#if !defined __64BIT__
|
||||||
|
#define __64BIT__
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_ALLOCA_H
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||||
|
#if !defined alloca
|
||||||
|
#define alloca(n) _alloca(n)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined arraysize
|
||||||
|
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
||||||
|
#endif
|
||||||
|
#if !defined assert_static
|
||||||
|
/* see "Compile-Time Assertions" by Ralf Holly,
|
||||||
|
* C/C++ Users Journal, November 2004
|
||||||
|
*/
|
||||||
|
#define assert_static(e) \
|
||||||
|
do { \
|
||||||
|
enum { assert_static__ = 1/(e) }; \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined PAWN_DLL
|
||||||
|
#if !defined AMX_NATIVE_CALL
|
||||||
|
#define AMX_NATIVE_CALL __stdcall
|
||||||
|
#endif
|
||||||
|
#if !defined AMXAPI
|
||||||
|
#define AMXAPI __stdcall
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* calling convention for native functions */
|
||||||
|
#if !defined AMX_NATIVE_CALL
|
||||||
|
#define AMX_NATIVE_CALL
|
||||||
|
#endif
|
||||||
|
/* calling convention for all interface functions and callback functions */
|
||||||
|
#if !defined AMXAPI
|
||||||
|
#if defined STDECL
|
||||||
|
#define AMXAPI __stdcall
|
||||||
|
#elif defined CDECL
|
||||||
|
#define AMXAPI __cdecl
|
||||||
|
#elif defined GCC_HASCLASSVISIBILITY
|
||||||
|
#define AMXAPI __attribute__ ((visibility("default")))
|
||||||
|
#else
|
||||||
|
#define AMXAPI
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if !defined AMXEXPORT
|
||||||
|
#define AMXEXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* File format version (in CUR_FILE_VERSION)
|
||||||
|
* 0 (original version)
|
||||||
|
* 1 (opcodes JUMP.pri, SWITCH and CASETBL)
|
||||||
|
* 2 (compressed files)
|
||||||
|
* 3 (public variables)
|
||||||
|
* 4 (opcodes SWAP.pri/alt and PUSHADDR)
|
||||||
|
* 5 (tagnames table)
|
||||||
|
* 6 (reformatted header)
|
||||||
|
* 7 (name table, opcodes SYMTAG & SYSREQ.D)
|
||||||
|
* 8 (opcode STMT, renewed debug interface)
|
||||||
|
* 9 (macro opcodes)
|
||||||
|
* MIN_FILE_VERSION is the lowest file version number that the current AMX
|
||||||
|
* implementation supports. If the AMX file header gets new fields, this number
|
||||||
|
* often needs to be incremented. MAX_AMX_VERSION is the lowest AMX version that
|
||||||
|
* is needed to support the current file version. When there are new opcodes,
|
||||||
|
* this number needs to be incremented.
|
||||||
|
* The file version supported by the JIT may run behind MIN_AMX_VERSION. So
|
||||||
|
* there is an extra constant for it: MAX_FILE_VER_JIT.
|
||||||
|
*/
|
||||||
|
#define CUR_FILE_VERSION 9 /* current file version; also the current AMX version */
|
||||||
|
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
|
||||||
|
#define MIN_AMX_VERSION 9 /* minimum AMX version needed to support the current file format */
|
||||||
|
#define MAX_FILE_VER_JIT 8 /* file version supported by the JIT */
|
||||||
|
#define MIN_AMX_VER_JIT 8 /* AMX version supported by the JIT */
|
||||||
|
|
||||||
|
#if !defined PAWN_CELL_SIZE
|
||||||
|
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||||
|
#endif
|
||||||
|
#if PAWN_CELL_SIZE==16
|
||||||
|
typedef uint16_t ucell;
|
||||||
|
typedef int16_t cell;
|
||||||
|
#elif PAWN_CELL_SIZE==32
|
||||||
|
typedef uint32_t ucell;
|
||||||
|
typedef int32_t cell;
|
||||||
|
#elif PAWN_CELL_SIZE==64
|
||||||
|
typedef uint64_t ucell;
|
||||||
|
typedef int64_t cell;
|
||||||
|
#else
|
||||||
|
#error Unsupported cell size (PAWN_CELL_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UNPACKEDMAX (((cell)1 << (sizeof(cell)-1)*8) - 1)
|
||||||
|
#define UNLIMITED (~1u >> 1)
|
||||||
|
|
||||||
|
struct tagAMX;
|
||||||
|
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
||||||
|
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
||||||
|
cell *result, cell *params);
|
||||||
|
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||||
|
typedef int (AMXAPI *AMX_IDLE)(struct tagAMX *amx, int AMXAPI Exec(struct tagAMX *, cell *, int));
|
||||||
|
#if !defined _FAR
|
||||||
|
#define _FAR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
||||||
|
* about pragma pack in a header file */
|
||||||
|
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||||
|
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||||
|
*/
|
||||||
|
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
|
||||||
|
#define AMX_NO_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __GNUC__
|
||||||
|
#define PACKED __attribute__((packed))
|
||||||
|
#else
|
||||||
|
#define PACKED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined AMX_NO_ALIGN
|
||||||
|
#if defined LINUX || defined __FreeBSD__
|
||||||
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
|
#elif defined MACOS && defined __MWERKS__
|
||||||
|
#pragma options align=mac68k
|
||||||
|
#else
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
|
#if defined __TURBOC__
|
||||||
|
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct tagAMX_NATIVE_INFO {
|
||||||
|
const char _FAR *name PACKED;
|
||||||
|
AMX_NATIVE func PACKED;
|
||||||
|
} AMX_NATIVE_INFO;
|
||||||
|
|
||||||
|
#define AMX_USERNUM 4
|
||||||
|
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
||||||
|
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
||||||
|
|
||||||
|
typedef struct tagAMX_FUNCSTUB {
|
||||||
|
ucell address PACKED;
|
||||||
|
char name[sEXPMAX+1] PACKED;
|
||||||
|
} AMX_FUNCSTUB;
|
||||||
|
|
||||||
|
typedef struct tagFUNCSTUBNT {
|
||||||
|
ucell address PACKED;
|
||||||
|
uint32_t nameofs PACKED;
|
||||||
|
} AMX_FUNCSTUBNT;
|
||||||
|
|
||||||
|
/* The AMX structure is the internal structure for many functions. Not all
|
||||||
|
* fields are valid at all times; many fields are cached in local variables.
|
||||||
|
*/
|
||||||
|
typedef struct tagAMX {
|
||||||
|
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
||||||
|
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
||||||
|
AMX_CALLBACK callback PACKED;
|
||||||
|
AMX_DEBUG debug PACKED; /* debug callback */
|
||||||
|
/* for external functions a few registers must be accessible from the outside */
|
||||||
|
cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */
|
||||||
|
cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */
|
||||||
|
cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */
|
||||||
|
cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */
|
||||||
|
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
||||||
|
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||||
|
int flags PACKED; /* current status, see amx_Flags() */
|
||||||
|
/* user data */
|
||||||
|
long usertags[AMX_USERNUM] PACKED;
|
||||||
|
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||||
|
/* native functions can raise an error */
|
||||||
|
int error PACKED;
|
||||||
|
/* passing parameters requires a "count" field */
|
||||||
|
int paramcount;
|
||||||
|
/* the sleep opcode needs to store the full AMX status */
|
||||||
|
cell pri PACKED;
|
||||||
|
cell alt PACKED;
|
||||||
|
cell reset_stk PACKED;
|
||||||
|
cell reset_hea PACKED;
|
||||||
|
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
||||||
|
#if defined JIT
|
||||||
|
/* support variables for the JIT */
|
||||||
|
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||||
|
long code_size PACKED; /* estimated memory footprint of the native code */
|
||||||
|
#endif
|
||||||
|
} AMX;
|
||||||
|
|
||||||
|
/* The AMX_HEADER structure is both the memory format as the file format. The
|
||||||
|
* structure is used internaly.
|
||||||
|
*/
|
||||||
|
typedef struct tagAMX_HEADER {
|
||||||
|
int32_t size PACKED; /* size of the "file" */
|
||||||
|
uint16_t magic PACKED; /* signature */
|
||||||
|
char file_version PACKED; /* file format version */
|
||||||
|
char amx_version PACKED; /* required version of the AMX */
|
||||||
|
int16_t flags PACKED;
|
||||||
|
int16_t defsize PACKED; /* size of a definition record */
|
||||||
|
int32_t cod PACKED; /* initial value of COD - code block */
|
||||||
|
int32_t dat PACKED; /* initial value of DAT - data block */
|
||||||
|
int32_t hea PACKED; /* initial value of HEA - start of the heap */
|
||||||
|
int32_t stp PACKED; /* initial value of STP - stack top */
|
||||||
|
int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
|
||||||
|
int32_t publics PACKED; /* offset to the "public functions" table */
|
||||||
|
int32_t natives PACKED; /* offset to the "native functions" table */
|
||||||
|
int32_t libraries PACKED; /* offset to the table of libraries */
|
||||||
|
int32_t pubvars PACKED; /* the "public variables" table */
|
||||||
|
int32_t tags PACKED; /* the "public tagnames" table */
|
||||||
|
int32_t nametable PACKED; /* name table */
|
||||||
|
} AMX_HEADER;
|
||||||
|
|
||||||
|
#if PAWN_CELL_SIZE==16
|
||||||
|
#define AMX_MAGIC 0xf1e2
|
||||||
|
#elif PAWN_CELL_SIZE==32
|
||||||
|
#define AMX_MAGIC 0xf1e0
|
||||||
|
#elif PAWN_CELL_SIZE==64
|
||||||
|
#define AMX_MAGIC 0xf1e1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AMX_ERR_NONE,
|
||||||
|
/* reserve the first 15 error codes for exit codes of the abstract machine */
|
||||||
|
AMX_ERR_EXIT, /* forced exit */
|
||||||
|
AMX_ERR_ASSERT, /* assertion failed */
|
||||||
|
AMX_ERR_STACKERR, /* stack/heap collision */
|
||||||
|
AMX_ERR_BOUNDS, /* index out of bounds */
|
||||||
|
AMX_ERR_MEMACCESS, /* invalid memory access */
|
||||||
|
AMX_ERR_INVINSTR, /* invalid instruction */
|
||||||
|
AMX_ERR_STACKLOW, /* stack underflow */
|
||||||
|
AMX_ERR_HEAPLOW, /* heap underflow */
|
||||||
|
AMX_ERR_CALLBACK, /* no callback, or invalid callback */
|
||||||
|
AMX_ERR_NATIVE, /* native function failed */
|
||||||
|
AMX_ERR_DIVIDE, /* divide by zero */
|
||||||
|
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
||||||
|
AMX_ERR_INVSTATE, /* invalid state for this access */
|
||||||
|
|
||||||
|
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||||
|
AMX_ERR_FORMAT, /* invalid file format */
|
||||||
|
AMX_ERR_VERSION, /* file is for a newer version of the AMX */
|
||||||
|
AMX_ERR_NOTFOUND, /* function not found */
|
||||||
|
AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */
|
||||||
|
AMX_ERR_DEBUG, /* debugger cannot run */
|
||||||
|
AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */
|
||||||
|
AMX_ERR_USERDATA, /* unable to set user data field (table full) */
|
||||||
|
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
||||||
|
AMX_ERR_PARAMS, /* parameter error */
|
||||||
|
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
||||||
|
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
||||||
|
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
||||||
|
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
||||||
|
#define AMX_FLAG_SLEEP 0x08 /* script uses the sleep instruction (possible re-entry or power-down mode) */
|
||||||
|
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no BREAK opcodes */
|
||||||
|
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
||||||
|
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
||||||
|
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
|
||||||
|
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
||||||
|
|
||||||
|
#define AMX_EXEC_MAIN (-1) /* start at program entry point */
|
||||||
|
#define AMX_EXEC_CONT (-2) /* continue from last address */
|
||||||
|
|
||||||
|
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
|
||||||
|
|
||||||
|
#if !defined AMX_COMPACTMARGIN
|
||||||
|
#define AMX_COMPACTMARGIN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* for native functions that use floating point parameters, the following
|
||||||
|
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||||
|
* changing the bit pattern
|
||||||
|
*/
|
||||||
|
#if PAWN_CELL_SIZE==32
|
||||||
|
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||||
|
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
||||||
|
#elif PAWN_CELL_SIZE==64
|
||||||
|
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||||
|
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
||||||
|
#else
|
||||||
|
#error Unsupported cell size
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define amx_StrParam(amx,param,result) \
|
||||||
|
do { \
|
||||||
|
cell *amx_cstr_; int amx_length_; \
|
||||||
|
amx_GetAddr((amx), (param), &amx_cstr_); \
|
||||||
|
amx_StrLen(amx_cstr_, &amx_length_); \
|
||||||
|
if (amx_length_ > 0 && \
|
||||||
|
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
||||||
|
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_ + 1); \
|
||||||
|
else (result) = NULL; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
uint16_t * AMXAPI amx_Align16(uint16_t *v);
|
||||||
|
uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
||||||
|
#if defined _I64_MAX || defined HAVE_I64
|
||||||
|
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
||||||
|
#endif
|
||||||
|
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
|
||||||
|
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
|
||||||
|
int AMXAPI amx_Cleanup(AMX *amx);
|
||||||
|
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
||||||
|
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
||||||
|
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
|
||||||
|
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
|
||||||
|
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
||||||
|
int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
|
||||||
|
int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
|
||||||
|
int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
|
||||||
|
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
|
||||||
|
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
|
||||||
|
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
|
||||||
|
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
|
||||||
|
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
||||||
|
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
||||||
|
int AMXAPI amx_Init(AMX *amx, void *program);
|
||||||
|
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
||||||
|
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
||||||
|
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
||||||
|
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
|
||||||
|
int AMXAPI amx_NumNatives(AMX *amx, int *number);
|
||||||
|
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
||||||
|
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
||||||
|
int AMXAPI amx_NumTags(AMX *amx, int *number);
|
||||||
|
int AMXAPI amx_Push(AMX *amx, cell value);
|
||||||
|
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
|
||||||
|
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
|
||||||
|
int AMXAPI amx_RaiseError(AMX *amx, int error);
|
||||||
|
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||||
|
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
|
||||||
|
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
||||||
|
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
||||||
|
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
|
||||||
|
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
|
||||||
|
int AMXAPI amx_StrLen(const cell *cstring, int *length);
|
||||||
|
int AMXAPI amx_UTF8Check(const char *string, int *length);
|
||||||
|
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
|
||||||
|
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
|
||||||
|
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
||||||
|
|
||||||
|
#if PAWN_CELL_SIZE==16
|
||||||
|
#define amx_AlignCell(v) amx_Align16(v)
|
||||||
|
#elif PAWN_CELL_SIZE==32
|
||||||
|
#define amx_AlignCell(v) amx_Align32(v)
|
||||||
|
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
|
||||||
|
#define amx_AlignCell(v) amx_Align64(v)
|
||||||
|
#else
|
||||||
|
#error Unsupported cell size
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define amx_RegisterFunc(amx, name, func) \
|
||||||
|
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
|
||||||
|
|
||||||
|
#if !defined AMX_NO_ALIGN
|
||||||
|
#if defined LINUX || defined __FreeBSD__
|
||||||
|
#pragma pack() /* reset default packing */
|
||||||
|
#elif defined MACOS && defined __MWERKS__
|
||||||
|
#pragma options align=reset
|
||||||
|
#else
|
||||||
|
#pragma pack(pop) /* reset previous packing */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMX_H_INCLUDED */
|
172
compiler-init/amxdbg.h
Normal file
172
compiler-init/amxdbg.h
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/* Abstract Machine for the Pawn compiler, debugger support
|
||||||
|
*
|
||||||
|
* This file contains extra definitions that are convenient for debugger
|
||||||
|
* support.
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 2005-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: amxdbg.h 3519 2006-02-17 17:57:04Z thiadmer $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AMXDBG_H_INCLUDED
|
||||||
|
#define AMXDBG_H_INCLUDED
|
||||||
|
|
||||||
|
#ifndef AMX_H_INCLUDED
|
||||||
|
#include "amx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||||
|
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||||
|
*/
|
||||||
|
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||||
|
#define AMX_NO_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __GNUC__
|
||||||
|
#define PACKED __attribute__((packed))
|
||||||
|
#else
|
||||||
|
#define PACKED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined AMX_NO_ALIGN
|
||||||
|
#if defined LINUX || defined __FreeBSD__
|
||||||
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
|
#elif defined MACOS && defined __MWERKS__
|
||||||
|
#pragma options align=mac68k
|
||||||
|
#else
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
|
#if defined __TURBOC__
|
||||||
|
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG_HDR {
|
||||||
|
int32_t size PACKED; /* size of the debug information chunk */
|
||||||
|
uint16_t magic PACKED; /* signature, must be 0xf1ef */
|
||||||
|
char file_version PACKED; /* file format version */
|
||||||
|
char amx_version PACKED; /* required version of the AMX */
|
||||||
|
int16_t flags PACKED; /* currently unused */
|
||||||
|
int16_t files PACKED; /* number of entries in the "file" table */
|
||||||
|
int16_t lines PACKED; /* number of entries in the "line" table */
|
||||||
|
int16_t symbols PACKED; /* number of entries in the "symbol" table */
|
||||||
|
int16_t tags PACKED; /* number of entries in the "tag" table */
|
||||||
|
int16_t automatons PACKED; /* number of entries in the "automaton" table */
|
||||||
|
int16_t states PACKED; /* number of entries in the "state" table */
|
||||||
|
} PACKED AMX_DBG_HDR;
|
||||||
|
#define AMX_DBG_MAGIC 0xf1ef
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG_FILE {
|
||||||
|
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
|
||||||
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
|
} PACKED AMX_DBG_FILE;
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG_LINE {
|
||||||
|
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
|
||||||
|
int32_t line PACKED; /* line number */
|
||||||
|
} PACKED AMX_DBG_LINE;
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG_SYMBOL {
|
||||||
|
ucell address PACKED; /* address in the data segment or relative to the frame */
|
||||||
|
int16_t tag PACKED; /* tag for the symbol */
|
||||||
|
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
|
||||||
|
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
|
||||||
|
char ident PACKED; /* kind of symbol (function/variable) */
|
||||||
|
char vclass PACKED; /* class of symbol (global/local) */
|
||||||
|
int16_t dim PACKED; /* number of dimensions */
|
||||||
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
|
} PACKED AMX_DBG_SYMBOL;
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG_SYMDIM {
|
||||||
|
int16_t tag PACKED; /* tag for the array dimension */
|
||||||
|
ucell size PACKED; /* size of the array dimension */
|
||||||
|
} PACKED AMX_DBG_SYMDIM;
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG_TAG {
|
||||||
|
int16_t tag PACKED; /* tag id */
|
||||||
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
|
} PACKED AMX_DBG_TAG;
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG_MACHINE {
|
||||||
|
int16_t automaton PACKED; /* automaton id */
|
||||||
|
ucell address PACKED; /* address of state variable */
|
||||||
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
|
} PACKED AMX_DBG_MACHINE;
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG_STATE {
|
||||||
|
int16_t state PACKED; /* state id */
|
||||||
|
int16_t automaton PACKED; /* automaton id */
|
||||||
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
|
} PACKED AMX_DBG_STATE;
|
||||||
|
|
||||||
|
typedef struct tagAMX_DBG {
|
||||||
|
AMX_DBG_HDR *hdr PACKED; /* points to the AMX_DBG header */
|
||||||
|
AMX_DBG_FILE **filetbl PACKED;
|
||||||
|
AMX_DBG_LINE *linetbl PACKED;
|
||||||
|
AMX_DBG_SYMBOL **symboltbl PACKED;
|
||||||
|
AMX_DBG_TAG **tagtbl PACKED;
|
||||||
|
AMX_DBG_MACHINE **automatontbl PACKED;
|
||||||
|
AMX_DBG_STATE **statetbl PACKED;
|
||||||
|
} PACKED AMX_DBG;
|
||||||
|
|
||||||
|
#if !defined iVARIABLE
|
||||||
|
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
||||||
|
#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
|
||||||
|
#define iARRAY 3
|
||||||
|
#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
|
||||||
|
#define iFUNCTN 9
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg);
|
||||||
|
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, FILE *fp);
|
||||||
|
|
||||||
|
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename);
|
||||||
|
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname);
|
||||||
|
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line);
|
||||||
|
|
||||||
|
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address);
|
||||||
|
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address);
|
||||||
|
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name);
|
||||||
|
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name);
|
||||||
|
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name);
|
||||||
|
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym);
|
||||||
|
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim);
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined AMX_NO_ALIGN
|
||||||
|
#if defined LINUX || defined __FreeBSD__
|
||||||
|
#pragma pack() /* reset default packing */
|
||||||
|
#elif defined MACOS && defined __MWERKS__
|
||||||
|
#pragma options align=reset
|
||||||
|
#else
|
||||||
|
#pragma pack(pop) /* reset previous packing */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMXDBG_H_INCLUDED */
|
257
compiler-init/libpawnc.c
Normal file
257
compiler-init/libpawnc.c
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
/* LIBPAWNC.C
|
||||||
|
*
|
||||||
|
* A "glue file" for building the Pawn compiler as a DLL or shared library.
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 2000-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: libsc.c 3114 2005-03-17 14:48:29Z thiadmer $
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "sc.h"
|
||||||
|
#include "memfile.h"
|
||||||
|
|
||||||
|
/* pc_printf()
|
||||||
|
* Called for general purpose "console" output. This function prints general
|
||||||
|
* purpose messages; errors go through pc_error(). The function is modelled
|
||||||
|
* after printf().
|
||||||
|
*/
|
||||||
|
int pc_printf(const char *message,...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list argptr;
|
||||||
|
|
||||||
|
va_start(argptr,message);
|
||||||
|
ret=vprintf(message,argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pc_error()
|
||||||
|
* Called for producing error output.
|
||||||
|
* number the error number (as documented in the manual)
|
||||||
|
* message a string describing the error with embedded %d and %s tokens
|
||||||
|
* filename the name of the file currently being parsed
|
||||||
|
* firstline the line number at which the expression started on which
|
||||||
|
* the error was found, or -1 if there is no "starting line"
|
||||||
|
* lastline the line number at which the error was detected
|
||||||
|
* argptr a pointer to the first of a series of arguments (for macro
|
||||||
|
* "va_arg")
|
||||||
|
* Return:
|
||||||
|
* If the function returns 0, the parser attempts to continue compilation.
|
||||||
|
* On a non-zero return value, the parser aborts.
|
||||||
|
*/
|
||||||
|
int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr)
|
||||||
|
{
|
||||||
|
static char *prefix[3]={ "error", "fatal error", "warning" };
|
||||||
|
|
||||||
|
if (number!=0) {
|
||||||
|
char *pre;
|
||||||
|
|
||||||
|
pre=prefix[number/100];
|
||||||
|
if (firstline>=0)
|
||||||
|
fprintf(stderr,"%s(%d -- %d) : %s %03d: ",filename,firstline,lastline,pre,number);
|
||||||
|
else
|
||||||
|
fprintf(stderr,"%s(%d) : %s %03d: ",filename,lastline,pre,number);
|
||||||
|
} /* if */
|
||||||
|
vfprintf(stderr,message,argptr);
|
||||||
|
fflush(stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pc_opensrc()
|
||||||
|
* Opens a source file (or include file) for reading. The "file" does not have
|
||||||
|
* to be a physical file, one might compile from memory.
|
||||||
|
* filename the name of the "file" to read from
|
||||||
|
* Return:
|
||||||
|
* The function must return a pointer, which is used as a "magic cookie" to
|
||||||
|
* all I/O functions. When failing to open the file for reading, the
|
||||||
|
* function must return NULL.
|
||||||
|
* Note:
|
||||||
|
* Several "source files" may be open at the same time. Specifically, one
|
||||||
|
* file can be open for reading and another for writing.
|
||||||
|
*/
|
||||||
|
void *pc_opensrc(char *filename)
|
||||||
|
{
|
||||||
|
return fopen(filename,"rt");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pc_createsrc()
|
||||||
|
* Creates/overwrites a source file for writing. The "file" does not have
|
||||||
|
* to be a physical file, one might compile from memory.
|
||||||
|
* filename the name of the "file" to create
|
||||||
|
* Return:
|
||||||
|
* The function must return a pointer which is used as a "magic cookie" to
|
||||||
|
* all I/O functions. When failing to open the file for reading, the
|
||||||
|
* function must return NULL.
|
||||||
|
* Note:
|
||||||
|
* Several "source files" may be open at the same time. Specifically, one
|
||||||
|
* file can be open for reading and another for writing.
|
||||||
|
*/
|
||||||
|
void *pc_createsrc(char *filename)
|
||||||
|
{
|
||||||
|
return fopen(filename,"wt");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pc_closesrc()
|
||||||
|
* Closes a source file (or include file). The "handle" parameter has the
|
||||||
|
* value that pc_opensrc() returned in an earlier call.
|
||||||
|
*/
|
||||||
|
void pc_closesrc(void *handle)
|
||||||
|
{
|
||||||
|
assert(handle!=NULL);
|
||||||
|
fclose((FILE*)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pc_resetsrc()
|
||||||
|
* "position" may only hold a pointer that was previously obtained from
|
||||||
|
* pc_getpossrc()
|
||||||
|
*/
|
||||||
|
void pc_resetsrc(void *handle,void *position)
|
||||||
|
{
|
||||||
|
assert(handle!=NULL);
|
||||||
|
fsetpos((FILE*)handle,(fpos_t *)position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pc_readsrc()
|
||||||
|
* Reads a single line from the source file (or up to a maximum number of
|
||||||
|
* characters if the line in the input file is too long).
|
||||||
|
*/
|
||||||
|
char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
|
||||||
|
{
|
||||||
|
return fgets((char*)target,maxchars,(FILE*)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pc_writesrc()
|
||||||
|
* Writes to to the source file. There is no automatic line ending; to end a
|
||||||
|
* line, write a "\n".
|
||||||
|
*/
|
||||||
|
int pc_writesrc(void *handle,unsigned char *source)
|
||||||
|
{
|
||||||
|
return fputs((char*)source,(FILE*)handle) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *pc_getpossrc(void *handle)
|
||||||
|
{
|
||||||
|
static fpos_t lastpos; /* may need to have a LIFO stack of such positions */
|
||||||
|
|
||||||
|
fgetpos((FILE*)handle,&lastpos);
|
||||||
|
return &lastpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pc_eofsrc(void *handle)
|
||||||
|
{
|
||||||
|
return feof((FILE*)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* should return a pointer, which is used as a "magic cookie" to all I/O
|
||||||
|
* functions; return NULL for failure
|
||||||
|
*/
|
||||||
|
void *pc_openasm(char *filename)
|
||||||
|
{
|
||||||
|
#if defined __MSDOS__ || defined SC_LIGHT
|
||||||
|
return fopen(filename,"w+t");
|
||||||
|
#else
|
||||||
|
return mfcreate(filename);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void pc_closeasm(void *handle, int deletefile)
|
||||||
|
{
|
||||||
|
#if defined __MSDOS__ || defined SC_LIGHT
|
||||||
|
if (handle!=NULL)
|
||||||
|
fclose((FILE*)handle);
|
||||||
|
if (deletefile)
|
||||||
|
remove(outfname);
|
||||||
|
#else
|
||||||
|
if (handle!=NULL) {
|
||||||
|
if (!deletefile)
|
||||||
|
mfdump((MEMFILE*)handle);
|
||||||
|
mfclose((MEMFILE*)handle);
|
||||||
|
} /* if */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void pc_resetasm(void *handle)
|
||||||
|
{
|
||||||
|
assert(handle!=NULL);
|
||||||
|
#if defined __MSDOS__ || defined SC_LIGHT
|
||||||
|
fflush((FILE*)handle);
|
||||||
|
fseek((FILE*)handle,0,SEEK_SET);
|
||||||
|
#else
|
||||||
|
mfseek((MEMFILE*)handle,0,SEEK_SET);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int pc_writeasm(void *handle,char *string)
|
||||||
|
{
|
||||||
|
#if defined __MSDOS__ || defined SC_LIGHT
|
||||||
|
return fputs(string,(FILE*)handle) >= 0;
|
||||||
|
#else
|
||||||
|
return mfputs((MEMFILE*)handle,string);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char *pc_readasm(void *handle, char *string, int maxchars)
|
||||||
|
{
|
||||||
|
#if defined __MSDOS__ || defined SC_LIGHT
|
||||||
|
return fgets(string,maxchars,(FILE*)handle);
|
||||||
|
#else
|
||||||
|
return mfgets((MEMFILE*)handle,string,maxchars);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should return a pointer, which is used as a "magic cookie" to all I/O
|
||||||
|
* functions; return NULL for failure.
|
||||||
|
*/
|
||||||
|
void *pc_openbin(char *filename)
|
||||||
|
{
|
||||||
|
return memfile_creat(filename, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pc_closebin(void *handle,int deletefile)
|
||||||
|
{
|
||||||
|
if (deletefile)
|
||||||
|
{
|
||||||
|
memfile_destroy((memfile_t *)handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pc_resetbin()
|
||||||
|
* Can seek to any location in the file.
|
||||||
|
* The offset is always from the start of the file.
|
||||||
|
*/
|
||||||
|
void pc_resetbin(void *handle,long offset)
|
||||||
|
{
|
||||||
|
memfile_seek((memfile_t *)handle, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pc_writebin(void *handle,void *buffer,int size)
|
||||||
|
{
|
||||||
|
return memfile_write((memfile_t *)handle, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
long pc_lengthbin(void *handle)
|
||||||
|
{
|
||||||
|
return memfile_tell((memfile_t *)handle);
|
||||||
|
}
|
55
compiler-init/libpawnc.rc
Normal file
55
compiler-init/libpawnc.rc
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#if defined WIN32 || defined _WIN32 || defined __WIN32__
|
||||||
|
# include <winver.h>
|
||||||
|
#else
|
||||||
|
# include <ver.h>
|
||||||
|
#endif
|
||||||
|
#include "svnrev.h"
|
||||||
|
|
||||||
|
AppIcon ICON "pawn.ico"
|
||||||
|
|
||||||
|
/* Version information
|
||||||
|
*
|
||||||
|
* All strings MUST have an explicit \0. See the Windows SDK documentation
|
||||||
|
* for details on version information and the VERSIONINFO structure.
|
||||||
|
*/
|
||||||
|
#define VERSION SMC_VERSION
|
||||||
|
#define REVISION SMC_REVISION
|
||||||
|
#define BUILD SMC_BUILD
|
||||||
|
#define VERSIONSTR SMC_VERSTRING
|
||||||
|
#define VERSIONNAME "smcomp.exe\0"
|
||||||
|
#define VERSIONDESCRIPTION "SourcePawn Compiler\0"
|
||||||
|
#define VERSIONPRODUCTNAME "smcomp\0"
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION VERSION, REVISION, BUILD, 0
|
||||||
|
PRODUCTVERSION VERSION, REVISION, BUILD, 0
|
||||||
|
FILEFLAGSMASK 0x0000003FL
|
||||||
|
FILEFLAGS 0
|
||||||
|
#if defined(WIN32)
|
||||||
|
FILEOS VOS__WINDOWS32
|
||||||
|
#else
|
||||||
|
FILEOS VOS__WINDOWS16
|
||||||
|
#endif
|
||||||
|
FILETYPE VFT_DLL
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904E4"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "(C)1998-2006 ITB CompuPhase, AlliedModders LLC\0"
|
||||||
|
VALUE "FileDescription", VERSIONDESCRIPTION
|
||||||
|
VALUE "FileVersion", VERSIONSTR
|
||||||
|
VALUE "InternalName", VERSIONNAME
|
||||||
|
VALUE "LegalCopyright", "(C)1998-2006 ITB CompuPhase, AlliedModders LLC\0"
|
||||||
|
VALUE "OriginalFilename", VERSIONNAME
|
||||||
|
VALUE "ProductName", VERSIONPRODUCTNAME
|
||||||
|
VALUE "ProductVersion", VERSIONSTR
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1252
|
||||||
|
END
|
||||||
|
END
|
124
compiler-init/lstring.c
Normal file
124
compiler-init/lstring.c
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/* Safe string copying and concatenation
|
||||||
|
* These routines are originally distributed in two separate files. I have
|
||||||
|
* copied the files verbatim in this single source file, including all comments.
|
||||||
|
* The only change is that the second set of include files is commented out
|
||||||
|
* (there is no need to include the same files twice).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lstring.h"
|
||||||
|
|
||||||
|
#if !defined HAVE_SAFESTR
|
||||||
|
|
||||||
|
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/types.h> already included through lstring.h
|
||||||
|
*/
|
||||||
|
#include <string.h> /* for strlen() */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy src to string dst of size siz. At most siz-1 characters
|
||||||
|
* will be copied. Always NUL terminates (unless siz == 0).
|
||||||
|
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
strlcpy(char *dst, const char *src, size_t siz)
|
||||||
|
{
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
size_t n = siz;
|
||||||
|
|
||||||
|
/* Copy as many bytes as will fit */
|
||||||
|
if (n != 0 && --n != 0) {
|
||||||
|
do {
|
||||||
|
if ((*d++ = *s++) == 0)
|
||||||
|
break;
|
||||||
|
} while (--n != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||||
|
if (n == 0) {
|
||||||
|
if (siz != 0)
|
||||||
|
*d = '\0'; /* NUL-terminate dst */
|
||||||
|
while (*s++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(s - src - 1); /* count does not include NUL */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/types.h> already included
|
||||||
|
#include <string.h> already included
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||||
|
* full size of dst, not space left). At most siz-1 characters
|
||||||
|
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||||
|
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||||
|
* If retval >= siz, truncation occurred.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
strlcat(char *dst, const char *src, size_t siz)
|
||||||
|
{
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
size_t n = siz;
|
||||||
|
size_t dlen;
|
||||||
|
|
||||||
|
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||||
|
while (n-- != 0 && *d != '\0')
|
||||||
|
d++;
|
||||||
|
dlen = d - dst;
|
||||||
|
n = siz - dlen;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return(dlen + strlen(s));
|
||||||
|
while (*s != '\0') {
|
||||||
|
if (n != 1) {
|
||||||
|
*d++ = *s;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
*d = '\0';
|
||||||
|
|
||||||
|
return(dlen + (s - src)); /* count does not include NUL */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if !defined HAVE_SAFESTR */
|
18
compiler-init/lstring.h
Normal file
18
compiler-init/lstring.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/* prototypes for strlcpy() and strlcat() */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#if defined __WATCOMC__ && __WATCOMC__ >= 1240
|
||||||
|
/* OpenWatcom introduced BSD "safe string functions" with version 1.4 */
|
||||||
|
#define HAVE_SAFESTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined HAVE_SAFESTR
|
||||||
|
|
||||||
|
size_t
|
||||||
|
strlcpy(char *dst, const char *src, size_t siz);
|
||||||
|
|
||||||
|
size_t
|
||||||
|
strlcat(char *dst, const char *src, size_t siz);
|
||||||
|
|
||||||
|
#endif
|
105
compiler-init/memfile.c
Normal file
105
compiler-init/memfile.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#include "memfile.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include "osdefs.h"
|
||||||
|
|
||||||
|
memfile_t *memfile_creat(const char *name, size_t init)
|
||||||
|
{
|
||||||
|
memfile_t mf;
|
||||||
|
memfile_t *pmf;
|
||||||
|
|
||||||
|
mf.size = init;
|
||||||
|
mf.base = (char *)malloc(init);
|
||||||
|
mf.usedoffs = 0;
|
||||||
|
if (!mf.base)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mf.offs = 0;
|
||||||
|
mf._static = 0;
|
||||||
|
|
||||||
|
pmf = (memfile_t *)malloc(sizeof(memfile_t));
|
||||||
|
memcpy(pmf, &mf, sizeof(memfile_t));
|
||||||
|
|
||||||
|
pmf->name = strdup(name);
|
||||||
|
|
||||||
|
return pmf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void memfile_destroy(memfile_t *mf)
|
||||||
|
{
|
||||||
|
if (!mf->_static)
|
||||||
|
{
|
||||||
|
free(mf->name);
|
||||||
|
free(mf->base);
|
||||||
|
free(mf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void memfile_seek(memfile_t *mf, long seek)
|
||||||
|
{
|
||||||
|
mf->offs = seek;
|
||||||
|
}
|
||||||
|
|
||||||
|
long memfile_tell(memfile_t *mf)
|
||||||
|
{
|
||||||
|
return mf->offs;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t memfile_read(memfile_t *mf, void *buffer, size_t maxsize)
|
||||||
|
{
|
||||||
|
if (!maxsize || mf->offs >= mf->usedoffs)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mf->usedoffs - mf->offs < (long)maxsize)
|
||||||
|
{
|
||||||
|
maxsize = mf->usedoffs - mf->offs;
|
||||||
|
if (!maxsize)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer, mf->base + mf->offs, maxsize);
|
||||||
|
|
||||||
|
mf->offs += maxsize;
|
||||||
|
|
||||||
|
return maxsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memfile_write(memfile_t *mf, void *buffer, size_t size)
|
||||||
|
{
|
||||||
|
if (mf->offs + size > mf->size)
|
||||||
|
{
|
||||||
|
size_t newsize = (mf->size + size) * 2;
|
||||||
|
if (mf->_static)
|
||||||
|
{
|
||||||
|
char *oldbase = mf->base;
|
||||||
|
mf->base = (char *)malloc(newsize);
|
||||||
|
if (!mf->base)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(mf->base, oldbase, mf->size);
|
||||||
|
} else {
|
||||||
|
mf->base = (char *)realloc(mf->base, newsize);
|
||||||
|
if (!mf->base)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mf->_static = 0;
|
||||||
|
mf->size = newsize;
|
||||||
|
}
|
||||||
|
memcpy(mf->base + mf->offs, buffer, size);
|
||||||
|
mf->offs += size;
|
||||||
|
|
||||||
|
if (mf->offs > mf->usedoffs)
|
||||||
|
{
|
||||||
|
mf->usedoffs = mf->offs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
23
compiler-init/memfile.h
Normal file
23
compiler-init/memfile.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _INCLUDE_MEMFILE_H
|
||||||
|
#define _INCLUDE_MEMFILE_H
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
typedef struct memfile_s
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *base;
|
||||||
|
long offs;
|
||||||
|
long usedoffs;
|
||||||
|
size_t size;
|
||||||
|
int _static;
|
||||||
|
} memfile_t;
|
||||||
|
|
||||||
|
memfile_t *memfile_creat(const char *name, size_t init);
|
||||||
|
void memfile_destroy(memfile_t *mf);
|
||||||
|
void memfile_seek(memfile_t *mf, long seek);
|
||||||
|
int memfile_write(memfile_t *mf, void *buffer, size_t size);
|
||||||
|
size_t memfile_read(memfile_t *mf, void *buffer, size_t maxsize);
|
||||||
|
long memfile_tell(memfile_t *mf);
|
||||||
|
|
||||||
|
#endif //_INCLUDE_MEMFILE_H
|
108
compiler-init/osdefs.h
Normal file
108
compiler-init/osdefs.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/* __MSDOS__ set when compiling for DOS (not Windows)
|
||||||
|
* _Windows set when compiling for any version of Microsoft Windows
|
||||||
|
* __WIN32__ set when compiling for Windows95 or WindowsNT (32 bit mode)
|
||||||
|
* __32BIT__ set when compiling in 32-bit "flat" mode (DOS or Windows)
|
||||||
|
*
|
||||||
|
* Copyright 1998-2005, ITB CompuPhase, The Netherlands.
|
||||||
|
* info@compuphase.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OSDEFS_H
|
||||||
|
#define _OSDEFS_H
|
||||||
|
|
||||||
|
/* Every compiler uses different "default" macros to indicate the mode
|
||||||
|
* it is in. Throughout the source, we use the Borland C++ macros, so
|
||||||
|
* the macros of Watcom C/C++ and Microsoft Visual C/C++ are mapped to
|
||||||
|
* those of Borland C++.
|
||||||
|
*/
|
||||||
|
#if defined(__WATCOMC__)
|
||||||
|
# if defined(__WINDOWS__) || defined(__NT__)
|
||||||
|
# define _Windows 1
|
||||||
|
# endif
|
||||||
|
# ifdef __386__
|
||||||
|
# define __32BIT__ 1
|
||||||
|
# endif
|
||||||
|
# if defined(_Windows) && defined(__32BIT__)
|
||||||
|
# define __WIN32__ 1
|
||||||
|
# endif
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# if defined(_WINDOWS) || defined(_WIN32)
|
||||||
|
# define _Windows 1
|
||||||
|
# endif
|
||||||
|
# ifdef _WIN32
|
||||||
|
# define __WIN32__ 1
|
||||||
|
# define __32BIT__ 1
|
||||||
|
# endif
|
||||||
|
# if _MSC_VER >= 1400
|
||||||
|
# if !defined _CRT_SECURE_NO_DEPRECATE
|
||||||
|
# define _CRT_SECURE_NO_DEPRECATE
|
||||||
|
# endif
|
||||||
|
# define strdup _strdup
|
||||||
|
# define stricmp _stricmp
|
||||||
|
# define access _access
|
||||||
|
# define chdir _chdir
|
||||||
|
# define strdup _strdup
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __FreeBSD__
|
||||||
|
#include <sys/endian.h>
|
||||||
|
#elif defined LINUX
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Linux NOW has these */
|
||||||
|
#if !defined BIG_ENDIAN
|
||||||
|
#define BIG_ENDIAN 4321
|
||||||
|
#endif
|
||||||
|
#if !defined LITTLE_ENDIAN
|
||||||
|
#define LITTLE_ENDIAN 1234
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* educated guess, BYTE_ORDER is undefined, i386 is common => little endian */
|
||||||
|
#if !defined BYTE_ORDER
|
||||||
|
#if defined UCLINUX
|
||||||
|
#define BYTE_ORDER BIG_ENDIAN
|
||||||
|
#else
|
||||||
|
#define BYTE_ORDER LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __MSDOS__ || defined __WIN32__ || defined _Windows
|
||||||
|
#define DIRSEP_CHAR '\\'
|
||||||
|
#elif defined macintosh
|
||||||
|
#define DIRSEP_CHAR ':'
|
||||||
|
#else
|
||||||
|
#define DIRSEP_CHAR '/' /* directory separator character */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* _MAX_PATH is sometimes called differently and it may be in limits.h or
|
||||||
|
* stdlib.h instead of stdio.h.
|
||||||
|
*/
|
||||||
|
#if !defined _MAX_PATH
|
||||||
|
/* not defined, perhaps stdio.h was not included */
|
||||||
|
#if !defined PATH_MAX
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
#if !defined _MAX_PATH && !defined PATH_MAX
|
||||||
|
/* no _MAX_PATH and no MAX_PATH, perhaps it is in limits.h */
|
||||||
|
#include <limits.h>
|
||||||
|
#endif
|
||||||
|
#if !defined _MAX_PATH && !defined PATH_MAX
|
||||||
|
/* no _MAX_PATH and no MAX_PATH, perhaps it is in stdlib.h */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
/* if _MAX_PATH is undefined, try common alternative names */
|
||||||
|
#if !defined _MAX_PATH
|
||||||
|
#if defined MAX_PATH
|
||||||
|
#define _MAX_PATH MAX_PATH
|
||||||
|
#elif defined _POSIX_PATH_MAX
|
||||||
|
#define _MAX_PATH _POSIX_PATH_MAX
|
||||||
|
#else
|
||||||
|
/* everything failed, actually we have a problem here... */
|
||||||
|
#define _MAX_PATH 1024
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _OSDEFS_H */
|
BIN
compiler-init/pawn.ico
Normal file
BIN
compiler-init/pawn.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
30
compiler-init/pawncc.c
Normal file
30
compiler-init/pawncc.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* Pawn compiler driver
|
||||||
|
*
|
||||||
|
* Function and variable definition and declaration, statement parser.
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: Sc1.c 3114 2005-03-17 14:48:29Z thiadmer $
|
||||||
|
*/
|
||||||
|
#include "sc.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return pc_compile(argc,argv);
|
||||||
|
}
|
813
compiler-init/sc.h
Normal file
813
compiler-init/sc.h
Normal file
@ -0,0 +1,813 @@
|
|||||||
|
/* Pawn compiler
|
||||||
|
*
|
||||||
|
* Drafted after the Small-C compiler Version 2.01, originally created
|
||||||
|
* by Ron Cain, july 1980, and enhanced by James E. Hendrix.
|
||||||
|
*
|
||||||
|
* This version comes close to a complete rewrite.
|
||||||
|
*
|
||||||
|
* Copyright R. Cain, 1980
|
||||||
|
* Copyright J.E. Hendrix, 1982, 1983
|
||||||
|
* Copyright ITB CompuPhase, 1997-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: sc.h 3590 2006-06-24 14:16:39Z thiadmer $
|
||||||
|
*/
|
||||||
|
#ifndef SC_H_INCLUDED
|
||||||
|
#define SC_H_INCLUDED
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined __BORLANDC__ && defined _Windows && !(defined __32BIT__ || defined __WIN32__)
|
||||||
|
/* setjmp() and longjmp() not well supported in 16-bit windows */
|
||||||
|
#include <windows.h>
|
||||||
|
typedef int jmp_buf[9];
|
||||||
|
#define setjmp(b) Catch(b)
|
||||||
|
#define longjmp(b,e) Throw(b,e)
|
||||||
|
#else
|
||||||
|
#include <setjmp.h>
|
||||||
|
#endif
|
||||||
|
#include "osdefs.h"
|
||||||
|
#include "amx.h"
|
||||||
|
|
||||||
|
/* Note: the "cell" and "ucell" types are defined in AMX.H */
|
||||||
|
|
||||||
|
#define PUBLIC_CHAR '@' /* character that defines a function "public" */
|
||||||
|
#define CTRL_CHAR '\\' /* default control character */
|
||||||
|
#define sCHARBITS 8 /* size of a packed character */
|
||||||
|
|
||||||
|
#define sDIMEN_MAX 4 /* maximum number of array dimensions */
|
||||||
|
#define sLINEMAX 1024 /* input line length (in characters) */
|
||||||
|
#define sCOMP_STACK 32 /* maximum nesting of #if .. #endif sections */
|
||||||
|
#define sDEF_LITMAX 500 /* initial size of the literal pool, in "cells" */
|
||||||
|
#define sDEF_AMXSTACK 4096 /* default stack size for AMX files */
|
||||||
|
#define PREPROC_TERM '\x7f'/* termination character for preprocessor expressions (the "DEL" code) */
|
||||||
|
#define sDEF_PREFIX "sourcemod.inc" /* default prefix filename */
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
void *pv; /* e.g. a name */
|
||||||
|
int i;
|
||||||
|
} stkitem; /* type of items stored on the compiler stack */
|
||||||
|
|
||||||
|
typedef struct s_arginfo { /* function argument info */
|
||||||
|
char name[sNAMEMAX+1];
|
||||||
|
char ident; /* iVARIABLE, iREFERENCE, iREFARRAY or iVARARGS */
|
||||||
|
char usage; /* uCONST */
|
||||||
|
int *tags; /* argument tag id. list */
|
||||||
|
int numtags; /* number of tags in the tag list */
|
||||||
|
int dim[sDIMEN_MAX];
|
||||||
|
int idxtag[sDIMEN_MAX];
|
||||||
|
int numdim; /* number of dimensions */
|
||||||
|
unsigned char hasdefault; /* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */
|
||||||
|
union {
|
||||||
|
cell val; /* default value */
|
||||||
|
struct {
|
||||||
|
char *symname; /* name of another symbol */
|
||||||
|
short level; /* indirection level for that symbol */
|
||||||
|
} size; /* used for "sizeof" default value */
|
||||||
|
struct {
|
||||||
|
cell *data; /* values of default array */
|
||||||
|
int size; /* complete length of default array */
|
||||||
|
int arraysize; /* size to reserve on the heap */
|
||||||
|
cell addr; /* address of the default array in the data segment */
|
||||||
|
} array;
|
||||||
|
} defvalue; /* default value, or pointer to default array */
|
||||||
|
int defvalue_tag; /* tag of the default value */
|
||||||
|
} arginfo;
|
||||||
|
|
||||||
|
/* Equate table, tagname table, library table */
|
||||||
|
typedef struct s_constvalue {
|
||||||
|
struct s_constvalue *next;
|
||||||
|
char name[sNAMEMAX+1];
|
||||||
|
cell value;
|
||||||
|
int index; /* index level, for constants referring to array sizes/tags
|
||||||
|
* automaton id. for states and automatons
|
||||||
|
* tag for enumeration lists */
|
||||||
|
} constvalue;
|
||||||
|
|
||||||
|
/* Symbol table format
|
||||||
|
*
|
||||||
|
* The symbol name read from the input file is stored in "name", the
|
||||||
|
* value of "addr" is written to the output file. The address in "addr"
|
||||||
|
* depends on the class of the symbol:
|
||||||
|
* global offset into the data segment
|
||||||
|
* local offset relative to the stack frame
|
||||||
|
* label generated hexadecimal number
|
||||||
|
* function offset into code segment
|
||||||
|
*/
|
||||||
|
typedef struct s_symbol {
|
||||||
|
struct s_symbol *next;
|
||||||
|
struct s_symbol *parent; /* hierarchical types (multi-dimensional arrays) */
|
||||||
|
char name[sNAMEMAX+1];
|
||||||
|
uint32_t hash; /* value derived from name, for quicker searching */
|
||||||
|
cell addr; /* address or offset (or value for constant, index for native function) */
|
||||||
|
cell codeaddr; /* address (in the code segment) where the symbol declaration starts */
|
||||||
|
char vclass; /* sLOCAL if "addr" refers to a local symbol */
|
||||||
|
char ident; /* see below for possible values */
|
||||||
|
short usage; /* see below for possible values */
|
||||||
|
char flags; /* see below for possible values */
|
||||||
|
int compound; /* compound level (braces nesting level) */
|
||||||
|
int tag; /* tagname id */
|
||||||
|
union {
|
||||||
|
int declared; /* label: how many local variables are declared */
|
||||||
|
struct {
|
||||||
|
int index; /* array & enum: tag of array indices or the enum item */
|
||||||
|
int field; /* enumeration fields, where a size is attached to the field */
|
||||||
|
} tags; /* extra tags */
|
||||||
|
constvalue *lib; /* native function: library it is part of */
|
||||||
|
long stacksize; /* normal/public function: stack requirements */
|
||||||
|
} x; /* 'x' for 'extra' */
|
||||||
|
union {
|
||||||
|
arginfo *arglist; /* types of all parameters for functions */
|
||||||
|
constvalue *enumlist;/* list of names for the "root" of an enumeration */
|
||||||
|
struct {
|
||||||
|
cell length; /* arrays: length (size) */
|
||||||
|
short level; /* number of dimensions below this level */
|
||||||
|
} array;
|
||||||
|
} dim; /* for 'dimension', both functions and arrays */
|
||||||
|
constvalue *states; /* list of state function/state variable ids + addresses */
|
||||||
|
int fnumber; /* static global variables: file number in which the declaration is visible */
|
||||||
|
int lnumber; /* line number (in the current source file) for the declaration */
|
||||||
|
struct s_symbol **refer; /* referrer list, functions that "use" this symbol */
|
||||||
|
int numrefers; /* number of entries in the referrer list */
|
||||||
|
char *documentation; /* optional documentation string */
|
||||||
|
} symbol;
|
||||||
|
|
||||||
|
|
||||||
|
/* Possible entries for "ident". These are used in the "symbol", "value"
|
||||||
|
* and arginfo structures. Not every constant is valid for every use.
|
||||||
|
* In an argument list, the list is terminated with a "zero" ident; labels
|
||||||
|
* cannot be passed as function arguments, so the value 0 is overloaded.
|
||||||
|
*/
|
||||||
|
#define iLABEL 0
|
||||||
|
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
||||||
|
#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
|
||||||
|
#define iARRAY 3
|
||||||
|
#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
|
||||||
|
#define iARRAYCELL 5 /* array element, cell that must be fetched indirectly */
|
||||||
|
#define iARRAYCHAR 6 /* array element, character from cell from array */
|
||||||
|
#define iEXPRESSION 7 /* expression result, has no address (rvalue) */
|
||||||
|
#define iCONSTEXPR 8 /* constant expression (or constant symbol) */
|
||||||
|
#define iFUNCTN 9
|
||||||
|
#define iREFFUNC 10
|
||||||
|
#define iVARARGS 11 /* function specified ... as argument(s) */
|
||||||
|
|
||||||
|
/* Possible entries for "usage"
|
||||||
|
*
|
||||||
|
* This byte is used as a serie of bits, the syntax is different for
|
||||||
|
* functions and other symbols:
|
||||||
|
*
|
||||||
|
* VARIABLE
|
||||||
|
* bits: 0 (uDEFINE) the variable is defined in the source file
|
||||||
|
* 1 (uREAD) the variable is "read" (accessed) in the source file
|
||||||
|
* 2 (uWRITTEN) the variable is altered (assigned a value)
|
||||||
|
* 3 (uCONST) the variable is constant (may not be assigned to)
|
||||||
|
* 4 (uPUBLIC) the variable is public
|
||||||
|
* 6 (uSTOCK) the variable is discardable (without warning)
|
||||||
|
*
|
||||||
|
* FUNCTION
|
||||||
|
* bits: 0 (uDEFINE) the function is defined ("implemented") in the source file
|
||||||
|
* 1 (uREAD) the function is invoked in the source file
|
||||||
|
* 2 (uRETVALUE) the function returns a value (or should return a value)
|
||||||
|
* 3 (uPROTOTYPED) the function was prototyped (implicitly via a definition or explicitly)
|
||||||
|
* 4 (uPUBLIC) the function is public
|
||||||
|
* 5 (uNATIVE) the function is native
|
||||||
|
* 6 (uSTOCK) the function is discardable (without warning)
|
||||||
|
* 7 (uMISSING) the function is not implemented in this source file
|
||||||
|
* 8 (uFORWARD) the function is explicitly forwardly declared
|
||||||
|
*
|
||||||
|
* CONSTANT
|
||||||
|
* bits: 0 (uDEFINE) the symbol is defined in the source file
|
||||||
|
* 1 (uREAD) the constant is "read" (accessed) in the source file
|
||||||
|
* 2 (uWRITTEN) redundant, but may be set for constants passed by reference
|
||||||
|
* 3 (uPREDEF) the constant is pre-defined and should be kept between passes
|
||||||
|
* 5 (uENUMROOT) the constant is the "root" of an enumeration
|
||||||
|
* 6 (uENUMFIELD) the constant is a field in a named enumeration
|
||||||
|
*/
|
||||||
|
#define uDEFINE 0x001
|
||||||
|
#define uREAD 0x002
|
||||||
|
#define uWRITTEN 0x004
|
||||||
|
#define uRETVALUE 0x004 /* function returns (or should return) a value */
|
||||||
|
#define uCONST 0x008
|
||||||
|
#define uPROTOTYPED 0x008
|
||||||
|
#define uPREDEF 0x008 /* constant is pre-defined */
|
||||||
|
#define uPUBLIC 0x010
|
||||||
|
#define uNATIVE 0x020
|
||||||
|
#define uENUMROOT 0x020
|
||||||
|
#define uSTOCK 0x040
|
||||||
|
#define uENUMFIELD 0x040
|
||||||
|
#define uMISSING 0x080
|
||||||
|
#define uFORWARD 0x100
|
||||||
|
/* uRETNONE is not stored in the "usage" field of a symbol. It is
|
||||||
|
* used during parsing a function, to detect a mix of "return;" and
|
||||||
|
* "return value;" in a few special cases.
|
||||||
|
*/
|
||||||
|
#define uRETNONE 0x10
|
||||||
|
|
||||||
|
#define flgDEPRICATED 0x01 /* symbol is depricated (avoid use) */
|
||||||
|
|
||||||
|
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
|
||||||
|
#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
|
||||||
|
|
||||||
|
#define uMAINFUNC "main"
|
||||||
|
#define uENTRYFUNC "entry"
|
||||||
|
|
||||||
|
#define sGLOBAL 0 /* global variable/constant class (no states) */
|
||||||
|
#define sLOCAL 1 /* local variable/constant */
|
||||||
|
#define sSTATIC 2 /* global life, local scope */
|
||||||
|
|
||||||
|
#define sSTATEVAR 3 /* criterion to find variables (sSTATEVAR implies a global variable) */
|
||||||
|
|
||||||
|
typedef struct s_value {
|
||||||
|
symbol *sym; /* symbol in symbol table, NULL for (constant) expression */
|
||||||
|
cell constval; /* value of the constant expression (if ident==iCONSTEXPR)
|
||||||
|
* also used for the size of a literal array */
|
||||||
|
int tag; /* tag (of the expression) */
|
||||||
|
int cmptag; /* for searching symbols: choose the one with the matching tag */
|
||||||
|
char ident; /* iCONSTEXPR, iVARIABLE, iARRAY, iARRAYCELL,
|
||||||
|
* iEXPRESSION or iREFERENCE */
|
||||||
|
char boolresult; /* boolean result for relational operators */
|
||||||
|
cell *arrayidx; /* last used array indices, for checking self assignment */
|
||||||
|
} value;
|
||||||
|
|
||||||
|
/* "while" statement queue (also used for "for" and "do - while" loops) */
|
||||||
|
enum {
|
||||||
|
wqBRK, /* used to restore stack for "break" */
|
||||||
|
wqCONT, /* used to restore stack for "continue" */
|
||||||
|
wqLOOP, /* loop start label number */
|
||||||
|
wqEXIT, /* loop exit label number (jump if false) */
|
||||||
|
/* --- */
|
||||||
|
wqSIZE /* "while queue" size */
|
||||||
|
};
|
||||||
|
#define wqTABSZ (24*wqSIZE) /* 24 nested loop statements */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
statIDLE, /* not compiling yet */
|
||||||
|
statFIRST, /* first pass */
|
||||||
|
statWRITE, /* writing output */
|
||||||
|
statSKIP, /* skipping output */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct s_stringlist {
|
||||||
|
struct s_stringlist *next;
|
||||||
|
char *line;
|
||||||
|
} stringlist;
|
||||||
|
|
||||||
|
typedef struct s_stringpair {
|
||||||
|
struct s_stringpair *next;
|
||||||
|
char *first;
|
||||||
|
char *second;
|
||||||
|
int matchlength;
|
||||||
|
} stringpair;
|
||||||
|
|
||||||
|
/* macros for code generation */
|
||||||
|
#define opcodes(n) ((n)*sizeof(cell)) /* opcode size */
|
||||||
|
#define opargs(n) ((n)*sizeof(cell)) /* size of typical argument */
|
||||||
|
|
||||||
|
/* Tokens recognized by lex()
|
||||||
|
* Some of these constants are assigned as well to the variable "lastst"
|
||||||
|
*/
|
||||||
|
#define tFIRST 256 /* value of first multi-character operator */
|
||||||
|
#define tMIDDLE 280 /* value of last multi-character operator */
|
||||||
|
#define tLAST 326 /* value of last multi-character match-able token */
|
||||||
|
/* multi-character operators */
|
||||||
|
#define taMULT 256 /* *= */
|
||||||
|
#define taDIV 257 /* /= */
|
||||||
|
#define taMOD 258 /* %= */
|
||||||
|
#define taADD 259 /* += */
|
||||||
|
#define taSUB 260 /* -= */
|
||||||
|
#define taSHL 261 /* <<= */
|
||||||
|
#define taSHRU 262 /* >>>= */
|
||||||
|
#define taSHR 263 /* >>= */
|
||||||
|
#define taAND 264 /* &= */
|
||||||
|
#define taXOR 265 /* ^= */
|
||||||
|
#define taOR 266 /* |= */
|
||||||
|
#define tlOR 267 /* || */
|
||||||
|
#define tlAND 268 /* && */
|
||||||
|
#define tlEQ 269 /* == */
|
||||||
|
#define tlNE 270 /* != */
|
||||||
|
#define tlLE 271 /* <= */
|
||||||
|
#define tlGE 272 /* >= */
|
||||||
|
#define tSHL 273 /* << */
|
||||||
|
#define tSHRU 274 /* >>> */
|
||||||
|
#define tSHR 275 /* >> */
|
||||||
|
#define tINC 276 /* ++ */
|
||||||
|
#define tDEC 277 /* -- */
|
||||||
|
#define tELLIPS 278 /* ... */
|
||||||
|
#define tDBLDOT 279 /* .. */
|
||||||
|
#define tDBLCOLON 280 /* :: */
|
||||||
|
/* reserved words (statements) */
|
||||||
|
#define tASSERT 281
|
||||||
|
#define tBREAK 282
|
||||||
|
#define tCASE 283
|
||||||
|
#define tCHAR 284
|
||||||
|
#define tCONST 285
|
||||||
|
#define tCONTINUE 286
|
||||||
|
#define tDEFAULT 287
|
||||||
|
#define tDEFINED 288
|
||||||
|
#define tDO 289
|
||||||
|
#define tELSE 290
|
||||||
|
#define tENUM 291
|
||||||
|
#define tEXIT 292
|
||||||
|
#define tFOR 293
|
||||||
|
#define tFORWARD 294
|
||||||
|
#define tGOTO 295
|
||||||
|
#define tIF 296
|
||||||
|
#define tNATIVE 297
|
||||||
|
#define tNEW 298
|
||||||
|
#define tDECL 299
|
||||||
|
#define tOPERATOR 300
|
||||||
|
#define tPUBLIC 301
|
||||||
|
#define tRETURN 303
|
||||||
|
#define tSIZEOF 303
|
||||||
|
#define tSLEEP 304
|
||||||
|
#define tSTATE 305
|
||||||
|
#define tSTATIC 306
|
||||||
|
#define tSTOCK 307
|
||||||
|
#define tSWITCH 308
|
||||||
|
#define tTAGOF 309
|
||||||
|
#define tWHILE 310
|
||||||
|
/* compiler directives */
|
||||||
|
#define tpASSERT 311 /* #assert */
|
||||||
|
#define tpDEFINE 312
|
||||||
|
#define tpELSE 313 /* #else */
|
||||||
|
#define tpELSEIF 314 /* #elseif */
|
||||||
|
#define tpEMIT 315
|
||||||
|
#define tpENDIF 316
|
||||||
|
#define tpENDINPUT 317
|
||||||
|
#define tpENDSCRPT 318
|
||||||
|
#define tpERROR 319
|
||||||
|
#define tpFILE 320
|
||||||
|
#define tpIF 321 /* #if */
|
||||||
|
#define tINCLUDE 322
|
||||||
|
#define tpLINE 323
|
||||||
|
#define tpPRAGMA 324
|
||||||
|
#define tpTRYINCLUDE 325
|
||||||
|
#define tpUNDEF 326
|
||||||
|
/* semicolon is a special case, because it can be optional */
|
||||||
|
#define tTERM 327 /* semicolon or newline */
|
||||||
|
#define tENDEXPR 328 /* forced end of expression */
|
||||||
|
/* other recognized tokens */
|
||||||
|
#define tNUMBER 329 /* integer number */
|
||||||
|
#define tRATIONAL 330 /* rational number */
|
||||||
|
#define tSYMBOL 331
|
||||||
|
#define tLABEL 332
|
||||||
|
#define tSTRING 333
|
||||||
|
#define tEXPR 334 /* for assigment to "lastst" only */
|
||||||
|
|
||||||
|
/* (reversed) evaluation of staging buffer */
|
||||||
|
#define sSTARTREORDER 0x01
|
||||||
|
#define sENDREORDER 0x02
|
||||||
|
#define sEXPRSTART 0x80 /* top bit set, rest is free */
|
||||||
|
#define sMAXARGS 127 /* relates to the bit pattern of sEXPRSTART */
|
||||||
|
|
||||||
|
#define sDOCSEP 0x01 /* to separate documentation comments between functions */
|
||||||
|
|
||||||
|
/* codes for ffabort() */
|
||||||
|
#define xEXIT 1 /* exit code in PRI */
|
||||||
|
#define xASSERTION 2 /* abort caused by failing assertion */
|
||||||
|
#define xSTACKERROR 3 /* stack/heap overflow */
|
||||||
|
#define xBOUNDSERROR 4 /* array index out of bounds */
|
||||||
|
#define xMEMACCESS 5 /* data access error */
|
||||||
|
#define xINVINSTR 6 /* invalid instruction */
|
||||||
|
#define xSTACKUNDERFLOW 7 /* stack underflow */
|
||||||
|
#define xHEAPUNDERFLOW 8 /* heap underflow */
|
||||||
|
#define xCALLBACKERR 9 /* no, or invalid, callback */
|
||||||
|
#define xSLEEP 12 /* sleep, exit code in PRI, tag in ALT */
|
||||||
|
|
||||||
|
/* Miscellaneous */
|
||||||
|
#if !defined TRUE
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
#define sIN_CSEG 1 /* if parsing CODE */
|
||||||
|
#define sIN_DSEG 2 /* if parsing DATA */
|
||||||
|
#define sCHKBOUNDS 1 /* bit position in "debug" variable: check bounds */
|
||||||
|
#define sSYMBOLIC 2 /* bit position in "debug" variable: symbolic info */
|
||||||
|
#define sRESET 0 /* reset error flag */
|
||||||
|
#define sFORCESET 1 /* force error flag on */
|
||||||
|
#define sEXPRMARK 2 /* mark start of expression */
|
||||||
|
#define sEXPRRELEASE 3 /* mark end of expression */
|
||||||
|
#define sSETPOS 4 /* set line number for the error */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
sOPTIMIZE_NONE, /* no optimization */
|
||||||
|
sOPTIMIZE_NOMACRO, /* no macro instructions */
|
||||||
|
sOPTIMIZE_DEFAULT, /* full optimization */
|
||||||
|
/* ----- */
|
||||||
|
sOPTIMIZE_NUMBER
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum s_regid {
|
||||||
|
sPRI, /* indicates the primary register */
|
||||||
|
sALT, /* indicates the secundary register */
|
||||||
|
} regid;
|
||||||
|
|
||||||
|
typedef enum s_optmark {
|
||||||
|
sEXPR, /* end of expression (for expressions that form a statement) */
|
||||||
|
sPARM, /* end of parameter (in a function parameter list) */
|
||||||
|
sLDECL, /* start of local declaration (variable) */
|
||||||
|
} optmark;
|
||||||
|
|
||||||
|
#define suSLEEP_INSTR 0x01 /* the "sleep" instruction was used */
|
||||||
|
|
||||||
|
#if INT_MAX<0x8000u
|
||||||
|
#define PUBLICTAG 0x8000u
|
||||||
|
#define FIXEDTAG 0x4000u
|
||||||
|
#else
|
||||||
|
#define PUBLICTAG 0x80000000Lu
|
||||||
|
#define FIXEDTAG 0x40000000Lu
|
||||||
|
#endif
|
||||||
|
#define TAGMASK (~PUBLICTAG)
|
||||||
|
#define CELL_MAX (((ucell)1 << (sizeof(cell)*8-1)) - 1)
|
||||||
|
|
||||||
|
|
||||||
|
/* interface functions */
|
||||||
|
#if defined __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions you call from the "driver" program
|
||||||
|
*/
|
||||||
|
int pc_compile(int argc, char **argv);
|
||||||
|
int pc_addconstant(char *name,cell value,int tag);
|
||||||
|
int pc_addtag(char *name);
|
||||||
|
int pc_enablewarning(int number,int enable);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions called from the compiler (to be implemented by you)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* general console output */
|
||||||
|
int pc_printf(const char *message,...);
|
||||||
|
|
||||||
|
/* error report function */
|
||||||
|
int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr);
|
||||||
|
|
||||||
|
/* input from source file */
|
||||||
|
void *pc_opensrc(char *filename); /* reading only */
|
||||||
|
void *pc_createsrc(char *filename);
|
||||||
|
void pc_closesrc(void *handle); /* never delete */
|
||||||
|
void pc_resetsrc(void *handle,void *position); /* reset to a position marked earlier */
|
||||||
|
char *pc_readsrc(void *handle,unsigned char *target,int maxchars);
|
||||||
|
int pc_writesrc(void *handle,unsigned char *source);
|
||||||
|
void *pc_getpossrc(void *handle); /* mark the current position */
|
||||||
|
int pc_eofsrc(void *handle);
|
||||||
|
|
||||||
|
/* output to intermediate (.ASM) file */
|
||||||
|
void *pc_openasm(char *filename); /* read/write */
|
||||||
|
void pc_closeasm(void *handle,int deletefile);
|
||||||
|
void pc_resetasm(void *handle);
|
||||||
|
int pc_writeasm(void *handle,char *str);
|
||||||
|
char *pc_readasm(void *handle,char *target,int maxchars);
|
||||||
|
|
||||||
|
/* output to binary (.AMX) file */
|
||||||
|
void *pc_openbin(char *filename);
|
||||||
|
void pc_closebin(void *handle,int deletefile);
|
||||||
|
void pc_resetbin(void *handle,long offset);
|
||||||
|
int pc_writebin(void *handle,void *buffer,int size);
|
||||||
|
long pc_lengthbin(void *handle); /* return the length of the file */
|
||||||
|
|
||||||
|
#if defined __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* by default, functions and variables used in throughout the compiler
|
||||||
|
* files are "external"
|
||||||
|
*/
|
||||||
|
#if !defined SC_FUNC
|
||||||
|
#define SC_FUNC
|
||||||
|
#endif
|
||||||
|
#if !defined SC_VDECL
|
||||||
|
#define SC_VDECL extern
|
||||||
|
#endif
|
||||||
|
#if !defined SC_VDEFINE
|
||||||
|
#define SC_VDEFINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* function prototypes in SC1.C */
|
||||||
|
SC_FUNC void set_extension(char *filename,char *extension,int force);
|
||||||
|
SC_FUNC symbol *fetchfunc(char *name,int tag);
|
||||||
|
SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag);
|
||||||
|
SC_FUNC char *funcdisplayname(char *dest,char *funcname);
|
||||||
|
SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr);
|
||||||
|
SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,int index);
|
||||||
|
SC_FUNC constvalue *find_constval(constvalue *table,char *name,int index);
|
||||||
|
SC_FUNC void delete_consttable(constvalue *table);
|
||||||
|
SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag);
|
||||||
|
SC_FUNC void exporttag(int tag);
|
||||||
|
SC_FUNC void sc_attachdocumentation(symbol *sym);
|
||||||
|
|
||||||
|
/* function prototypes in SC2.C */
|
||||||
|
#define PUSHSTK_P(v) { stkitem s_; s_.pv=(v); pushstk(s_); }
|
||||||
|
#define PUSHSTK_I(v) { stkitem s_; s_.i=(v); pushstk(s_); }
|
||||||
|
#define POPSTK_P() (popstk().pv)
|
||||||
|
#define POPSTK_I() (popstk().i)
|
||||||
|
SC_FUNC void pushstk(stkitem val);
|
||||||
|
SC_FUNC stkitem popstk(void);
|
||||||
|
SC_FUNC void clearstk(void);
|
||||||
|
SC_FUNC int plungequalifiedfile(char *name); /* explicit path included */
|
||||||
|
SC_FUNC int plungefile(char *name,int try_currentpath,int try_includepaths); /* search through "include" paths */
|
||||||
|
SC_FUNC void preprocess(void);
|
||||||
|
SC_FUNC void lexinit(void);
|
||||||
|
SC_FUNC int lex(cell *lexvalue,char **lexsym);
|
||||||
|
SC_FUNC void lexpush(void);
|
||||||
|
SC_FUNC void lexclr(int clreol);
|
||||||
|
SC_FUNC int matchtoken(int token);
|
||||||
|
SC_FUNC int tokeninfo(cell *val,char **str);
|
||||||
|
SC_FUNC int needtoken(int token);
|
||||||
|
SC_FUNC void litadd(cell value);
|
||||||
|
SC_FUNC void litinsert(cell value,int pos);
|
||||||
|
SC_FUNC int alphanum(char c);
|
||||||
|
SC_FUNC int ishex(char c);
|
||||||
|
SC_FUNC void delete_symbol(symbol *root,symbol *sym);
|
||||||
|
SC_FUNC void delete_symbols(symbol *root,int level,int del_labels,int delete_functions);
|
||||||
|
SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom);
|
||||||
|
SC_FUNC void markusage(symbol *sym,int usage);
|
||||||
|
SC_FUNC uint32_t namehash(const char *name);
|
||||||
|
SC_FUNC symbol *findglb(const char *name,int filter);
|
||||||
|
SC_FUNC symbol *findloc(const char *name);
|
||||||
|
SC_FUNC symbol *findconst(const char *name,int *matchtag);
|
||||||
|
SC_FUNC symbol *finddepend(const symbol *parent);
|
||||||
|
SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,
|
||||||
|
int usage);
|
||||||
|
SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
|
||||||
|
int dim[],int numdim,int idxtag[]);
|
||||||
|
SC_FUNC int getlabel(void);
|
||||||
|
SC_FUNC char *itoh(ucell val);
|
||||||
|
|
||||||
|
/* function prototypes in SC3.C */
|
||||||
|
SC_FUNC int check_userop(void (*oper)(void),int tag1,int tag2,int numparam,
|
||||||
|
value *lval,int *resulttag);
|
||||||
|
SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce);
|
||||||
|
SC_FUNC int expression(cell *val,int *tag,symbol **symptr,int chkfuncresult);
|
||||||
|
SC_FUNC int sc_getstateid(constvalue **automaton,constvalue **state);
|
||||||
|
SC_FUNC cell array_totalsize(symbol *sym);
|
||||||
|
|
||||||
|
/* function prototypes in SC4.C */
|
||||||
|
SC_FUNC void writeleader(symbol *root);
|
||||||
|
SC_FUNC void writetrailer(void);
|
||||||
|
SC_FUNC void begcseg(void);
|
||||||
|
SC_FUNC void begdseg(void);
|
||||||
|
SC_FUNC void setline(int chkbounds);
|
||||||
|
SC_FUNC void setfiledirect(char *name);
|
||||||
|
SC_FUNC void setlinedirect(int line);
|
||||||
|
SC_FUNC void setlabel(int index);
|
||||||
|
SC_FUNC void markexpr(optmark type,const char *name,cell offset);
|
||||||
|
SC_FUNC void startfunc(char *fname);
|
||||||
|
SC_FUNC void endfunc(void);
|
||||||
|
SC_FUNC void alignframe(int numbytes);
|
||||||
|
SC_FUNC void rvalue(value *lval);
|
||||||
|
SC_FUNC void address(symbol *ptr,regid reg);
|
||||||
|
SC_FUNC void store(value *lval);
|
||||||
|
SC_FUNC void loadreg(cell address,regid reg);
|
||||||
|
SC_FUNC void storereg(cell address,regid reg);
|
||||||
|
SC_FUNC void memcopy(cell size);
|
||||||
|
SC_FUNC void copyarray(symbol *sym,cell size);
|
||||||
|
SC_FUNC void fillarray(symbol *sym,cell size,cell value);
|
||||||
|
SC_FUNC void ldconst(cell val,regid reg);
|
||||||
|
SC_FUNC void moveto1(void);
|
||||||
|
SC_FUNC void pushreg(regid reg);
|
||||||
|
SC_FUNC void pushval(cell val);
|
||||||
|
SC_FUNC void popreg(regid reg);
|
||||||
|
SC_FUNC void swap1(void);
|
||||||
|
SC_FUNC void ffswitch(int label);
|
||||||
|
SC_FUNC void ffcase(cell value,char *labelname,int newtable);
|
||||||
|
SC_FUNC void ffcall(symbol *sym,const char *label,int numargs);
|
||||||
|
SC_FUNC void ffret(int remparams);
|
||||||
|
SC_FUNC void ffabort(int reason);
|
||||||
|
SC_FUNC void ffbounds(cell size);
|
||||||
|
SC_FUNC void jumplabel(int number);
|
||||||
|
SC_FUNC void defstorage(void);
|
||||||
|
SC_FUNC void modstk(int delta);
|
||||||
|
SC_FUNC void setstk(cell value);
|
||||||
|
SC_FUNC void modheap(int delta);
|
||||||
|
SC_FUNC void setheap_pri(void);
|
||||||
|
SC_FUNC void setheap(cell value);
|
||||||
|
SC_FUNC void cell2addr(void);
|
||||||
|
SC_FUNC void cell2addr_alt(void);
|
||||||
|
SC_FUNC void addr2cell(void);
|
||||||
|
SC_FUNC void char2addr(void);
|
||||||
|
SC_FUNC void charalign(void);
|
||||||
|
SC_FUNC void addconst(cell value);
|
||||||
|
|
||||||
|
/* Code generation functions for arithmetic operators.
|
||||||
|
*
|
||||||
|
* Syntax: o[u|s|b]_name
|
||||||
|
* | | | +--- name of operator
|
||||||
|
* | | +----- underscore
|
||||||
|
* | +--------- "u"nsigned operator, "s"igned operator or "b"oth
|
||||||
|
* +------------- "o"perator
|
||||||
|
*/
|
||||||
|
SC_FUNC void os_mult(void); /* multiplication (signed) */
|
||||||
|
SC_FUNC void os_div(void); /* division (signed) */
|
||||||
|
SC_FUNC void os_mod(void); /* modulus (signed) */
|
||||||
|
SC_FUNC void ob_add(void); /* addition */
|
||||||
|
SC_FUNC void ob_sub(void); /* subtraction */
|
||||||
|
SC_FUNC void ob_sal(void); /* shift left (arithmetic) */
|
||||||
|
SC_FUNC void os_sar(void); /* shift right (arithmetic, signed) */
|
||||||
|
SC_FUNC void ou_sar(void); /* shift right (logical, unsigned) */
|
||||||
|
SC_FUNC void ob_or(void); /* bitwise or */
|
||||||
|
SC_FUNC void ob_xor(void); /* bitwise xor */
|
||||||
|
SC_FUNC void ob_and(void); /* bitwise and */
|
||||||
|
SC_FUNC void ob_eq(void); /* equality */
|
||||||
|
SC_FUNC void ob_ne(void); /* inequality */
|
||||||
|
SC_FUNC void relop_prefix(void);
|
||||||
|
SC_FUNC void relop_suffix(void);
|
||||||
|
SC_FUNC void os_le(void); /* less or equal (signed) */
|
||||||
|
SC_FUNC void os_ge(void); /* greater or equal (signed) */
|
||||||
|
SC_FUNC void os_lt(void); /* less (signed) */
|
||||||
|
SC_FUNC void os_gt(void); /* greater (signed) */
|
||||||
|
|
||||||
|
SC_FUNC void lneg(void);
|
||||||
|
SC_FUNC void neg(void);
|
||||||
|
SC_FUNC void invert(void);
|
||||||
|
SC_FUNC void nooperation(void);
|
||||||
|
SC_FUNC void inc(value *lval);
|
||||||
|
SC_FUNC void dec(value *lval);
|
||||||
|
SC_FUNC void jmp_ne0(int number);
|
||||||
|
SC_FUNC void jmp_eq0(int number);
|
||||||
|
SC_FUNC void outval(cell val,int newline);
|
||||||
|
|
||||||
|
/* function prototypes in SC5.C */
|
||||||
|
SC_FUNC int error(int number,...);
|
||||||
|
SC_FUNC void errorset(int code,int line);
|
||||||
|
|
||||||
|
/* function prototypes in SC6.C */
|
||||||
|
SC_FUNC int assemble(FILE *fout,FILE *fin);
|
||||||
|
|
||||||
|
/* function prototypes in SC7.C */
|
||||||
|
SC_FUNC void stgbuffer_cleanup(void);
|
||||||
|
SC_FUNC void stgmark(char mark);
|
||||||
|
SC_FUNC void stgwrite(const char *st);
|
||||||
|
SC_FUNC void stgout(int index);
|
||||||
|
SC_FUNC void stgdel(int index,cell code_index);
|
||||||
|
SC_FUNC int stgget(int *index,cell *code_index);
|
||||||
|
SC_FUNC void stgset(int onoff);
|
||||||
|
SC_FUNC int phopt_init(void);
|
||||||
|
SC_FUNC int phopt_cleanup(void);
|
||||||
|
|
||||||
|
/* function prototypes in SCLIST.C */
|
||||||
|
SC_FUNC char* duplicatestring(const char* sourcestring);
|
||||||
|
SC_FUNC stringpair *insert_alias(char *name,char *alias);
|
||||||
|
SC_FUNC stringpair *find_alias(char *name);
|
||||||
|
SC_FUNC int lookup_alias(char *target,char *name);
|
||||||
|
SC_FUNC void delete_aliastable(void);
|
||||||
|
SC_FUNC stringlist *insert_path(char *path);
|
||||||
|
SC_FUNC char *get_path(int index);
|
||||||
|
SC_FUNC void delete_pathtable(void);
|
||||||
|
SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen);
|
||||||
|
SC_FUNC int get_subst(int index,char **pattern,char **substitution);
|
||||||
|
SC_FUNC stringpair *find_subst(char *name,int length);
|
||||||
|
SC_FUNC int delete_subst(char *name,int length);
|
||||||
|
SC_FUNC void delete_substtable(void);
|
||||||
|
SC_FUNC stringlist *insert_sourcefile(char *string);
|
||||||
|
SC_FUNC char *get_sourcefile(int index);
|
||||||
|
SC_FUNC void delete_sourcefiletable(void);
|
||||||
|
SC_FUNC stringlist *insert_docstring(char *string);
|
||||||
|
SC_FUNC char *get_docstring(int index);
|
||||||
|
SC_FUNC void delete_docstring(int index);
|
||||||
|
SC_FUNC void delete_docstringtable(void);
|
||||||
|
SC_FUNC stringlist *insert_autolist(char *string);
|
||||||
|
SC_FUNC char *get_autolist(int index);
|
||||||
|
SC_FUNC void delete_autolisttable(void);
|
||||||
|
SC_FUNC stringlist *insert_dbgfile(const char *filename);
|
||||||
|
SC_FUNC stringlist *insert_dbgline(int linenr);
|
||||||
|
SC_FUNC stringlist *insert_dbgsymbol(symbol *sym);
|
||||||
|
SC_FUNC char *get_dbgstring(int index);
|
||||||
|
SC_FUNC void delete_dbgstringtable(void);
|
||||||
|
|
||||||
|
/* function prototypes in SCMEMFILE.C */
|
||||||
|
#if !defined tMEMFILE
|
||||||
|
typedef unsigned char MEMFILE;
|
||||||
|
#define tMEMFILE 1
|
||||||
|
#endif
|
||||||
|
MEMFILE *mfcreate(char *filename);
|
||||||
|
void mfclose(MEMFILE *mf);
|
||||||
|
int mfdump(MEMFILE *mf);
|
||||||
|
long mflength(MEMFILE *mf);
|
||||||
|
long mfseek(MEMFILE *mf,long offset,int whence);
|
||||||
|
unsigned int mfwrite(MEMFILE *mf,unsigned char *buffer,unsigned int size);
|
||||||
|
unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size);
|
||||||
|
char *mfgets(MEMFILE *mf,char *string,unsigned int size);
|
||||||
|
int mfputs(MEMFILE *mf,char *string);
|
||||||
|
|
||||||
|
/* function prototypes in SCI18N.C */
|
||||||
|
#define MAXCODEPAGE 12
|
||||||
|
SC_FUNC int cp_path(const char *root,const char *directory);
|
||||||
|
SC_FUNC int cp_set(const char *name);
|
||||||
|
SC_FUNC cell cp_translate(const unsigned char *string,const unsigned char **endptr);
|
||||||
|
SC_FUNC cell get_utf8_char(const unsigned char *string,const unsigned char **endptr);
|
||||||
|
SC_FUNC int scan_utf8(FILE *fp,const char *filename);
|
||||||
|
|
||||||
|
/* function prototypes in SCSTATE.C */
|
||||||
|
SC_FUNC constvalue *automaton_add(const char *name);
|
||||||
|
SC_FUNC constvalue *automaton_find(const char *name);
|
||||||
|
SC_FUNC constvalue *automaton_findid(int id);
|
||||||
|
SC_FUNC constvalue *state_add(const char *name,int fsa_id);
|
||||||
|
SC_FUNC constvalue *state_find(const char *name,int fsa_id);
|
||||||
|
SC_FUNC constvalue *state_findid(int id);
|
||||||
|
SC_FUNC void state_buildlist(int **list,int *listsize,int *count,int stateid);
|
||||||
|
SC_FUNC int state_addlist(int *list,int count,int fsa_id);
|
||||||
|
SC_FUNC void state_deletetable(void);
|
||||||
|
SC_FUNC int state_getfsa(int listid);
|
||||||
|
SC_FUNC int state_count(int listid);
|
||||||
|
SC_FUNC int state_inlist(int listid,int state);
|
||||||
|
SC_FUNC int state_listitem(int listid,int index);
|
||||||
|
SC_FUNC void state_conflict(symbol *root);
|
||||||
|
SC_FUNC int state_conflict_id(int listid1,int listid2);
|
||||||
|
|
||||||
|
/* external variables (defined in scvars.c) */
|
||||||
|
#if !defined SC_SKIP_VDECL
|
||||||
|
SC_VDECL symbol loctab; /* local symbol table */
|
||||||
|
SC_VDECL symbol glbtab; /* global symbol table */
|
||||||
|
SC_VDECL cell *litq; /* the literal queue */
|
||||||
|
SC_VDECL unsigned char pline[]; /* the line read from the input file */
|
||||||
|
SC_VDECL const unsigned char *lptr;/* points to the current position in "pline" */
|
||||||
|
SC_VDECL constvalue tagname_tab;/* tagname table */
|
||||||
|
SC_VDECL constvalue libname_tab;/* library table (#pragma library "..." syntax) */
|
||||||
|
SC_VDECL constvalue *curlibrary;/* current library */
|
||||||
|
SC_VDECL int pc_addlibtable; /* is the library table added to the AMX file? */
|
||||||
|
SC_VDECL symbol *curfunc; /* pointer to current function */
|
||||||
|
SC_VDECL char *inpfname; /* name of the file currently read from */
|
||||||
|
SC_VDECL char outfname[]; /* intermediate (assembler) file name */
|
||||||
|
SC_VDECL char binfname[]; /* binary file name */
|
||||||
|
SC_VDECL char errfname[]; /* error file name */
|
||||||
|
SC_VDECL char sc_ctrlchar; /* the control character (or escape character) */
|
||||||
|
SC_VDECL char sc_ctrlchar_org;/* the default control character */
|
||||||
|
SC_VDECL int litidx; /* index to literal table */
|
||||||
|
SC_VDECL int litmax; /* current size of the literal table */
|
||||||
|
SC_VDECL int stgidx; /* index to the staging buffer */
|
||||||
|
SC_VDECL int sc_labnum; /* number of (internal) labels */
|
||||||
|
SC_VDECL int staging; /* true if staging output */
|
||||||
|
SC_VDECL cell declared; /* number of local cells declared */
|
||||||
|
SC_VDECL cell glb_declared; /* number of global cells declared */
|
||||||
|
SC_VDECL cell code_idx; /* number of bytes with generated code */
|
||||||
|
SC_VDECL int ntv_funcid; /* incremental number of native function */
|
||||||
|
SC_VDECL int errnum; /* number of errors */
|
||||||
|
SC_VDECL int warnnum; /* number of warnings */
|
||||||
|
SC_VDECL int sc_debug; /* debug/optimization options (bit field) */
|
||||||
|
SC_VDECL int sc_packstr; /* strings are packed by default? */
|
||||||
|
SC_VDECL int sc_asmfile; /* create .ASM file? */
|
||||||
|
SC_VDECL int sc_listing; /* create .LST file? */
|
||||||
|
SC_VDECL int sc_compress; /* compress bytecode? */
|
||||||
|
SC_VDECL int sc_needsemicolon;/* semicolon required to terminate expressions? */
|
||||||
|
SC_VDECL int sc_dataalign; /* data alignment value */
|
||||||
|
SC_VDECL int sc_alignnext; /* must frame of the next function be aligned? */
|
||||||
|
SC_VDECL int pc_docexpr; /* must expression be attached to documentation comment? */
|
||||||
|
SC_VDECL int curseg; /* 1 if currently parsing CODE, 2 if parsing DATA */
|
||||||
|
SC_VDECL cell pc_stksize; /* stack size */
|
||||||
|
SC_VDECL cell pc_amxlimit; /* abstract machine size limit (code + data, or only code) */
|
||||||
|
SC_VDECL cell pc_amxram; /* abstract machine data size limit */
|
||||||
|
SC_VDECL int freading; /* is there an input file ready for reading? */
|
||||||
|
SC_VDECL int fline; /* the line number in the current file */
|
||||||
|
SC_VDECL short fnumber; /* number of files in the file table (debugging) */
|
||||||
|
SC_VDECL short fcurrent; /* current file being processed (debugging) */
|
||||||
|
SC_VDECL short sc_intest; /* true if inside a test */
|
||||||
|
SC_VDECL int sideeffect; /* true if an expression causes a side-effect */
|
||||||
|
SC_VDECL int stmtindent; /* current indent of the statement */
|
||||||
|
SC_VDECL int indent_nowarn; /* skip warning "217 loose indentation" */
|
||||||
|
SC_VDECL int sc_tabsize; /* number of spaces that a TAB represents */
|
||||||
|
SC_VDECL short sc_allowtags; /* allow/detect tagnames in lex() */
|
||||||
|
SC_VDECL int sc_status; /* read/write status */
|
||||||
|
SC_VDECL int sc_rationaltag; /* tag for rational numbers */
|
||||||
|
SC_VDECL int rational_digits; /* number of fractional digits */
|
||||||
|
SC_VDECL int sc_allowproccall;/* allow/detect tagnames in lex() */
|
||||||
|
SC_VDECL short sc_is_utf8; /* is this source file in UTF-8 encoding */
|
||||||
|
SC_VDECL char *pc_depricate; /* if non-NULL, mark next declaration as depricated */
|
||||||
|
SC_VDECL int sc_curstates; /* ID of the current state list */
|
||||||
|
SC_VDECL int pc_optimize; /* (peephole) optimization level */
|
||||||
|
SC_VDECL int pc_memflags; /* special flags for the stack/heap usage */
|
||||||
|
|
||||||
|
SC_VDECL constvalue sc_automaton_tab; /* automaton table */
|
||||||
|
SC_VDECL constvalue sc_state_tab; /* state table */
|
||||||
|
|
||||||
|
SC_VDECL FILE *inpf; /* file read from (source or include) */
|
||||||
|
SC_VDECL FILE *inpf_org; /* main source file */
|
||||||
|
SC_VDECL FILE *outf; /* file written to */
|
||||||
|
|
||||||
|
SC_VDECL jmp_buf errbuf; /* target of longjmp() on a fatal error */
|
||||||
|
|
||||||
|
#if !defined SC_LIGHT
|
||||||
|
SC_VDECL int sc_makereport; /* generate a cross-reference report */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SC_SKIP_VDECL */
|
||||||
|
|
||||||
|
#endif /* SC_H_INCLUDED */
|
5605
compiler-init/sc1.c
Normal file
5605
compiler-init/sc1.c
Normal file
File diff suppressed because it is too large
Load Diff
2801
compiler-init/sc2.c
Normal file
2801
compiler-init/sc2.c
Normal file
File diff suppressed because it is too large
Load Diff
2453
compiler-init/sc3.c
Normal file
2453
compiler-init/sc3.c
Normal file
File diff suppressed because it is too large
Load Diff
1331
compiler-init/sc4.c
Normal file
1331
compiler-init/sc4.c
Normal file
File diff suppressed because it is too large
Load Diff
228
compiler-init/sc5.c
Normal file
228
compiler-init/sc5.c
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/* Pawn compiler - Error message system
|
||||||
|
* In fact a very simple system, using only 'panic mode'.
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 1997-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: sc5.c 3579 2006-06-06 13:35:29Z thiadmer $
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
#if defined LINUX || defined __GNUC__
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h> /* ANSI standardized variable argument list functions */
|
||||||
|
#include <string.h>
|
||||||
|
#if defined FORTIFY
|
||||||
|
#include <alloc/fortify.h>
|
||||||
|
#endif
|
||||||
|
#include "sc.h"
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sc5.scp"
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NUM_WARNINGS (sizeof warnmsg / sizeof warnmsg[0])
|
||||||
|
static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */
|
||||||
|
|
||||||
|
static int errflag;
|
||||||
|
static int errstart; /* line number at which the instruction started */
|
||||||
|
static int errline; /* forced line number for the error message */
|
||||||
|
|
||||||
|
/* error
|
||||||
|
*
|
||||||
|
* Outputs an error message (note: msg is passed optionally).
|
||||||
|
* If an error is found, the variable "errflag" is set and subsequent
|
||||||
|
* errors are ignored until lex() finds a semicolumn or a keyword
|
||||||
|
* (lex() resets "errflag" in that case).
|
||||||
|
*
|
||||||
|
* Global references: inpfname (reffered to only)
|
||||||
|
* fline (reffered to only)
|
||||||
|
* fcurrent (reffered to only)
|
||||||
|
* errflag (altered)
|
||||||
|
*/
|
||||||
|
SC_FUNC int error(int number,...)
|
||||||
|
{
|
||||||
|
static char *prefix[3]={ "error", "fatal error", "warning" };
|
||||||
|
static int lastline,errorcount;
|
||||||
|
static short lastfile;
|
||||||
|
char *msg,*pre;
|
||||||
|
va_list argptr;
|
||||||
|
char string[128];
|
||||||
|
|
||||||
|
/* errflag is reset on each semicolon.
|
||||||
|
* In a two-pass compiler, an error should not be reported twice. Therefore
|
||||||
|
* the error reporting is enabled only in the second pass (and only when
|
||||||
|
* actually producing output). Fatal errors may never be ignored.
|
||||||
|
*/
|
||||||
|
if ((errflag || sc_status!=statWRITE) && (number<100 || number>=200))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* also check for disabled warnings */
|
||||||
|
if (number>=200) {
|
||||||
|
int index=(number-200)/8;
|
||||||
|
int mask=1 << ((number-200)%8);
|
||||||
|
if ((warndisable[index] & mask)!=0)
|
||||||
|
return 0;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (number<100){
|
||||||
|
msg=errmsg[number-1];
|
||||||
|
pre=prefix[0];
|
||||||
|
errflag=TRUE; /* set errflag (skip rest of erroneous expression) */
|
||||||
|
errnum++;
|
||||||
|
} else if (number<200){
|
||||||
|
msg=fatalmsg[number-100];
|
||||||
|
pre=prefix[1];
|
||||||
|
errnum++; /* a fatal error also counts as an error */
|
||||||
|
} else {
|
||||||
|
msg=warnmsg[number-200];
|
||||||
|
pre=prefix[2];
|
||||||
|
warnnum++;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
strexpand(string,(unsigned char *)msg,sizeof string,SCPACK_TABLE);
|
||||||
|
|
||||||
|
assert(errstart<=fline);
|
||||||
|
if (errline>0)
|
||||||
|
errstart=errline;
|
||||||
|
else
|
||||||
|
errline=fline;
|
||||||
|
assert(errstart<=errline);
|
||||||
|
va_start(argptr,number);
|
||||||
|
if (strlen(errfname)==0) {
|
||||||
|
int start= (errstart==errline) ? -1 : errstart;
|
||||||
|
if (pc_error(number,string,inpfname,start,errline,argptr)) {
|
||||||
|
if (outf!=NULL) {
|
||||||
|
pc_closeasm(outf,TRUE);
|
||||||
|
outf=NULL;
|
||||||
|
} /* if */
|
||||||
|
longjmp(errbuf,3); /* user abort */
|
||||||
|
} /* if */
|
||||||
|
} else {
|
||||||
|
FILE *fp=fopen(errfname,"a");
|
||||||
|
if (fp!=NULL) {
|
||||||
|
if (errstart>=0 && errstart!=errline)
|
||||||
|
fprintf(fp,"%s(%d -- %d) : %s %03d: ",inpfname,errstart,errline,pre,number);
|
||||||
|
else
|
||||||
|
fprintf(fp,"%s(%d) : %s %03d: ",inpfname,errline,pre,number);
|
||||||
|
vfprintf(fp,string,argptr);
|
||||||
|
fclose(fp);
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
va_end(argptr);
|
||||||
|
|
||||||
|
if (number>=100 && number<200 || errnum>25){
|
||||||
|
if (strlen(errfname)==0) {
|
||||||
|
va_start(argptr,number);
|
||||||
|
pc_error(0,"\nCompilation aborted.",NULL,0,0,argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
} /* if */
|
||||||
|
if (outf!=NULL) {
|
||||||
|
pc_closeasm(outf,TRUE);
|
||||||
|
outf=NULL;
|
||||||
|
} /* if */
|
||||||
|
longjmp(errbuf,2); /* fatal error, quit */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
errline=-1;
|
||||||
|
/* check whether we are seeing many errors on the same line */
|
||||||
|
if ((errstart<0 && lastline!=fline) || lastline<errstart || lastline>fline || fcurrent!=lastfile)
|
||||||
|
errorcount=0;
|
||||||
|
lastline=fline;
|
||||||
|
lastfile=fcurrent;
|
||||||
|
if (number<200)
|
||||||
|
errorcount++;
|
||||||
|
if (errorcount>=3)
|
||||||
|
error(107); /* too many error/warning messages on one line */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void errorset(int code,int line)
|
||||||
|
{
|
||||||
|
switch (code) {
|
||||||
|
case sRESET:
|
||||||
|
errflag=FALSE; /* start reporting errors */
|
||||||
|
break;
|
||||||
|
case sFORCESET:
|
||||||
|
errflag=TRUE; /* stop reporting errors */
|
||||||
|
break;
|
||||||
|
case sEXPRMARK:
|
||||||
|
errstart=fline; /* save start line number */
|
||||||
|
break;
|
||||||
|
case sEXPRRELEASE:
|
||||||
|
errstart=-1; /* forget start line number */
|
||||||
|
errline=-1;
|
||||||
|
break;
|
||||||
|
case sSETPOS:
|
||||||
|
errline=line;
|
||||||
|
break;
|
||||||
|
} /* switch */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sc_enablewarning()
|
||||||
|
* Enables or disables a warning (errors cannot be disabled).
|
||||||
|
* Initially all warnings are enabled. The compiler does this by setting bits
|
||||||
|
* for the *disabled* warnings and relying on the array to be zero-initialized.
|
||||||
|
*
|
||||||
|
* Parameter enable can be:
|
||||||
|
* o 0 for disable
|
||||||
|
* o 1 for enable
|
||||||
|
* o 2 for toggle
|
||||||
|
*/
|
||||||
|
int pc_enablewarning(int number,int enable)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
unsigned char mask;
|
||||||
|
|
||||||
|
if (number<200)
|
||||||
|
return FALSE; /* errors and fatal errors cannot be disabled */
|
||||||
|
number -= 200;
|
||||||
|
if (number>=NUM_WARNINGS)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
index=number/8;
|
||||||
|
mask=(unsigned char)(1 << (number%8));
|
||||||
|
switch (enable) {
|
||||||
|
case 0:
|
||||||
|
warndisable[index] |= mask;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
warndisable[index] &= (unsigned char)~mask;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
warndisable[index] ^= mask;
|
||||||
|
break;
|
||||||
|
} /* switch */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SCPACK_TABLE
|
342
compiler-init/sc5.scp
Normal file
342
compiler-init/sc5.scp
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
/* Pawn compiler - Error message strings (plain and compressed formats)
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 2000-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: sc5.sch 3590 2006-06-24 14:16:39Z thiadmer $
|
||||||
|
*/
|
||||||
|
|
||||||
|
SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]);
|
||||||
|
|
||||||
|
#define SCPACK_TABLE errstr_table
|
||||||
|
/*-*SCPACK start of pair table, do not change or remove this line */
|
||||||
|
unsigned char errstr_table[][2] = {
|
||||||
|
{101,32}, {111,110}, {116,32}, {105,110}, {97,114}, {116,105}, {100,32}, {115,32}, {101,114}, {97,108}, {101,110}, {37,115}, {133,129}, {34,139}, {141,34}, {117,110},
|
||||||
|
{110,111}, {114,101}, {115,105}, {121,32}, {97,116}, {111,114}, {97,110}, {32,142}, {109,98}, {115,116}, {41,10}, {100,101}, {109,138}, {101,134}, {98,108}, {140,32},
|
||||||
|
{111,108}, {114,97}, {144,130}, {118,137}, {143,99}, {102,164}, {115,121}, {166,152}, {167,160}, {117,115}, {97,32}, {115,146}, {97,158}, {149,32}, {132,161}, {105,134},
|
||||||
|
{103,32}, {163,175}, {103,117}, {178,156}, {136,32}, {132,179}, {131,177}, {111,102}, {116,104}, {101,120}, {105,135}, {165,159}, {101,100}, {99,104}, {118,132}, {168,151},
|
||||||
|
{105,172}, {190,192}, {155,102}, {174,147}, {183,32}, {109,97}, {116,111}, {99,129}, {101,135}, {181,130}, {98,128}, {115,10}, {112,145}, {153,148}, {44,32}, {40,191},
|
||||||
|
{169,130}, {151,10}, {101,10}, {207,154}, {109,208}, {116,97}, {105,99}, {194,131}, {193,128}, {34,32}, {129,32}, {132,97}, {100,105}, {146,122}, {110,32}, {137,32},
|
||||||
|
{104,97}, {101,108}, {117,108}, {99,111}, {108,111}, {109,148}, {199,153}, {58,209}, {111,112}, {97,115}, {108,128}, {232,136}, {230,150}, {150,32}, {204,171}, {131,176},
|
||||||
|
{212,202}, {102,105}, {119,105}, {185,238}, {109,112}, {116,136}, {165,140}, {197,147}, {102,149}, {111,32}, {131,32}, {213,176}, {110,117}, {115,117}, {118,128}
|
||||||
|
};
|
||||||
|
/*-*SCPACK end of pair table, do not change or remove this line */
|
||||||
|
|
||||||
|
static char *errmsg[] = {
|
||||||
|
#ifdef SCPACK
|
||||||
|
/*001*/ "expected token: \"%s\", but found \"%s\"\n",
|
||||||
|
/*002*/ "only a single statement (or expression) can follow each \"case\"\n",
|
||||||
|
/*003*/ "declaration of a local variable must appear in a compound block\n",
|
||||||
|
/*004*/ "function \"%s\" is not implemented\n",
|
||||||
|
/*005*/ "function may not have arguments\n",
|
||||||
|
/*006*/ "must be assigned to an array\n",
|
||||||
|
/*007*/ "operator cannot be redefined\n",
|
||||||
|
/*008*/ "must be a constant expression; assumed zero\n",
|
||||||
|
/*009*/ "invalid array size (negative, zero or out of bounds)\n",
|
||||||
|
/*010*/ "invalid function or declaration\n",
|
||||||
|
/*011*/ "invalid outside functions\n",
|
||||||
|
/*012*/ "invalid function call, not a valid address\n",
|
||||||
|
/*013*/ "no entry point (no public functions)\n",
|
||||||
|
/*014*/ "invalid statement; not in switch\n",
|
||||||
|
/*015*/ "\"default\" case must be the last case in switch statement\n",
|
||||||
|
/*016*/ "multiple defaults in \"switch\"\n",
|
||||||
|
/*017*/ "undefined symbol \"%s\"\n",
|
||||||
|
/*018*/ "initialization data exceeds declared size\n",
|
||||||
|
/*019*/ "not a label: \"%s\"\n",
|
||||||
|
/*020*/ "invalid symbol name \"%s\"\n",
|
||||||
|
/*021*/ "symbol already defined: \"%s\"\n",
|
||||||
|
/*022*/ "must be lvalue (non-constant)\n",
|
||||||
|
/*023*/ "array assignment must be simple assignment\n",
|
||||||
|
/*024*/ "\"break\" or \"continue\" is out of context\n",
|
||||||
|
/*025*/ "function heading differs from prototype\n",
|
||||||
|
/*026*/ "no matching \"#if...\"\n",
|
||||||
|
/*027*/ "invalid character constant\n",
|
||||||
|
/*028*/ "invalid subscript (not an array or too many subscripts): \"%s\"\n",
|
||||||
|
/*029*/ "invalid expression, assumed zero\n",
|
||||||
|
/*030*/ "compound statement not closed at the end of file (started at line %d)\n",
|
||||||
|
/*031*/ "unknown directive\n",
|
||||||
|
/*032*/ "array index out of bounds (variable \"%s\")\n",
|
||||||
|
/*033*/ "array must be indexed (variable \"%s\")\n",
|
||||||
|
/*034*/ "argument does not have a default value (argument %d)\n",
|
||||||
|
/*035*/ "argument type mismatch (argument %d)\n",
|
||||||
|
/*036*/ "empty statement\n",
|
||||||
|
/*037*/ "invalid string (possibly non-terminated string)\n",
|
||||||
|
/*038*/ "extra characters on line\n",
|
||||||
|
/*039*/ "constant symbol has no size\n",
|
||||||
|
/*040*/ "duplicate \"case\" label (value %d)\n",
|
||||||
|
/*041*/ "invalid ellipsis, array size is not known\n",
|
||||||
|
/*042*/ "invalid combination of class specifiers\n",
|
||||||
|
/*043*/ "character constant exceeds range for packed string\n",
|
||||||
|
/*044*/ "positional parameters must precede all named parameters\n",
|
||||||
|
/*045*/ "too many function arguments\n",
|
||||||
|
/*046*/ "unknown array size (variable \"%s\")\n",
|
||||||
|
/*047*/ "array sizes do not match, or destination array is too small\n",
|
||||||
|
/*048*/ "array dimensions do not match\n",
|
||||||
|
/*049*/ "invalid line continuation\n",
|
||||||
|
/*050*/ "invalid range\n",
|
||||||
|
/*051*/ "invalid subscript, use \"[ ]\" operators on major dimensions\n",
|
||||||
|
/*052*/ "multi-dimensional arrays must be fully initialized\n",
|
||||||
|
/*053*/ "exceeding maximum number of dimensions\n",
|
||||||
|
/*054*/ "unmatched closing brace (\"}\")\n",
|
||||||
|
/*055*/ "start of function body without function header\n",
|
||||||
|
/*056*/ "arrays, local variables and function arguments cannot be public (variable \"%s\")\n",
|
||||||
|
/*057*/ "unfinished expression before compiler directive\n",
|
||||||
|
/*058*/ "duplicate argument; same argument is passed twice\n",
|
||||||
|
/*059*/ "function argument may not have a default value (variable \"%s\")\n",
|
||||||
|
/*060*/ "multiple \"#else\" directives between \"#if ... #endif\"\n",
|
||||||
|
/*061*/ "\"#elseif\" directive follows an \"#else\" directive\n",
|
||||||
|
/*062*/ "number of operands does not fit the operator\n",
|
||||||
|
/*063*/ "function result tag of operator \"%s\" must be \"%s\"\n",
|
||||||
|
/*064*/ "cannot change predefined operators\n",
|
||||||
|
/*065*/ "function argument may only have a single tag (argument %d)\n",
|
||||||
|
/*066*/ "function argument may not be a reference argument or an array (argument \"%s\")\n",
|
||||||
|
/*067*/ "variable cannot be both a reference and an array (variable \"%s\")\n",
|
||||||
|
/*068*/ "invalid rational number precision in #pragma\n",
|
||||||
|
/*069*/ "rational number format already defined\n",
|
||||||
|
/*070*/ "rational number support was not enabled\n",
|
||||||
|
/*071*/ "user-defined operator must be declared before use (function \"%s\")\n",
|
||||||
|
/*072*/ "\"sizeof\" operator is invalid on \"function\" symbols\n",
|
||||||
|
/*073*/ "function argument must be an array (argument \"%s\")\n",
|
||||||
|
/*074*/ "#define pattern must start with an alphabetic character\n",
|
||||||
|
/*075*/ "input line too long (after substitutions)\n",
|
||||||
|
/*076*/ "syntax error in the expression, or invalid function call\n",
|
||||||
|
/*077*/ "malformed UTF-8 encoding, or corrupted file: %s\n",
|
||||||
|
/*078*/ "function uses both \"return\" and \"return <value>\"\n",
|
||||||
|
/*079*/ "inconsistent return types (array & non-array)\n",
|
||||||
|
/*080*/ "unknown symbol, or not a constant symbol (symbol \"%s\")\n",
|
||||||
|
/*081*/ "cannot take a tag as a default value for an indexed array parameter (symbol \"%s\")\n",
|
||||||
|
/*082*/ "user-defined operators and native functions may not have states\n",
|
||||||
|
/*083*/ "a function or variable may only belong to a single automaton (symbol \"%s\")\n",
|
||||||
|
/*084*/ "state conflict: one of the states is already assigned to another implementation (symbol \"%s\")\n",
|
||||||
|
/*085*/ "no states are defined for symbol \"%s\"\n",
|
||||||
|
/*086*/ "unknown automaton \"%s\"\n",
|
||||||
|
/*087*/ "unknown state \"%s\" for automaton \"%s\"\n",
|
||||||
|
/*088*/ "public variables and local variables may not have states (symbol \"%s\")\n",
|
||||||
|
/*089*/ "state variables may not be initialized (symbol \"%s\")\n",
|
||||||
|
/*090*/ "public functions may not return arrays (symbol \"%s\")\n",
|
||||||
|
/*091*/ "ambiguous constant; tag override is required (symbol \"%s\")\n"
|
||||||
|
#else
|
||||||
|
"\271pect\235\306k\212:\227\316bu\202fo\217\206\216\012",
|
||||||
|
"\201l\223\252s\203g\352\315e\234\202(\255\363\201) c\355f\240\344w ea\275 \042c\351e\042\012",
|
||||||
|
"\233cl\333\237\304\252\344c\337\330\324appe\204 \372\252\343\364o\217\206\236ock\012",
|
||||||
|
"\366\227 \272\242i\364le\234t\274\012",
|
||||||
|
"\273\367\242\340\376\265t\313",
|
||||||
|
"\360a\253gn\235\306 \355\256y\012",
|
||||||
|
"\353\224\255c\226\242\312\221\327\274\012",
|
||||||
|
"\360\252\354\202\363\201; \351\375m\235z\210o\012",
|
||||||
|
"\266\303\335\200(nega\205ve\316z\210\371\255ou\202\304bo\217ds\232",
|
||||||
|
"\266\273\255\233cl\333\214\012",
|
||||||
|
"\266out\222d\200\366\313",
|
||||||
|
"\266\273c\211l\316\242\252\261add\221s\313",
|
||||||
|
"\220 \212tr\223po\203\202(\220 pu\236\326 \366s\232",
|
||||||
|
"\266\315e\234t; \242\372s\362t\275\012",
|
||||||
|
"\042\302a\342t\331c\351\200\360\270\200l\351\202c\351\200\372s\362t\275 \315e\234t\012",
|
||||||
|
"m\342\205p\352\302a\342t\207\372\042s\362t\275\042\012",
|
||||||
|
"\217\327\235\277\012",
|
||||||
|
"\203i\205\211iza\237d\224\252\271ce\274\207\233cl\204\235\335\322",
|
||||||
|
"\242\252lab\341\347",
|
||||||
|
"\266\250 nam\200\216\012",
|
||||||
|
"\250 \211\221ad\223\327\274\347",
|
||||||
|
"\360l\243u\200(n\201-\354t\232",
|
||||||
|
"\303a\253gn\234\202\360\222\364\352a\253gn\234t\012",
|
||||||
|
"\042b\221ak\331\255\042\307t\203ue\331\272ou\202\304\307t\271t\012",
|
||||||
|
"\273head\357\334ff\210\207from pro\306typ\322",
|
||||||
|
"\220 \345\275\357\042#if...\042\012",
|
||||||
|
"\266\275\333ct\264\354t\012",
|
||||||
|
"\266\375bscrip\202(\242\355\303\255\306\371m\226\223\375bscripts)\347",
|
||||||
|
"\266\363\201\316\351\375m\235z\210o\012",
|
||||||
|
"\343\364o\217\206\315e\234\202\242c\344s\235a\202\270\200\212\206\304\361\352(\231\204t\235a\202l\203\200%d\232",
|
||||||
|
"\217k\220w\336\334\221c\205v\322",
|
||||||
|
"\303\203\233x ou\202\304bo\217d\207(\330\216\232",
|
||||||
|
"\303\360\203\233x\235(\330\216\232",
|
||||||
|
"\311do\310\242\340\376\252\302a\342\202\243u\200(\311%d\232",
|
||||||
|
"\311typ\200mis\345\275 (\311%d\232",
|
||||||
|
"e\364t\223\315e\234t\012",
|
||||||
|
"\266\231r\357(po\253\236\223n\201-\365m\203\224\235\231r\203g\232",
|
||||||
|
"\271t\241 \275\333c\365\207\332l\203\322",
|
||||||
|
"\354\202\250 \340\207\220 \335\322",
|
||||||
|
"dupl\326\224\200\042c\351e\331lab\341 (\243u\200%d\232",
|
||||||
|
"\266\341lip\222s\316\303\335\200\272\242k\220wn\012",
|
||||||
|
"\266\343\230\203a\237\304cl\351\207speci\361\210\313",
|
||||||
|
"\275\333ct\264\354\202\271ce\274\207r\226g\200f\255pack\235\231r\203g\012",
|
||||||
|
"po\222\214\337p\333me\365\207\324\314c\274\200\211l nam\235p\333me\365\313",
|
||||||
|
"\306\371m\226\223\273\265t\313",
|
||||||
|
"\217k\220w\336\303\335\200(\330\216\232",
|
||||||
|
"\303\335\310d\371\242\345\275\316\255\233\231\203a\237\303\272\306\371sm\211l\012",
|
||||||
|
"\303\334\234\222\201\207d\371\242\345\275\012",
|
||||||
|
"\266l\203\200\307t\203ua\214\012",
|
||||||
|
"\266r\226g\322",
|
||||||
|
"\266\375bscript\316\251\200\042[ ]\331\353\224\225\207\332\305j\255\334\234\222\201\313",
|
||||||
|
"m\342\205-\334\234\222\201\337\256y\207\360f\342l\223\203i\205\211iz\274\012",
|
||||||
|
"\271ce\274\357\305ximum \374\230\264\304\334\234\222\201\313",
|
||||||
|
"\217\345\275\235c\344s\357b\241c\200(\042}\042\232",
|
||||||
|
"\231\204\202\304\273bod\223\362\270ou\202\273head\210\012",
|
||||||
|
"\256ys\316\344c\337\301\310\226\206\273\265t\207c\226\242\312pu\236\326 (\330\216\232",
|
||||||
|
"\217f\203ish\235\363\332be\370\200\343\364il\264\334\221c\205v\322",
|
||||||
|
"dupl\326\224\200\265t; sam\200\311\272p\351s\235tw\326\322",
|
||||||
|
"\273\311\367\242\340\376\252\302a\342\202\243u\200(\330\216\232",
|
||||||
|
"m\342\205p\352\042#\341se\331\334\221c\205v\310betwe\212 \042#if ... #\212\334f\042\012",
|
||||||
|
"\042#\341seif\331\334\221c\205\376f\240\344w\207\355\042#\341se\331\334\221c\205v\322",
|
||||||
|
"\374\230\264\304\353\226d\207do\310\242\361\202\270\200\353\224\225\012",
|
||||||
|
"\273\221s\342\202\373\304\353\224\225\227 \360\216\012",
|
||||||
|
"c\226\242\275\226g\200\314\327\235\353\224\225\313",
|
||||||
|
"\273\311\367\201l\223\340\376\252s\203g\352\373(\311%d\232",
|
||||||
|
"\273\311\367\242\312\252\221f\210\212c\200\311\255\355\303(\311\216\232",
|
||||||
|
"\330c\226\242\312bo\270 \252\221f\210\212c\200\226\206\355\303(\330\216\232",
|
||||||
|
"\266\241\214\337\374\230\264\314ci\222\332\372#p\241g\305\012",
|
||||||
|
"\241\214\337\374\230\264\370\305\202\211\221ad\223\327\274\012",
|
||||||
|
"\241\214\337\374\230\264\375pp\225\202wa\207\242\212\254\274\012",
|
||||||
|
"\251\210-\327\235\353\224\255\360\233cl\204\235be\370\200\251\200(\366\227\232",
|
||||||
|
"\042\335e\267\331\353\224\255\272\266\332\042\366\331\250\313",
|
||||||
|
"\273\311\360\355\303(\311\216\232",
|
||||||
|
"#\327\200p\224\365\336\324\231\204\202\362\270 \355\211p\340be\205c \275\333c\365\012",
|
||||||
|
"\203pu\202l\203\200\306\371l\201\260(aft\264\375bs\205tu\214s\232",
|
||||||
|
"\246n\325x \210r\255\372\270\200\363\201\316\255\266\273c\211l\012",
|
||||||
|
"m\211\370m\235UTF-8 \212\343d\203g\316\255c\225rupt\235\361le: \213\012",
|
||||||
|
"\273\251\310bo\270 \042\221turn\331\226\206\042\221tur\336<\243ue>\042\012",
|
||||||
|
"\203\307\222\231\212\202\221tur\336typ\310(\303& n\201-\256y\232",
|
||||||
|
"\217k\220w\336\250\316\255\242\252\354\202\250 \323",
|
||||||
|
"c\226\242\325k\200\252\373a\207\252\302a\342\202\243u\200f\255\355\203\233x\235\303p\333met\264\323",
|
||||||
|
"\251\210-\327\235\353\224\225\207\226\206na\205\376\366\207\367\242\340\376\315e\313",
|
||||||
|
"\252\273\255\330\367\201l\223b\341\201\260\306 \252s\203g\352au\306\345\332\323",
|
||||||
|
"\315\200\307fl\326t: \201\200\304\270\200\315\310\272\211\221ad\223a\253gn\235\306 a\220\270\264i\364le\234\325\237\323",
|
||||||
|
"\220 \315\310\204\200\327\235f\255\277\012",
|
||||||
|
"\217k\220w\336au\306\345\201\321",
|
||||||
|
"\217k\220w\336\315\200\216 f\255au\306\345\201\321",
|
||||||
|
"pu\236\326 \301\310\226\206\344c\337\301\310\367\242\340\376\315\310\323",
|
||||||
|
"\315\200\301\310\367\242\312\203i\205\211iz\235\323",
|
||||||
|
"pu\236\326 \366\207\367\242\221tur\336\256y\207\323",
|
||||||
|
"a\230i\262ou\207\354t; \373ov\210rid\200\272\221qui\221\206\323"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *fatalmsg[] = {
|
||||||
|
#ifdef SCPACK
|
||||||
|
/*100*/ "cannot read from file: \"%s\"\n",
|
||||||
|
/*101*/ "cannot write to file: \"%s\"\n",
|
||||||
|
/*102*/ "table overflow: \"%s\"\n",
|
||||||
|
/* table can be: loop table
|
||||||
|
* literal table
|
||||||
|
* staging buffer
|
||||||
|
* option table (response file)
|
||||||
|
* peephole optimizer table
|
||||||
|
*/
|
||||||
|
/*103*/ "insufficient memory\n",
|
||||||
|
/*104*/ "invalid assembler instruction \"%s\"\n",
|
||||||
|
/*105*/ "numeric overflow, exceeding capacity\n",
|
||||||
|
/*106*/ "compiled script exceeds the maximum memory size (%ld bytes)\n",
|
||||||
|
/*107*/ "too many error messages on one line\n",
|
||||||
|
/*108*/ "codepage mapping file not found\n",
|
||||||
|
/*109*/ "invalid path: \"%s\"\n",
|
||||||
|
/*110*/ "assertion failed: %s\n",
|
||||||
|
/*111*/ "user error: %s\n",
|
||||||
|
#else
|
||||||
|
"c\226\242\221a\206from \361le\347",
|
||||||
|
"c\226\242writ\200\306 \361le\347",
|
||||||
|
"t\254\200ov\210f\344w\347",
|
||||||
|
"\203\375ff\326i\212\202mem\225y\012",
|
||||||
|
"\266\351se\230l\264\203\231ruc\214\321",
|
||||||
|
"\374m\210\326 ov\210f\344w\316\271ce\274\357capacity\012",
|
||||||
|
"\343\364il\235scrip\202\271ce\274\207\270\200\305ximum mem\225\223\335\200(%l\206bytes\232",
|
||||||
|
"\306\371m\226\223\210r\255messag\310\332\201\200l\203\322",
|
||||||
|
"\343\233pag\200\305pp\357\361\352\242fo\217d\012",
|
||||||
|
"\266p\224h\347",
|
||||||
|
"\351s\210\237fail\274: \213\012",
|
||||||
|
"\251\264\210r\225: \213\012"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *warnmsg[] = {
|
||||||
|
#ifdef SCPACK
|
||||||
|
/*200*/ "symbol \"%s\" is truncated to %d characters\n",
|
||||||
|
/*201*/ "redefinition of constant/macro (symbol \"%s\")\n",
|
||||||
|
/*202*/ "number of arguments does not match definition\n",
|
||||||
|
/*203*/ "symbol is never used: \"%s\"\n",
|
||||||
|
/*204*/ "symbol is assigned a value that is never used: \"%s\"\n",
|
||||||
|
/*205*/ "redundant code: constant expression is zero\n",
|
||||||
|
/*206*/ "redundant test: constant expression is non-zero\n",
|
||||||
|
/*207*/ "unknown #pragma\n",
|
||||||
|
/*208*/ "function with tag result used before definition, forcing reparse\n",
|
||||||
|
/*209*/ "function \"%s\" should return a value\n",
|
||||||
|
/*210*/ "possible use of symbol before initialization: \"%s\"\n",
|
||||||
|
/*211*/ "possibly unintended assignment\n",
|
||||||
|
/*212*/ "possibly unintended bitwise operation\n",
|
||||||
|
/*213*/ "tag mismatch\n",
|
||||||
|
/*214*/ "possibly a \"const\" array argument was intended: \"%s\"\n",
|
||||||
|
/*215*/ "expression has no effect\n",
|
||||||
|
/*216*/ "nested comment\n",
|
||||||
|
/*217*/ "loose indentation\n",
|
||||||
|
/*218*/ "old style prototypes used with optional semicolumns\n",
|
||||||
|
/*219*/ "local variable \"%s\" shadows a variable at a preceding level\n",
|
||||||
|
/*220*/ "expression with tag override must appear between parentheses\n",
|
||||||
|
/*221*/ "label name \"%s\" shadows tag name\n",
|
||||||
|
/*222*/ "number of digits exceeds rational number precision\n",
|
||||||
|
/*223*/ "redundant \"sizeof\": argument size is always 1 (symbol \"%s\")\n",
|
||||||
|
/*224*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n",
|
||||||
|
/*225*/ "unreachable code\n",
|
||||||
|
/*226*/ "a variable is assigned to itself (symbol \"%s\")\n",
|
||||||
|
/*227*/ "more initiallers than enum fields\n",
|
||||||
|
/*228*/ "length of initialler exceeds size of the enum field\n",
|
||||||
|
/*229*/ "index tag mismatch (symbol \"%s\")\n",
|
||||||
|
/*230*/ "no implementation for state \"%s\" in function \"%s\", no fall-back\n",
|
||||||
|
/*231*/ "state specification on forward declaration is ignored\n",
|
||||||
|
/*232*/ "output file is written, but with compact encoding disabled\n",
|
||||||
|
/*233*/ "state variable \"%s\" shadows a global variable\n",
|
||||||
|
/*234*/ "function is depricated (symbol \"%s\") %s\n",
|
||||||
|
/*235*/ "public function lacks forward declaration (symbol \"%s\")\n",
|
||||||
|
/*236*/ "unknown parameter in substitution (incorrect #define pattern)\n"
|
||||||
|
#else
|
||||||
|
"\277 \272tr\244\224\235\306 %\206\275\333c\365\313",
|
||||||
|
"\221\327i\237\304\354t/\305cr\371\323",
|
||||||
|
"\374\230\264\304\265t\207do\310\242\345\275 \327i\214\012",
|
||||||
|
"\250 \272nev\264\251\274\347",
|
||||||
|
"\250 \272a\253gn\235\252\243u\200\270a\202\272nev\264\251\274\347",
|
||||||
|
"\221d\217d\226\202\343\233: \354\202\363\332\272z\210o\012",
|
||||||
|
"\221d\217d\226\202te\231: \354\202\363\332\272n\201-z\210o\012",
|
||||||
|
"\217k\220w\336#p\241g\305\012",
|
||||||
|
"\273\362\270 \373\221s\342\202\251\235be\370\200\327i\214\316\370c\357\221p\204s\322",
|
||||||
|
"\366\227 sho\342\206\221tur\336\252\243u\322",
|
||||||
|
"po\253\236\200\251\200\304\250 be\370\200\203i\205\211iza\214\347",
|
||||||
|
"po\253\236\223\217\203t\212\233\206a\253gn\234t\012",
|
||||||
|
"po\253\236\223\217\203t\212\233\206bit\362s\200\353a\214\012",
|
||||||
|
"\373mis\345\275\012",
|
||||||
|
"po\253\236\223\252\042\346\331\303\311wa\207\203t\212\233d\347",
|
||||||
|
"\363\332\340\207\220 effect\012",
|
||||||
|
"ne\231\235\343m\234t\012",
|
||||||
|
"\344os\200\203d\212\325\214\012",
|
||||||
|
"\240\206\231y\352pro\306typ\310\251\235\362\270 \350\214\337sem\326\240umn\313",
|
||||||
|
"\344c\337\330\216 s\340dow\207\252\330a\202\252\314c\274\357lev\341\012",
|
||||||
|
"\363\332\362\270 \373ov\210rid\200\324appe\204 betwe\212 p\204\212\270ese\313",
|
||||||
|
"lab\341 nam\200\216 s\340dow\207\373nam\322",
|
||||||
|
"\374\230\264\304\334git\207\271ce\274\207\241\214\337\374\230\264\314ci\222\201\012",
|
||||||
|
"\221d\217d\226\202\042\335e\267\042: \311\335\200\272\211way\2071 \323",
|
||||||
|
"\203\233\365m\203\224\200\303\335\200\372\042\335e\267\331\363\332\323",
|
||||||
|
"\217\221a\275\254\200\343\233\012",
|
||||||
|
"\252\330\272a\253gn\235\306 its\341f \323",
|
||||||
|
"m\225\200\203i\205\211l\210\207\270\355\212um \361\341d\313",
|
||||||
|
"l\212g\270 \304\203i\205\211l\264\271ce\274\207\335\200\304\270\200\212um \361\341d\012",
|
||||||
|
"\203\233x \373mis\345\275 \323",
|
||||||
|
"\220 i\364le\234\325\237f\255\315\200\216 \372\366\227\316\220 f\211l-back\012",
|
||||||
|
"\315\200specif\326a\237\332\370w\204\206\233cl\333\237\272ig\220\221d\012",
|
||||||
|
"outpu\202\361\352\272writt\212\316bu\202\362\270 \343\364ac\202\212\343d\357\334s\254\274\012",
|
||||||
|
"\315\200\330\216 s\340dow\207\252g\344b\337\301\322",
|
||||||
|
"\273\272\233pr\326\224\235\317) \213\012",
|
||||||
|
"pu\236\326 \273lack\207\370w\204\206\233cl\333\237\323",
|
||||||
|
"\217k\220w\336p\333met\264\372\375bs\205tu\237(\203c\225\221c\202#\327\200p\224\365n\232"
|
||||||
|
#endif
|
||||||
|
};
|
1298
compiler-init/sc6.c
Normal file
1298
compiler-init/sc6.c
Normal file
File diff suppressed because it is too large
Load Diff
703
compiler-init/sc7.c
Normal file
703
compiler-init/sc7.c
Normal file
@ -0,0 +1,703 @@
|
|||||||
|
/* Pawn compiler - Staging buffer and optimizer
|
||||||
|
*
|
||||||
|
* The staging buffer
|
||||||
|
* ------------------
|
||||||
|
* The staging buffer allows buffered output of generated code, deletion
|
||||||
|
* of redundant code, optimization by a tinkering process and reversing
|
||||||
|
* the ouput of evaluated expressions (which is used for the reversed
|
||||||
|
* evaluation of arguments in functions).
|
||||||
|
* Initially, stgwrite() writes to the file directly, but after a call to
|
||||||
|
* stgset(TRUE), output is redirected to the buffer. After a call to
|
||||||
|
* stgset(FALSE), stgwrite()'s output is directed to the file again. Thus
|
||||||
|
* only one routine is used for writing to the output, which can be
|
||||||
|
* buffered output or direct output.
|
||||||
|
*
|
||||||
|
* staging buffer variables: stgbuf - the buffer
|
||||||
|
* stgidx - current index in the staging buffer
|
||||||
|
* staging - if true, write to the staging buffer;
|
||||||
|
* if false, write to file directly.
|
||||||
|
*
|
||||||
|
* The peephole optimizer uses a dual "pipeline". The staging buffer (described
|
||||||
|
* above) gets optimized for each expression or sub-expression in a function
|
||||||
|
* call. The peephole optimizer is recursive, but it does not span multiple
|
||||||
|
* sub-expressions. However, the data gets written to a second buffer that
|
||||||
|
* behaves much like the staging buffer. This second buffer gathers all
|
||||||
|
* optimized strings from the staging buffer for a complete expression. The
|
||||||
|
* peephole optmizer then runs over this second buffer to find optimzations
|
||||||
|
* across function parameter boundaries.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 1997-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: sc7.c 3579 2006-06-06 13:35:29Z thiadmer $
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h> /* for atoi() */
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#if defined FORTIFY
|
||||||
|
#include <alloc/fortify.h>
|
||||||
|
#endif
|
||||||
|
#include "sc.h"
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sc7.scp"
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int stgstring(char *start,char *end);
|
||||||
|
static void stgopt(char *start,char *end,int (*outputfunc)(char *str));
|
||||||
|
|
||||||
|
|
||||||
|
#define sSTG_GROW 512
|
||||||
|
#define sSTG_MAX 20480
|
||||||
|
|
||||||
|
static char *stgbuf=NULL;
|
||||||
|
static int stgmax=0; /* current size of the staging buffer */
|
||||||
|
|
||||||
|
static char *stgpipe=NULL;
|
||||||
|
static int pipemax=0; /* current size of the stage pipe, a second staging buffer */
|
||||||
|
static int pipeidx=0;
|
||||||
|
|
||||||
|
#define CHECK_STGBUFFER(index) if ((int)(index)>=stgmax) grow_stgbuffer(&stgbuf, stgmax, (index)+1)
|
||||||
|
#define CHECK_STGPIPE(index) if ((int)(index)>=pipemax) grow_stgbuffer(&stgpipe, pipemax, (index)+1)
|
||||||
|
|
||||||
|
static void grow_stgbuffer(char **buffer, int curmax, int requiredsize)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
int clear= (*buffer==NULL); /* if previously none, empty buffer explicitly */
|
||||||
|
|
||||||
|
assert(curmax<requiredsize);
|
||||||
|
/* if the staging buffer (holding intermediate code for one line) grows
|
||||||
|
* over a few kBytes, there is probably a run-away expression
|
||||||
|
*/
|
||||||
|
if (requiredsize>sSTG_MAX)
|
||||||
|
error(102,"staging buffer"); /* staging buffer overflow (fatal error) */
|
||||||
|
curmax=requiredsize+sSTG_GROW;
|
||||||
|
if (*buffer!=NULL)
|
||||||
|
p=(char *)realloc(*buffer,curmax*sizeof(char));
|
||||||
|
else
|
||||||
|
p=(char *)malloc(curmax*sizeof(char));
|
||||||
|
if (p==NULL)
|
||||||
|
error(102,"staging buffer"); /* staging buffer overflow (fatal error) */
|
||||||
|
*buffer=p;
|
||||||
|
if (clear)
|
||||||
|
**buffer='\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void stgbuffer_cleanup(void)
|
||||||
|
{
|
||||||
|
if (stgbuf!=NULL) {
|
||||||
|
free(stgbuf);
|
||||||
|
stgbuf=NULL;
|
||||||
|
stgmax=0;
|
||||||
|
} /* if */
|
||||||
|
if (stgpipe!=NULL) {
|
||||||
|
free(stgpipe);
|
||||||
|
stgpipe=NULL;
|
||||||
|
pipemax=0;
|
||||||
|
pipeidx=0;
|
||||||
|
} /* if */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the variables "stgidx" and "staging" are declared in "scvars.c" */
|
||||||
|
|
||||||
|
/* stgmark
|
||||||
|
*
|
||||||
|
* Copies a mark into the staging buffer. At this moment there are three
|
||||||
|
* possible marks:
|
||||||
|
* sSTARTREORDER identifies the beginning of a series of expression
|
||||||
|
* strings that must be written to the output file in
|
||||||
|
* reordered order
|
||||||
|
* sENDREORDER identifies the end of 'reverse evaluation'
|
||||||
|
* sEXPRSTART + idx only valid within a block that is evaluated in
|
||||||
|
* reordered order, it identifies the start of an
|
||||||
|
* expression; the "idx" value is the argument position
|
||||||
|
*
|
||||||
|
* Global references: stgidx (altered)
|
||||||
|
* stgbuf (altered)
|
||||||
|
* staging (referred to only)
|
||||||
|
*/
|
||||||
|
SC_FUNC void stgmark(char mark)
|
||||||
|
{
|
||||||
|
if (staging) {
|
||||||
|
CHECK_STGBUFFER(stgidx);
|
||||||
|
stgbuf[stgidx++]=mark;
|
||||||
|
} /* if */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rebuffer(char *str)
|
||||||
|
{
|
||||||
|
if (sc_status==statWRITE) {
|
||||||
|
if (pipeidx>=2 && stgpipe[pipeidx-1]=='\0' && stgpipe[pipeidx-2]!='\n')
|
||||||
|
pipeidx-=1; /* overwrite last '\0' */
|
||||||
|
while (*str!='\0') { /* copy to staging buffer */
|
||||||
|
CHECK_STGPIPE(pipeidx);
|
||||||
|
stgpipe[pipeidx++]=*str++;
|
||||||
|
} /* while */
|
||||||
|
CHECK_STGPIPE(pipeidx);
|
||||||
|
stgpipe[pipeidx++]='\0';
|
||||||
|
} /* if */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int filewrite(char *str)
|
||||||
|
{
|
||||||
|
if (sc_status==statWRITE)
|
||||||
|
return pc_writeasm(outf,str);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stgwrite
|
||||||
|
*
|
||||||
|
* Writes the string "st" to the staging buffer or to the output file. In the
|
||||||
|
* case of writing to the staging buffer, the terminating byte of zero is
|
||||||
|
* copied too, but... the optimizer can only work on complete lines (not on
|
||||||
|
* fractions of it. Therefore if the string is staged, if the last character
|
||||||
|
* written to the buffer is a '\0' and the previous-to-last is not a '\n',
|
||||||
|
* the string is concatenated to the last string in the buffer (the '\0' is
|
||||||
|
* overwritten). This also means an '\n' used in the middle of a string isn't
|
||||||
|
* recognized and could give wrong results with the optimizer.
|
||||||
|
* Even when writing to the output file directly, all strings are buffered
|
||||||
|
* until a whole line is complete.
|
||||||
|
*
|
||||||
|
* Global references: stgidx (altered)
|
||||||
|
* stgbuf (altered)
|
||||||
|
* staging (referred to only)
|
||||||
|
*/
|
||||||
|
SC_FUNC void stgwrite(const char *st)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (staging) {
|
||||||
|
assert(stgidx==0 || stgbuf!=NULL); /* staging buffer must be valid if there is (apparently) something in it */
|
||||||
|
if (stgidx>=2 && stgbuf[stgidx-1]=='\0' && stgbuf[stgidx-2]!='\n')
|
||||||
|
stgidx-=1; /* overwrite last '\0' */
|
||||||
|
while (*st!='\0') { /* copy to staging buffer */
|
||||||
|
CHECK_STGBUFFER(stgidx);
|
||||||
|
stgbuf[stgidx++]=*st++;
|
||||||
|
} /* while */
|
||||||
|
CHECK_STGBUFFER(stgidx);
|
||||||
|
stgbuf[stgidx++]='\0';
|
||||||
|
} else {
|
||||||
|
len=(stgbuf!=NULL) ? strlen(stgbuf) : 0;
|
||||||
|
CHECK_STGBUFFER(len+strlen(st)+1);
|
||||||
|
strcat(stgbuf,st);
|
||||||
|
len=strlen(stgbuf);
|
||||||
|
if (len>0 && stgbuf[len-1]=='\n') {
|
||||||
|
filewrite(stgbuf);
|
||||||
|
stgbuf[0]='\0';
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stgout
|
||||||
|
*
|
||||||
|
* Writes the staging buffer to the output file via stgstring() (for
|
||||||
|
* reversing expressions in the buffer) and stgopt() (for optimizing). It
|
||||||
|
* resets "stgidx".
|
||||||
|
*
|
||||||
|
* Global references: stgidx (altered)
|
||||||
|
* stgbuf (referred to only)
|
||||||
|
* staging (referred to only)
|
||||||
|
*/
|
||||||
|
SC_FUNC void stgout(int index)
|
||||||
|
{
|
||||||
|
int reordered=0;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (!staging)
|
||||||
|
return;
|
||||||
|
assert(pipeidx==0);
|
||||||
|
|
||||||
|
/* first pass: sub-expressions */
|
||||||
|
if (sc_status==statWRITE)
|
||||||
|
reordered=stgstring(&stgbuf[index],&stgbuf[stgidx]);
|
||||||
|
stgidx=index;
|
||||||
|
|
||||||
|
/* second pass: optimize the buffer created in the first pass */
|
||||||
|
if (sc_status==statWRITE) {
|
||||||
|
if (reordered) {
|
||||||
|
stgopt(stgpipe,stgpipe+pipeidx,filewrite);
|
||||||
|
} else {
|
||||||
|
/* there is no sense in re-optimizing if the order of the sub-expressions
|
||||||
|
* did not change; so output directly
|
||||||
|
*/
|
||||||
|
for (idx=0; idx<pipeidx; idx+=strlen(stgpipe+idx)+1)
|
||||||
|
filewrite(stgpipe+idx);
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
pipeidx=0; /* reset second pipe */
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *start,*end;
|
||||||
|
} argstack;
|
||||||
|
|
||||||
|
/* stgstring
|
||||||
|
*
|
||||||
|
* Analyses whether code strings should be output to the file as they appear
|
||||||
|
* in the staging buffer or whether portions of it should be re-ordered.
|
||||||
|
* Re-ordering takes place in function argument lists; Pawn passes arguments
|
||||||
|
* to functions from right to left. When arguments are "named" rather than
|
||||||
|
* positional, the order in the source stream is indeterminate.
|
||||||
|
* This function calls itself recursively in case it needs to re-order code
|
||||||
|
* strings, and it uses a private stack (or list) to mark the start and the
|
||||||
|
* end of expressions in their correct (reversed) order.
|
||||||
|
* In any case, stgstring() sends a block as large as possible to the
|
||||||
|
* optimizer stgopt().
|
||||||
|
*
|
||||||
|
* In "reorder" mode, each set of code strings must start with the token
|
||||||
|
* sEXPRSTART, even the first. If the token sSTARTREORDER is represented
|
||||||
|
* by '[', sENDREORDER by ']' and sEXPRSTART by '|' the following applies:
|
||||||
|
* '[]...' valid, but useless; no output
|
||||||
|
* '[|...] valid, but useless; only one string
|
||||||
|
* '[|...|...] valid and usefull
|
||||||
|
* '[...|...] invalid, first string doesn't start with '|'
|
||||||
|
* '[|...|] invalid
|
||||||
|
*/
|
||||||
|
static int stgstring(char *start,char *end)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
int nest,argc,arg;
|
||||||
|
argstack *stack;
|
||||||
|
int reordered=0;
|
||||||
|
|
||||||
|
while (start<end) {
|
||||||
|
if (*start==sSTARTREORDER) {
|
||||||
|
start+=1; /* skip token */
|
||||||
|
/* allocate a argstack with sMAXARGS items */
|
||||||
|
stack=(argstack *)malloc(sMAXARGS*sizeof(argstack));
|
||||||
|
if (stack==NULL)
|
||||||
|
error(103); /* insufficient memory */
|
||||||
|
reordered=1; /* mark that the expression is reordered */
|
||||||
|
nest=1; /* nesting counter */
|
||||||
|
argc=0; /* argument counter */
|
||||||
|
arg=-1; /* argument index; no valid argument yet */
|
||||||
|
do {
|
||||||
|
switch (*start) {
|
||||||
|
case sSTARTREORDER:
|
||||||
|
nest++;
|
||||||
|
start++;
|
||||||
|
break;
|
||||||
|
case sENDREORDER:
|
||||||
|
nest--;
|
||||||
|
start++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((*start & sEXPRSTART)==sEXPRSTART) {
|
||||||
|
if (nest==1) {
|
||||||
|
if (arg>=0)
|
||||||
|
stack[arg].end=start-1; /* finish previous argument */
|
||||||
|
arg=(unsigned char)*start - sEXPRSTART;
|
||||||
|
stack[arg].start=start+1;
|
||||||
|
if (arg>=argc)
|
||||||
|
argc=arg+1;
|
||||||
|
} /* if */
|
||||||
|
start++;
|
||||||
|
} else {
|
||||||
|
start+=strlen(start)+1;
|
||||||
|
} /* if */
|
||||||
|
} /* switch */
|
||||||
|
} while (nest); /* enddo */
|
||||||
|
if (arg>=0)
|
||||||
|
stack[arg].end=start-1; /* finish previous argument */
|
||||||
|
while (argc>0) {
|
||||||
|
argc--;
|
||||||
|
stgstring(stack[argc].start,stack[argc].end);
|
||||||
|
} /* while */
|
||||||
|
free(stack);
|
||||||
|
} else {
|
||||||
|
ptr=start;
|
||||||
|
while (ptr<end && *ptr!=sSTARTREORDER)
|
||||||
|
ptr+=strlen(ptr)+1;
|
||||||
|
stgopt(start,ptr,rebuffer);
|
||||||
|
start=ptr;
|
||||||
|
} /* if */
|
||||||
|
} /* while */
|
||||||
|
return reordered;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stgdel
|
||||||
|
*
|
||||||
|
* Scraps code from the staging buffer by resetting "stgidx" to "index".
|
||||||
|
*
|
||||||
|
* Global references: stgidx (altered)
|
||||||
|
* staging (reffered to only)
|
||||||
|
*/
|
||||||
|
SC_FUNC void stgdel(int index,cell code_index)
|
||||||
|
{
|
||||||
|
if (staging) {
|
||||||
|
stgidx=index;
|
||||||
|
code_idx=code_index;
|
||||||
|
} /* if */
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int stgget(int *index,cell *code_index)
|
||||||
|
{
|
||||||
|
if (staging) {
|
||||||
|
*index=stgidx;
|
||||||
|
*code_index=code_idx;
|
||||||
|
} /* if */
|
||||||
|
return staging;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stgset
|
||||||
|
*
|
||||||
|
* Sets staging on or off. If it's turned off, the staging buffer must be
|
||||||
|
* initialized to an empty string. If it's turned on, the routine makes sure
|
||||||
|
* the index ("stgidx") is set to 0 (it should already be 0).
|
||||||
|
*
|
||||||
|
* Global references: staging (altered)
|
||||||
|
* stgidx (altered)
|
||||||
|
* stgbuf (contents altered)
|
||||||
|
*/
|
||||||
|
SC_FUNC void stgset(int onoff)
|
||||||
|
{
|
||||||
|
staging=onoff;
|
||||||
|
if (staging){
|
||||||
|
assert(stgidx==0);
|
||||||
|
stgidx=0;
|
||||||
|
CHECK_STGBUFFER(stgidx);
|
||||||
|
/* write any contents that may be put in the buffer by stgwrite()
|
||||||
|
* when "staging" was 0
|
||||||
|
*/
|
||||||
|
if (strlen(stgbuf)>0)
|
||||||
|
filewrite(stgbuf);
|
||||||
|
} /* if */
|
||||||
|
stgbuf[0]='\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* phopt_init
|
||||||
|
* Initialize all sequence strings of the peehole optimizer. The strings
|
||||||
|
* are embedded in the .EXE file in compressed format, here we expand
|
||||||
|
* them (and allocate memory for the sequences).
|
||||||
|
*/
|
||||||
|
static SEQUENCE *sequences;
|
||||||
|
|
||||||
|
SC_FUNC int phopt_init(void)
|
||||||
|
{
|
||||||
|
int number, i, len;
|
||||||
|
char str[160];
|
||||||
|
|
||||||
|
/* count number of sequences */
|
||||||
|
for (number=0; sequences_cmp[number].find!=NULL; number++)
|
||||||
|
/* nothing */;
|
||||||
|
number++; /* include an item for the NULL terminator */
|
||||||
|
|
||||||
|
if ((sequences=(SEQUENCE*)malloc(number * sizeof(SEQUENCE)))==NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* pre-initialize all to NULL (in case of failure) */
|
||||||
|
for (i=0; i<number; i++) {
|
||||||
|
sequences[i].find=NULL;
|
||||||
|
sequences[i].replace=NULL;
|
||||||
|
sequences[i].savesize=0;
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
/* expand all strings */
|
||||||
|
for (i=0; i<number-1; i++) {
|
||||||
|
len = strexpand(str,(unsigned char*)sequences_cmp[i].find,sizeof str,SCPACK_TABLE);
|
||||||
|
assert(len<=sizeof str);
|
||||||
|
assert(len==(int)strlen(str)+1);
|
||||||
|
sequences[i].find=(char*)malloc(len);
|
||||||
|
if (sequences[i].find!=NULL)
|
||||||
|
strcpy(sequences[i].find,str);
|
||||||
|
len = strexpand(str,(unsigned char*)sequences_cmp[i].replace,sizeof str,SCPACK_TABLE);
|
||||||
|
assert(len<=sizeof str);
|
||||||
|
assert(len==(int)strlen(str)+1);
|
||||||
|
sequences[i].replace=(char*)malloc(len);
|
||||||
|
if (sequences[i].replace!=NULL)
|
||||||
|
strcpy(sequences[i].replace,str);
|
||||||
|
sequences[i].savesize=sequences_cmp[i].savesize;
|
||||||
|
if (sequences[i].find==NULL || sequences[i].replace==NULL)
|
||||||
|
return phopt_cleanup();
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int phopt_cleanup(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (sequences!=NULL) {
|
||||||
|
i=0;
|
||||||
|
while (sequences[i].find!=NULL || sequences[i].replace!=NULL) {
|
||||||
|
if (sequences[i].find!=NULL)
|
||||||
|
free(sequences[i].find);
|
||||||
|
if (sequences[i].replace!=NULL)
|
||||||
|
free(sequences[i].replace);
|
||||||
|
i++;
|
||||||
|
} /* while */
|
||||||
|
free(sequences);
|
||||||
|
sequences=NULL;
|
||||||
|
} /* if */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_OPT_VARS 5
|
||||||
|
#define MAX_OPT_CAT 5 /* max. values that are concatenated */
|
||||||
|
#if sNAMEMAX > (PAWN_CELL_SIZE/4) * MAX_OPT_CAT
|
||||||
|
#define MAX_ALIAS sNAMEMAX
|
||||||
|
#else
|
||||||
|
#define MAX_ALIAS (PAWN_CELL_SIZE/4) * MAX_OPT_CAT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int matchsequence(char *start,char *end,char *pattern,
|
||||||
|
char symbols[MAX_OPT_VARS][MAX_ALIAS+1],
|
||||||
|
int *match_length)
|
||||||
|
{
|
||||||
|
int var,i;
|
||||||
|
char str[MAX_ALIAS+1];
|
||||||
|
char *start_org=start;
|
||||||
|
cell value;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
*match_length=0;
|
||||||
|
for (var=0; var<MAX_OPT_VARS; var++)
|
||||||
|
symbols[var][0]='\0';
|
||||||
|
|
||||||
|
while (*start=='\t' || *start==' ')
|
||||||
|
start++;
|
||||||
|
while (*pattern) {
|
||||||
|
if (start>=end)
|
||||||
|
return FALSE;
|
||||||
|
switch (*pattern) {
|
||||||
|
case '%': /* new "symbol" */
|
||||||
|
pattern++;
|
||||||
|
assert(isdigit(*pattern));
|
||||||
|
var=atoi(pattern) - 1;
|
||||||
|
assert(var>=0 && var<MAX_OPT_VARS);
|
||||||
|
assert(*start=='-' || alphanum(*start));
|
||||||
|
for (i=0; start<end && (*start=='-' || *start=='+' || alphanum(*start)); i++,start++) {
|
||||||
|
assert(i<=MAX_ALIAS);
|
||||||
|
str[i]=*start;
|
||||||
|
} /* for */
|
||||||
|
str[i]='\0';
|
||||||
|
if (symbols[var][0]!='\0') {
|
||||||
|
if (strcmp(symbols[var],str)!=0)
|
||||||
|
return FALSE; /* symbols should be identical */
|
||||||
|
} else {
|
||||||
|
strcpy(symbols[var],str);
|
||||||
|
} /* if */
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
value=-strtol(pattern+1,&pattern,16);
|
||||||
|
ptr=itoh((ucell)value);
|
||||||
|
while (*ptr!='\0') {
|
||||||
|
if (tolower(*start) != tolower(*ptr))
|
||||||
|
return FALSE;
|
||||||
|
start++;
|
||||||
|
ptr++;
|
||||||
|
} /* while */
|
||||||
|
pattern--; /* there is an increment following at the end of the loop */
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
if (*start!='\t' && *start!=' ')
|
||||||
|
return FALSE;
|
||||||
|
while (start<end && (*start=='\t' || *start==' '))
|
||||||
|
start++;
|
||||||
|
break;
|
||||||
|
case '!':
|
||||||
|
while (start<end && (*start=='\t' || *start==' '))
|
||||||
|
start++; /* skip trailing white space */
|
||||||
|
if (*start==';')
|
||||||
|
while (start<end && *start!='\n')
|
||||||
|
start++; /* skip trailing comment */
|
||||||
|
if (*start!='\n')
|
||||||
|
return FALSE;
|
||||||
|
assert(*(start+1)=='\0');
|
||||||
|
start+=2; /* skip '\n' and '\0' */
|
||||||
|
if (*(pattern+1)!='\0')
|
||||||
|
while (start<end && *start=='\t' || *start==' ')
|
||||||
|
start++; /* skip leading white space of next instruction */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (tolower(*start) != tolower(*pattern))
|
||||||
|
return FALSE;
|
||||||
|
start++;
|
||||||
|
} /* switch */
|
||||||
|
pattern++;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
*match_length=(int)(start-start_org);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *replacesequence(char *pattern,char symbols[MAX_OPT_VARS][MAX_ALIAS+1],int *repl_length)
|
||||||
|
{
|
||||||
|
char *lptr;
|
||||||
|
int var;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
|
/* calculate the length of the new buffer
|
||||||
|
* this is the length of the pattern plus the length of all symbols (note
|
||||||
|
* that the same symbol may occur multiple times in the pattern) plus
|
||||||
|
* line endings and startings ('\t' to start a line and '\n\0' to end one)
|
||||||
|
*/
|
||||||
|
assert(repl_length!=NULL);
|
||||||
|
*repl_length=0;
|
||||||
|
lptr=pattern;
|
||||||
|
while (*lptr) {
|
||||||
|
switch (*lptr) {
|
||||||
|
case '%':
|
||||||
|
lptr++; /* skip '%' */
|
||||||
|
assert(isdigit(*lptr));
|
||||||
|
var=atoi(lptr) - 1;
|
||||||
|
assert(var>=0 && var<MAX_OPT_VARS);
|
||||||
|
assert(symbols[var][0]!='\0'); /* variable should be defined */
|
||||||
|
*repl_length+=strlen(symbols[var]);
|
||||||
|
break;
|
||||||
|
case '!':
|
||||||
|
*repl_length+=3; /* '\t', '\n' & '\0' */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*repl_length+=1;
|
||||||
|
} /* switch */
|
||||||
|
lptr++;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
/* allocate a buffer to replace the sequence in */
|
||||||
|
if ((buffer=(char*)malloc(*repl_length))==NULL)
|
||||||
|
return (char*)error(103);
|
||||||
|
|
||||||
|
/* replace the pattern into this temporary buffer */
|
||||||
|
lptr=buffer;
|
||||||
|
*lptr++='\t'; /* the "replace" patterns do not have tabs */
|
||||||
|
while (*pattern) {
|
||||||
|
assert((int)(lptr-buffer)<*repl_length);
|
||||||
|
switch (*pattern) {
|
||||||
|
case '%':
|
||||||
|
/* write out the symbol */
|
||||||
|
pattern++;
|
||||||
|
assert(isdigit(*pattern));
|
||||||
|
var=atoi(pattern) - 1;
|
||||||
|
assert(var>=0 && var<MAX_OPT_VARS);
|
||||||
|
assert(symbols[var][0]!='\0'); /* variable should be defined */
|
||||||
|
strcpy(lptr,symbols[var]);
|
||||||
|
lptr+=strlen(symbols[var]);
|
||||||
|
break;
|
||||||
|
case '!':
|
||||||
|
/* finish the line, optionally start the next line with an indent */
|
||||||
|
*lptr++='\n';
|
||||||
|
*lptr++='\0';
|
||||||
|
if (*(pattern+1)!='\0')
|
||||||
|
*lptr++='\t';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*lptr++=*pattern;
|
||||||
|
} /* switch */
|
||||||
|
pattern++;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
assert((int)(lptr-buffer)==*repl_length);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void strreplace(char *dest,char *replace,int sub_length,int repl_length,int dest_length)
|
||||||
|
{
|
||||||
|
int offset=sub_length-repl_length;
|
||||||
|
if (offset>0) { /* delete a section */
|
||||||
|
memmove(dest,dest+offset,dest_length-offset);
|
||||||
|
memset(dest+dest_length-offset,0xcc,offset); /* not needed, but for cleanlyness */
|
||||||
|
} else if (offset<0) { /* insert a section */
|
||||||
|
memmove(dest-offset, dest, dest_length);
|
||||||
|
} /* if */
|
||||||
|
memcpy(dest, replace, repl_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stgopt
|
||||||
|
*
|
||||||
|
* Optimizes the staging buffer by checking for series of instructions that
|
||||||
|
* can be coded more compact. The routine expects the lines in the staging
|
||||||
|
* buffer to be separated with '\n' and '\0' characters.
|
||||||
|
*
|
||||||
|
* The longest sequences should probably be checked first.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void stgopt(char *start,char *end,int (*outputfunc)(char *str))
|
||||||
|
{
|
||||||
|
char symbols[MAX_OPT_VARS][MAX_ALIAS+1];
|
||||||
|
int seq,match_length,repl_length;
|
||||||
|
int matches;
|
||||||
|
char *debut=start; /* save original start of the buffer */
|
||||||
|
|
||||||
|
assert(sequences!=NULL);
|
||||||
|
/* do not match anything if debug-level is maximum */
|
||||||
|
if (pc_optimize>sOPTIMIZE_NONE && sc_status==statWRITE) {
|
||||||
|
do {
|
||||||
|
matches=0;
|
||||||
|
start=debut;
|
||||||
|
while (start<end) {
|
||||||
|
seq=0;
|
||||||
|
while (sequences[seq].find!=NULL) {
|
||||||
|
assert(seq>=0);
|
||||||
|
if (*sequences[seq].find=='\0') {
|
||||||
|
if (pc_optimize==sOPTIMIZE_NOMACRO) {
|
||||||
|
break; /* don't look further */
|
||||||
|
} else {
|
||||||
|
seq++; /* continue with next string */
|
||||||
|
continue;
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
if (matchsequence(start,end,sequences[seq].find,symbols,&match_length)) {
|
||||||
|
char *replace=replacesequence(sequences[seq].replace,symbols,&repl_length);
|
||||||
|
/* If the replacement is bigger than the original section, we may need
|
||||||
|
* to "grow" the staging buffer. This is quite complex, due to the
|
||||||
|
* re-ordering of expressions that can also happen in the staging
|
||||||
|
* buffer. In addition, it should not happen: the peephole optimizer
|
||||||
|
* must replace sequences with *shorter* sequences, not longer ones.
|
||||||
|
* So, I simply forbid sequences that are longer than the ones they
|
||||||
|
* are meant to replace.
|
||||||
|
*/
|
||||||
|
assert(match_length>=repl_length);
|
||||||
|
if (match_length>=repl_length) {
|
||||||
|
strreplace(start,replace,match_length,repl_length,(int)(end-start));
|
||||||
|
end-=match_length-repl_length;
|
||||||
|
free(replace);
|
||||||
|
code_idx-=sequences[seq].savesize;
|
||||||
|
seq=0; /* restart search for matches */
|
||||||
|
matches++;
|
||||||
|
} else {
|
||||||
|
/* actually, we should never get here (match_length<repl_length) */
|
||||||
|
assert(0);
|
||||||
|
seq++;
|
||||||
|
} /* if */
|
||||||
|
} else {
|
||||||
|
seq++;
|
||||||
|
} /* if */
|
||||||
|
} /* while */
|
||||||
|
assert(sequences[seq].find==NULL || *sequences[seq].find=='\0' && pc_optimize==sOPTIMIZE_NOMACRO);
|
||||||
|
start += strlen(start) + 1; /* to next string */
|
||||||
|
} /* while (start<end) */
|
||||||
|
} while (matches>0);
|
||||||
|
} /* if (pc_optimize>sOPTIMIZE_NONE && sc_status==statWRITE) */
|
||||||
|
|
||||||
|
for (start=debut; start<end; start+=strlen(start)+1)
|
||||||
|
outputfunc(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SCPACK_TABLE
|
2022
compiler-init/sc7.scp
Normal file
2022
compiler-init/sc7.scp
Normal file
File diff suppressed because it is too large
Load Diff
68
compiler-init/scexpand.c
Normal file
68
compiler-init/scexpand.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* expand.c -- Byte Pair Encoding decompression */
|
||||||
|
/* Copyright 1996 Philip Gage */
|
||||||
|
|
||||||
|
/* Byte Pair Compression 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).
|
||||||
|
*
|
||||||
|
* The decompressor has been modified by me (Thiadmer
|
||||||
|
* Riemersma) to accept a string as input, instead of a
|
||||||
|
* complete file.
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "sc.h"
|
||||||
|
|
||||||
|
#define STACKSIZE 16
|
||||||
|
|
||||||
|
SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2])
|
||||||
|
{
|
||||||
|
unsigned char stack[STACKSIZE];
|
||||||
|
short c, top = 0;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
assert(maxlen > 0);
|
||||||
|
len = 1; /* already 1 byte for '\0' */
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
/* Pop byte from stack or read byte from the input string */
|
||||||
|
if (top)
|
||||||
|
c = stack[--top];
|
||||||
|
else if ((c = *(unsigned char *)source++) == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Push pair on stack or output byte to the output string */
|
||||||
|
if (c > 127) {
|
||||||
|
assert(top+2 <= STACKSIZE);
|
||||||
|
stack[top++] = pairtable[c-128][1];
|
||||||
|
stack[top++] = pairtable[c-128][0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
len++;
|
||||||
|
if (maxlen > 1) { /* reserve one byte for the '\0' */
|
||||||
|
*dest++ = (char)c;
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*dest = '\0';
|
||||||
|
return len; /* return number of bytes decoded */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 /*for testing*/
|
||||||
|
#include "sc5.scp"
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char str[128];
|
||||||
|
|
||||||
|
for (i=0; i<58; i++) {
|
||||||
|
strexpand(str, errmsg[i], sizeof str, SCPACK_TABLE);
|
||||||
|
printf("%s", str);
|
||||||
|
} /* for */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
428
compiler-init/sci18n.c
Normal file
428
compiler-init/sci18n.c
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
/* Codepage translation to Unicode, and UTF-8 support
|
||||||
|
*
|
||||||
|
* The translation is based on codepage mapping files that are distributed
|
||||||
|
* by the Unicode consortium, see ftp://ftp.unicode.org/Public/MAPPINGS/.
|
||||||
|
*
|
||||||
|
* Character sets with a maximum of 256 codes are translated via a lookup
|
||||||
|
* table (these are Single-Byte Character Sets). Character sets like Shift-JIS
|
||||||
|
* with single-byte characters and multi-byte characters (introduced by a
|
||||||
|
* leader byte) are split into two tables: the 256-entry lookup table for
|
||||||
|
* the single-byte characters and an extended table for the multi-byte
|
||||||
|
* characters. The extended table is allocated dynamically; the lookup table
|
||||||
|
* is allocated statically, so loading SBCS tables cannot fail (if the tables
|
||||||
|
* themselves are valid, of course).
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 2004-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: CODEPAGE.C,v 1.0 2004-02-18 12:13:04+01 thiadmer Exp thiadmer $
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sc.h"
|
||||||
|
|
||||||
|
#if !defined TRUE
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
#if !defined _MAX_PATH
|
||||||
|
#define _MAX_PATH 250
|
||||||
|
#endif
|
||||||
|
#if !defined DIRSEP_CHAR
|
||||||
|
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
|
#define DIRSEP_CHAR '/'
|
||||||
|
#elif defined macintosh
|
||||||
|
#define DIRSEP_CHAR ':'
|
||||||
|
#else
|
||||||
|
#define DIRSEP_CHAR '\\'
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined ELEMENTS
|
||||||
|
#define ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined NO_CODEPAGE
|
||||||
|
|
||||||
|
#if !defined MAXCODEPAGE
|
||||||
|
#define MAXCODEPAGE 12 /* typically "cp" + 4 digits + ".txt" */
|
||||||
|
#endif
|
||||||
|
#define INVALID 0xffffu /* 0xffff and 0xfffe are invalid Unicode characters */
|
||||||
|
#define LEADBYTE 0xfffeu
|
||||||
|
|
||||||
|
struct wordpair {
|
||||||
|
unsigned short index;
|
||||||
|
wchar_t code;
|
||||||
|
};
|
||||||
|
static char cprootpath[_MAX_PATH] = { DIRSEP_CHAR, '\0' };
|
||||||
|
static wchar_t bytetable[256];
|
||||||
|
static struct wordpair *wordtable = NULL;
|
||||||
|
static unsigned wordtablesize = 0;
|
||||||
|
static unsigned wordtabletop = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* read in a line delimited by '\r' or '\n'; do NOT store the '\r' or '\n' into
|
||||||
|
* the string and ignore empty lines
|
||||||
|
* returns 1 for success and 0 for failure
|
||||||
|
*/
|
||||||
|
static int cp_readline(FILE *fp,char *string,size_t size)
|
||||||
|
{
|
||||||
|
size_t count=0;
|
||||||
|
int c;
|
||||||
|
assert(size>1);
|
||||||
|
while ((c=fgetc(fp))!=EOF && count<size-1) {
|
||||||
|
if (c=='\r' || c=='\n') {
|
||||||
|
if (count>0) /* '\r' or '\n' ends a string */
|
||||||
|
break;
|
||||||
|
/* if count==0, the line started with a '\r' or '\n', or perhaps line
|
||||||
|
* ends in the file are '\r\n' and we read and stopped on the '\r' of
|
||||||
|
* the preceding line
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
string[count++]=(char)c;
|
||||||
|
} /* if */
|
||||||
|
} /* while */
|
||||||
|
string[count]='\0';
|
||||||
|
return count>0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cp_path() sets the directory where all codepage files must be found (if
|
||||||
|
* the parameter to cp_set() specifies a full path, that is used instead).
|
||||||
|
* The path is specified into two parts: root and directory; the full path
|
||||||
|
* for the codepage direcory is just the concatenation of the two, with a
|
||||||
|
* directory separator in between. The directory is given in two parts,
|
||||||
|
* because often a program already retrieves its "home" directory and the
|
||||||
|
* codepages are most conveniently stored in a subdirectory of this home
|
||||||
|
* directory.
|
||||||
|
*/
|
||||||
|
SC_FUNC int cp_path(const char *root, const char *directory)
|
||||||
|
{
|
||||||
|
size_t len1,len2;
|
||||||
|
int add_slash1,add_slash2;
|
||||||
|
|
||||||
|
len1= (root!=NULL) ? strlen(root) : 0;
|
||||||
|
add_slash1= (len1==0 || root[len1-1]!=DIRSEP_CHAR);
|
||||||
|
len2= (directory!=NULL) ? strlen(directory) : 0;
|
||||||
|
add_slash2= (len2>0 && root[len2-1]!=DIRSEP_CHAR);
|
||||||
|
if (len1+add_slash1+len2+add_slash2>=(_MAX_PATH-MAXCODEPAGE))
|
||||||
|
return FALSE; /* full filename may not fit */
|
||||||
|
if (root!=NULL)
|
||||||
|
strcpy(cprootpath,root);
|
||||||
|
if (add_slash1) {
|
||||||
|
assert(len1==0 || cprootpath[len1]=='\0');
|
||||||
|
cprootpath[len1]=DIRSEP_CHAR;
|
||||||
|
cprootpath[len1+1]='\0';
|
||||||
|
} /* if */
|
||||||
|
if (directory!=NULL)
|
||||||
|
strcat(cprootpath,directory);
|
||||||
|
if (add_slash2) {
|
||||||
|
assert(cprootpath[len1+add_slash1+len2]=='\0');
|
||||||
|
cprootpath[len1+add_slash1+len2]=DIRSEP_CHAR;
|
||||||
|
cprootpath[len1+add_slash1+len2+1]='\0';
|
||||||
|
} /* if */
|
||||||
|
cp_set(NULL); /* start with a "linear" table (no translation) */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cp_set() loads a codepage from a file. The name parameter may be a
|
||||||
|
* filename (including a full path) or it may be a partial codepage name.
|
||||||
|
* If the name parameter is NULL, the codepage is cleared to be a "linear"
|
||||||
|
* table (no translation).
|
||||||
|
* The following files are attempted to open (where <name> specifies the
|
||||||
|
* value of the parameter):
|
||||||
|
* <name>
|
||||||
|
* <cprootpath>/<name>
|
||||||
|
* <cprootpath>/<name>.txt
|
||||||
|
* <cprootpath>/cp<name>
|
||||||
|
* <cprootpath>/cp<name>.txt
|
||||||
|
*/
|
||||||
|
SC_FUNC int cp_set(const char *name)
|
||||||
|
{
|
||||||
|
char filename[_MAX_PATH];
|
||||||
|
FILE *fp=NULL;
|
||||||
|
unsigned index;
|
||||||
|
|
||||||
|
/* for name==NULL, set up an identity table */
|
||||||
|
if (name==NULL || *name=='\0') {
|
||||||
|
if (wordtable!=NULL) {
|
||||||
|
free(wordtable);
|
||||||
|
wordtable=NULL;
|
||||||
|
wordtablesize=0;
|
||||||
|
wordtabletop=0;
|
||||||
|
} /* if */
|
||||||
|
for (index=0; index<ELEMENTS(bytetable); index++)
|
||||||
|
bytetable[index]=(wchar_t)index;
|
||||||
|
return TRUE;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
/* try to open the file as-is */
|
||||||
|
if (strchr(name,DIRSEP_CHAR)!=NULL)
|
||||||
|
fp=fopen(name,"rt");
|
||||||
|
if (fp==NULL) {
|
||||||
|
/* try opening the file in the "root path" for codepages */
|
||||||
|
if (strlen(name)>MAXCODEPAGE)
|
||||||
|
return 0;
|
||||||
|
assert(strlen(name)+strlen(cprootpath)<_MAX_PATH);
|
||||||
|
strcpy(filename,cprootpath);
|
||||||
|
strcat(filename,name);
|
||||||
|
fp=fopen(filename,"rt");
|
||||||
|
} /* if */
|
||||||
|
if (fp==NULL) {
|
||||||
|
/* try opening the file in the "root path" for codepages, with a ".txt" extension */
|
||||||
|
if (strlen(name)+4>=MAXCODEPAGE)
|
||||||
|
return 0;
|
||||||
|
assert(strlen(filename)+4<_MAX_PATH);
|
||||||
|
strcat(filename,".txt");
|
||||||
|
fp=fopen(filename,"rt");
|
||||||
|
} /* if */
|
||||||
|
if (fp==NULL) {
|
||||||
|
/* try opening the file in the "root path" for codepages, with "cp" prefixed before the name */
|
||||||
|
if (strlen(name)+2>MAXCODEPAGE)
|
||||||
|
return 0;
|
||||||
|
assert(2+strlen(name)+strlen(cprootpath)<_MAX_PATH);
|
||||||
|
strcpy(filename,cprootpath);
|
||||||
|
strcat(filename,"cp");
|
||||||
|
strcat(filename,name);
|
||||||
|
fp=fopen(filename,"rt");
|
||||||
|
} /* if */
|
||||||
|
if (fp==NULL) {
|
||||||
|
/* try opening the file in the "root path" for codepages, with "cp" prefixed an ".txt" appended */
|
||||||
|
if (strlen(name)+2+4>MAXCODEPAGE)
|
||||||
|
return 0;
|
||||||
|
assert(strlen(filename)+4<_MAX_PATH);
|
||||||
|
strcat(filename,".txt");
|
||||||
|
fp=fopen(filename,"rt");
|
||||||
|
} /* if */
|
||||||
|
if (fp==NULL)
|
||||||
|
return FALSE; /* all failed */
|
||||||
|
|
||||||
|
/* clear the tables */
|
||||||
|
for (index=0; index<ELEMENTS(bytetable); index++)
|
||||||
|
bytetable[index]=INVALID; /* special code meaning "not found" */
|
||||||
|
assert(wordtablesize==0 && wordtabletop==0 && wordtable==NULL
|
||||||
|
|| wordtablesize>0 && wordtable!=NULL);
|
||||||
|
if (wordtable!=NULL) {
|
||||||
|
free(wordtable);
|
||||||
|
wordtable=NULL;
|
||||||
|
wordtablesize=0;
|
||||||
|
wordtabletop=0;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
/* read in the table */
|
||||||
|
while (cp_readline(fp,filename,sizeof filename)) {
|
||||||
|
char *ptr;
|
||||||
|
if ((ptr=strchr(filename,'#'))!=NULL)
|
||||||
|
*ptr='\0'; /* strip of comment */
|
||||||
|
for (ptr=filename; *ptr>0 && *ptr<' '; ptr++)
|
||||||
|
/* nothing */; /* skip leading whitespace */
|
||||||
|
if (*ptr!='\0') {
|
||||||
|
/* content on line */
|
||||||
|
unsigned code=LEADBYTE;
|
||||||
|
int num=sscanf(ptr,"%i %i",&index,&code);
|
||||||
|
/* if sscanf() returns 1 and the index is in range 0..255, then the
|
||||||
|
* code is a DBCS lead byte; if sscanf() returns 2 and index>=256, this
|
||||||
|
* is a double byte pair (lead byte + follower)
|
||||||
|
*/
|
||||||
|
if (num>=1 && index<256) {
|
||||||
|
bytetable[index]=(wchar_t)code;
|
||||||
|
} else if (num==2 && index>=256 && index<LEADBYTE) {
|
||||||
|
/* store the DBCS character in wordtable */
|
||||||
|
if (wordtabletop>=wordtablesize) {
|
||||||
|
/* grow the list */
|
||||||
|
int newsize;
|
||||||
|
struct wordpair *newblock;
|
||||||
|
newsize= (wordtablesize==0) ? 128 : 2*wordtablesize;
|
||||||
|
newblock=(struct wordpair *)malloc(newsize*sizeof(*wordtable));
|
||||||
|
if (newblock!=NULL) {
|
||||||
|
memcpy(newblock,wordtable,wordtabletop*sizeof(*wordtable));
|
||||||
|
free(wordtable);
|
||||||
|
wordtable=newblock;
|
||||||
|
wordtablesize=newsize;
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
if (wordtabletop<wordtablesize) {
|
||||||
|
/* insert at sorted position */
|
||||||
|
int pos=wordtabletop;
|
||||||
|
assert(wordtable!=NULL);
|
||||||
|
while (pos>0 && (unsigned)wordtable[pos-1].index>index) {
|
||||||
|
wordtable[pos]=wordtable[pos-1];
|
||||||
|
pos--;
|
||||||
|
} /* while */
|
||||||
|
wordtable[pos].index=(unsigned short)index;
|
||||||
|
wordtable[pos].code=(wchar_t)code;
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC cell cp_translate(const unsigned char *string,const unsigned char **endptr)
|
||||||
|
{
|
||||||
|
wchar_t result;
|
||||||
|
|
||||||
|
result=bytetable[*string++];
|
||||||
|
/* check whether this is a leader code */
|
||||||
|
if ((unsigned)result==LEADBYTE && wordtable!=NULL) {
|
||||||
|
/* look up the code via binary search */
|
||||||
|
int low,high,mid;
|
||||||
|
unsigned short index=(unsigned short)(((*(string-1)) << 8) | *string);
|
||||||
|
string++;
|
||||||
|
assert(wordtabletop>0);
|
||||||
|
low=0;
|
||||||
|
high=wordtabletop-1;
|
||||||
|
while (low<high) {
|
||||||
|
mid=(low+high)/2;
|
||||||
|
assert(low<=mid && mid<high);
|
||||||
|
if (index>wordtable[mid].index)
|
||||||
|
low=mid+1;
|
||||||
|
else
|
||||||
|
high=mid;
|
||||||
|
} /* while */
|
||||||
|
assert(low==high);
|
||||||
|
if (wordtable[low].index==index)
|
||||||
|
result=wordtable[low].code;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (endptr!=NULL)
|
||||||
|
*endptr=string;
|
||||||
|
return (cell)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NO_CODEPAGE */
|
||||||
|
|
||||||
|
#if !defined NO_UTF8
|
||||||
|
SC_FUNC cell get_utf8_char(const unsigned char *string,const unsigned char **endptr)
|
||||||
|
{
|
||||||
|
int follow=0;
|
||||||
|
long lowmark=0;
|
||||||
|
unsigned char ch;
|
||||||
|
cell result=0;
|
||||||
|
|
||||||
|
if (endptr!=NULL)
|
||||||
|
*endptr=string;
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
ch=*string++;
|
||||||
|
|
||||||
|
if (follow>0 && (ch & 0xc0)==0x80) {
|
||||||
|
/* leader code is active, combine with earlier code */
|
||||||
|
result=(result << 6) | (ch & 0x3f);
|
||||||
|
if (--follow==0) {
|
||||||
|
/* encoding a character in more bytes than is strictly needed,
|
||||||
|
* is not really valid UTF-8; we are strict here to increase
|
||||||
|
* the chance of heuristic dectection of non-UTF-8 text
|
||||||
|
* (JAVA writes zero bytes as a 2-byte code UTF-8, which is invalid)
|
||||||
|
*/
|
||||||
|
if (result<lowmark)
|
||||||
|
return -1;
|
||||||
|
/* the code positions 0xd800--0xdfff and 0xfffe & 0xffff do not
|
||||||
|
* exist in UCS-4 (and hence, they do not exist in Unicode)
|
||||||
|
*/
|
||||||
|
if (result>=0xd800 && result<=0xdfff || result==0xfffe || result==0xffff)
|
||||||
|
return -1;
|
||||||
|
} /* if */
|
||||||
|
break;
|
||||||
|
} else if (follow==0 && (ch & 0x80)==0x80) {
|
||||||
|
/* UTF-8 leader code */
|
||||||
|
if ((ch & 0xe0)==0xc0) {
|
||||||
|
/* 110xxxxx 10xxxxxx */
|
||||||
|
follow=1;
|
||||||
|
lowmark=0x80L;
|
||||||
|
result=ch & 0x1f;
|
||||||
|
} else if ((ch & 0xf0)==0xe0) {
|
||||||
|
/* 1110xxxx 10xxxxxx 10xxxxxx (16 bits, BMP plane) */
|
||||||
|
follow=2;
|
||||||
|
lowmark=0x800L;
|
||||||
|
result=ch & 0x0f;
|
||||||
|
} else if ((ch & 0xf8)==0xf0) {
|
||||||
|
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
|
||||||
|
follow=3;
|
||||||
|
lowmark=0x10000L;
|
||||||
|
result=ch & 0x07;
|
||||||
|
} else if ((ch & 0xfc)==0xf8) {
|
||||||
|
/* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
|
||||||
|
follow=4;
|
||||||
|
lowmark=0x200000L;
|
||||||
|
result=ch & 0x03;
|
||||||
|
} else if ((ch & 0xfe)==0xfc) {
|
||||||
|
/* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (32 bits) */
|
||||||
|
follow=5;
|
||||||
|
lowmark=0x4000000L;
|
||||||
|
result=ch & 0x01;
|
||||||
|
} else {
|
||||||
|
/* this is invalid UTF-8 */
|
||||||
|
return -1;
|
||||||
|
} /* if */
|
||||||
|
} else if (follow==0 && (ch & 0x80)==0x00) {
|
||||||
|
/* 0xxxxxxx (US-ASCII) */
|
||||||
|
result=ch;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/* this is invalid UTF-8 */
|
||||||
|
return -1;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
if (endptr!=NULL)
|
||||||
|
*endptr=string;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SC_FUNC int scan_utf8(FILE *fp,const char *filename)
|
||||||
|
{
|
||||||
|
#if defined NO_UTF8
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
void *resetpos=pc_getpossrc(fp);
|
||||||
|
int utf8=TRUE;
|
||||||
|
int firstchar=TRUE,bom_found=FALSE;
|
||||||
|
const unsigned char *ptr;
|
||||||
|
|
||||||
|
while (utf8 && pc_readsrc(fp,pline,sLINEMAX)!=NULL) {
|
||||||
|
ptr=pline;
|
||||||
|
if (firstchar) {
|
||||||
|
/* check whether the very first character on the very first line
|
||||||
|
* starts with a BYTE order mark
|
||||||
|
*/
|
||||||
|
cell c=get_utf8_char(ptr,&ptr);
|
||||||
|
bom_found= (c==0xfeff);
|
||||||
|
utf8= (c>=0);
|
||||||
|
firstchar=FALSE;
|
||||||
|
} /* if */
|
||||||
|
while (utf8 && *ptr!='\0')
|
||||||
|
utf8= (get_utf8_char(ptr,&ptr)>=0);
|
||||||
|
} /* while */
|
||||||
|
pc_resetsrc(fp,resetpos);
|
||||||
|
if (bom_found) {
|
||||||
|
unsigned char bom[3];
|
||||||
|
if (!utf8)
|
||||||
|
error(77,filename); /* malformed UTF-8 encoding */
|
||||||
|
pc_readsrc(fp,bom,3);
|
||||||
|
assert(bom[0]==0xef && bom[1]==0xbb && bom[2]==0xbf);
|
||||||
|
} /* if */
|
||||||
|
return utf8;
|
||||||
|
#endif /* NO_UTF8 */
|
||||||
|
}
|
486
compiler-init/sclist.c
Normal file
486
compiler-init/sclist.c
Normal file
@ -0,0 +1,486 @@
|
|||||||
|
/* Pawn compiler - maintenance of various lists
|
||||||
|
*
|
||||||
|
* o Name list (aliases)
|
||||||
|
* o Include path list
|
||||||
|
* o Macro defintions (text substitutions)
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 2001-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: sclist.c 3579 2006-06-06 13:35:29Z thiadmer $
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sc.h"
|
||||||
|
|
||||||
|
#if defined FORTIFY
|
||||||
|
#include <alloc/fortify.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* a "private" implementation of strdup(), so that porting
|
||||||
|
* to other memory allocators becomes easier.
|
||||||
|
* By Søren Hannibal.
|
||||||
|
*/
|
||||||
|
SC_FUNC char* duplicatestring(const char* sourcestring)
|
||||||
|
{
|
||||||
|
char* result=(char*)malloc(strlen(sourcestring)+1);
|
||||||
|
strcpy(result,sourcestring);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static stringpair *insert_stringpair(stringpair *root,char *first,char *second,int matchlength)
|
||||||
|
{
|
||||||
|
stringpair *cur,*pred;
|
||||||
|
|
||||||
|
assert(root!=NULL);
|
||||||
|
assert(first!=NULL);
|
||||||
|
assert(second!=NULL);
|
||||||
|
/* create a new node, and check whether all is okay */
|
||||||
|
if ((cur=(stringpair*)malloc(sizeof(stringpair)))==NULL)
|
||||||
|
return NULL;
|
||||||
|
cur->first=duplicatestring(first);
|
||||||
|
cur->second=duplicatestring(second);
|
||||||
|
cur->matchlength=matchlength;
|
||||||
|
if (cur->first==NULL || cur->second==NULL) {
|
||||||
|
if (cur->first!=NULL)
|
||||||
|
free(cur->first);
|
||||||
|
if (cur->second!=NULL)
|
||||||
|
free(cur->second);
|
||||||
|
free(cur);
|
||||||
|
return NULL;
|
||||||
|
} /* if */
|
||||||
|
/* link the node to the tree, find the position */
|
||||||
|
for (pred=root; pred->next!=NULL && strcmp(pred->next->first,first)<0; pred=pred->next)
|
||||||
|
/* nothing */;
|
||||||
|
cur->next=pred->next;
|
||||||
|
pred->next=cur;
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete_stringpairtable(stringpair *root)
|
||||||
|
{
|
||||||
|
stringpair *cur, *next;
|
||||||
|
|
||||||
|
assert(root!=NULL);
|
||||||
|
cur=root->next;
|
||||||
|
while (cur!=NULL) {
|
||||||
|
next=cur->next;
|
||||||
|
assert(cur->first!=NULL);
|
||||||
|
assert(cur->second!=NULL);
|
||||||
|
free(cur->first);
|
||||||
|
free(cur->second);
|
||||||
|
free(cur);
|
||||||
|
cur=next;
|
||||||
|
} /* while */
|
||||||
|
memset(root,0,sizeof(stringpair));
|
||||||
|
}
|
||||||
|
|
||||||
|
static stringpair *find_stringpair(stringpair *cur,char *first,int matchlength)
|
||||||
|
{
|
||||||
|
int result=0;
|
||||||
|
|
||||||
|
assert(matchlength>0); /* the function cannot handle zero-length comparison */
|
||||||
|
assert(first!=NULL);
|
||||||
|
while (cur!=NULL && result<=0) {
|
||||||
|
result=(int)*cur->first - (int)*first;
|
||||||
|
if (result==0 && matchlength==cur->matchlength) {
|
||||||
|
result=strncmp(cur->first,first,matchlength);
|
||||||
|
if (result==0)
|
||||||
|
return cur;
|
||||||
|
} /* if */
|
||||||
|
cur=cur->next;
|
||||||
|
} /* while */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int delete_stringpair(stringpair *root,stringpair *item)
|
||||||
|
{
|
||||||
|
stringpair *cur;
|
||||||
|
|
||||||
|
assert(root!=NULL);
|
||||||
|
cur=root;
|
||||||
|
while (cur->next!=NULL) {
|
||||||
|
if (cur->next==item) {
|
||||||
|
cur->next=item->next; /* unlink from list */
|
||||||
|
assert(item->first!=NULL);
|
||||||
|
assert(item->second!=NULL);
|
||||||
|
free(item->first);
|
||||||
|
free(item->second);
|
||||||
|
free(item);
|
||||||
|
return TRUE;
|
||||||
|
} /* if */
|
||||||
|
cur=cur->next;
|
||||||
|
} /* while */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- string list functions ----------------------------------- */
|
||||||
|
static stringlist *insert_string(stringlist *root,char *string)
|
||||||
|
{
|
||||||
|
stringlist *cur;
|
||||||
|
|
||||||
|
assert(string!=NULL);
|
||||||
|
if ((cur=(stringlist*)malloc(sizeof(stringlist)))==NULL)
|
||||||
|
error(103); /* insufficient memory (fatal error) */
|
||||||
|
if ((cur->line=duplicatestring(string))==NULL)
|
||||||
|
error(103); /* insufficient memory (fatal error) */
|
||||||
|
/* insert as "last" */
|
||||||
|
assert(root!=NULL);
|
||||||
|
while (root->next!=NULL)
|
||||||
|
root=root->next;
|
||||||
|
cur->next=root->next;
|
||||||
|
root->next=cur;
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *get_string(stringlist *root,int index)
|
||||||
|
{
|
||||||
|
stringlist *cur;
|
||||||
|
|
||||||
|
assert(root!=NULL);
|
||||||
|
cur=root->next;
|
||||||
|
while (cur!=NULL && index-->0)
|
||||||
|
cur=cur->next;
|
||||||
|
if (cur!=NULL) {
|
||||||
|
assert(cur->line!=NULL);
|
||||||
|
return cur->line;
|
||||||
|
} /* if */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int delete_string(stringlist *root,int index)
|
||||||
|
{
|
||||||
|
stringlist *cur,*item;
|
||||||
|
|
||||||
|
assert(root!=NULL);
|
||||||
|
for (cur=root; cur->next!=NULL && index>0; cur=cur->next,index--)
|
||||||
|
/* nothing */;
|
||||||
|
if (cur->next!=NULL) {
|
||||||
|
item=cur->next;
|
||||||
|
cur->next=item->next; /* unlink from list */
|
||||||
|
assert(item->line!=NULL);
|
||||||
|
free(item->line);
|
||||||
|
free(item);
|
||||||
|
return TRUE;
|
||||||
|
} /* if */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_stringtable(stringlist *root)
|
||||||
|
{
|
||||||
|
stringlist *cur,*next;
|
||||||
|
|
||||||
|
assert(root!=NULL);
|
||||||
|
cur=root->next;
|
||||||
|
while (cur!=NULL) {
|
||||||
|
next=cur->next;
|
||||||
|
assert(cur->line!=NULL);
|
||||||
|
free(cur->line);
|
||||||
|
free(cur);
|
||||||
|
cur=next;
|
||||||
|
} /* while */
|
||||||
|
memset(root,0,sizeof(stringlist));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- alias table --------------------------------------------- */
|
||||||
|
static stringpair alias_tab = {NULL, NULL, NULL}; /* alias table */
|
||||||
|
|
||||||
|
SC_FUNC stringpair *insert_alias(char *name,char *alias)
|
||||||
|
{
|
||||||
|
stringpair *cur;
|
||||||
|
|
||||||
|
assert(name!=NULL);
|
||||||
|
assert(strlen(name)<=sNAMEMAX);
|
||||||
|
assert(alias!=NULL);
|
||||||
|
assert(strlen(alias)<=sNAMEMAX);
|
||||||
|
if ((cur=insert_stringpair(&alias_tab,name,alias,strlen(name)))==NULL)
|
||||||
|
error(103); /* insufficient memory (fatal error) */
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int lookup_alias(char *target,char *name)
|
||||||
|
{
|
||||||
|
stringpair *cur=find_stringpair(alias_tab.next,name,strlen(name));
|
||||||
|
if (cur!=NULL) {
|
||||||
|
assert(strlen(cur->second)<=sNAMEMAX);
|
||||||
|
strcpy(target,cur->second);
|
||||||
|
} /* if */
|
||||||
|
return cur!=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_aliastable(void)
|
||||||
|
{
|
||||||
|
delete_stringpairtable(&alias_tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- include paths list -------------------------------------- */
|
||||||
|
static stringlist includepaths = {NULL, NULL}; /* directory list for include files */
|
||||||
|
|
||||||
|
SC_FUNC stringlist *insert_path(char *path)
|
||||||
|
{
|
||||||
|
return insert_string(&includepaths,path);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC char *get_path(int index)
|
||||||
|
{
|
||||||
|
return get_string(&includepaths,index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_pathtable(void)
|
||||||
|
{
|
||||||
|
delete_stringtable(&includepaths);
|
||||||
|
assert(includepaths.next==NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- text substitution patterns ------------------------------ */
|
||||||
|
#if !defined NO_DEFINE
|
||||||
|
|
||||||
|
static stringpair substpair = { NULL, NULL, NULL}; /* list of substitution pairs */
|
||||||
|
|
||||||
|
static stringpair *substindex['z'-PUBLIC_CHAR+1]; /* quick index to first character */
|
||||||
|
static void adjustindex(char c)
|
||||||
|
{
|
||||||
|
stringpair *cur;
|
||||||
|
assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_' || c==PUBLIC_CHAR);
|
||||||
|
assert(PUBLIC_CHAR<'A' && 'A'<'_' && '_'<'z');
|
||||||
|
|
||||||
|
for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next)
|
||||||
|
/* nothing */;
|
||||||
|
substindex[(int)c-PUBLIC_CHAR]=cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen)
|
||||||
|
{
|
||||||
|
stringpair *cur;
|
||||||
|
|
||||||
|
assert(pattern!=NULL);
|
||||||
|
assert(substitution!=NULL);
|
||||||
|
if ((cur=insert_stringpair(&substpair,pattern,substitution,prefixlen))==NULL)
|
||||||
|
error(103); /* insufficient memory (fatal error) */
|
||||||
|
adjustindex(*pattern);
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC stringpair *find_subst(char *name,int length)
|
||||||
|
{
|
||||||
|
stringpair *item;
|
||||||
|
assert(name!=NULL);
|
||||||
|
assert(length>0);
|
||||||
|
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
|
||||||
|
item=substindex[(int)*name-PUBLIC_CHAR];
|
||||||
|
if (item!=NULL)
|
||||||
|
item=find_stringpair(item,name,length);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int delete_subst(char *name,int length)
|
||||||
|
{
|
||||||
|
stringpair *item;
|
||||||
|
assert(name!=NULL);
|
||||||
|
assert(length>0);
|
||||||
|
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
|
||||||
|
item=substindex[(int)*name-PUBLIC_CHAR];
|
||||||
|
if (item!=NULL)
|
||||||
|
item=find_stringpair(item,name,length);
|
||||||
|
if (item==NULL)
|
||||||
|
return FALSE;
|
||||||
|
delete_stringpair(&substpair,item);
|
||||||
|
adjustindex(*name);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_substtable(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
delete_stringpairtable(&substpair);
|
||||||
|
for (i=0; i<sizeof substindex/sizeof substindex[0]; i++)
|
||||||
|
substindex[i]=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !defined NO_SUBST */
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- input file list ----------------------------------------- */
|
||||||
|
static stringlist sourcefiles = {NULL, NULL};
|
||||||
|
|
||||||
|
SC_FUNC stringlist *insert_sourcefile(char *string)
|
||||||
|
{
|
||||||
|
return insert_string(&sourcefiles,string);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC char *get_sourcefile(int index)
|
||||||
|
{
|
||||||
|
return get_string(&sourcefiles,index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_sourcefiletable(void)
|
||||||
|
{
|
||||||
|
delete_stringtable(&sourcefiles);
|
||||||
|
assert(sourcefiles.next==NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- documentation tags -------------------------------------- */
|
||||||
|
#if !defined SC_LIGHT
|
||||||
|
static stringlist docstrings = {NULL, NULL};
|
||||||
|
|
||||||
|
SC_FUNC stringlist *insert_docstring(char *string)
|
||||||
|
{
|
||||||
|
return insert_string(&docstrings,string);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC char *get_docstring(int index)
|
||||||
|
{
|
||||||
|
return get_string(&docstrings,index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_docstring(int index)
|
||||||
|
{
|
||||||
|
delete_string(&docstrings,index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_docstringtable(void)
|
||||||
|
{
|
||||||
|
delete_stringtable(&docstrings);
|
||||||
|
assert(docstrings.next==NULL);
|
||||||
|
}
|
||||||
|
#endif /* !defined SC_LIGHT */
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- autolisting --------------------------------------------- */
|
||||||
|
static stringlist autolist = {NULL, NULL};
|
||||||
|
|
||||||
|
SC_FUNC stringlist *insert_autolist(char *string)
|
||||||
|
{
|
||||||
|
return insert_string(&autolist,string);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC char *get_autolist(int index)
|
||||||
|
{
|
||||||
|
return get_string(&autolist,index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_autolisttable(void)
|
||||||
|
{
|
||||||
|
delete_stringtable(&autolist);
|
||||||
|
assert(autolist.next==NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- debug information --------------------------------------- */
|
||||||
|
|
||||||
|
/* These macros are adapted from LibDGG libdgg-int64.h, see
|
||||||
|
* http://www.dennougedougakkai-ndd.org/pub/libdgg/
|
||||||
|
*/
|
||||||
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
|
||||||
|
#define __STDC_FORMAT_MACROS
|
||||||
|
#define __STDC_CONSTANT_MACROS
|
||||||
|
#include <inttypes.h> /* automatically includes stdint.h */
|
||||||
|
#elif (defined _MSC_VER || defined __BORLANDC__) && (defined _I64_MAX || defined HAVE_I64)
|
||||||
|
#define PRId64 "I64d"
|
||||||
|
#define PRIx64 "I64x"
|
||||||
|
#else
|
||||||
|
#define PRId64 "lld"
|
||||||
|
#define PRIx64 "llx"
|
||||||
|
#endif
|
||||||
|
#if PAWN_CELL_SIZE==64
|
||||||
|
#define PRIdC PRId64
|
||||||
|
#define PRIxC PRIx64
|
||||||
|
#elif PAWN_CELL_SIZE==32
|
||||||
|
#define PRIdC "ld"
|
||||||
|
#define PRIxC "lx"
|
||||||
|
#else
|
||||||
|
#define PRIdC "d"
|
||||||
|
#define PRIxC "x"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static stringlist dbgstrings = {NULL, NULL};
|
||||||
|
|
||||||
|
SC_FUNC stringlist *insert_dbgfile(const char *filename)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
|
||||||
|
char string[_MAX_PATH+40];
|
||||||
|
assert(filename!=NULL);
|
||||||
|
assert(strlen(filename)+40<sizeof string);
|
||||||
|
sprintf(string,"F:%" PRIxC " %s",code_idx,filename);
|
||||||
|
return insert_string(&dbgstrings,string);
|
||||||
|
} /* if */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC stringlist *insert_dbgline(int linenr)
|
||||||
|
{
|
||||||
|
if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
|
||||||
|
char string[40];
|
||||||
|
if (linenr>0)
|
||||||
|
linenr--; /* line numbers are zero-based in the debug information */
|
||||||
|
sprintf(string,"L:%" PRIxC " %x",code_idx,linenr);
|
||||||
|
return insert_string(&dbgstrings,string);
|
||||||
|
} /* if */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
|
||||||
|
{
|
||||||
|
if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
|
||||||
|
char string[2*sNAMEMAX+128];
|
||||||
|
char symname[2*sNAMEMAX+16];
|
||||||
|
|
||||||
|
funcdisplayname(symname,sym->name);
|
||||||
|
/* address tag:name codestart codeend ident vclass [tag:dim ...] */
|
||||||
|
if (sym->ident==iFUNCTN) {
|
||||||
|
sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x",
|
||||||
|
sym->addr,sym->tag,symname,sym->addr,sym->codeaddr,sym->ident,sym->vclass);
|
||||||
|
} else {
|
||||||
|
sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x",
|
||||||
|
sym->addr,sym->tag,symname,sym->codeaddr,code_idx,sym->ident,sym->vclass);
|
||||||
|
} /* if */
|
||||||
|
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
|
||||||
|
#if !defined NDEBUG
|
||||||
|
int count=sym->dim.array.level;
|
||||||
|
#endif
|
||||||
|
symbol *sub;
|
||||||
|
strcat(string," [ ");
|
||||||
|
for (sub=sym; sub!=NULL; sub=finddepend(sub)) {
|
||||||
|
assert(sub->dim.array.level==count--);
|
||||||
|
sprintf(string+strlen(string),"%x:%x ",sub->x.tags.index,sub->dim.array.length);
|
||||||
|
} /* for */
|
||||||
|
strcat(string,"]");
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return insert_string(&dbgstrings,string);
|
||||||
|
} /* if */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC char *get_dbgstring(int index)
|
||||||
|
{
|
||||||
|
return get_string(&dbgstrings,index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void delete_dbgstringtable(void)
|
||||||
|
{
|
||||||
|
delete_stringtable(&dbgstrings);
|
||||||
|
assert(dbgstrings.next==NULL);
|
||||||
|
}
|
179
compiler-init/scmemfil.c
Normal file
179
compiler-init/scmemfil.c
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/* Pawn compiler
|
||||||
|
*
|
||||||
|
* Routines to maintain a "text file" in memory.
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 2003-2006
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from the
|
||||||
|
* use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: scmemfil.c 3579 2006-06-06 13:35:29Z thiadmer $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "memfile.h"
|
||||||
|
|
||||||
|
#if defined FORTIFY
|
||||||
|
#include <alloc/fortify.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define BUFFERSIZE 512u
|
||||||
|
|
||||||
|
/* For every block, except the first:
|
||||||
|
* buffer points to a block that is BUFFERSIZE long that holds the data
|
||||||
|
* bufpos is the "used size" of the block
|
||||||
|
* For the first block:
|
||||||
|
* buffer points to the "file name"
|
||||||
|
* bufpos is the current "file pointer"
|
||||||
|
*/
|
||||||
|
typedef memfile_t MEMFILE;
|
||||||
|
#define tMEMFILE 1
|
||||||
|
|
||||||
|
#include "sc.h"
|
||||||
|
|
||||||
|
|
||||||
|
MEMFILE *mfcreate(char *filename)
|
||||||
|
{
|
||||||
|
return memfile_creat(filename, 4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mfclose(MEMFILE *mf)
|
||||||
|
{
|
||||||
|
memfile_destroy(mf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mfdump(MEMFILE *mf)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int okay;
|
||||||
|
|
||||||
|
assert(mf!=NULL);
|
||||||
|
/* create the file */
|
||||||
|
fp=fopen(mf->name, "wb");
|
||||||
|
if (fp==NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
okay=1;
|
||||||
|
okay = okay & (fwrite(mf->base, mf->usedoffs, 1, fp)==(size_t)mf->usedoffs);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return okay;
|
||||||
|
}
|
||||||
|
|
||||||
|
long mflength(MEMFILE *mf)
|
||||||
|
{
|
||||||
|
return mf->usedoffs;
|
||||||
|
}
|
||||||
|
|
||||||
|
long mfseek(MEMFILE *mf,long offset,int whence)
|
||||||
|
{
|
||||||
|
long length;
|
||||||
|
|
||||||
|
assert(mf!=NULL);
|
||||||
|
if (mf->usedoffs == 0)
|
||||||
|
return 0L; /* early exit: not a single byte in the file */
|
||||||
|
|
||||||
|
/* find the size of the memory file */
|
||||||
|
length=mflength(mf);
|
||||||
|
|
||||||
|
/* convert the offset to an absolute position */
|
||||||
|
switch (whence) {
|
||||||
|
case SEEK_SET:
|
||||||
|
break;
|
||||||
|
case SEEK_CUR:
|
||||||
|
offset+=mf->offs;
|
||||||
|
break;
|
||||||
|
case SEEK_END:
|
||||||
|
assert(offset<=0);
|
||||||
|
offset+=length;
|
||||||
|
break;
|
||||||
|
} /* switch */
|
||||||
|
|
||||||
|
/* clamp to the file length limit */
|
||||||
|
if (offset<0)
|
||||||
|
offset=0;
|
||||||
|
else if (offset>length)
|
||||||
|
offset=length;
|
||||||
|
|
||||||
|
/* set new position and return it */
|
||||||
|
memfile_seek(mf, offset);
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int mfwrite(MEMFILE *mf,unsigned char *buffer,unsigned int size)
|
||||||
|
{
|
||||||
|
return (memfile_write(mf, buffer, size) ? size : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size)
|
||||||
|
{
|
||||||
|
return memfile_read(mf, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *mfgets(MEMFILE *mf,char *string,unsigned int size)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
unsigned int read;
|
||||||
|
long seek;
|
||||||
|
|
||||||
|
assert(mf!=NULL);
|
||||||
|
|
||||||
|
read=mfread(mf,(unsigned char *)string,size);
|
||||||
|
if (read==0)
|
||||||
|
return NULL;
|
||||||
|
seek=0L;
|
||||||
|
|
||||||
|
/* make sure that the string is zero-terminated */
|
||||||
|
assert(read<=size);
|
||||||
|
if (read<size) {
|
||||||
|
string[read]='\0';
|
||||||
|
} else {
|
||||||
|
string[size-1]='\0';
|
||||||
|
seek=-1; /* undo reading the character that gets overwritten */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
/* find the first '\n' */
|
||||||
|
ptr=strchr(string,'\n');
|
||||||
|
if (ptr!=NULL) {
|
||||||
|
*(ptr+1)='\0';
|
||||||
|
seek=(long)(ptr-string)+1-(long)read;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
/* undo over-read */
|
||||||
|
assert(seek<=0); /* should seek backward only */
|
||||||
|
if (seek!=0)
|
||||||
|
mfseek(mf,seek,SEEK_CUR);
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mfputs(MEMFILE *mf,char *string)
|
||||||
|
{
|
||||||
|
unsigned int written,length;
|
||||||
|
|
||||||
|
assert(mf!=NULL);
|
||||||
|
|
||||||
|
length=strlen(string);
|
||||||
|
written=mfwrite(mf,(unsigned char *)string,length);
|
||||||
|
return written==length;
|
||||||
|
}
|
375
compiler-init/scstate.c
Normal file
375
compiler-init/scstate.c
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
/* Pawn compiler
|
||||||
|
*
|
||||||
|
* Machine and state maintenance.
|
||||||
|
*
|
||||||
|
* Three lists are maintained here:
|
||||||
|
* - A list of automatons (state machines): these hold a name, a unique id
|
||||||
|
* (in the "index" field) and the memory address of a cell that holds the
|
||||||
|
* current state of the automaton (in the "value" field).
|
||||||
|
* - A list of states for each automaton: a name, an automaton id (in the
|
||||||
|
* "index" field) and a unique id for the state (unique in the automaton;
|
||||||
|
* states belonging to different automatons may have the same id).
|
||||||
|
* - A list of state combinations. Each function may belong to a set of states.
|
||||||
|
* This list assigns a unique id to the combination of the automaton and all
|
||||||
|
* states.
|
||||||
|
*
|
||||||
|
* For a function/variable that has states, there is a fourth list, which is
|
||||||
|
* attached to the "symbol" structure. This list contains the code label (in
|
||||||
|
* the "name" field, only for functions), the id of the state combinations (the
|
||||||
|
* state list id; it is stored in the "index" field) and the code address at
|
||||||
|
* which the function starts. The latter is currently unused.
|
||||||
|
*
|
||||||
|
* At the start of the compiled code, a set of stub functions is generated.
|
||||||
|
* Each stub function looks up the value of the "state selector" value for the
|
||||||
|
* automaton, and goes with a "switch" instruction to the start address of the
|
||||||
|
* function. This happens in SC4.C.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 2005-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: scstate.c 3579 2006-06-06 13:35:29Z thiadmer $
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sc.h"
|
||||||
|
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
|
#include <sclinux.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined FORTIFY
|
||||||
|
#include <alloc/fortify.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct s_statelist {
|
||||||
|
struct s_statelist *next;
|
||||||
|
int *states; /* list of states in this combination */
|
||||||
|
int numstates; /* number of items in the above list */
|
||||||
|
int fsa; /* automaton id */
|
||||||
|
int listid; /* unique id for this combination list */
|
||||||
|
} statelist;
|
||||||
|
|
||||||
|
static statelist statelist_tab = { NULL, NULL, 0, 0, 0}; /* state combinations table */
|
||||||
|
|
||||||
|
|
||||||
|
static constvalue *find_automaton(const char *name,int *last)
|
||||||
|
{
|
||||||
|
constvalue *ptr;
|
||||||
|
|
||||||
|
assert(last!=NULL);
|
||||||
|
*last=0;
|
||||||
|
ptr=sc_automaton_tab.next;
|
||||||
|
while (ptr!=NULL) {
|
||||||
|
if (strcmp(name,ptr->name)==0)
|
||||||
|
return ptr;
|
||||||
|
if (ptr->index>*last)
|
||||||
|
*last=ptr->index;
|
||||||
|
ptr=ptr->next;
|
||||||
|
} /* while */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC constvalue *automaton_add(const char *name)
|
||||||
|
{
|
||||||
|
constvalue *ptr;
|
||||||
|
int last;
|
||||||
|
|
||||||
|
assert(strlen(name)<sizeof(ptr->name));
|
||||||
|
ptr=find_automaton(name,&last);
|
||||||
|
if (ptr==NULL) {
|
||||||
|
assert(last+1 <= SHRT_MAX);
|
||||||
|
ptr=append_constval(&sc_automaton_tab,name,(cell)0,(short)(last+1));
|
||||||
|
} /* if */
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC constvalue *automaton_find(const char *name)
|
||||||
|
{
|
||||||
|
int last;
|
||||||
|
return find_automaton(name,&last);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC constvalue *automaton_findid(int id)
|
||||||
|
{
|
||||||
|
constvalue *ptr;
|
||||||
|
for (ptr=sc_automaton_tab.next; ptr!=NULL && ptr->index!=id; ptr=ptr->next)
|
||||||
|
/* nothing */;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static constvalue *find_state(const char *name,int fsa,int *last)
|
||||||
|
{
|
||||||
|
constvalue *ptr;
|
||||||
|
|
||||||
|
assert(last!=NULL);
|
||||||
|
*last=0;
|
||||||
|
ptr=sc_state_tab.next;
|
||||||
|
while (ptr!=NULL) {
|
||||||
|
if (ptr->index==fsa) {
|
||||||
|
if (strcmp(name,ptr->name)==0)
|
||||||
|
return ptr;
|
||||||
|
if ((int)ptr->value>*last)
|
||||||
|
*last=(int)ptr->value;
|
||||||
|
} /* if */
|
||||||
|
ptr=ptr->next;
|
||||||
|
} /* while */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC constvalue *state_add(const char *name,int fsa)
|
||||||
|
{
|
||||||
|
constvalue *ptr;
|
||||||
|
int last;
|
||||||
|
|
||||||
|
assert(strlen(name)<sizeof(ptr->name));
|
||||||
|
ptr=find_state(name,fsa,&last);
|
||||||
|
if (ptr==NULL) {
|
||||||
|
assert(fsa <= SHRT_MAX);
|
||||||
|
ptr=append_constval(&sc_state_tab,name,(cell)(last+1),(short)fsa);
|
||||||
|
} /* if */
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC constvalue *state_find(const char *name,int fsa_id)
|
||||||
|
{
|
||||||
|
int last; /* dummy */
|
||||||
|
return find_state(name,fsa_id,&last);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC constvalue *state_findid(int id)
|
||||||
|
{
|
||||||
|
constvalue *ptr;
|
||||||
|
for (ptr=sc_state_tab.next; ptr!=NULL && ptr->value!=id; ptr=ptr->next)
|
||||||
|
/* nothing */;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void state_buildlist(int **list,int *listsize,int *count,int stateid)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
assert(list!=NULL);
|
||||||
|
assert(listsize!=NULL);
|
||||||
|
assert(*listsize>=0);
|
||||||
|
assert(count!=NULL);
|
||||||
|
assert(*count>=0);
|
||||||
|
assert(*count<=*listsize);
|
||||||
|
|
||||||
|
if (*count==*listsize) {
|
||||||
|
/* To avoid constantly calling malloc(), the list is grown by 4 states at
|
||||||
|
* a time.
|
||||||
|
*/
|
||||||
|
*listsize+=4;
|
||||||
|
*list=(int*)realloc(*list,*listsize*sizeof(int));
|
||||||
|
if (*list==NULL)
|
||||||
|
error(103); /* insufficient memory */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
/* find the insertion point (the list has to stay sorted) */
|
||||||
|
for (idx=0; idx<*count && *list[idx]<stateid; idx++)
|
||||||
|
/* nothing */;
|
||||||
|
if (idx<*count)
|
||||||
|
memmove(&(*list)[idx+1],&(*list)[idx],(int)((*count-idx+1)*sizeof(int)));
|
||||||
|
(*list)[idx]=stateid;
|
||||||
|
*count+=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static statelist *state_findlist(int *list,int count,int fsa,int *last)
|
||||||
|
{
|
||||||
|
statelist *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
assert(count>0);
|
||||||
|
assert(last!=NULL);
|
||||||
|
*last=0;
|
||||||
|
ptr=statelist_tab.next;
|
||||||
|
while (ptr!=NULL) {
|
||||||
|
if (ptr->listid>*last)
|
||||||
|
*last=ptr->listid;
|
||||||
|
if (ptr->fsa==fsa && ptr->numstates==count) {
|
||||||
|
/* compare all states */
|
||||||
|
for (i=0; i<count && ptr->states[i]==list[i]; i++)
|
||||||
|
/* nothing */;
|
||||||
|
if (i==count)
|
||||||
|
return ptr;
|
||||||
|
} /* if */
|
||||||
|
ptr=ptr->next;
|
||||||
|
} /* while */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static statelist *state_getlist_ptr(int listid)
|
||||||
|
{
|
||||||
|
statelist *ptr;
|
||||||
|
|
||||||
|
assert(listid>0);
|
||||||
|
for (ptr=statelist_tab.next; ptr!=NULL && ptr->listid!=listid; ptr=ptr->next)
|
||||||
|
/* nothing */;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int state_addlist(int *list,int count,int fsa)
|
||||||
|
{
|
||||||
|
statelist *ptr;
|
||||||
|
int last;
|
||||||
|
|
||||||
|
assert(list!=NULL);
|
||||||
|
assert(count>0);
|
||||||
|
ptr=state_findlist(list,count,fsa,&last);
|
||||||
|
if (ptr==NULL) {
|
||||||
|
if ((ptr=(statelist*)malloc(sizeof(statelist)))==NULL)
|
||||||
|
error(103); /* insufficient memory */
|
||||||
|
if ((ptr->states=(int*)malloc(count*sizeof(int)))==NULL) {
|
||||||
|
free(ptr);
|
||||||
|
error(103); /* insufficient memory */
|
||||||
|
} /* if */
|
||||||
|
memcpy(ptr->states,list,count*sizeof(int));
|
||||||
|
ptr->numstates=count;
|
||||||
|
ptr->fsa=fsa;
|
||||||
|
ptr->listid=last+1;
|
||||||
|
ptr->next=statelist_tab.next;
|
||||||
|
statelist_tab.next=ptr;
|
||||||
|
} /* if */
|
||||||
|
assert(ptr!=NULL);
|
||||||
|
return ptr->listid;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void state_deletetable(void)
|
||||||
|
{
|
||||||
|
statelist *ptr;
|
||||||
|
|
||||||
|
while (statelist_tab.next!=NULL) {
|
||||||
|
ptr=statelist_tab.next;
|
||||||
|
/* unlink first */
|
||||||
|
statelist_tab.next=ptr->next;
|
||||||
|
/* then delete */
|
||||||
|
assert(ptr->states!=NULL);
|
||||||
|
free(ptr->states);
|
||||||
|
free(ptr);
|
||||||
|
} /* while */
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int state_getfsa(int listid)
|
||||||
|
{
|
||||||
|
statelist *ptr;
|
||||||
|
|
||||||
|
assert(listid>=0);
|
||||||
|
if (listid==0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ptr=state_getlist_ptr(listid);
|
||||||
|
return (ptr!=NULL) ? ptr->fsa : -1; /* fsa 0 exists */
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int state_count(int listid)
|
||||||
|
{
|
||||||
|
statelist *ptr=state_getlist_ptr(listid);
|
||||||
|
if (ptr==NULL)
|
||||||
|
return 0; /* unknown list, no states in it */
|
||||||
|
return ptr->numstates;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int state_inlist(int listid,int state)
|
||||||
|
{
|
||||||
|
statelist *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ptr=state_getlist_ptr(listid);
|
||||||
|
if (ptr==NULL)
|
||||||
|
return FALSE; /* unknown list, state not in it */
|
||||||
|
for (i=0; i<ptr->numstates; i++)
|
||||||
|
if (ptr->states[i]==state)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC int state_listitem(int listid,int index)
|
||||||
|
{
|
||||||
|
statelist *ptr;
|
||||||
|
|
||||||
|
ptr=state_getlist_ptr(listid);
|
||||||
|
assert(ptr!=NULL);
|
||||||
|
assert(index>=0 && index<ptr->numstates);
|
||||||
|
return ptr->states[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int checkconflict(statelist *psrc,statelist *ptgt)
|
||||||
|
{
|
||||||
|
int s,t;
|
||||||
|
|
||||||
|
assert(psrc!=NULL);
|
||||||
|
assert(ptgt!=NULL);
|
||||||
|
for (s=0; s<psrc->numstates; s++)
|
||||||
|
for (t=0; t<ptgt->numstates; t++)
|
||||||
|
if (psrc->states[s]==ptgt->states[t])
|
||||||
|
return 1; /* state conflict */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function searches whether one of the states in the list of statelist id's
|
||||||
|
* of a symbol exists in any other statelist id's of the same function; it also
|
||||||
|
* verifies that all definitions of the symbol are in the same automaton.
|
||||||
|
*/
|
||||||
|
SC_FUNC void state_conflict(symbol *root)
|
||||||
|
{
|
||||||
|
statelist *psrc,*ptgt;
|
||||||
|
constvalue *srcptr,*tgtptr;
|
||||||
|
symbol *sym;
|
||||||
|
|
||||||
|
assert(root!=NULL);
|
||||||
|
for (sym=root->next; sym!=NULL; sym=sym->next) {
|
||||||
|
if (sym->parent!=NULL || sym->ident!=iFUNCTN)
|
||||||
|
continue; /* hierarchical data type or no function */
|
||||||
|
if (sym->states==NULL)
|
||||||
|
continue; /* this function has no states */
|
||||||
|
for (srcptr=sym->states->next; srcptr!=NULL; srcptr=srcptr->next) {
|
||||||
|
if (srcptr->index==-1)
|
||||||
|
continue; /* state list id -1 is a special case */
|
||||||
|
psrc=state_getlist_ptr(srcptr->index);
|
||||||
|
assert(psrc!=NULL);
|
||||||
|
for (tgtptr=srcptr->next; tgtptr!=NULL; tgtptr=tgtptr->next) {
|
||||||
|
if (tgtptr->index==-1)
|
||||||
|
continue; /* state list id -1 is a special case */
|
||||||
|
ptgt=state_getlist_ptr(tgtptr->index);
|
||||||
|
assert(ptgt!=NULL);
|
||||||
|
if (psrc->fsa!=ptgt->fsa && strcmp(sym->name,uENTRYFUNC)!=0)
|
||||||
|
error(83,sym->name); /* this function is part of another machine */
|
||||||
|
if (checkconflict(psrc,ptgt))
|
||||||
|
error(84,sym->name); /* state conflict */
|
||||||
|
} /* for (tgtptr) */
|
||||||
|
} /* for (srcptr) */
|
||||||
|
} /* for (sym) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check whether the two state lists (whose ids are passed in) share any
|
||||||
|
* states
|
||||||
|
*/
|
||||||
|
SC_FUNC int state_conflict_id(int listid1,int listid2)
|
||||||
|
{
|
||||||
|
statelist *psrc,*ptgt;
|
||||||
|
|
||||||
|
psrc=state_getlist_ptr(listid1);
|
||||||
|
assert(psrc!=NULL);
|
||||||
|
ptgt=state_getlist_ptr(listid2);
|
||||||
|
assert(ptgt!=NULL);
|
||||||
|
return checkconflict(psrc,ptgt);
|
||||||
|
}
|
113
compiler-init/scvars.c
Normal file
113
compiler-init/scvars.c
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/* Pawn compiler
|
||||||
|
*
|
||||||
|
* Global (cross-module) variables.
|
||||||
|
*
|
||||||
|
* Copyright (c) ITB CompuPhase, 1997-2006
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software in
|
||||||
|
* a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
* Version: $Id: scvars.c 3577 2006-06-02 16:22:52Z thiadmer $
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h> /* for _MAX_PATH */
|
||||||
|
#include "sc.h"
|
||||||
|
|
||||||
|
/* global variables
|
||||||
|
*
|
||||||
|
* All global variables that are shared amongst the compiler files are
|
||||||
|
* declared here.
|
||||||
|
*/
|
||||||
|
SC_VDEFINE symbol loctab; /* local symbol table */
|
||||||
|
SC_VDEFINE symbol glbtab; /* global symbol table */
|
||||||
|
SC_VDEFINE cell *litq; /* the literal queue */
|
||||||
|
SC_VDEFINE unsigned char pline[sLINEMAX+1]; /* the line read from the input file */
|
||||||
|
SC_VDEFINE const unsigned char *lptr; /* points to the current position in "pline" */
|
||||||
|
SC_VDEFINE constvalue tagname_tab = { NULL, "", 0, 0}; /* tagname table */
|
||||||
|
SC_VDEFINE constvalue libname_tab = { NULL, "", 0, 0}; /* library table (#pragma library "..." syntax) */
|
||||||
|
SC_VDEFINE constvalue *curlibrary = NULL; /* current library */
|
||||||
|
SC_VDEFINE int pc_addlibtable = TRUE; /* is the library table added to the AMX file? */
|
||||||
|
SC_VDEFINE symbol *curfunc; /* pointer to current function */
|
||||||
|
SC_VDEFINE char *inpfname; /* pointer to name of the file currently read from */
|
||||||
|
SC_VDEFINE char outfname[_MAX_PATH]; /* intermediate (assembler) file name */
|
||||||
|
SC_VDEFINE char binfname[_MAX_PATH]; /* binary file name */
|
||||||
|
SC_VDEFINE char errfname[_MAX_PATH]; /* error file name */
|
||||||
|
SC_VDEFINE char sc_ctrlchar = CTRL_CHAR; /* the control character (or escape character)*/
|
||||||
|
SC_VDEFINE char sc_ctrlchar_org = CTRL_CHAR;/* the default control character */
|
||||||
|
SC_VDEFINE int litidx = 0; /* index to literal table */
|
||||||
|
SC_VDEFINE int litmax = sDEF_LITMAX; /* current size of the literal table */
|
||||||
|
SC_VDEFINE int stgidx = 0; /* index to the staging buffer */
|
||||||
|
SC_VDEFINE int sc_labnum = 0; /* number of (internal) labels */
|
||||||
|
SC_VDEFINE int staging = 0; /* true if staging output */
|
||||||
|
SC_VDEFINE cell declared = 0; /* number of local cells declared */
|
||||||
|
SC_VDEFINE cell glb_declared=0; /* number of global cells declared */
|
||||||
|
SC_VDEFINE cell code_idx = 0; /* number of bytes with generated code */
|
||||||
|
SC_VDEFINE int ntv_funcid= 0; /* incremental number of native function */
|
||||||
|
SC_VDEFINE int errnum = 0; /* number of errors */
|
||||||
|
SC_VDEFINE int warnnum = 0; /* number of warnings */
|
||||||
|
SC_VDEFINE int sc_debug = sCHKBOUNDS; /* by default: bounds checking+assertions */
|
||||||
|
SC_VDEFINE int sc_packstr= FALSE; /* strings are packed by default? */
|
||||||
|
SC_VDEFINE int sc_asmfile= FALSE; /* create .ASM file? */
|
||||||
|
SC_VDEFINE int sc_listing= FALSE; /* create .LST file? */
|
||||||
|
SC_VDEFINE int sc_compress=TRUE; /* compress bytecode? */
|
||||||
|
SC_VDEFINE int sc_needsemicolon=TRUE;/* semicolon required to terminate expressions? */
|
||||||
|
SC_VDEFINE int sc_dataalign=sizeof(cell);/* data alignment value */
|
||||||
|
SC_VDEFINE int sc_alignnext=FALSE; /* must frame of the next function be aligned? */
|
||||||
|
SC_VDEFINE int pc_docexpr=FALSE; /* must expression be attached to documentation comment? */
|
||||||
|
SC_VDEFINE int curseg = 0; /* 1 if currently parsing CODE, 2 if parsing DATA */
|
||||||
|
SC_VDEFINE cell pc_stksize=sDEF_AMXSTACK;/* default stack size */
|
||||||
|
SC_VDEFINE cell pc_amxlimit=0; /* default abstract machine size limit = none */
|
||||||
|
SC_VDEFINE cell pc_amxram=0; /* default abstract machine data size limit = none */
|
||||||
|
SC_VDEFINE int freading = FALSE; /* Is there an input file ready for reading? */
|
||||||
|
SC_VDEFINE int fline = 0; /* the line number in the current file */
|
||||||
|
SC_VDEFINE short fnumber = 0; /* the file number in the file table (debugging) */
|
||||||
|
SC_VDEFINE short fcurrent= 0; /* current file being processed (debugging) */
|
||||||
|
SC_VDEFINE short sc_intest=FALSE; /* true if inside a test */
|
||||||
|
SC_VDEFINE int sideeffect= 0; /* true if an expression causes a side-effect */
|
||||||
|
SC_VDEFINE int stmtindent= 0; /* current indent of the statement */
|
||||||
|
SC_VDEFINE int indent_nowarn=FALSE;/* skip warning "217 loose indentation" */
|
||||||
|
SC_VDEFINE int sc_tabsize=8; /* number of spaces that a TAB represents */
|
||||||
|
SC_VDEFINE short sc_allowtags=TRUE; /* allow/detect tagnames in lex() */
|
||||||
|
SC_VDEFINE int sc_status; /* read/write status */
|
||||||
|
SC_VDEFINE int sc_rationaltag=0; /* tag for rational numbers */
|
||||||
|
SC_VDEFINE int rational_digits=0; /* number of fractional digits */
|
||||||
|
SC_VDEFINE int sc_allowproccall=0; /* allow/detect tagnames in lex() */
|
||||||
|
SC_VDEFINE short sc_is_utf8=FALSE; /* is this source file in UTF-8 encoding */
|
||||||
|
SC_VDEFINE char *pc_depricate=NULL;/* if non-null, mark next declaration as depricated */
|
||||||
|
SC_VDEFINE int sc_curstates=0; /* ID of the current state list */
|
||||||
|
SC_VDEFINE int pc_optimize=sOPTIMIZE_NOMACRO; /* (peephole) optimization level */
|
||||||
|
SC_VDEFINE int pc_memflags=0; /* special flags for the stack/heap usage */
|
||||||
|
|
||||||
|
SC_VDEFINE constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */
|
||||||
|
SC_VDEFINE constvalue sc_state_tab = { NULL, "", 0, 0}; /* state table */
|
||||||
|
|
||||||
|
SC_VDEFINE FILE *inpf = NULL; /* file read from (source or include) */
|
||||||
|
SC_VDEFINE FILE *inpf_org= NULL; /* main source file */
|
||||||
|
SC_VDEFINE FILE *outf = NULL; /* (intermediate) text file written to */
|
||||||
|
|
||||||
|
SC_VDEFINE jmp_buf errbuf;
|
||||||
|
|
||||||
|
#if !defined SC_LIGHT
|
||||||
|
SC_VDEFINE int sc_makereport=FALSE; /* generate a cross-reference report */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __WATCOMC__ && !defined NDEBUG
|
||||||
|
/* Watcom's CVPACK dislikes .OBJ files without functions */
|
||||||
|
static int dummyfunc(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
21
compiler-init/spcomp.sln
Normal file
21
compiler-init/spcomp.sln
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spcomp", "spcomp.vcproj", "{B4C844FF-008D-4BD5-B82F-DC06E706C64B}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
|
Debug = Debug
|
||||||
|
Release = Release
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfiguration) = postSolution
|
||||||
|
{B4C844FF-008D-4BD5-B82F-DC06E706C64B}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{B4C844FF-008D-4BD5-B82F-DC06E706C64B}.Debug.Build.0 = Debug|Win32
|
||||||
|
{B4C844FF-008D-4BD5-B82F-DC06E706C64B}.Release.ActiveCfg = Release|Win32
|
||||||
|
{B4C844FF-008D-4BD5-B82F-DC06E706C64B}.Release.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
305
compiler-init/spcomp.vcproj
Normal file
305
compiler-init/spcomp.vcproj
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="7.10"
|
||||||
|
Name="spcomp"
|
||||||
|
ProjectGUID="{B4C844FF-008D-4BD5-B82F-DC06E706C64B}"
|
||||||
|
RootNamespace="spcomp"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\libpawnc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lstring.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\memfile.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\pawncc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc1.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc2.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc3.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc4.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc5.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc6.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc7.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\scexpand.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sci18n.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sclist.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\scmemfil.c"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\scstate.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\scvars.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\amx.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lstring.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\memfile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\osdefs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\svnrev.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\libpawnc.rc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc5.scp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sc7.scp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
9
compiler-init/svnrev.h
Normal file
9
compiler-init/svnrev.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#define SMC_VERSION 1
|
||||||
|
#define SMC_REVISION 0
|
||||||
|
#define SMC_BUILD 1
|
||||||
|
#define SMC_VERSTRING "1.0.1.3599"
|
||||||
|
|
||||||
|
#define SVN_REV 3599
|
||||||
|
#define SVN_REVSTR "3599"
|
||||||
|
#define SVN_REVDATE "2006-07-05"
|
||||||
|
#define SVN_REVSTAMP 20060705L
|
Loading…
Reference in New Issue
Block a user