Initial import of Pawn (Small 3.0)
This commit is contained in:
		
							
								
								
									
										52
									
								
								compiler/libpc300/CMakeLists.txt
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										52
									
								
								compiler/libpc300/CMakeLists.txt
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
#build file for CMake, see http://www.cmake.org/
 | 
			
		||||
 | 
			
		||||
PROJECT(pawnc)
 | 
			
		||||
 | 
			
		||||
# check for optional include files
 | 
			
		||||
INCLUDE(${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake)
 | 
			
		||||
CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H)
 | 
			
		||||
IF(HAVE_UNISTD_H)
 | 
			
		||||
  ADD_DEFINITIONS(-DHAVE_UNISTD_H)
 | 
			
		||||
ENDIF(HAVE_UNISTD_H)
 | 
			
		||||
CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H)
 | 
			
		||||
IF(HAVE_INTTYPES_H)
 | 
			
		||||
  ADD_DEFINITIONS(-DHAVE_INTTYPES_H)
 | 
			
		||||
ENDIF(HAVE_INTTYPES_H)
 | 
			
		||||
CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H)
 | 
			
		||||
IF(HAVE_STDINT_H)
 | 
			
		||||
  ADD_DEFINITIONS(-DHAVE_STDINT_H)
 | 
			
		||||
ENDIF(HAVE_STDINT_H)
 | 
			
		||||
CHECK_INCLUDE_FILE("alloca.h" HAVE_ALLOCA_H)
 | 
			
		||||
IF(HAVE_ALLOCA_H)
 | 
			
		||||
  ADD_DEFINITIONS(-DHAVE_ALLOCA_H)
 | 
			
		||||
ENDIF(HAVE_ALLOCA_H)
 | 
			
		||||
 | 
			
		||||
IF(UNIX)
 | 
			
		||||
  ADD_DEFINITIONS(-DLINUX -DENABLE_BINRELOC -g)
 | 
			
		||||
  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../linux)
 | 
			
		||||
ENDIF(UNIX)
 | 
			
		||||
 | 
			
		||||
# The Pawn compiler shared library
 | 
			
		||||
SET(PAWNC_SRCS sc1.c sc2.c sc3.c sc4.c sc5.c sc6.c sc7.c
 | 
			
		||||
	scexpand.c sci18n.c sclist.c scmemfil.c scstate.c scvars.c
 | 
			
		||||
	libpawnc.c)
 | 
			
		||||
SET_SOURCE_FILES_PROPERTIES(sc1.c COMPILE_FLAGS -DNO_MAIN)
 | 
			
		||||
IF(WIN32)
 | 
			
		||||
  SET(PAWNC_SRCS ${PAWNC_SRCS} libpawnc.def libpawnc.rc)
 | 
			
		||||
  SET_SOURCE_FILES_PROPERTIES(libpawnc.c COMPILE_FLAGS -DPAWNC_DLL)
 | 
			
		||||
ENDIF(WIN32)
 | 
			
		||||
IF(UNIX)
 | 
			
		||||
  SET(PAWNC_SRCS ${PAWNC_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/../linux/prefix.c)
 | 
			
		||||
ENDIF(UNIX)
 | 
			
		||||
ADD_LIBRARY(pawnc SHARED ${PAWNC_SRCS})
 | 
			
		||||
IF(UNIX)
 | 
			
		||||
  ADD_CUSTOM_COMMAND(TARGET pawnc POST_BUILD COMMAND strip ARGS -K pc_compile -K pc_addconstant -K pc_addtag -K pc_enablewarning libpawnc.so)
 | 
			
		||||
ENDIF(UNIX)
 | 
			
		||||
 | 
			
		||||
# The Pawn compiler driver (console program)
 | 
			
		||||
SET(PAWNCC_SRCS pawncc.c)
 | 
			
		||||
IF(WIN32)
 | 
			
		||||
  SET(PAWNCC_SRCS ${PAWNCC_SRCS} pawncc.def libpawnc.rc)
 | 
			
		||||
ENDIF(WIN32)
 | 
			
		||||
ADD_EXECUTABLE(pawncc ${PAWNCC_SRCS})
 | 
			
		||||
TARGET_LINK_LIBRARIES(pawncc pawnc)
 | 
			
		||||
							
								
								
									
										439
									
								
								compiler/libpc300/amx.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										439
									
								
								compiler/libpc300/amx.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,439 @@
 | 
			
		||||
/*  Pawn Abstract Machine (for the Pawn language)
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 1997-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined FREEBSD && !defined __FreeBSD__
 | 
			
		||||
  #define __FreeBSD__
 | 
			
		||||
#endif
 | 
			
		||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
 | 
			
		||||
  #include <sclinux.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef AMX_H_INCLUDED
 | 
			
		||||
#define AMX_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#if defined HAVE_STDINT_H
 | 
			
		||||
  #include <stdint.h>
 | 
			
		||||
#else
 | 
			
		||||
  #if defined __LCC__ || defined __DMC__ || defined LINUX
 | 
			
		||||
    #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
 | 
			
		||||
 | 
			
		||||
#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                          Required AMX version
 | 
			
		||||
 *   0 (original version)                       0
 | 
			
		||||
 *   1 (opcodes JUMP.pri, SWITCH and CASETBL)   1
 | 
			
		||||
 *   2 (compressed files)                       2
 | 
			
		||||
 *   3 (public variables)                       2
 | 
			
		||||
 *   4 (opcodes SWAP.pri/alt and PUSHADDR)      4
 | 
			
		||||
 *   5 (tagnames table)                         4
 | 
			
		||||
 *   6 (reformatted header)                     6
 | 
			
		||||
 *   7 (name table, opcodes SYMTAG & SYSREQ.D)  7
 | 
			
		||||
 *   8 (opcode STMT, renewed debug interface)   8
 | 
			
		||||
 */
 | 
			
		||||
#define CUR_FILE_VERSION  8     /* 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   8     /* minimum AMX version needed to support the current file format */
 | 
			
		||||
 | 
			
		||||
#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   ((1L << (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);
 | 
			
		||||
#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;
 | 
			
		||||
} 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;
 | 
			
		||||
} PACKED AMX_FUNCSTUB;
 | 
			
		||||
 | 
			
		||||
typedef struct tagFUNCSTUBNT {
 | 
			
		||||
  ucell address         PACKED;
 | 
			
		||||
  uint32_t nameofs      PACKED;
 | 
			
		||||
} 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
 | 
			
		||||
} PACKED 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 */
 | 
			
		||||
} PACKED 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_BYTEOPC  0x08  /* opcode is a byte (not a cell) */
 | 
			
		||||
#define AMX_FLAG_NOCHECKS 0x10  /* no array bounds checking; no STMT opcode */
 | 
			
		||||
#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_); \
 | 
			
		||||
      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/libpc300/amxdbg.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										172
									
								
								compiler/libpc300/amxdbg.h
									
									
									
									
									
										Executable 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
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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 */
 | 
			
		||||
} AMX_DBG_HDR           PACKED;
 | 
			
		||||
#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 */
 | 
			
		||||
} AMX_DBG_FILE          PACKED;
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
} AMX_DBG_LINE          PACKED;
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
} AMX_DBG_SYMBOL        PACKED;
 | 
			
		||||
 | 
			
		||||
typedef struct tagAMX_DBG_SYMDIM {
 | 
			
		||||
  int16_t tag           PACKED; /* tag for the array dimension */
 | 
			
		||||
  ucell   size          PACKED; /* size of the array dimension */
 | 
			
		||||
} AMX_DBG_SYMDIM        PACKED;
 | 
			
		||||
 | 
			
		||||
typedef struct tagAMX_DBG_TAG {
 | 
			
		||||
  int16_t tag           PACKED; /* tag id */
 | 
			
		||||
  const char name[1]    PACKED; /* ASCII string, zero-terminated */
 | 
			
		||||
} AMX_DBG_TAG           PACKED;
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
} AMX_DBG_MACHINE       PACKED;
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
} AMX_DBG_STATE         PACKED;
 | 
			
		||||
 | 
			
		||||
typedef struct tagAMX_DBG {
 | 
			
		||||
  AMX_DBG_HDR     _FAR *hdr         PACKED; /* points to the AMX_DBG header */
 | 
			
		||||
  AMX_DBG_FILE    _FAR **filetbl    PACKED;
 | 
			
		||||
  AMX_DBG_LINE    _FAR *linetbl     PACKED;
 | 
			
		||||
  AMX_DBG_SYMBOL  _FAR **symboltbl  PACKED;
 | 
			
		||||
  AMX_DBG_TAG     _FAR **tagtbl     PACKED;
 | 
			
		||||
  AMX_DBG_MACHINE _FAR **automatontbl PACKED;
 | 
			
		||||
  AMX_DBG_STATE   _FAR **statetbl   PACKED;
 | 
			
		||||
} AMX_DBG                           PACKED;
 | 
			
		||||
 | 
			
		||||
#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 */
 | 
			
		||||
							
								
								
									
										79
									
								
								compiler/libpc300/dllmain.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										79
									
								
								compiler/libpc300/dllmain.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
/*  DLL support functions for dynamically loadable extension libraries.
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 2004-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined _UNICODE || defined __UNICODE__ || defined UNICODE
 | 
			
		||||
# if !defined UNICODE   /* for Windows */
 | 
			
		||||
#   define UNICODE
 | 
			
		||||
# endif
 | 
			
		||||
# if !defined _UNICODE  /* for C library */
 | 
			
		||||
#   define _UNICODE
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
 | 
			
		||||
#if !defined UNUSED_PARAM
 | 
			
		||||
  #define UNUSED_PARAM(p) ((void)(p))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
HINSTANCE hinstDLL;
 | 
			
		||||
 | 
			
		||||
/* Especially Watcom C/C++ does not like DLLs that do not have a LibMain()
 | 
			
		||||
 * set. Apparently, the start address is not set well, and some required
 | 
			
		||||
 * initializations are not done.
 | 
			
		||||
 */
 | 
			
		||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
 | 
			
		||||
 | 
			
		||||
  BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID lpRes)
 | 
			
		||||
  {
 | 
			
		||||
    UNUSED_PARAM(lpRes);
 | 
			
		||||
    switch (dwReason) {
 | 
			
		||||
    case DLL_PROCESS_ATTACH:
 | 
			
		||||
      hinstDLL=hinst;
 | 
			
		||||
      break;
 | 
			
		||||
    case DLL_PROCESS_DETACH:
 | 
			
		||||
      break;
 | 
			
		||||
    } /* switch */
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
  int FAR PASCAL LibMain(HINSTANCE hinst, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine)
 | 
			
		||||
  {
 | 
			
		||||
    UNUSED_PARAM(wDataSeg);
 | 
			
		||||
    UNUSED_PARAM(wHeapSize);
 | 
			
		||||
    UNUSED_PARAM(lpszCmdLine);
 | 
			
		||||
    hinstDLL=hinst;
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int FAR PASCAL _export WEP(int param)
 | 
			
		||||
  {
 | 
			
		||||
    UNUSED_PARAM(param);
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif /* __WIN32__ */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										334
									
								
								compiler/libpc300/libpawnc.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										334
									
								
								compiler/libpc300/libpawnc.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,334 @@
 | 
			
		||||
/*  LIBPAWNC.C
 | 
			
		||||
 *
 | 
			
		||||
 *  A "glue file" for building the Pawn compiler as a DLL or shared library.
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 2000-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "sc.h"
 | 
			
		||||
 | 
			
		||||
#if defined PAWNC_DLL
 | 
			
		||||
 | 
			
		||||
# include "dllmain.c"
 | 
			
		||||
 | 
			
		||||
# define MAX_ARGS   100
 | 
			
		||||
# if !defined UNUSED_PARAM
 | 
			
		||||
#   define UNUSED_PARAM(p) ((void)(p))
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
  static char *argv[MAX_ARGS];
 | 
			
		||||
  static int  argc;
 | 
			
		||||
 | 
			
		||||
  LPSTR dll_skipwhite(LPSTR ptr)
 | 
			
		||||
  {
 | 
			
		||||
    assert(ptr!=NULL);
 | 
			
		||||
    while (*ptr<=' ' && *ptr!='\0')
 | 
			
		||||
      ptr++;
 | 
			
		||||
    return ptr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if PAWN_CELL_SIZE==32
 | 
			
		||||
#define EXCOMPILER	Compile32
 | 
			
		||||
#else
 | 
			
		||||
#define EXCOMPILER	Compile64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
# if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined __NT__
 | 
			
		||||
  __declspec (dllexport)
 | 
			
		||||
  void EXCOMPILER(HWND hwnd, HINSTANCE hinst, LPSTR lpCommandLine, int nCmdShow)
 | 
			
		||||
# else
 | 
			
		||||
  void extern EXCOMPILER(HWND hwnd, HINSTANCE hinst, LPSTR lpCommandLine, int nCmdShow)
 | 
			
		||||
# endif
 | 
			
		||||
  {
 | 
			
		||||
    char RootPath[_MAX_PATH];
 | 
			
		||||
    LPSTR ptr;
 | 
			
		||||
 | 
			
		||||
    /* RUNDLL32 may have passed us a HWND and a HINSTANCE, but we can hardly
 | 
			
		||||
     * trust these. They may not contain values that we can use.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /* the root path in argv[0] */
 | 
			
		||||
    GetModuleFileName(hinstDLL, RootPath, sizeof RootPath);
 | 
			
		||||
    argv[argc++]=RootPath;
 | 
			
		||||
 | 
			
		||||
    /* all other options */
 | 
			
		||||
    assert(lpCommandLine!=NULL);
 | 
			
		||||
    ptr=dll_skipwhite(lpCommandLine);
 | 
			
		||||
    while (*ptr!='\0') {
 | 
			
		||||
      if (*ptr=='"') {
 | 
			
		||||
        argv[argc++]=ptr+1;
 | 
			
		||||
        while (*ptr!='"' && *ptr!='\0')
 | 
			
		||||
          ptr++;
 | 
			
		||||
      } else {
 | 
			
		||||
        argv[argc++]=ptr;
 | 
			
		||||
        while (*ptr>' ')
 | 
			
		||||
          ptr++;
 | 
			
		||||
      } /* if */
 | 
			
		||||
      if (*ptr!='\0')
 | 
			
		||||
        *ptr++='\0';
 | 
			
		||||
      ptr=dll_skipwhite(ptr);
 | 
			
		||||
    } /* while */
 | 
			
		||||
    pc_compile(argc,argv);
 | 
			
		||||
    UNUSED_PARAM(hwnd);
 | 
			
		||||
    UNUSED_PARAM(hinst);
 | 
			
		||||
    UNUSED_PARAM(nCmdShow);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#else /* PAWNC_DLL */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* PAWNC_DLL */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 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,...)
 | 
			
		||||
{
 | 
			
		||||
#if PAWN_CELL_SIZE==32
 | 
			
		||||
  int ret;
 | 
			
		||||
  va_list argptr;
 | 
			
		||||
 | 
			
		||||
  va_start(argptr,message);
 | 
			
		||||
  ret=vprintf(message,argptr);
 | 
			
		||||
  va_end(argptr);
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
#else
 | 
			
		||||
  return 1;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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)
 | 
			
		||||
{
 | 
			
		||||
#if PAWN_CELL_SIZE==32
 | 
			
		||||
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);
 | 
			
		||||
#endif
 | 
			
		||||
  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 fopen(filename,"wb");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pc_closebin(void *handle,int deletefile)
 | 
			
		||||
{
 | 
			
		||||
  fclose((FILE*)handle);
 | 
			
		||||
  if (deletefile)
 | 
			
		||||
    remove(binfname);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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)
 | 
			
		||||
{
 | 
			
		||||
  fflush((FILE*)handle);
 | 
			
		||||
  fseek((FILE*)handle,offset,SEEK_SET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pc_writebin(void *handle,void *buffer,int size)
 | 
			
		||||
{
 | 
			
		||||
  return (int)fwrite(buffer,1,size,(FILE*)handle) == size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
long pc_lengthbin(void *handle)
 | 
			
		||||
{
 | 
			
		||||
  return ftell((FILE*)handle);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								compiler/libpc300/libpawnc.def
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								compiler/libpc300/libpawnc.def
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
LIBRARY       PAWNC
 | 
			
		||||
DESCRIPTION   'Pawn compiler'
 | 
			
		||||
 | 
			
		||||
EXPORTS Compile
 | 
			
		||||
        pc_compile
 | 
			
		||||
        pc_addconstant
 | 
			
		||||
        pc_addtag
 | 
			
		||||
        pc_enablewarning
 | 
			
		||||
							
								
								
									
										5
									
								
								compiler/libpc300/libpawnc.lbc
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								compiler/libpc300/libpawnc.lbc
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
++_Compile@16        .libpawnc .Compile
 | 
			
		||||
++pc_compile         .libpawnc .pc_compile
 | 
			
		||||
++pc_addconstant     .libpawnc .pc_addconstant
 | 
			
		||||
++pc_addtag          .libpawnc .pc_addtag
 | 
			
		||||
++pc_enablewarning   .libpawnc .pc_enablewarning                                     
 | 
			
		||||
							
								
								
									
										62
									
								
								compiler/libpc300/libpawnc.rc
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										62
									
								
								compiler/libpc300/libpawnc.rc
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#if defined WIN32 || defined _WIN32 || defined __WIN32__
 | 
			
		||||
#  include <winver.h>
 | 
			
		||||
#else
 | 
			
		||||
#  include <ver.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
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              3
 | 
			
		||||
#define REVISION             0
 | 
			
		||||
#define BUILD                0
 | 
			
		||||
#define VERSIONSTR           "3.0.0\0"
 | 
			
		||||
#if defined STAND_ALONE
 | 
			
		||||
#define VERSIONNAME          "pawncc.exe\0"
 | 
			
		||||
#define VERSIONDESCRIPTION   "Pawn Compiler\0"
 | 
			
		||||
#define VERSIONPRODUCTNAME   "pawncc\0"
 | 
			
		||||
#else
 | 
			
		||||
#define VERSIONNAME          "libpawnc.dll\0"
 | 
			
		||||
#define VERSIONDESCRIPTION   "Pawn Compiler library\0"
 | 
			
		||||
#define VERSIONPRODUCTNAME   "libpawnc\0"
 | 
			
		||||
#endif
 | 
			
		||||
#define VERSIONCOMPANYNAME   "ITB CompuPhase\0"
 | 
			
		||||
#define VERSIONCOPYRIGHT     "Copyright \251 1998-2005 ITB CompuPhase\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",      VERSIONCOMPANYNAME
 | 
			
		||||
            VALUE "FileDescription",  VERSIONDESCRIPTION
 | 
			
		||||
            VALUE "FileVersion",      VERSIONSTR
 | 
			
		||||
            VALUE "InternalName",     VERSIONNAME
 | 
			
		||||
            VALUE "LegalCopyright",   VERSIONCOPYRIGHT
 | 
			
		||||
            VALUE "OriginalFilename", VERSIONNAME
 | 
			
		||||
            VALUE "ProductName",      VERSIONPRODUCTNAME
 | 
			
		||||
            VALUE "ProductVersion",   VERSIONSTR
 | 
			
		||||
        END
 | 
			
		||||
    END
 | 
			
		||||
 | 
			
		||||
    BLOCK "VarFileInfo"
 | 
			
		||||
    BEGIN
 | 
			
		||||
        VALUE "Translation", 0x409, 1252
 | 
			
		||||
    END
 | 
			
		||||
END
 | 
			
		||||
							
								
								
									
										27
									
								
								compiler/libpc300/libpc300.sln
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								compiler/libpc300/libpc300.sln
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
Microsoft Visual Studio Solution File, Format Version 8.00
 | 
			
		||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpc300", "libpc300.vcproj", "{19B72687-080B-437A-917A-12AEB0031635}"
 | 
			
		||||
	ProjectSection(ProjectDependencies) = postProject
 | 
			
		||||
	EndProjectSection
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfiguration) = preSolution
 | 
			
		||||
		Debug = Debug
 | 
			
		||||
		Release = Release
 | 
			
		||||
		Release32 = Release32
 | 
			
		||||
		Release64 = Release64
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ProjectConfiguration) = postSolution
 | 
			
		||||
		{19B72687-080B-437A-917A-12AEB0031635}.Debug.ActiveCfg = Release|Win32
 | 
			
		||||
		{19B72687-080B-437A-917A-12AEB0031635}.Debug.Build.0 = Release|Win32
 | 
			
		||||
		{19B72687-080B-437A-917A-12AEB0031635}.Release.ActiveCfg = Release|Win32
 | 
			
		||||
		{19B72687-080B-437A-917A-12AEB0031635}.Release.Build.0 = Release|Win32
 | 
			
		||||
		{19B72687-080B-437A-917A-12AEB0031635}.Release32.ActiveCfg = Release32|Win32
 | 
			
		||||
		{19B72687-080B-437A-917A-12AEB0031635}.Release32.Build.0 = Release32|Win32
 | 
			
		||||
		{19B72687-080B-437A-917A-12AEB0031635}.Release64.ActiveCfg = Release64|Win32
 | 
			
		||||
		{19B72687-080B-437A-917A-12AEB0031635}.Release64.Build.0 = Release64|Win32
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ExtensibilityGlobals) = postSolution
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ExtensibilityAddIns) = postSolution
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
EndGlobal
 | 
			
		||||
							
								
								
									
										276
									
								
								compiler/libpc300/libpc300.vcproj
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										276
									
								
								compiler/libpc300/libpc300.vcproj
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,276 @@
 | 
			
		||||
<?xml version="1.0" encoding="Windows-1252"?>
 | 
			
		||||
<VisualStudioProject
 | 
			
		||||
	ProjectType="Visual C++"
 | 
			
		||||
	Version="7.10"
 | 
			
		||||
	Name="libpc300"
 | 
			
		||||
	ProjectGUID="{19B72687-080B-437A-917A-12AEB0031635}"
 | 
			
		||||
	Keyword="Win32Proj">
 | 
			
		||||
	<Platforms>
 | 
			
		||||
		<Platform
 | 
			
		||||
			Name="Win32"/>
 | 
			
		||||
	</Platforms>
 | 
			
		||||
	<Configurations>
 | 
			
		||||
		<Configuration
 | 
			
		||||
			Name="Debug|Win32"
 | 
			
		||||
			OutputDirectory="Debug"
 | 
			
		||||
			IntermediateDirectory="Debug"
 | 
			
		||||
			ConfigurationType="2"
 | 
			
		||||
			CharacterSet="2">
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCCLCompilerTool"
 | 
			
		||||
				Optimization="0"
 | 
			
		||||
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS"
 | 
			
		||||
				MinimalRebuild="TRUE"
 | 
			
		||||
				BasicRuntimeChecks="3"
 | 
			
		||||
				RuntimeLibrary="1"
 | 
			
		||||
				UsePrecompiledHeader="0"
 | 
			
		||||
				WarningLevel="3"
 | 
			
		||||
				Detect64BitPortabilityProblems="TRUE"
 | 
			
		||||
				DebugInformationFormat="4"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCCustomBuildTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCLinkerTool"
 | 
			
		||||
				OutputFile="$(OutDir)/libpc300.dll"
 | 
			
		||||
				LinkIncremental="2"
 | 
			
		||||
				GenerateDebugInformation="TRUE"
 | 
			
		||||
				ProgramDatabaseFile="$(OutDir)/libpc300.pdb"
 | 
			
		||||
				SubSystem="2"
 | 
			
		||||
				ImportLibrary="$(OutDir)/libpc300.lib"
 | 
			
		||||
				TargetMachine="1"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCMIDLTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPostBuildEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPreBuildEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPreLinkEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCResourceCompilerTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCWebServiceProxyGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCXMLDataGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCWebDeploymentTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCManagedWrapperGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 | 
			
		||||
		</Configuration>
 | 
			
		||||
		<Configuration
 | 
			
		||||
			Name="Release|Win32"
 | 
			
		||||
			OutputDirectory="Release"
 | 
			
		||||
			IntermediateDirectory="Release"
 | 
			
		||||
			ConfigurationType="2"
 | 
			
		||||
			CharacterSet="2">
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCCLCompilerTool"
 | 
			
		||||
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS"
 | 
			
		||||
				RuntimeLibrary="0"
 | 
			
		||||
				UsePrecompiledHeader="0"
 | 
			
		||||
				WarningLevel="3"
 | 
			
		||||
				Detect64BitPortabilityProblems="TRUE"
 | 
			
		||||
				DebugInformationFormat="3"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCCustomBuildTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCLinkerTool"
 | 
			
		||||
				OutputFile="$(OutDir)/libpc300.dll"
 | 
			
		||||
				LinkIncremental="1"
 | 
			
		||||
				GenerateDebugInformation="TRUE"
 | 
			
		||||
				SubSystem="2"
 | 
			
		||||
				OptimizeReferences="2"
 | 
			
		||||
				EnableCOMDATFolding="2"
 | 
			
		||||
				ImportLibrary="$(OutDir)/libpc300.lib"
 | 
			
		||||
				TargetMachine="1"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCMIDLTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPostBuildEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPreBuildEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPreLinkEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCResourceCompilerTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCWebServiceProxyGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCXMLDataGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCWebDeploymentTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCManagedWrapperGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 | 
			
		||||
		</Configuration>
 | 
			
		||||
		<Configuration
 | 
			
		||||
			Name="Release32|Win32"
 | 
			
		||||
			OutputDirectory="$(ConfigurationName)"
 | 
			
		||||
			IntermediateDirectory="$(ConfigurationName)"
 | 
			
		||||
			ConfigurationType="2"
 | 
			
		||||
			CharacterSet="2">
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCCLCompilerTool"
 | 
			
		||||
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=32;NO_MAIN"
 | 
			
		||||
				RuntimeLibrary="0"
 | 
			
		||||
				UsePrecompiledHeader="0"
 | 
			
		||||
				WarningLevel="3"
 | 
			
		||||
				Detect64BitPortabilityProblems="FALSE"
 | 
			
		||||
				DebugInformationFormat="3"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCCustomBuildTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCLinkerTool"
 | 
			
		||||
				OutputFile="$(OutDir)/amxxpc32.dll"
 | 
			
		||||
				LinkIncremental="1"
 | 
			
		||||
				GenerateDebugInformation="TRUE"
 | 
			
		||||
				SubSystem="2"
 | 
			
		||||
				OptimizeReferences="2"
 | 
			
		||||
				EnableCOMDATFolding="2"
 | 
			
		||||
				ImportLibrary="$(OutDir)/libpc300.lib"
 | 
			
		||||
				TargetMachine="1"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCMIDLTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPostBuildEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPreBuildEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPreLinkEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCResourceCompilerTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCWebServiceProxyGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCXMLDataGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCWebDeploymentTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCManagedWrapperGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 | 
			
		||||
		</Configuration>
 | 
			
		||||
		<Configuration
 | 
			
		||||
			Name="Release64|Win32"
 | 
			
		||||
			OutputDirectory="$(ConfigurationName)"
 | 
			
		||||
			IntermediateDirectory="$(ConfigurationName)"
 | 
			
		||||
			ConfigurationType="2"
 | 
			
		||||
			CharacterSet="2">
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCCLCompilerTool"
 | 
			
		||||
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=64;NO_MAIN"
 | 
			
		||||
				RuntimeLibrary="0"
 | 
			
		||||
				UsePrecompiledHeader="0"
 | 
			
		||||
				WarningLevel="3"
 | 
			
		||||
				Detect64BitPortabilityProblems="FALSE"
 | 
			
		||||
				DebugInformationFormat="3"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCCustomBuildTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCLinkerTool"
 | 
			
		||||
				OutputFile="$(OutDir)/amxxpc64.dll"
 | 
			
		||||
				LinkIncremental="1"
 | 
			
		||||
				GenerateDebugInformation="TRUE"
 | 
			
		||||
				SubSystem="2"
 | 
			
		||||
				OptimizeReferences="2"
 | 
			
		||||
				EnableCOMDATFolding="2"
 | 
			
		||||
				ImportLibrary="$(OutDir)/libpc300.lib"
 | 
			
		||||
				TargetMachine="1"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCMIDLTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPostBuildEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPreBuildEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCPreLinkEventTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCResourceCompilerTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCWebServiceProxyGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCXMLDataGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCWebDeploymentTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCManagedWrapperGeneratorTool"/>
 | 
			
		||||
			<Tool
 | 
			
		||||
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 | 
			
		||||
		</Configuration>
 | 
			
		||||
	</Configurations>
 | 
			
		||||
	<References>
 | 
			
		||||
	</References>
 | 
			
		||||
	<Files>
 | 
			
		||||
		<Filter
 | 
			
		||||
			Name="Source Files"
 | 
			
		||||
			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
 | 
			
		||||
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
 | 
			
		||||
			<File
 | 
			
		||||
				RelativePath=".\libpawnc.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">
 | 
			
		||||
			</File>
 | 
			
		||||
			<File
 | 
			
		||||
				RelativePath=".\scstate.c">
 | 
			
		||||
			</File>
 | 
			
		||||
			<File
 | 
			
		||||
				RelativePath=".\scstub.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=".\sc.h">
 | 
			
		||||
			</File>
 | 
			
		||||
		</Filter>
 | 
			
		||||
		<Filter
 | 
			
		||||
			Name="Resource Files"
 | 
			
		||||
			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
 | 
			
		||||
			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
 | 
			
		||||
			<File
 | 
			
		||||
				RelativePath=".\libpawnc.rc">
 | 
			
		||||
			</File>
 | 
			
		||||
		</Filter>
 | 
			
		||||
	</Files>
 | 
			
		||||
	<Globals>
 | 
			
		||||
	</Globals>
 | 
			
		||||
</VisualStudioProject>
 | 
			
		||||
							
								
								
									
										94
									
								
								compiler/libpc300/osdefs.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										94
									
								
								compiler/libpc300/osdefs.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
/* __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
 | 
			
		||||
#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 instead
 | 
			
		||||
 * stdio.h.
 | 
			
		||||
 */
 | 
			
		||||
#if !defined _MAX_PATH
 | 
			
		||||
  /* not defined, perhaps stdio.h was not included */
 | 
			
		||||
  #include <stdio.h>
 | 
			
		||||
  #if !defined _MAX_PATH
 | 
			
		||||
    /* still undefined, try a common alternative name */
 | 
			
		||||
    #if defined MAX_PATH
 | 
			
		||||
      #define _MAX_PATH    MAX_PATH
 | 
			
		||||
    #else
 | 
			
		||||
      /* no _MAX_PATH and no MAX_PATH, perhaps it is in limits.h */
 | 
			
		||||
      #include <limits.h>
 | 
			
		||||
      #if defined PATH_MAX
 | 
			
		||||
        #define _MAX_PATH  PATH_MAX
 | 
			
		||||
      #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
 | 
			
		||||
 | 
			
		||||
#endif  /* _OSDEFS_H */
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								compiler/libpc300/pawn.ico
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								compiler/libpc300/pawn.ico
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 8.3 KiB  | 
							
								
								
									
										30
									
								
								compiler/libpc300/pawncc.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								compiler/libpc300/pawncc.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
/*  Pawn compiler driver
 | 
			
		||||
 *
 | 
			
		||||
 *  Function and variable definition and declaration, statement parser.
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#include "sc.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  return pc_compile(argc,argv);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								compiler/libpc300/pawncc.def
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								compiler/libpc300/pawncc.def
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
NAME          PAWNCC
 | 
			
		||||
DESCRIPTION   'Pawn compiler'
 | 
			
		||||
							
								
								
									
										780
									
								
								compiler/libpc300/sc.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										780
									
								
								compiler/libpc300/sc.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,780 @@
 | 
			
		||||
/*  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-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#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     3    /* maximum number of array dimensions */
 | 
			
		||||
#define sLINEMAX     511    /* 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   "default.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;
 | 
			
		||||
  short index;          /* index level, for constants referring to array sizes/tags
 | 
			
		||||
                         * automaton id. for states and automatons */
 | 
			
		||||
} 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 */
 | 
			
		||||
  char usage;           /* see below for possible values */
 | 
			
		||||
  int compound;         /* compound level (braces nesting level) */
 | 
			
		||||
  int tag;              /* tagname id */
 | 
			
		||||
  int fieldtag;         /* enumeration fields, where a size is attached to the field */
 | 
			
		||||
  union {
 | 
			
		||||
    int declared;       /* label: how many local variables are declared */
 | 
			
		||||
    int idxtag;         /* array & enum: tag of array indices or the enum item */
 | 
			
		||||
    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 addresses */
 | 
			
		||||
  int fnumber;          /* static global variables: file number in which the declaration is visible */
 | 
			
		||||
  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
 | 
			
		||||
 *        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
 | 
			
		||||
 *
 | 
			
		||||
 *  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   0x01
 | 
			
		||||
#define uREAD     0x02
 | 
			
		||||
#define uWRITTEN  0x04
 | 
			
		||||
#define uRETVALUE 0x04  /* function returns (or should return) a value */
 | 
			
		||||
#define uCONST    0x08
 | 
			
		||||
#define uPROTOTYPED 0x08
 | 
			
		||||
#define uPREDEF   0x08  /* constant is pre-defined */
 | 
			
		||||
#define uPUBLIC   0x10
 | 
			
		||||
#define uNATIVE   0x20
 | 
			
		||||
#define uENUMROOT 0x20
 | 
			
		||||
#define uSTOCK    0x40
 | 
			
		||||
#define uENUMFIELD 0x40
 | 
			
		||||
#define uMISSING  0x80
 | 
			
		||||
/* 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 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/local variable/constant class */
 | 
			
		||||
#define sLOCAL    1
 | 
			
		||||
#define sSTATIC   2     /* global life, local scope */
 | 
			
		||||
 | 
			
		||||
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;              /* tagname id (of the expression) */
 | 
			
		||||
  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    325    /* 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 tOPERATOR 299
 | 
			
		||||
#define tPUBLIC  300
 | 
			
		||||
#define tRETURN  301
 | 
			
		||||
#define tSIZEOF  302
 | 
			
		||||
#define tSLEEP   303
 | 
			
		||||
#define tSTATE   304
 | 
			
		||||
#define tSTATIC  305
 | 
			
		||||
#define tSTOCK   306
 | 
			
		||||
#define tSWITCH  307
 | 
			
		||||
#define tTAGOF   308
 | 
			
		||||
#define tWHILE   309
 | 
			
		||||
/* compiler directives */
 | 
			
		||||
#define tpASSERT 310    /* #assert */
 | 
			
		||||
#define tpDEFINE 311
 | 
			
		||||
#define tpELSE   312    /* #else */
 | 
			
		||||
#define tpELSEIF 313    /* #elseif */
 | 
			
		||||
#define tpEMIT   314
 | 
			
		||||
#define tpENDIF  315
 | 
			
		||||
#define tpENDINPUT 316
 | 
			
		||||
#define tpENDSCRPT 317
 | 
			
		||||
#define tpERROR  318
 | 
			
		||||
#define tpFILE   319
 | 
			
		||||
#define tpIF     320    /* #if */
 | 
			
		||||
#define tINCLUDE 321
 | 
			
		||||
#define tpLINE   322
 | 
			
		||||
#define tpPRAGMA 323
 | 
			
		||||
#define tpTRYINCLUDE 324
 | 
			
		||||
#define tpUNDEF  325
 | 
			
		||||
/* semicolon is a special case, because it can be optional */
 | 
			
		||||
#define tTERM    326    /* semicolon or newline */
 | 
			
		||||
#define tENDEXPR 327    /* forced end of expression */
 | 
			
		||||
/* other recognized tokens */
 | 
			
		||||
#define tNUMBER  328    /* integer number */
 | 
			
		||||
#define tRATIONAL 329   /* rational number */
 | 
			
		||||
#define tSYMBOL  330
 | 
			
		||||
#define tLABEL   331
 | 
			
		||||
#define tSTRING  332
 | 
			
		||||
#define tEXPR    333    /* 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 sNOOPTIMIZE     4       /* bit position in "debug" variable: no optimization */
 | 
			
		||||
#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 */
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
#if INT_MAX<0x8000u
 | 
			
		||||
  #define PUBLICTAG   0x8000u
 | 
			
		||||
  #define FIXEDTAG    0x4000u
 | 
			
		||||
#else
 | 
			
		||||
  #define PUBLICTAG   0x80000000Lu
 | 
			
		||||
  #define FIXEDTAG    0x40000000Lu
 | 
			
		||||
#endif
 | 
			
		||||
#define TAGMASK       (~PUBLICTAG)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 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,short index);
 | 
			
		||||
SC_FUNC constvalue *find_constval(constvalue *table,char *name,short 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);
 | 
			
		||||
SC_FUNC symbol *findloc(const char *name);
 | 
			
		||||
SC_FUNC symbol *findconst(const char *name);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
/* 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 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(void);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
/* 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);
 | 
			
		||||
 | 
			
		||||
/* 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 sc_stksize;     /* stack size */
 | 
			
		||||
SC_VDECL cell sc_amxlimit;    /* abstract machine size limit */
 | 
			
		||||
SC_VDECL int freading;        /* is there an input file ready for reading? */
 | 
			
		||||
SC_VDECL int fline;           /* the line number in the current file */
 | 
			
		||||
SC_VDECL short fnumber;       /* number of files in the file table (debugging) */
 | 
			
		||||
SC_VDECL short fcurrent;      /* current file being processed (debugging) */
 | 
			
		||||
SC_VDECL short 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 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 */
 | 
			
		||||
							
								
								
									
										5555
									
								
								compiler/libpc300/sc1.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										5555
									
								
								compiler/libpc300/sc1.c
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2707
									
								
								compiler/libpc300/sc2.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2707
									
								
								compiler/libpc300/sc2.c
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2338
									
								
								compiler/libpc300/sc3.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2338
									
								
								compiler/libpc300/sc3.c
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1304
									
								
								compiler/libpc300/sc4.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1304
									
								
								compiler/libpc300/sc4.c
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										217
									
								
								compiler/libpc300/sc5.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										217
									
								
								compiler/libpc300/sc5.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,217 @@
 | 
			
		||||
/*  Pawn compiler - Error message system
 | 
			
		||||
 *  In fact a very simple system, using only 'panic mode'.
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 1997-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#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 "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 */
 | 
			
		||||
 | 
			
		||||
/*  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);
 | 
			
		||||
  va_start(argptr,number);
 | 
			
		||||
  if (strlen(errfname)==0) {
 | 
			
		||||
    int start= (errstart==fline) ? -1 : errstart;
 | 
			
		||||
    if (pc_error(number,string,inpfname,start,fline,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!=fline)
 | 
			
		||||
        fprintf(fp,"%s(%d -- %d) : %s %03d: ",inpfname,errstart,fline,pre,number);
 | 
			
		||||
      else
 | 
			
		||||
        fprintf(fp,"%s(%d) : %s %03d: ",inpfname,fline,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 */
 | 
			
		||||
 | 
			
		||||
  /* 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)
 | 
			
		||||
{
 | 
			
		||||
  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 */
 | 
			
		||||
    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
 | 
			
		||||
							
								
								
									
										326
									
								
								compiler/libpc300/sc5.scp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										326
									
								
								compiler/libpc300/sc5.scp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,326 @@
 | 
			
		||||
/*  Pawn compiler - Error message strings (plain and compressed formats)
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 2000-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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_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,110}, {101,114}, {97,108}, {133,129}, {37,115}, {34,140}, {141,34}, {117,110},
 | 
			
		||||
  {115,105}, {110,111}, {114,101}, {121,32}, {97,110}, {111,114}, {97,116}, {109,136}, {100,101}, {139,32}, {115,116}, {101,134}, {109,98}, {41,10}, {118,138}, {114,97},
 | 
			
		||||
  {143,99}, {145,130}, {32,142}, {102,160}, {117,115}, {98,108}, {111,108}, {97,32}, {115,144}, {163,153}, {105,134}, {132,159}, {149,32}, {158,170}, {115,121}, {117,151},
 | 
			
		||||
  {174,156}, {103,32}, {176,166}, {103,175}, {131,173}, {132,179}, {116,104}, {101,120}, {137,32}, {101,100}, {111,102}, {99,104}, {105,135}, {171,147}, {152,102}, {116,111},
 | 
			
		||||
  {186,32}, {97,165}, {99,129}, {181,130}, {101,10}, {115,10}, {112,146}, {164,130}, {98,128}, {162,10}, {44,32}, {109,199}, {109,97}, {193,128}, {34,32}, {129,32},
 | 
			
		||||
  {116,97}, {100,105}, {144,122}, {190,131}, {118,132}, {101,135}, {154,150}, {102,105}, {212,105}, {101,108}, {117,108}, {99,111}, {109,150}, {58,201}, {216,205}, {132,97},
 | 
			
		||||
  {119,105}, {111,112}, {97,115}, {225,137}, {194,154}, {178,162}, {110,32}, {138,32}, {148,32}, {198,168}, {131,177}, {203,200}, {104,97}, {183,233}, {108,111}, {109,112},
 | 
			
		||||
  {148,130}, {108,128}, {229,157}, {142,157}, {40,242}, {110,117}, {118,128}, {116,137}, {116,10}, {102,149}, {227,150}, {101,151}, {245,156}, {111,32}, {145,32}
 | 
			
		||||
};
 | 
			
		||||
/*-*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 or zero)\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\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 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 function \"%s\"\n",
 | 
			
		||||
/*086*/  "unknown automaton \"%s\"\n",
 | 
			
		||||
/*087*/  "unknown state \"%s\" for automaton \"%s\"\n"
 | 
			
		||||
#else
 | 
			
		||||
  "\267pect\233\277k\210:\242\312bu\202fo\217\206\216\012",
 | 
			
		||||
  "\201l\223\247s\203g\361\326\373\202(\254\355\201) c\350f\246\356w ea\273 \042c\342e\042\012",
 | 
			
		||||
  "\230cl\337\231\300\247\356c\347\336\313appe\204 \203 \247\333\357o\217\206\245ock\012",
 | 
			
		||||
  "\251\216 \274\241i\357l\373t\271\012",
 | 
			
		||||
  "\251\314\223\241\354\366\265t\305",
 | 
			
		||||
  "\353a\250gn\233\277 \350\253y\012",
 | 
			
		||||
  "\372\254c\224\241\310\222\323\271\012",
 | 
			
		||||
  "\353\247\344\360\355\201; \342sum\233z\211o\012",
 | 
			
		||||
  "\264\275\322\200(nega\205\366\254z\211o\235",
 | 
			
		||||
  "\264\251\254\230cl\337\213\012",
 | 
			
		||||
  "\264out\220d\200\243\213\305",
 | 
			
		||||
  "\264\251c\212l\312\241\247\255add\222s\305",
 | 
			
		||||
  "\376\210tr\223po\203\202(\376pu\245ic \243\213s\235",
 | 
			
		||||
  "\264\326\373t; \241\203 s\340t\273\012",
 | 
			
		||||
  "\042\276a\332t\316c\342\200\353\266\200l\342\202c\342\200\203 s\340t\273 \326\373\370",
 | 
			
		||||
  "m\332\205p\361\276a\332t\207\203 \042s\340t\273\042\012",
 | 
			
		||||
  "\217\323\233\262\311",
 | 
			
		||||
  "\203i\205\212iza\231d\226\247\267ce\271\207\230cl\204\233\322\304",
 | 
			
		||||
  "\241\247lab\331\335",
 | 
			
		||||
  "\264\262 nam\200\216\012",
 | 
			
		||||
  "\262 \212\222ad\223\323\271\335",
 | 
			
		||||
  "\353l\236u\200(n\201-\344\224t\235",
 | 
			
		||||
  "\275a\250gn\227\202\353\220\357\361a\250gn\227\370",
 | 
			
		||||
  "\042b\222ak\316\254\042\302t\203ue\316\274ou\202\300\302t\267\370",
 | 
			
		||||
  "\251head\352\321ff\211\207from pro\277typ\304",
 | 
			
		||||
  "\376\334\273\352\042#if...\042\012",
 | 
			
		||||
  "\264\273\337ct\270\344\224\370",
 | 
			
		||||
  "\264subscrip\202(\241\350\275\254\277\375m\224\223subscripts)\335",
 | 
			
		||||
  "\264\355\201\312\342sum\233z\211o\012",
 | 
			
		||||
  "\333\357o\217\206\326\373\202\241c\356s\233a\202\266\200\210\206\300\327l\304",
 | 
			
		||||
  "\217k\221w\346\321\222c\205v\304",
 | 
			
		||||
  "\275\203\230x ou\202\300bo\217d\207(\336\363",
 | 
			
		||||
  "\275\353\203\230x\233(\336\363",
 | 
			
		||||
  "\303do\325\241\354\366\247\276a\332\202\236u\200(\303%d\235",
 | 
			
		||||
  "\303typ\200mis\334\273 (\303%d\235",
 | 
			
		||||
  "e\357t\223\326\373\370",
 | 
			
		||||
  "\264\232r\352(po\250\245\223n\201-\367m\203\226\233\232r\203g\235",
 | 
			
		||||
  "\267t\237 \273\337c\367\207\317l\203\304",
 | 
			
		||||
  "\344\360\262 \354\207\376\322\304",
 | 
			
		||||
  "duplic\226\200\042c\342e\316lab\331 (\236u\200%d\235",
 | 
			
		||||
  "\264\331lip\220s\312\275\322\200\274\241k\221wn\012",
 | 
			
		||||
  "\264\333\234\203a\231\300cl\342\207speci\327\211\305",
 | 
			
		||||
  "\273\337ct\270\344\360\267ce\271\207r\224g\200f\254pack\233\232r\203g\012",
 | 
			
		||||
  "po\220\213\347p\337me\367\207\313\306c\271\200\212l nam\233p\337me\367\305",
 | 
			
		||||
  "\277\375m\224\223\251\265t\305",
 | 
			
		||||
  "\217k\221w\346\275\322\200(\336\363",
 | 
			
		||||
  "\275\322\325d\375\241\334\273\312\254\230\232\203a\231\275\274\277\375sm\212l\012",
 | 
			
		||||
  "\275\321\227\220\201\207d\375\241\334\273\012",
 | 
			
		||||
  "\264l\203\200\302t\203ua\213\012",
 | 
			
		||||
  "\264r\224g\304",
 | 
			
		||||
  "\264subscript\312\244\200\042[ ]\316\372\225\207\317\314j\254\321\227\220\201\305",
 | 
			
		||||
  "m\332\205-\321\227\220\201\347\253y\207\353f\332l\223\203i\205\212iz\271\012",
 | 
			
		||||
  "\267ce\271\352\314ximum \374\270\300\321\227\220\201\305",
 | 
			
		||||
  "\217\334\273\233c\356s\352b\237c\304",
 | 
			
		||||
  "\232\204\202\300\251bod\223\340\266ou\202\251head\211\012",
 | 
			
		||||
  "\253ys\312\356c\347\330\301\325\224\206\251\265t\207c\224\241\310pu\245ic (\336\363",
 | 
			
		||||
  "\217f\203ish\233\355\317be\371\200\333\357il\270\321\222c\205v\304",
 | 
			
		||||
  "duplic\226\200\265t; sam\200\303\274p\342s\233t\340c\304",
 | 
			
		||||
  "\251\303\314\223\241\354\366\247\276a\332\202\236u\200(\336\363",
 | 
			
		||||
  "m\332\205p\361\042#\331se\316\321\222c\205v\325betwe\210 \042#if ... #\210\321f\042\012",
 | 
			
		||||
  "\042#\331seif\316\321\222c\205\366f\246\356w\207\350\042#\331se\316\321\222c\205v\304",
 | 
			
		||||
  "\374\270\300\343\224d\207do\325\241\327\202\266\200\372\225\012",
 | 
			
		||||
  "\251\222s\332\202\320\261\300\372\225\242 \353\216\012",
 | 
			
		||||
  "c\224\241\273\224g\200\306\323\233\372\225\305",
 | 
			
		||||
  "\251\303\314\223\201l\223\354\366\247s\203g\361\320\261(\303%d\235",
 | 
			
		||||
  "\251\303\314\223\241\310\247\222f\211\210c\200\303\254\350\275(\303\363",
 | 
			
		||||
  "\336c\224\241\310bo\266 \247\222f\211\210c\200\224\206\350\275(\336\363",
 | 
			
		||||
  "\264\237\213\347\374\270\306ci\220\317\203 #p\237g\314\012",
 | 
			
		||||
  "\237\213\347\374\270\371\314\202\212\222ad\223\323\271\012",
 | 
			
		||||
  "\237\213\347\374\270supp\225\202wa\207\241\210\301\271\012",
 | 
			
		||||
  "\244\211-\323\233\372\254\353\230cl\204\233be\371\200\244\200(\251\363",
 | 
			
		||||
  "\042\322e\272\316\372\254\274\264\317\042\243\213\316\262\305",
 | 
			
		||||
  "\251\303\353\350\275(\303\363",
 | 
			
		||||
  "#\323\200p\226\367\346\313\232\204\202\340\266 \350\212p\354be\205c \273\337c\367\012",
 | 
			
		||||
  "\203pu\202l\203\200\277\375l\201\261(aft\270subs\205tu\213s\235",
 | 
			
		||||
  "\256n\320x \211r\254\203 \266\200\355\201\312\254\264\251c\212l\012",
 | 
			
		||||
  "m\212\371m\233UTF-8 \210\333d\203g\312\254c\225rupt\233\327le: \214\012",
 | 
			
		||||
  "\251\244\325bo\266 \042\222turn\316\224\206\042\222tur\346<\236ue>\042\012",
 | 
			
		||||
  "\203\302\220\232\210\202\222tur\346typ\325(\275& n\201-\253y\235",
 | 
			
		||||
  "\217k\221w\346\262\312\254\241\247\344\360\262 \364",
 | 
			
		||||
  "c\224\241\320k\200\247\320\261a\207\247\276a\332\202\236u\200f\254\350\203\230x\233\275p\337met\270\364",
 | 
			
		||||
  "\244\211-\323\233\372\225\207\224\206na\205\366\243\213\207\314\223\241\354\366\326e\305",
 | 
			
		||||
  "\247\251\314\223\201l\223b\331\201\261\277 \247s\203g\361au\277\334\317\364",
 | 
			
		||||
  "\326\200\302flict: \201\200\300\266\200\326\325\274\212\222ad\223a\250gn\233\277 a\221\266\270i\357l\373\320\231\364",
 | 
			
		||||
  "\376\326\325\204\200\323\233f\254\251\216\012",
 | 
			
		||||
  "\217k\221w\346au\277\334\201\311",
 | 
			
		||||
  "\217k\221w\346\326\200\216 f\254au\277\334\201\311"
 | 
			
		||||
#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\224\241\222a\206from \327le\335",
 | 
			
		||||
  "c\224\241writ\200\277 \327le\335",
 | 
			
		||||
  "t\315ov\211f\356w\335",
 | 
			
		||||
  "\203suf\327ci\210\202mem\225y\012",
 | 
			
		||||
  "\264\342se\234l\270\203\232ruc\231\216\012",
 | 
			
		||||
  "\365m\211ic ov\211f\356w\312\267ce\271\352capacity\012",
 | 
			
		||||
  "\333\357il\233scrip\202\267ce\271\207\266\200\314ximum mem\225\223\322\200(%l\206bytes\235",
 | 
			
		||||
  "\277\375m\224\223\211r\254messag\325\317\201\200l\203\304",
 | 
			
		||||
  "\333\230pag\200\314pp\352\327\361\241fo\217d\012",
 | 
			
		||||
  "\264p\226h\335",
 | 
			
		||||
  "\342s\211\231fail\271: \214\012",
 | 
			
		||||
  "\244\270\211r\225: \214\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\" / 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"
 | 
			
		||||
#else
 | 
			
		||||
  "\345 \274tr\240\226\233\277 %\206\273\337c\367\305",
 | 
			
		||||
  "\222\323i\231\300\344\224t/\314cr\375\364",
 | 
			
		||||
  "\374\270\300\265t\207do\325\241\334\273 \323i\213\012",
 | 
			
		||||
  "\262 \274nev\270\244\271\335",
 | 
			
		||||
  "\262 \274a\250gn\233\247\236u\200\266a\202\274nev\270\244\271\335",
 | 
			
		||||
  "\222d\217d\360\333\230: \344\360\355\317\274z\211o\012",
 | 
			
		||||
  "\222d\217d\360te\232: \344\360\355\317\274n\201-z\211o\012",
 | 
			
		||||
  "\217k\221w\346#p\237g\314\012",
 | 
			
		||||
  "\251\340\266 \320\261\222s\332\202\244\233be\371\200\323i\213\312\371c\352\222p\204s\304",
 | 
			
		||||
  "\251\216 sho\332\206\222tur\346\247\236u\304",
 | 
			
		||||
  "po\250\245\200\244\200\300\262 be\371\200\203i\205\212iza\213\335",
 | 
			
		||||
  "po\250\245\223\217\203t\210\230\206a\250gn\227\370",
 | 
			
		||||
  "po\250\245\223\217\203t\210\230\206bit\340s\200\343a\213\012",
 | 
			
		||||
  "\320\261mis\334\273\012",
 | 
			
		||||
  "po\250\245\223\247\042\344\316\275\303wa\207\203t\210\230d\335",
 | 
			
		||||
  "\355\317\354\207\376effec\370",
 | 
			
		||||
  "ne\232\233\333m\227\370",
 | 
			
		||||
  "\356os\200\203d\210\320\213\012",
 | 
			
		||||
  "\246\206\232y\361pro\277typ\325\244\233\340\266 \341\213\347semic\246umn\305",
 | 
			
		||||
  "\356c\347\336\216 s\354dow\207\247\336a\202\247\306c\271\352lev\331\012",
 | 
			
		||||
  "\355\317\340\266 \320\261ov\211rid\200\313appe\204 betwe\210 p\204\210\266ese\305",
 | 
			
		||||
  "lab\331 nam\200\216 s\354dow\207\320\261nam\304",
 | 
			
		||||
  "\374\270\300\321git\207\267ce\271\207\237\213\347\374\270\306ci\220\201\012",
 | 
			
		||||
  "\222d\217d\360\042\322e\272\042: \303\322\200\274\212way\2071 \364",
 | 
			
		||||
  "\203\230\367m\203\226\200\275\322\200\203 \042\322e\272\316\355\317\364",
 | 
			
		||||
  "\217\222a\273\315\333\230\012",
 | 
			
		||||
  "\247\336\274a\250gn\233\277 its\331f \364",
 | 
			
		||||
  "m\225\200\203i\205\212l\211\207\266\350\210um \327\331d\305",
 | 
			
		||||
  "l\210g\266 \300\203i\205\212l\270\267ce\271\207\322\200\300\266\200\210um \327\331d\012",
 | 
			
		||||
  "\203\230x \320\261mis\334\273 \364",
 | 
			
		||||
  "\376i\357l\373\320\231f\254\326\200\216 / \251\216\312\376f\212l-back\012",
 | 
			
		||||
  "\326\200speci\327ca\231\317\371w\204\206\230cl\337\231\274ig\221\222d\012",
 | 
			
		||||
  "outpu\202\327\361\274writt\210\312bu\202\340\266 \333\357ac\202\210\333d\352\321s\301\271\012"
 | 
			
		||||
#endif
 | 
			
		||||
       };
 | 
			
		||||
							
								
								
									
										1162
									
								
								compiler/libpc300/sc6.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1162
									
								
								compiler/libpc300/sc6.c
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										631
									
								
								compiler/libpc300/sc7.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										631
									
								
								compiler/libpc300/sc7.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,631 @@
 | 
			
		||||
/*  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.
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 1997-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>     /* for atoi() */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#if defined FORTIFY
 | 
			
		||||
  #include "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 void stgstring(char *start,char *end);
 | 
			
		||||
static void stgopt(char *start,char *end);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define sSTG_GROW   512
 | 
			
		||||
#define sSTG_MAX    20480
 | 
			
		||||
 | 
			
		||||
static char *stgbuf = NULL;
 | 
			
		||||
static int stgmax = 0;  /* current size of the staging buffer */
 | 
			
		||||
 | 
			
		||||
#define CHECK_STGBUFFER(index) if ((int)(index)>=stgmax) grow_stgbuffer((index)+1)
 | 
			
		||||
 | 
			
		||||
static void grow_stgbuffer(int requiredsize)
 | 
			
		||||
{
 | 
			
		||||
  char *p;
 | 
			
		||||
  int clear = stgbuf==NULL;     /* if previously none, empty buffer explicitly */
 | 
			
		||||
 | 
			
		||||
  assert(stgmax<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) */
 | 
			
		||||
  stgmax=requiredsize+sSTG_GROW;
 | 
			
		||||
  if (stgbuf!=NULL)
 | 
			
		||||
    p=(char *)realloc(stgbuf,stgmax*sizeof(char));
 | 
			
		||||
  else
 | 
			
		||||
    p=(char *)malloc(stgmax*sizeof(char));
 | 
			
		||||
  if (p==NULL)
 | 
			
		||||
    error(102,"staging buffer");    /* staging buffer overflow (fatal error) */
 | 
			
		||||
  stgbuf=p;
 | 
			
		||||
  if (clear)
 | 
			
		||||
    *stgbuf='\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SC_FUNC void stgbuffer_cleanup(void)
 | 
			
		||||
{
 | 
			
		||||
  if (stgbuf!=NULL) {
 | 
			
		||||
    free(stgbuf);
 | 
			
		||||
    stgbuf=NULL;
 | 
			
		||||
    stgmax=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 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;
 | 
			
		||||
 | 
			
		||||
  CHECK_STGBUFFER(0);
 | 
			
		||||
  if (staging) {
 | 
			
		||||
    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 {
 | 
			
		||||
    CHECK_STGBUFFER(strlen(stgbuf)+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)
 | 
			
		||||
{
 | 
			
		||||
  if (!staging)
 | 
			
		||||
    return;
 | 
			
		||||
  stgstring(&stgbuf[index],&stgbuf[stgidx]);
 | 
			
		||||
  stgidx=index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 void stgstring(char *start,char *end)
 | 
			
		||||
{
 | 
			
		||||
  char *ptr;
 | 
			
		||||
  int nest,argc,arg;
 | 
			
		||||
  argstack *stack;
 | 
			
		||||
 | 
			
		||||
  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 */
 | 
			
		||||
      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);
 | 
			
		||||
      start=ptr;
 | 
			
		||||
    } /* if */
 | 
			
		||||
  } /* while */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*  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    4
 | 
			
		||||
#define MAX_OPT_CAT     4       /* 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!='\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)
 | 
			
		||||
{
 | 
			
		||||
  char symbols[MAX_OPT_VARS][MAX_ALIAS+1];
 | 
			
		||||
  int seq,match_length,repl_length;
 | 
			
		||||
  int matches;
 | 
			
		||||
  char *debut=start;
 | 
			
		||||
 | 
			
		||||
  assert(sequences!=NULL);
 | 
			
		||||
  /* do not match anything if debug-level is maximum */
 | 
			
		||||
  if ((sc_debug & sNOOPTIMIZE)==0 && sc_status==statWRITE) {
 | 
			
		||||
    do {
 | 
			
		||||
      matches=0;
 | 
			
		||||
      start=debut;
 | 
			
		||||
      while (start<end) {
 | 
			
		||||
        seq=0;
 | 
			
		||||
        while (sequences[seq].find!=NULL) {
 | 
			
		||||
          assert(seq>=0);
 | 
			
		||||
          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);
 | 
			
		||||
        start += strlen(start) + 1;       /* to next string */
 | 
			
		||||
      } /* while (start<end) */
 | 
			
		||||
    } while (matches>0);
 | 
			
		||||
  } /* if ((sc_debug & sNOOPTIMIZE)==0 && sc_status==statWRITE) */
 | 
			
		||||
 | 
			
		||||
  for (start=debut; start<end; start+=strlen(start)+1)
 | 
			
		||||
    filewrite(start);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef SCPACK_TABLE
 | 
			
		||||
							
								
								
									
										1613
									
								
								compiler/libpc300/sc7.scp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1613
									
								
								compiler/libpc300/sc7.scp
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										68
									
								
								compiler/libpc300/scexpand.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										68
									
								
								compiler/libpc300/scexpand.c
									
									
									
									
									
										Executable 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/libpc300/sci18n.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										428
									
								
								compiler/libpc300/sci18n.c
									
									
									
									
									
										Executable 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-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#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 */
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										459
									
								
								compiler/libpc300/sclist.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										459
									
								
								compiler/libpc300/sclist.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,459 @@
 | 
			
		||||
/*  Pawn compiler  - maintenance of various lists
 | 
			
		||||
 *
 | 
			
		||||
 *  o  Name list (aliases)
 | 
			
		||||
 *  o  Include path list
 | 
			
		||||
 *  o  Macro defintions (text substitutions)
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 2001-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "sc.h"
 | 
			
		||||
 | 
			
		||||
#if defined FORTIFY
 | 
			
		||||
  #include "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'-'A'+1]; /* quick index to first character */
 | 
			
		||||
static void adjustindex(char c)
 | 
			
		||||
{
 | 
			
		||||
  stringpair *cur;
 | 
			
		||||
  assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_');
 | 
			
		||||
  assert('A'<'_' && '_'<'z');
 | 
			
		||||
 | 
			
		||||
  for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next)
 | 
			
		||||
    /* nothing */;
 | 
			
		||||
  substindex[(int)c-'A']=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=='_');
 | 
			
		||||
  item=substindex[(int)*name-'A'];
 | 
			
		||||
  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=='_');
 | 
			
		||||
  item=substindex[(int)*name-'A'];
 | 
			
		||||
  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 --------------------------------------- */
 | 
			
		||||
 | 
			
		||||
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:%08lx %s",(long)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:%08lx %04x",(long)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];
 | 
			
		||||
    #if !defined NDEBUG
 | 
			
		||||
      int count=0;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    funcdisplayname(symname,sym->name);
 | 
			
		||||
    /* address tag:name codestart codeend ident vclass [tag:dim ...] */
 | 
			
		||||
    if (sym->ident==iFUNCTN)
 | 
			
		||||
      sprintf(string,"S:%08lx %x:%s %08lx %08lx %x %x",sym->addr,sym->tag,
 | 
			
		||||
              symname,sym->addr,sym->codeaddr,sym->ident,sym->vclass);
 | 
			
		||||
    else
 | 
			
		||||
      sprintf(string,"S:%08lx %x:%s %08lx %08lx %x %x",sym->addr,sym->tag,
 | 
			
		||||
              symname,sym->codeaddr,code_idx,sym->ident,sym->vclass);
 | 
			
		||||
    if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
 | 
			
		||||
      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.idxtag,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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										339
									
								
								compiler/libpc300/scmemfil.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										339
									
								
								compiler/libpc300/scmemfil.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,339 @@
 | 
			
		||||
/*  Pawn compiler
 | 
			
		||||
 *
 | 
			
		||||
 *  Routines to maintain a "text file" in memory.
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 2003-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#if defined FORTIFY
 | 
			
		||||
  #include "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 struct tagMEMFILE {
 | 
			
		||||
  struct tagMEMFILE *next;
 | 
			
		||||
  unsigned char *buffer;
 | 
			
		||||
  long bufpos;
 | 
			
		||||
} MEMFILE;
 | 
			
		||||
#define tMEMFILE  1
 | 
			
		||||
 | 
			
		||||
#include "sc.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MEMFILE *mfcreate(char *filename)
 | 
			
		||||
{
 | 
			
		||||
  MEMFILE *mf;
 | 
			
		||||
 | 
			
		||||
  /* create a first block that only holds the name */
 | 
			
		||||
  mf=(MEMFILE*)malloc(sizeof(MEMFILE));
 | 
			
		||||
  if (mf==NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  memset(mf,0,sizeof(MEMFILE));
 | 
			
		||||
  mf->buffer=(unsigned char*)strdup(filename);
 | 
			
		||||
  if (mf->buffer==NULL) {
 | 
			
		||||
    free(mf);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  } /* if */
 | 
			
		||||
  return mf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mfclose(MEMFILE *mf)
 | 
			
		||||
{
 | 
			
		||||
  MEMFILE *next;
 | 
			
		||||
 | 
			
		||||
  assert(mf!=NULL);
 | 
			
		||||
  while (mf!=NULL) {
 | 
			
		||||
    next=mf->next;
 | 
			
		||||
    assert(mf->buffer!=NULL);
 | 
			
		||||
    free(mf->buffer);
 | 
			
		||||
    free(mf);
 | 
			
		||||
    mf=next;
 | 
			
		||||
  } /* while */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int mfdump(MEMFILE *mf)
 | 
			
		||||
{
 | 
			
		||||
  FILE *fp;
 | 
			
		||||
  int okay;
 | 
			
		||||
 | 
			
		||||
  assert(mf!=NULL);
 | 
			
		||||
  /* create the file */
 | 
			
		||||
  fp=fopen((char*)mf->buffer,"wb");
 | 
			
		||||
  if (fp==NULL)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  okay=1;
 | 
			
		||||
  mf=mf->next;
 | 
			
		||||
  while (mf!=NULL) {
 | 
			
		||||
    assert(mf->buffer!=NULL);
 | 
			
		||||
    /* all blocks except the last should be fully filled */
 | 
			
		||||
    assert(mf->next==NULL || (unsigned long)mf->bufpos==BUFFERSIZE);
 | 
			
		||||
    okay=okay && fwrite(mf->buffer,1,(size_t)mf->bufpos,fp)==(size_t)mf->bufpos;
 | 
			
		||||
    mf=mf->next;
 | 
			
		||||
  } /* while */
 | 
			
		||||
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
  return okay;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
long mflength(MEMFILE *mf)
 | 
			
		||||
{
 | 
			
		||||
  long length;
 | 
			
		||||
 | 
			
		||||
  assert(mf!=NULL);
 | 
			
		||||
  /* find the size of the memory file */
 | 
			
		||||
  length=0L;
 | 
			
		||||
  mf=mf->next;          /* skip initial block */
 | 
			
		||||
  while (mf!=NULL) {
 | 
			
		||||
    assert(mf->next==NULL || (unsigned long)mf->bufpos==BUFFERSIZE);
 | 
			
		||||
    length+=mf->bufpos;
 | 
			
		||||
    mf=mf->next;
 | 
			
		||||
  } /* while */
 | 
			
		||||
 | 
			
		||||
  return length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
long mfseek(MEMFILE *mf,long offset,int whence)
 | 
			
		||||
{
 | 
			
		||||
  long length;
 | 
			
		||||
 | 
			
		||||
  assert(mf!=NULL);
 | 
			
		||||
  if (mf->next==NULL)
 | 
			
		||||
    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->bufpos;
 | 
			
		||||
    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 */
 | 
			
		||||
  mf->bufpos=offset;
 | 
			
		||||
  return offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int mfwrite(MEMFILE *mf,unsigned char *buffer,unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
  long length;
 | 
			
		||||
  long numblocks;
 | 
			
		||||
  int blockpos,blocksize;
 | 
			
		||||
  unsigned int bytes;
 | 
			
		||||
  MEMFILE *block;
 | 
			
		||||
 | 
			
		||||
  assert(mf!=NULL);
 | 
			
		||||
 | 
			
		||||
  /* see whether more memory must be allocated */
 | 
			
		||||
  length=mflength(mf);
 | 
			
		||||
  assert(mf->bufpos>=0 && mf->bufpos<=length);
 | 
			
		||||
  numblocks=(length+BUFFERSIZE-1)/BUFFERSIZE;   /* # allocated blocks */
 | 
			
		||||
  while (mf->bufpos+size>numblocks*BUFFERSIZE) {
 | 
			
		||||
    /* append a block */
 | 
			
		||||
    MEMFILE *last;
 | 
			
		||||
    block=(MEMFILE*)malloc(sizeof(MEMFILE));
 | 
			
		||||
    if (block==NULL)
 | 
			
		||||
      return 0;
 | 
			
		||||
    memset(block,0,sizeof(MEMFILE));
 | 
			
		||||
    block->buffer=(unsigned char*)malloc(BUFFERSIZE);
 | 
			
		||||
    if (block->buffer==NULL) {
 | 
			
		||||
      free(block);
 | 
			
		||||
      return 0;
 | 
			
		||||
    } /* if */
 | 
			
		||||
    for (last=mf; last->next!=NULL; last=last->next)
 | 
			
		||||
      /* nothing */;
 | 
			
		||||
    assert(last!=NULL);
 | 
			
		||||
    assert(last->next==NULL);
 | 
			
		||||
    last->next=block;
 | 
			
		||||
    numblocks++;
 | 
			
		||||
  } /* while */
 | 
			
		||||
 | 
			
		||||
  if (size==0)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  /* find the block to start writing to */
 | 
			
		||||
  numblocks=mf->bufpos/BUFFERSIZE;      /* # blocks to skip */
 | 
			
		||||
  block=mf->next;
 | 
			
		||||
  while (numblocks-->0) {
 | 
			
		||||
    assert(block!=NULL);
 | 
			
		||||
    block=block->next;
 | 
			
		||||
  } /* while */
 | 
			
		||||
  assert(block!=NULL);
 | 
			
		||||
 | 
			
		||||
  /* copy into memory */
 | 
			
		||||
  bytes=0;
 | 
			
		||||
  blockpos=(int)(mf->bufpos % BUFFERSIZE);
 | 
			
		||||
  do {
 | 
			
		||||
    blocksize=BUFFERSIZE-blockpos;
 | 
			
		||||
    assert(blocksize>=0);
 | 
			
		||||
    if ((unsigned int)blocksize>size)
 | 
			
		||||
      blocksize=size;
 | 
			
		||||
 | 
			
		||||
    assert(block!=NULL);
 | 
			
		||||
    memcpy(block->buffer+blockpos,buffer,blocksize);
 | 
			
		||||
    buffer+=blocksize;
 | 
			
		||||
    size-=blocksize;
 | 
			
		||||
    bytes+=blocksize;
 | 
			
		||||
 | 
			
		||||
    if (blockpos+blocksize>block->bufpos)
 | 
			
		||||
      block->bufpos=blockpos+blocksize;
 | 
			
		||||
    assert(block->bufpos>=0 && (unsigned long)block->bufpos<=BUFFERSIZE);
 | 
			
		||||
    block=block->next;
 | 
			
		||||
    blockpos=0;
 | 
			
		||||
  } while (size>0);
 | 
			
		||||
 | 
			
		||||
  /* adjust file pointer */
 | 
			
		||||
  mf->bufpos+=bytes;
 | 
			
		||||
 | 
			
		||||
  return bytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
  long length;
 | 
			
		||||
  long numblocks;
 | 
			
		||||
  int blockpos,blocksize;
 | 
			
		||||
  unsigned int bytes;
 | 
			
		||||
  MEMFILE *block;
 | 
			
		||||
 | 
			
		||||
  assert(mf!=NULL);
 | 
			
		||||
 | 
			
		||||
  /* adjust the size to read */
 | 
			
		||||
  length=mflength(mf);
 | 
			
		||||
  assert(mf->bufpos>=0 && mf->bufpos<=length);
 | 
			
		||||
  if (mf->bufpos+size>(unsigned long)length)
 | 
			
		||||
    size=(int)(length-mf->bufpos);
 | 
			
		||||
  assert(mf->bufpos+size<=(unsigned long)length);
 | 
			
		||||
  if (size==0)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  /* find the block to start reading from */
 | 
			
		||||
  numblocks=mf->bufpos/BUFFERSIZE;      /* # blocks to skip */
 | 
			
		||||
  block=mf->next;
 | 
			
		||||
  while (numblocks-->0) {
 | 
			
		||||
    assert(block!=NULL);
 | 
			
		||||
    block=block->next;
 | 
			
		||||
  } /* while */
 | 
			
		||||
  assert(block!=NULL);
 | 
			
		||||
 | 
			
		||||
  /* copy out of memory */
 | 
			
		||||
  bytes=0;
 | 
			
		||||
  blockpos=(int)(mf->bufpos % BUFFERSIZE);
 | 
			
		||||
  do {
 | 
			
		||||
    blocksize=BUFFERSIZE-blockpos;
 | 
			
		||||
    if ((unsigned int)blocksize>size)
 | 
			
		||||
      blocksize=size;
 | 
			
		||||
 | 
			
		||||
    assert(block!=NULL);
 | 
			
		||||
    assert(block->bufpos>=0 && (unsigned long)block->bufpos<=BUFFERSIZE);
 | 
			
		||||
    assert(blockpos+blocksize<=block->bufpos);
 | 
			
		||||
    memcpy(buffer,block->buffer+blockpos,blocksize);
 | 
			
		||||
    buffer+=blocksize;
 | 
			
		||||
    size-=blocksize;
 | 
			
		||||
    bytes+=blocksize;
 | 
			
		||||
 | 
			
		||||
    block=block->next;
 | 
			
		||||
    blockpos=0;
 | 
			
		||||
  } while (size>0);
 | 
			
		||||
 | 
			
		||||
  /* adjust file pointer */
 | 
			
		||||
  mf->bufpos+=bytes;
 | 
			
		||||
 | 
			
		||||
  return bytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										450
									
								
								compiler/libpc300/scpack.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										450
									
								
								compiler/libpc300/scpack.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,450 @@
 | 
			
		||||
/* compress.c -- Byte Pair Encoding compression */
 | 
			
		||||
/* Copyright 1996 Philip Gage */
 | 
			
		||||
 | 
			
		||||
/* This program appeared in the September 1997 issue of
 | 
			
		||||
 * C/C++ Users Journal. The original source code may still
 | 
			
		||||
 * be found at the web site of the magazine (www.cuj.com).
 | 
			
		||||
 *
 | 
			
		||||
 * It has been modified by me (Thiadmer Riemersma) to
 | 
			
		||||
 * compress only a section of the input file and to store
 | 
			
		||||
 * the compressed output along with the input as "C" strings.
 | 
			
		||||
 *
 | 
			
		||||
 * Compiling instructions:
 | 
			
		||||
 *  Borland C++ 16-bit (large memory model is required):
 | 
			
		||||
 *      bcc -ml scpack.c
 | 
			
		||||
 *
 | 
			
		||||
 *  Watcom C/C++ 32-bit:
 | 
			
		||||
 *      wcl386 scpack.c
 | 
			
		||||
 *
 | 
			
		||||
 *  GNU C (Linux), 32-bit:
 | 
			
		||||
 *      gcc scpack.c -o scpack
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#if UINT_MAX > 0xFFFFU
 | 
			
		||||
  #define MAXSIZE 1024*1024L
 | 
			
		||||
#else
 | 
			
		||||
  #define MAXSIZE UINT_MAX      /* Input file buffer size */
 | 
			
		||||
#endif
 | 
			
		||||
#define HASHSIZE 8192   /* Hash table size, power of 2 */
 | 
			
		||||
#define THRESHOLD   3   /* Increase for speed, min 3 */
 | 
			
		||||
 | 
			
		||||
#define START_TOKEN "#ifdef SCPACK" /* start reading the buffer here */
 | 
			
		||||
#define NAME_TOKEN  "#define SCPACK_TABLE"
 | 
			
		||||
#define SEP_TOKEN   "#define SCPACK_SEPARATOR"
 | 
			
		||||
#define TERM_TOKEN  "#define SCPACK_TERMINATOR"
 | 
			
		||||
#define TEMPFILE    "~SCPACK.TMP"
 | 
			
		||||
static char tablename[32+1] = "scpack_table";
 | 
			
		||||
static char separator[16]=",";
 | 
			
		||||
static char terminator[16]="";
 | 
			
		||||
 | 
			
		||||
int compress(unsigned char *buffer, unsigned buffersize, unsigned char pairtable[128][2])
 | 
			
		||||
{
 | 
			
		||||
  unsigned char *left, *right, *count;
 | 
			
		||||
  unsigned char a, b, bestcount;
 | 
			
		||||
  unsigned i, j, index, bestindex, code=128;
 | 
			
		||||
 | 
			
		||||
  /* Dynamically allocate buffers and check for errors */
 | 
			
		||||
  left = (unsigned char *)malloc(HASHSIZE);
 | 
			
		||||
  right = (unsigned char *)malloc(HASHSIZE);
 | 
			
		||||
  count = (unsigned char *)malloc(HASHSIZE);
 | 
			
		||||
  if (left==NULL || right==NULL || count==NULL) {
 | 
			
		||||
    printf("Error allocating memory\n");
 | 
			
		||||
    exit(1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Check for errors */
 | 
			
		||||
  for (i=0; i<buffersize; i++)
 | 
			
		||||
    if (buffer[i] > 127) {
 | 
			
		||||
      printf("This program works only on text files (7-bit ASCII)\n");
 | 
			
		||||
      exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  memset(pairtable, 0, 128*2*sizeof(char));
 | 
			
		||||
 | 
			
		||||
  do {  /* Replace frequent pairs with bytes 128..255 */
 | 
			
		||||
 | 
			
		||||
    /* Enter counts of all byte pairs into hash table */
 | 
			
		||||
    memset(count,0,HASHSIZE);
 | 
			
		||||
    for (i=0; i<buffersize-1; i++) {
 | 
			
		||||
      a = buffer[i];
 | 
			
		||||
      b = buffer[i+1];
 | 
			
		||||
      /* ignore any pair with a '\0' */
 | 
			
		||||
      if (a == 0 || b == 0)
 | 
			
		||||
        continue;
 | 
			
		||||
      index = (a ^ (b << 6)) & (HASHSIZE-1);
 | 
			
		||||
      while ((left[index] != a || right[index] != b) &&
 | 
			
		||||
             count[index] != 0)
 | 
			
		||||
        index = (index + 1) & (HASHSIZE-1);
 | 
			
		||||
      left[index] = a;
 | 
			
		||||
      right[index] = b;
 | 
			
		||||
      if (count[index] < 255)
 | 
			
		||||
        count[index] += (unsigned char)1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Search hash table for most frequent pair */
 | 
			
		||||
    bestcount = THRESHOLD - 1;
 | 
			
		||||
    for (i=0; i<HASHSIZE; i++) {
 | 
			
		||||
      if (count[i] > bestcount) {
 | 
			
		||||
        bestcount = count[i];
 | 
			
		||||
        bestindex = i;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Compress if enough occurrences of pair */
 | 
			
		||||
    if (bestcount >= THRESHOLD) {
 | 
			
		||||
 | 
			
		||||
      /* Add pair to table using code as index */
 | 
			
		||||
      a = pairtable[code-128][0] = left[bestindex];
 | 
			
		||||
      b = pairtable[code-128][1] = right[bestindex];
 | 
			
		||||
 | 
			
		||||
      /* Replace all pair occurrences with unused byte */
 | 
			
		||||
      for (i=0, j=0; i<buffersize; i++, j++)
 | 
			
		||||
        if (a == buffer[i] && b == buffer[i+1]) {
 | 
			
		||||
          buffer[j] = (unsigned char)code;
 | 
			
		||||
          ++i;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
          buffer[j] = buffer[i];
 | 
			
		||||
      buffersize = j;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      break;
 | 
			
		||||
  } while (++code < 255);
 | 
			
		||||
 | 
			
		||||
  /* done */
 | 
			
		||||
  free(left); free(right); free(count);
 | 
			
		||||
  return buffersize;  /* return adjusted buffersize */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int strmatch(char *str, char *token, int *indent)
 | 
			
		||||
{
 | 
			
		||||
  int i = 0;
 | 
			
		||||
 | 
			
		||||
  /* skip whitespace */
 | 
			
		||||
  while (*str==' ' || *str=='\t') {
 | 
			
		||||
    str++;
 | 
			
		||||
    i++;
 | 
			
		||||
  } /* while */
 | 
			
		||||
  if (strncmp(str,token,strlen(token))!=0)
 | 
			
		||||
    return 0;
 | 
			
		||||
  if (indent != NULL)
 | 
			
		||||
    *indent = i;
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void check_if(char *str,int linenr)
 | 
			
		||||
{
 | 
			
		||||
  if (strmatch(str,"#if",NULL)) {
 | 
			
		||||
    printf("Error: \"#if...\" preprocessor statement should not be in SCPACK section "
 | 
			
		||||
           "(line %d)\n", linenr);
 | 
			
		||||
    exit(1);
 | 
			
		||||
  } /* if */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int check_tablename(char *str)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (strmatch(str,NAME_TOKEN,NULL)) {
 | 
			
		||||
    str += strlen(NAME_TOKEN);
 | 
			
		||||
    while (*str==' ' || *str=='\t')
 | 
			
		||||
      str++;
 | 
			
		||||
    for (i=0; i<(sizeof tablename - 1) && *str!='\0' && strchr(" \t\n",*str)==NULL; i++, str++)
 | 
			
		||||
      tablename[i] = *str;
 | 
			
		||||
    tablename[i] = '\0';
 | 
			
		||||
    return 1;
 | 
			
		||||
  } /* if */
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int check_separator(char *str)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (strmatch(str,SEP_TOKEN,NULL)) {
 | 
			
		||||
    str += strlen(SEP_TOKEN);
 | 
			
		||||
    while (*str==' ' || *str=='\t')
 | 
			
		||||
      str++;
 | 
			
		||||
    for (i=0; i<(sizeof separator - 1) && *str!='\0' && strchr(" \t\n",*str)==NULL; i++, str++)
 | 
			
		||||
      separator[i] = *str;
 | 
			
		||||
    separator[i] = '\0';
 | 
			
		||||
    return 1;
 | 
			
		||||
  } /* if */
 | 
			
		||||
 | 
			
		||||
  if (strmatch(str,TERM_TOKEN,NULL)) {
 | 
			
		||||
    str += strlen(TERM_TOKEN);
 | 
			
		||||
    while (*str==' ' || *str=='\t')
 | 
			
		||||
      str++;
 | 
			
		||||
    for (i=0; i<(sizeof terminator - 1) && *str!='\0' && strchr(" \t\n",*str)==NULL; i++, str++)
 | 
			
		||||
      terminator[i] = *str;
 | 
			
		||||
    terminator[i] = '\0';
 | 
			
		||||
    return 1;
 | 
			
		||||
  } /* if */
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* readbuffer
 | 
			
		||||
 * Reads in the input file and stores all strings in the
 | 
			
		||||
 * section between "#ifdef SCPACK" and "#else" in a buffer.
 | 
			
		||||
 * Only text that is between double quotes is added to the
 | 
			
		||||
 * buffer; the \" escape code is handled. Multiple strings
 | 
			
		||||
 * on one line are handled.
 | 
			
		||||
 */
 | 
			
		||||
unsigned readbuffer(FILE *input, unsigned char *buffer)
 | 
			
		||||
{
 | 
			
		||||
  char str[256];
 | 
			
		||||
  unsigned buffersize;
 | 
			
		||||
  int i,linenr;
 | 
			
		||||
 | 
			
		||||
  linenr=0;
 | 
			
		||||
  buffersize=0;
 | 
			
		||||
 | 
			
		||||
  rewind(input);
 | 
			
		||||
  while (!feof(input)) {
 | 
			
		||||
    while (fgets(str,sizeof str,input)!=NULL) {
 | 
			
		||||
      linenr++;
 | 
			
		||||
      check_tablename(str);
 | 
			
		||||
      check_separator(str);
 | 
			
		||||
      if (strmatch(str,START_TOKEN,NULL))
 | 
			
		||||
        break;
 | 
			
		||||
    } /* while */
 | 
			
		||||
    if (!strmatch(str,START_TOKEN,NULL))
 | 
			
		||||
      return buffersize;  /* no (more) section found, quit */
 | 
			
		||||
 | 
			
		||||
    while (fgets(str,sizeof str,input)!=NULL) {
 | 
			
		||||
      linenr++;
 | 
			
		||||
      check_if(str,linenr);
 | 
			
		||||
      if (check_tablename(str))
 | 
			
		||||
        printf("Error: table name definition should not be in SCPACK section (line %d)\n", linenr);
 | 
			
		||||
      check_separator(str);
 | 
			
		||||
      if (strmatch(str,"#else",NULL))
 | 
			
		||||
        break;          /* done */
 | 
			
		||||
      /* add to the buffer only what is between double quotes */
 | 
			
		||||
      i=0;
 | 
			
		||||
      do {
 | 
			
		||||
        while (str[i]!='\0' && str[i]!='"')
 | 
			
		||||
          i++;
 | 
			
		||||
        if (str[i]=='"') {
 | 
			
		||||
          /* we are in a string */
 | 
			
		||||
          i++;
 | 
			
		||||
          while (str[i]!='\0' && str[i]!='"') {
 | 
			
		||||
            /* handle escape sequences */
 | 
			
		||||
            if (str[i]=='\\') {
 | 
			
		||||
              i++;
 | 
			
		||||
              switch (str[i]) {
 | 
			
		||||
              case 'a': /* alarm */
 | 
			
		||||
                buffer[buffersize++]='\a';
 | 
			
		||||
                i++;
 | 
			
		||||
                break;
 | 
			
		||||
              case 'b': /* backspace */
 | 
			
		||||
                buffer[buffersize++]='\b';
 | 
			
		||||
                i++;
 | 
			
		||||
                break;
 | 
			
		||||
              case 'f': /* form feed */
 | 
			
		||||
                buffer[buffersize++]='\f';
 | 
			
		||||
                i++;
 | 
			
		||||
                break;
 | 
			
		||||
              case 'n': /* newline */
 | 
			
		||||
                buffer[buffersize++]='\n';
 | 
			
		||||
                i++;
 | 
			
		||||
                break;
 | 
			
		||||
              case 'r': /* carriage return */
 | 
			
		||||
                buffer[buffersize++]='\n';
 | 
			
		||||
                i++;
 | 
			
		||||
                break;
 | 
			
		||||
              case 't': /* tab */
 | 
			
		||||
                buffer[buffersize++]='\t';
 | 
			
		||||
                i++;
 | 
			
		||||
                break;
 | 
			
		||||
              case '\'':
 | 
			
		||||
                buffer[buffersize++]='\'';
 | 
			
		||||
                i++;
 | 
			
		||||
                break;
 | 
			
		||||
              case '"':
 | 
			
		||||
                buffer[buffersize++]='"';
 | 
			
		||||
                i++;
 | 
			
		||||
                break;
 | 
			
		||||
              default:
 | 
			
		||||
                // ??? octal character code escapes and hexadecimal escapes
 | 
			
		||||
                //     not supported
 | 
			
		||||
                printf("Unknown escape sequence '\\%c' on line %d\n",
 | 
			
		||||
                       str[i], linenr);
 | 
			
		||||
              } /* switch */
 | 
			
		||||
            } else {
 | 
			
		||||
              buffer[buffersize++]=str[i++];
 | 
			
		||||
            } /* if */
 | 
			
		||||
          } /* while */
 | 
			
		||||
          if (str[i]=='"') {
 | 
			
		||||
            buffer[buffersize++]='\0'; /* terminate each string */
 | 
			
		||||
            i++;
 | 
			
		||||
          } else {
 | 
			
		||||
            printf("Error: unterminated string on line %d\n",linenr);
 | 
			
		||||
          } /* if */
 | 
			
		||||
        } /* if */
 | 
			
		||||
      } while (str[i]!='\0');
 | 
			
		||||
    } /* while - in SCPACK section */
 | 
			
		||||
    /* put in another '\0' to terminate the section */
 | 
			
		||||
    buffer[buffersize++]='\0';
 | 
			
		||||
  } /* while - !feof(input) */
 | 
			
		||||
  return buffersize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void write_pairtable(FILE *output, unsigned char pairtable[128][2], char *tablename)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  /* dump the pair table */
 | 
			
		||||
  fprintf(output, "/*-*SCPACK start of pair table, do not change or remove this line */\n");
 | 
			
		||||
  fprintf(output, "unsigned char %s[][2] = {", tablename);
 | 
			
		||||
  for (i=0; i<128 && pairtable[i][0]!=0 && pairtable[i][1]!=0; i++) {
 | 
			
		||||
    if ((i % 16)==0)
 | 
			
		||||
      fprintf(output, "\n  ");
 | 
			
		||||
    else
 | 
			
		||||
      fprintf(output, " ");
 | 
			
		||||
    fprintf(output, "{%d,%d}", pairtable[i][0], pairtable[i][1]);
 | 
			
		||||
    /* check if something follows this pair */
 | 
			
		||||
    if (i+1<128 && pairtable[i+1][0]!=0 && pairtable[i+1][1]!=0)
 | 
			
		||||
      fprintf(output, ",");
 | 
			
		||||
  } /* for */
 | 
			
		||||
  fprintf(output, "\n};\n");
 | 
			
		||||
  fprintf(output, "/*-*SCPACK end of pair table, do not change or remove this line */\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void writefile(FILE *input, FILE *output, unsigned char *buffer, unsigned buffersize, unsigned char pairtable[128][2])
 | 
			
		||||
{
 | 
			
		||||
  char str[256];
 | 
			
		||||
  int insection, indent, needseparator;
 | 
			
		||||
  unsigned char *bufptr;
 | 
			
		||||
 | 
			
		||||
  bufptr = buffer;
 | 
			
		||||
  insection = 0;
 | 
			
		||||
 | 
			
		||||
  rewind(input);
 | 
			
		||||
  while (!feof(input)) {
 | 
			
		||||
    while (fgets(str,sizeof str,input)!=NULL) {
 | 
			
		||||
      fprintf(output,"%s",str);
 | 
			
		||||
      if (check_tablename(str)) {
 | 
			
		||||
        write_pairtable(output, pairtable, tablename);
 | 
			
		||||
        /* strip an existing pair table from the file */
 | 
			
		||||
        if (fgets(str,sizeof str,input)!=NULL) {
 | 
			
		||||
          if (strmatch(str,"/*-*SCPACK",NULL)) {
 | 
			
		||||
            while (fgets(str,sizeof str,input)!=NULL)
 | 
			
		||||
              if (strmatch(str,"/*-*SCPACK",NULL))
 | 
			
		||||
                break;
 | 
			
		||||
          } else {
 | 
			
		||||
            fprintf(output,"%s",str);
 | 
			
		||||
          } /* if */
 | 
			
		||||
        } /* if */
 | 
			
		||||
      } /* if */
 | 
			
		||||
      if (strmatch(str,START_TOKEN,NULL))
 | 
			
		||||
        insection = 1;
 | 
			
		||||
      if (insection && strmatch(str,"#else",NULL))
 | 
			
		||||
        break;
 | 
			
		||||
    } /* while */
 | 
			
		||||
    if (!strmatch(str,"#else",&indent))
 | 
			
		||||
      return;           /* no (more) section found, quit */
 | 
			
		||||
    insection=0;
 | 
			
		||||
 | 
			
		||||
    /* dump the buffer as strings, separated with commas */
 | 
			
		||||
    needseparator = 0;
 | 
			
		||||
    while (*bufptr != '\0') {
 | 
			
		||||
      assert((unsigned)(bufptr-buffer) < buffersize);
 | 
			
		||||
      if (needseparator)
 | 
			
		||||
        fprintf(output, "%s\n",separator);
 | 
			
		||||
      fprintf(output, "%*c\"",indent+2,' ');
 | 
			
		||||
      /* loop over string */
 | 
			
		||||
      while (*bufptr != '\0') {
 | 
			
		||||
        if (*bufptr<' ' || *bufptr >= 128 || *bufptr == '"' || *bufptr == '\\')
 | 
			
		||||
          fprintf(output, "\\%03o", *bufptr);
 | 
			
		||||
        else
 | 
			
		||||
          fprintf(output, "%c", *bufptr);
 | 
			
		||||
        bufptr++;
 | 
			
		||||
      } /* while */
 | 
			
		||||
      fprintf(output, "\"");
 | 
			
		||||
      needseparator = 1;
 | 
			
		||||
      bufptr++;           /* skip '\0' */
 | 
			
		||||
    } /* while */
 | 
			
		||||
    fprintf(output, "%s\n",terminator);
 | 
			
		||||
    bufptr++;
 | 
			
		||||
 | 
			
		||||
    /* skip the input file until the #endif section */
 | 
			
		||||
    while (fgets(str,sizeof str,input)!=NULL) {
 | 
			
		||||
      if (strmatch(str,"#endif",NULL)) {
 | 
			
		||||
        fprintf(output,"%s",str);
 | 
			
		||||
        break;          /* done */
 | 
			
		||||
      } /* if */
 | 
			
		||||
    } /* while */
 | 
			
		||||
  } /* while - !feof(input) */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void usage(void)
 | 
			
		||||
{
 | 
			
		||||
  printf("Usage: scpack <filename> [output file]\n");
 | 
			
		||||
  exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  FILE *in, *out;
 | 
			
		||||
  unsigned char *buffer;
 | 
			
		||||
  unsigned buffersize, orgbuffersize;
 | 
			
		||||
  unsigned char pairtable[128][2];
 | 
			
		||||
 | 
			
		||||
  if (argc < 2 || argc > 3)
 | 
			
		||||
    usage();
 | 
			
		||||
  if ((in=fopen(argv[1],"rt"))==NULL) {
 | 
			
		||||
    printf("SCPACK: error opening input %s\n",argv[1]);
 | 
			
		||||
    usage();
 | 
			
		||||
  } /* if */
 | 
			
		||||
  if (argc == 2) {
 | 
			
		||||
    if ((out=fopen(TEMPFILE,"wt"))==NULL) {
 | 
			
		||||
      printf("SCPACK: error opening temporary file %s\n",TEMPFILE);
 | 
			
		||||
      usage();
 | 
			
		||||
    } /* if */
 | 
			
		||||
  } else {
 | 
			
		||||
    if ((out=fopen(argv[2],"wt"))==NULL) {
 | 
			
		||||
      printf("SCPACK: error opening output file %s\n",argv[2]);
 | 
			
		||||
      usage();
 | 
			
		||||
    } /* if */
 | 
			
		||||
  } /* if */
 | 
			
		||||
 | 
			
		||||
  buffer = (unsigned char *)malloc(MAXSIZE);
 | 
			
		||||
  if (buffer == NULL) {
 | 
			
		||||
    printf("SCPACK: error allocating memory\n");
 | 
			
		||||
    return 1;
 | 
			
		||||
  } /* if */
 | 
			
		||||
  /* 1. read the buffer
 | 
			
		||||
   * 2. compress the buffer
 | 
			
		||||
   * 3. copy the file, insert the compressed buffer
 | 
			
		||||
   */
 | 
			
		||||
  buffersize = readbuffer(in, buffer);
 | 
			
		||||
  orgbuffersize = buffersize;
 | 
			
		||||
  if (buffersize > 0) {
 | 
			
		||||
    buffersize = compress(buffer, buffersize, pairtable);
 | 
			
		||||
    writefile(in, out, buffer, buffersize, pairtable);
 | 
			
		||||
    printf("SCPACK: compression ratio: %ld%% (%d -> %d)\n",
 | 
			
		||||
           100L-(100L*buffersize)/orgbuffersize, orgbuffersize, buffersize);
 | 
			
		||||
  } else {
 | 
			
		||||
    printf("SCPACK: no SCPACK section found, nothing to do\n");
 | 
			
		||||
  } /* if */
 | 
			
		||||
  fclose(out);
 | 
			
		||||
  fclose(in);
 | 
			
		||||
  /* let the new file replace the old file */
 | 
			
		||||
  if (buffersize == 0) {
 | 
			
		||||
    if (argc == 2)
 | 
			
		||||
      remove(TEMPFILE);
 | 
			
		||||
    else
 | 
			
		||||
      remove(argv[2]);
 | 
			
		||||
  } else if (argc == 2) {
 | 
			
		||||
    remove(argv[1]);
 | 
			
		||||
    rename(TEMPFILE,argv[1]);
 | 
			
		||||
  } /* if */
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										347
									
								
								compiler/libpc300/scstate.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										347
									
								
								compiler/libpc300/scstate.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,347 @@
 | 
			
		||||
/*  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 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), 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
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#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 "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));
 | 
			
		||||
    /* for every new automaton, create an anonymous (invalid) state */
 | 
			
		||||
    state_add("",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=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];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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;
 | 
			
		||||
  int s,t;
 | 
			
		||||
  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 */
 | 
			
		||||
        for (s=0; s<psrc->numstates; s++)
 | 
			
		||||
          for (t=0; t<ptgt->numstates; t++)
 | 
			
		||||
            if (psrc->states[s]==ptgt->states[t])
 | 
			
		||||
              error(84,sym->name);      /* state conflict */
 | 
			
		||||
      } /* for (tgtptr) */
 | 
			
		||||
    } /* for (srcptr) */
 | 
			
		||||
  } /* for (sym) */
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								compiler/libpc300/scstub.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								compiler/libpc300/scstub.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
#include <process.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static char filename[] = "pccdos.exe";
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  int result;
 | 
			
		||||
 | 
			
		||||
  /* build a command line to pass on to the "DOS" program */
 | 
			
		||||
  char path[80], *ptr;
 | 
			
		||||
  strcpy(path,argv[0]);
 | 
			
		||||
  ptr=strrchr(path,'\\');
 | 
			
		||||
  if (ptr==NULL)
 | 
			
		||||
    ptr=strchr(path,':');
 | 
			
		||||
  if (ptr==NULL) {
 | 
			
		||||
    strcpy(path,filename);
 | 
			
		||||
  } else {
 | 
			
		||||
    strcpy(ptr+1,filename);
 | 
			
		||||
  } /* if */
 | 
			
		||||
 | 
			
		||||
  /* launch the DOS version of the tool */
 | 
			
		||||
  result=execv(path,argv);
 | 
			
		||||
  if (result==-1)
 | 
			
		||||
    printf("Error launching '%s'\n",path);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										108
									
								
								compiler/libpc300/scvars.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										108
									
								
								compiler/libpc300/scvars.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
/*  Pawn compiler
 | 
			
		||||
 *
 | 
			
		||||
 *  Global (cross-module) variables.
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) ITB CompuPhase, 1997-2005
 | 
			
		||||
 *
 | 
			
		||||
 *  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$
 | 
			
		||||
 */
 | 
			
		||||
#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 sc_stksize=sDEF_AMXSTACK;/* default stack size */
 | 
			
		||||
SC_VDEFINE cell sc_amxlimit=0;     /* default abstract machine 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 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
 | 
			
		||||
		Reference in New Issue
	
	Block a user