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