1.1 --- a/compiler-init/amx.h Sat Jul 15 05:02:38 2006 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,629 +0,0 @@
1.4 -/* Pawn Abstract Machine (for the Pawn language)
1.5 - *
1.6 - * Copyright (c) ITB CompuPhase, 1997-2006
1.7 - *
1.8 - * This software is provided "as-is", without any express or implied warranty.
1.9 - * In no event will the authors be held liable for any damages arising from
1.10 - * the use of this software.
1.11 - *
1.12 - * Permission is granted to anyone to use this software for any purpose,
1.13 - * including commercial applications, and to alter it and redistribute it
1.14 - * freely, subject to the following restrictions:
1.15 - *
1.16 - * 1. The origin of this software must not be misrepresented; you must not
1.17 - * claim that you wrote the original software. If you use this software in
1.18 - * a product, an acknowledgment in the product documentation would be
1.19 - * appreciated but is not required.
1.20 - * 2. Altered source versions must be plainly marked as such, and must not be
1.21 - * misrepresented as being the original software.
1.22 - * 3. This notice may not be removed or altered from any source distribution.
1.23 - *
1.24 - * Version: $Id: amx.h 3579 2006-06-06 13:35:29Z thiadmer $
1.25 - */
1.26 -
1.27 -#ifndef AMX_H_INCLUDED
1.28 -#define AMX_H_INCLUDED
1.29 -
1.30 -#include <stdlib.h> /* for size_t */
1.31 -#include <limits.h>
1.32 -
1.33 -#if defined FREEBSD && !defined __FreeBSD__
1.34 - #define __FreeBSD__
1.35 -#endif
1.36 -#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
1.37 - #include <sclinux.h>
1.38 -#endif
1.39 -
1.40 -#if defined __GNUC__
1.41 - #include <stdint.h>
1.42 - #define HAVE_STDINT_H
1.43 -#elif !defined HAVE_STDINT_H
1.44 - #if defined __LCC__ || defined __DMC__ || defined LINUX || (defined __WATCOMC__ && __WATCOMC__ >= 1200)
1.45 - #if defined HAVE_INTTYPES_H
1.46 - #include <inttypes.h>
1.47 - #else
1.48 - #include <stdint.h>
1.49 - #endif
1.50 - #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
1.51 - /* The ISO C99 defines the int16_t and int_32t types. If the compiler got
1.52 - * here, these types are probably undefined.
1.53 - */
1.54 - #if defined __MACH__
1.55 - #include <ppc/types.h>
1.56 - typedef unsigned short int uint16_t;
1.57 - typedef unsigned long int uint32_t;
1.58 - #elif defined __FreeBSD__
1.59 - #include <inttypes.h>
1.60 - #else
1.61 - typedef short int int16_t;
1.62 - typedef unsigned short int uint16_t;
1.63 - #if defined SN_TARGET_PS2
1.64 - typedef int int32_t;
1.65 - typedef unsigned int uint32_t;
1.66 - #else
1.67 - typedef long int int32_t;
1.68 - typedef unsigned long int uint32_t;
1.69 - #endif
1.70 - #if defined __WIN32__ || defined _WIN32 || defined WIN32
1.71 - typedef __int64 int64_t;
1.72 - typedef unsigned __int64 uint64_t;
1.73 - #define HAVE_I64
1.74 - #elif defined __GNUC__
1.75 - typedef long long int64_t;
1.76 - typedef unsigned long long uint64_t;
1.77 - #define HAVE_I64
1.78 - #endif
1.79 - #endif
1.80 - #endif
1.81 - #define HAVE_STDINT_H
1.82 -#endif
1.83 -#if defined _LP64 || defined WIN64 || defined _WIN64
1.84 - #if !defined __64BIT__
1.85 - #define __64BIT__
1.86 - #endif
1.87 -#endif
1.88 -
1.89 -#if HAVE_ALLOCA_H
1.90 - #include <alloca.h>
1.91 -#endif
1.92 -#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
1.93 - #if !defined alloca
1.94 - #define alloca(n) _alloca(n)
1.95 - #endif
1.96 -#endif
1.97 -
1.98 -#if !defined arraysize
1.99 - #define arraysize(array) (sizeof(array) / sizeof((array)[0]))
1.100 -#endif
1.101 -#if !defined assert_static
1.102 - /* see "Compile-Time Assertions" by Ralf Holly,
1.103 - * C/C++ Users Journal, November 2004
1.104 - */
1.105 - #define assert_static(e) \
1.106 - do { \
1.107 - enum { assert_static__ = 1/(e) }; \
1.108 - } while (0)
1.109 -#endif
1.110 -
1.111 -#ifdef __cplusplus
1.112 -extern "C" {
1.113 -#endif
1.114 -
1.115 -#if defined PAWN_DLL
1.116 - #if !defined AMX_NATIVE_CALL
1.117 - #define AMX_NATIVE_CALL __stdcall
1.118 - #endif
1.119 - #if !defined AMXAPI
1.120 - #define AMXAPI __stdcall
1.121 - #endif
1.122 -#endif
1.123 -
1.124 -/* calling convention for native functions */
1.125 -#if !defined AMX_NATIVE_CALL
1.126 - #define AMX_NATIVE_CALL
1.127 -#endif
1.128 -/* calling convention for all interface functions and callback functions */
1.129 -#if !defined AMXAPI
1.130 - #if defined STDECL
1.131 - #define AMXAPI __stdcall
1.132 - #elif defined CDECL
1.133 - #define AMXAPI __cdecl
1.134 - #elif defined GCC_HASCLASSVISIBILITY
1.135 - #define AMXAPI __attribute__ ((visibility("default")))
1.136 - #else
1.137 - #define AMXAPI
1.138 - #endif
1.139 -#endif
1.140 -#if !defined AMXEXPORT
1.141 - #define AMXEXPORT
1.142 -#endif
1.143 -
1.144 -/* File format version (in CUR_FILE_VERSION)
1.145 - * 0 (original version)
1.146 - * 1 (opcodes JUMP.pri, SWITCH and CASETBL)
1.147 - * 2 (compressed files)
1.148 - * 3 (public variables)
1.149 - * 4 (opcodes SWAP.pri/alt and PUSHADDR)
1.150 - * 5 (tagnames table)
1.151 - * 6 (reformatted header)
1.152 - * 7 (name table, opcodes SYMTAG & SYSREQ.D)
1.153 - * 8 (opcode STMT, renewed debug interface)
1.154 - * 9 (macro opcodes)
1.155 - * MIN_FILE_VERSION is the lowest file version number that the current AMX
1.156 - * implementation supports. If the AMX file header gets new fields, this number
1.157 - * often needs to be incremented. MAX_AMX_VERSION is the lowest AMX version that
1.158 - * is needed to support the current file version. When there are new opcodes,
1.159 - * this number needs to be incremented.
1.160 - * The file version supported by the JIT may run behind MIN_AMX_VERSION. So
1.161 - * there is an extra constant for it: MAX_FILE_VER_JIT.
1.162 - */
1.163 -#define CUR_FILE_VERSION 9 /* current file version; also the current AMX version */
1.164 -#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
1.165 -#define MIN_AMX_VERSION 9 /* minimum AMX version needed to support the current file format */
1.166 -#define MAX_FILE_VER_JIT 8 /* file version supported by the JIT */
1.167 -#define MIN_AMX_VER_JIT 8 /* AMX version supported by the JIT */
1.168 -
1.169 -#if !defined PAWN_CELL_SIZE
1.170 - #define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
1.171 -#endif
1.172 -#if PAWN_CELL_SIZE==16
1.173 - typedef uint16_t ucell;
1.174 - typedef int16_t cell;
1.175 -#elif PAWN_CELL_SIZE==32
1.176 - typedef uint32_t ucell;
1.177 - typedef int32_t cell;
1.178 -#elif PAWN_CELL_SIZE==64
1.179 - typedef uint64_t ucell;
1.180 - typedef int64_t cell;
1.181 -#else
1.182 - #error Unsupported cell size (PAWN_CELL_SIZE)
1.183 -#endif
1.184 -
1.185 -#define UNPACKEDMAX (((cell)1 << (sizeof(cell)-1)*8) - 1)
1.186 -#define UNLIMITED (~1u >> 1)
1.187 -
1.188 -struct tagAMX;
1.189 -typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
1.190 -typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
1.191 - cell *result, cell *params);
1.192 -typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
1.193 -typedef int (AMXAPI *AMX_IDLE)(struct tagAMX *amx, int AMXAPI Exec(struct tagAMX *, cell *, int));
1.194 -#if !defined _FAR
1.195 - #define _FAR
1.196 -#endif
1.197 -
1.198 -#if defined _MSC_VER
1.199 - #pragma warning(disable:4103) /* disable warning message 4103 that complains
1.200 - * about pragma pack in a header file */
1.201 - #pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
1.202 -#endif
1.203 -
1.204 -/* Some compilers do not support the #pragma align, which should be fine. Some
1.205 - * compilers give a warning on unknown #pragmas, which is not so fine...
1.206 - */
1.207 -#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
1.208 - #define AMX_NO_ALIGN
1.209 -#endif
1.210 -
1.211 -#if defined __GNUC__
1.212 - #define PACKED __attribute__((packed))
1.213 -#else
1.214 - #define PACKED
1.215 -#endif
1.216 -
1.217 -#if !defined AMX_NO_ALIGN
1.218 - #if defined LINUX || defined __FreeBSD__
1.219 - #pragma pack(1) /* structures must be packed (byte-aligned) */
1.220 - #elif defined MACOS && defined __MWERKS__
1.221 - #pragma options align=mac68k
1.222 - #else
1.223 - #pragma pack(push)
1.224 - #pragma pack(1) /* structures must be packed (byte-aligned) */
1.225 - #if defined __TURBOC__
1.226 - #pragma option -a- /* "pack" pragma for older Borland compilers */
1.227 - #endif
1.228 - #endif
1.229 -#endif
1.230 -
1.231 -typedef struct tagAMX_NATIVE_INFO {
1.232 - const char _FAR *name PACKED;
1.233 - AMX_NATIVE func PACKED;
1.234 -} AMX_NATIVE_INFO;
1.235 -
1.236 -#define AMX_USERNUM 4
1.237 -#define sEXPMAX 19 /* maximum name length for file version <= 6 */
1.238 -#define sNAMEMAX 31 /* maximum name length of symbol name */
1.239 -
1.240 -typedef struct tagAMX_FUNCSTUB {
1.241 - ucell address PACKED;
1.242 - char name[sEXPMAX+1] PACKED;
1.243 -} AMX_FUNCSTUB;
1.244 -
1.245 -typedef struct tagFUNCSTUBNT {
1.246 - ucell address PACKED;
1.247 - uint32_t nameofs PACKED;
1.248 -} AMX_FUNCSTUBNT;
1.249 -
1.250 -/* The AMX structure is the internal structure for many functions. Not all
1.251 - * fields are valid at all times; many fields are cached in local variables.
1.252 - */
1.253 -typedef struct tagAMX {
1.254 - unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
1.255 - unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
1.256 - AMX_CALLBACK callback PACKED;
1.257 - AMX_DEBUG debug PACKED; /* debug callback */
1.258 - /* for external functions a few registers must be accessible from the outside */
1.259 - cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */
1.260 - cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */
1.261 - cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */
1.262 - cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */
1.263 - cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
1.264 - cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
1.265 - int flags PACKED; /* current status, see amx_Flags() */
1.266 - /* user data */
1.267 - long usertags[AMX_USERNUM] PACKED;
1.268 - void _FAR *userdata[AMX_USERNUM] PACKED;
1.269 - /* native functions can raise an error */
1.270 - int error PACKED;
1.271 - /* passing parameters requires a "count" field */
1.272 - int paramcount;
1.273 - /* the sleep opcode needs to store the full AMX status */
1.274 - cell pri PACKED;
1.275 - cell alt PACKED;
1.276 - cell reset_stk PACKED;
1.277 - cell reset_hea PACKED;
1.278 - cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
1.279 - #if defined JIT
1.280 - /* support variables for the JIT */
1.281 - int reloc_size PACKED; /* required temporary buffer for relocations */
1.282 - long code_size PACKED; /* estimated memory footprint of the native code */
1.283 - #endif
1.284 -} AMX;
1.285 -
1.286 -/* The AMX_HEADER structure is both the memory format as the file format. The
1.287 - * structure is used internaly.
1.288 - */
1.289 -typedef struct tagAMX_HEADER {
1.290 - int32_t size PACKED; /* size of the "file" */
1.291 - uint16_t magic PACKED; /* signature */
1.292 - char file_version PACKED; /* file format version */
1.293 - char amx_version PACKED; /* required version of the AMX */
1.294 - int16_t flags PACKED;
1.295 - int16_t defsize PACKED; /* size of a definition record */
1.296 - int32_t cod PACKED; /* initial value of COD - code block */
1.297 - int32_t dat PACKED; /* initial value of DAT - data block */
1.298 - int32_t hea PACKED; /* initial value of HEA - start of the heap */
1.299 - int32_t stp PACKED; /* initial value of STP - stack top */
1.300 - int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
1.301 - int32_t publics PACKED; /* offset to the "public functions" table */
1.302 - int32_t natives PACKED; /* offset to the "native functions" table */
1.303 - int32_t libraries PACKED; /* offset to the table of libraries */
1.304 - int32_t pubvars PACKED; /* the "public variables" table */
1.305 - int32_t tags PACKED; /* the "public tagnames" table */
1.306 - int32_t nametable PACKED; /* name table */
1.307 -} AMX_HEADER;
1.308 -
1.309 -#if PAWN_CELL_SIZE==16
1.310 - #define AMX_MAGIC 0xf1e2
1.311 -#elif PAWN_CELL_SIZE==32
1.312 - #define AMX_MAGIC 0xf1e0
1.313 -#elif PAWN_CELL_SIZE==64
1.314 - #define AMX_MAGIC 0xf1e1
1.315 -#endif
1.316 -
1.317 -enum {
1.318 - AMX_ERR_NONE,
1.319 - /* reserve the first 15 error codes for exit codes of the abstract machine */
1.320 - AMX_ERR_EXIT, /* forced exit */
1.321 - AMX_ERR_ASSERT, /* assertion failed */
1.322 - AMX_ERR_STACKERR, /* stack/heap collision */
1.323 - AMX_ERR_BOUNDS, /* index out of bounds */
1.324 - AMX_ERR_MEMACCESS, /* invalid memory access */
1.325 - AMX_ERR_INVINSTR, /* invalid instruction */
1.326 - AMX_ERR_STACKLOW, /* stack underflow */
1.327 - AMX_ERR_HEAPLOW, /* heap underflow */
1.328 - AMX_ERR_CALLBACK, /* no callback, or invalid callback */
1.329 - AMX_ERR_NATIVE, /* native function failed */
1.330 - AMX_ERR_DIVIDE, /* divide by zero */
1.331 - AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
1.332 - AMX_ERR_INVSTATE, /* invalid state for this access */
1.333 -
1.334 - AMX_ERR_MEMORY = 16, /* out of memory */
1.335 - AMX_ERR_FORMAT, /* invalid file format */
1.336 - AMX_ERR_VERSION, /* file is for a newer version of the AMX */
1.337 - AMX_ERR_NOTFOUND, /* function not found */
1.338 - AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */
1.339 - AMX_ERR_DEBUG, /* debugger cannot run */
1.340 - AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */
1.341 - AMX_ERR_USERDATA, /* unable to set user data field (table full) */
1.342 - AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
1.343 - AMX_ERR_PARAMS, /* parameter error */
1.344 - AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
1.345 - AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
1.346 -};
1.347 -
1.348 -/* AMX_FLAG_CHAR16 0x01 no longer used */
1.349 -#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
1.350 -#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
1.351 -#define AMX_FLAG_SLEEP 0x08 /* script uses the sleep instruction (possible re-entry or power-down mode) */
1.352 -#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no BREAK opcodes */
1.353 -#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
1.354 -#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
1.355 -#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
1.356 -#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
1.357 -
1.358 -#define AMX_EXEC_MAIN (-1) /* start at program entry point */
1.359 -#define AMX_EXEC_CONT (-2) /* continue from last address */
1.360 -
1.361 -#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
1.362 -
1.363 -#if !defined AMX_COMPACTMARGIN
1.364 - #define AMX_COMPACTMARGIN 64
1.365 -#endif
1.366 -
1.367 -/* for native functions that use floating point parameters, the following
1.368 - * two macros are convenient for casting a "cell" into a "float" type _without_
1.369 - * changing the bit pattern
1.370 - */
1.371 -#if PAWN_CELL_SIZE==32
1.372 - #define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
1.373 - #define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
1.374 -#elif PAWN_CELL_SIZE==64
1.375 - #define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
1.376 - #define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
1.377 -#else
1.378 - #error Unsupported cell size
1.379 -#endif
1.380 -
1.381 -#define amx_StrParam(amx,param,result) \
1.382 - do { \
1.383 - cell *amx_cstr_; int amx_length_; \
1.384 - amx_GetAddr((amx), (param), &amx_cstr_); \
1.385 - amx_StrLen(amx_cstr_, &amx_length_); \
1.386 - if (amx_length_ > 0 && \
1.387 - ((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
1.388 - amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_ + 1); \
1.389 - else (result) = NULL; \
1.390 - } while (0)
1.391 -
1.392 -uint16_t * AMXAPI amx_Align16(uint16_t *v);
1.393 -uint32_t * AMXAPI amx_Align32(uint32_t *v);
1.394 -#if defined _I64_MAX || defined HAVE_I64
1.395 - uint64_t * AMXAPI amx_Align64(uint64_t *v);
1.396 -#endif
1.397 -int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
1.398 -int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
1.399 -int AMXAPI amx_Cleanup(AMX *amx);
1.400 -int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
1.401 -int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
1.402 -int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
1.403 -int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
1.404 -int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
1.405 -int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
1.406 -int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
1.407 -int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
1.408 -int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
1.409 -int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
1.410 -int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
1.411 -int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
1.412 -int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
1.413 -int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
1.414 -int AMXAPI amx_Init(AMX *amx, void *program);
1.415 -int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
1.416 -int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
1.417 -int AMXAPI amx_NameLength(AMX *amx, int *length);
1.418 -AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
1.419 -int AMXAPI amx_NumNatives(AMX *amx, int *number);
1.420 -int AMXAPI amx_NumPublics(AMX *amx, int *number);
1.421 -int AMXAPI amx_NumPubVars(AMX *amx, int *number);
1.422 -int AMXAPI amx_NumTags(AMX *amx, int *number);
1.423 -int AMXAPI amx_Push(AMX *amx, cell value);
1.424 -int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
1.425 -int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
1.426 -int AMXAPI amx_RaiseError(AMX *amx, int error);
1.427 -int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
1.428 -int AMXAPI amx_Release(AMX *amx, cell amx_addr);
1.429 -int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
1.430 -int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
1.431 -int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
1.432 -int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
1.433 -int AMXAPI amx_StrLen(const cell *cstring, int *length);
1.434 -int AMXAPI amx_UTF8Check(const char *string, int *length);
1.435 -int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
1.436 -int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
1.437 -int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
1.438 -
1.439 -#if PAWN_CELL_SIZE==16
1.440 - #define amx_AlignCell(v) amx_Align16(v)
1.441 -#elif PAWN_CELL_SIZE==32
1.442 - #define amx_AlignCell(v) amx_Align32(v)
1.443 -#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
1.444 - #define amx_AlignCell(v) amx_Align64(v)
1.445 -#else
1.446 - #error Unsupported cell size
1.447 -#endif
1.448 -
1.449 -#define amx_RegisterFunc(amx, name, func) \
1.450 - amx_Register((amx), amx_NativeInfo((name),(func)), 1);
1.451 -
1.452 -#if !defined AMX_NO_ALIGN
1.453 - #if defined LINUX || defined __FreeBSD__
1.454 - #pragma pack() /* reset default packing */
1.455 - #elif defined MACOS && defined __MWERKS__
1.456 - #pragma options align=reset
1.457 - #else
1.458 - #pragma pack(pop) /* reset previous packing */
1.459 - #endif
1.460 -#endif
1.461 -
1.462 -#ifdef __cplusplus
1.463 -}
1.464 -#endif
1.465 -
1.466 -typedef enum {
1.467 - OP_NONE, /* invalid opcode */
1.468 - OP_LOAD_PRI,
1.469 - OP_LOAD_ALT,
1.470 - OP_LOAD_S_PRI,
1.471 - OP_LOAD_S_ALT,
1.472 - OP_LREF_PRI,
1.473 - OP_LREF_ALT,
1.474 - OP_LREF_S_PRI,
1.475 - OP_LREF_S_ALT,
1.476 - OP_LOAD_I,
1.477 - OP_LODB_I,
1.478 - OP_CONST_PRI,
1.479 - OP_CONST_ALT,
1.480 - OP_ADDR_PRI,
1.481 - OP_ADDR_ALT,
1.482 - OP_STOR_PRI,
1.483 - OP_STOR_ALT,
1.484 - OP_STOR_S_PRI,
1.485 - OP_STOR_S_ALT,
1.486 - OP_SREF_PRI,
1.487 - OP_SREF_ALT,
1.488 - OP_SREF_S_PRI,
1.489 - OP_SREF_S_ALT,
1.490 - OP_STOR_I,
1.491 - OP_STRB_I,
1.492 - OP_LIDX,
1.493 - OP_LIDX_B,
1.494 - OP_IDXADDR,
1.495 - OP_IDXADDR_B,
1.496 - OP_ALIGN_PRI,
1.497 - OP_ALIGN_ALT,
1.498 - OP_LCTRL,
1.499 - OP_SCTRL,
1.500 - OP_MOVE_PRI,
1.501 - OP_MOVE_ALT,
1.502 - OP_XCHG,
1.503 - OP_PUSH_PRI,
1.504 - OP_PUSH_ALT,
1.505 - OP_PUSH_R,
1.506 - OP_PUSH_C,
1.507 - OP_PUSH,
1.508 - OP_PUSH_S,
1.509 - OP_POP_PRI,
1.510 - OP_POP_ALT,
1.511 - OP_STACK,
1.512 - OP_HEAP,
1.513 - OP_PROC,
1.514 - OP_RET,
1.515 - OP_RETN,
1.516 - OP_CALL,
1.517 - OP_CALL_PRI,
1.518 - OP_JUMP,
1.519 - OP_JREL,
1.520 - OP_JZER,
1.521 - OP_JNZ,
1.522 - OP_JEQ,
1.523 - OP_JNEQ,
1.524 - OP_JLESS,
1.525 - OP_JLEQ,
1.526 - OP_JGRTR,
1.527 - OP_JGEQ,
1.528 - OP_JSLESS,
1.529 - OP_JSLEQ,
1.530 - OP_JSGRTR,
1.531 - OP_JSGEQ,
1.532 - OP_SHL,
1.533 - OP_SHR,
1.534 - OP_SSHR,
1.535 - OP_SHL_C_PRI,
1.536 - OP_SHL_C_ALT,
1.537 - OP_SHR_C_PRI,
1.538 - OP_SHR_C_ALT,
1.539 - OP_SMUL,
1.540 - OP_SDIV,
1.541 - OP_SDIV_ALT,
1.542 - OP_UMUL,
1.543 - OP_UDIV,
1.544 - OP_UDIV_ALT,
1.545 - OP_ADD,
1.546 - OP_SUB,
1.547 - OP_SUB_ALT,
1.548 - OP_AND,
1.549 - OP_OR,
1.550 - OP_XOR,
1.551 - OP_NOT,
1.552 - OP_NEG,
1.553 - OP_INVERT,
1.554 - OP_ADD_C,
1.555 - OP_SMUL_C,
1.556 - OP_ZERO_PRI,
1.557 - OP_ZERO_ALT,
1.558 - OP_ZERO,
1.559 - OP_ZERO_S,
1.560 - OP_SIGN_PRI,
1.561 - OP_SIGN_ALT,
1.562 - OP_EQ,
1.563 - OP_NEQ,
1.564 - OP_LESS,
1.565 - OP_LEQ,
1.566 - OP_GRTR,
1.567 - OP_GEQ,
1.568 - OP_SLESS,
1.569 - OP_SLEQ,
1.570 - OP_SGRTR,
1.571 - OP_SGEQ,
1.572 - OP_EQ_C_PRI,
1.573 - OP_EQ_C_ALT,
1.574 - OP_INC_PRI,
1.575 - OP_INC_ALT,
1.576 - OP_INC,
1.577 - OP_INC_S,
1.578 - OP_INC_I,
1.579 - OP_DEC_PRI,
1.580 - OP_DEC_ALT,
1.581 - OP_DEC,
1.582 - OP_DEC_S,
1.583 - OP_DEC_I,
1.584 - OP_MOVS,
1.585 - OP_CMPS,
1.586 - OP_FILL,
1.587 - OP_HALT,
1.588 - OP_BOUNDS,
1.589 - OP_SYSREQ_PRI,
1.590 - OP_SYSREQ_C,
1.591 - OP_FILE, /* obsolete */
1.592 - OP_LINE, /* obsolete */
1.593 - OP_SYMBOL, /* obsolete */
1.594 - OP_SRANGE, /* obsolete */
1.595 - OP_JUMP_PRI,
1.596 - OP_SWITCH,
1.597 - OP_CASETBL,
1.598 - OP_SWAP_PRI,
1.599 - OP_SWAP_ALT,
1.600 - OP_PUSH_ADR,
1.601 - OP_NOP,
1.602 - OP_SYSREQ_N,
1.603 - OP_SYMTAG, /* obsolete */
1.604 - OP_BREAK,
1.605 - OP_PUSH2_C,
1.606 - OP_PUSH2,
1.607 - OP_PUSH2_S,
1.608 - OP_PUSH2_ADR,
1.609 - OP_PUSH3_C,
1.610 - OP_PUSH3,
1.611 - OP_PUSH3_S,
1.612 - OP_PUSH3_ADR,
1.613 - OP_PUSH4_C,
1.614 - OP_PUSH4,
1.615 - OP_PUSH4_S,
1.616 - OP_PUSH4_ADR,
1.617 - OP_PUSH5_C,
1.618 - OP_PUSH5,
1.619 - OP_PUSH5_S,
1.620 - OP_PUSH5_ADR,
1.621 - OP_LOAD_BOTH,
1.622 - OP_LOAD_S_BOTH,
1.623 - OP_CONST,
1.624 - OP_CONST_S,
1.625 - /* ----- */
1.626 - OP_SYSREQ_D,
1.627 - OP_SYSREQ_ND,
1.628 - /* ----- */
1.629 - OP_NUM_OPCODES
1.630 -} OPCODE;
1.631 -
1.632 -#endif /* AMX_H_INCLUDED */
2.1 --- a/compiler-init/amxdbg.h Sat Jul 15 05:02:38 2006 +0000
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,172 +0,0 @@
2.4 -/* Abstract Machine for the Pawn compiler, debugger support
2.5 - *
2.6 - * This file contains extra definitions that are convenient for debugger
2.7 - * support.
2.8 - *
2.9 - * Copyright (c) ITB CompuPhase, 2005-2006
2.10 - *
2.11 - * This software is provided "as-is", without any express or implied warranty.
2.12 - * In no event will the authors be held liable for any damages arising from
2.13 - * the use of this software.
2.14 - *
2.15 - * Permission is granted to anyone to use this software for any purpose,
2.16 - * including commercial applications, and to alter it and redistribute it
2.17 - * freely, subject to the following restrictions:
2.18 - *
2.19 - * 1. The origin of this software must not be misrepresented; you must not
2.20 - * claim that you wrote the original software. If you use this software in
2.21 - * a product, an acknowledgment in the product documentation would be
2.22 - * appreciated but is not required.
2.23 - * 2. Altered source versions must be plainly marked as such, and must not be
2.24 - * misrepresented as being the original software.
2.25 - * 3. This notice may not be removed or altered from any source distribution.
2.26 - *
2.27 - * Version: $Id: amxdbg.h 3519 2006-02-17 17:57:04Z thiadmer $
2.28 - */
2.29 -
2.30 -#ifndef AMXDBG_H_INCLUDED
2.31 -#define AMXDBG_H_INCLUDED
2.32 -
2.33 -#ifndef AMX_H_INCLUDED
2.34 - #include "amx.h"
2.35 -#endif
2.36 -
2.37 -#ifdef __cplusplus
2.38 -extern "C" {
2.39 -#endif
2.40 -
2.41 -/* Some compilers do not support the #pragma align, which should be fine. Some
2.42 - * compilers give a warning on unknown #pragmas, which is not so fine...
2.43 - */
2.44 -#if defined SN_TARGET_PS2 || defined __GNUC__
2.45 - #define AMX_NO_ALIGN
2.46 -#endif
2.47 -
2.48 -#if defined __GNUC__
2.49 - #define PACKED __attribute__((packed))
2.50 -#else
2.51 - #define PACKED
2.52 -#endif
2.53 -
2.54 -#if !defined AMX_NO_ALIGN
2.55 - #if defined LINUX || defined __FreeBSD__
2.56 - #pragma pack(1) /* structures must be packed (byte-aligned) */
2.57 - #elif defined MACOS && defined __MWERKS__
2.58 - #pragma options align=mac68k
2.59 - #else
2.60 - #pragma pack(push)
2.61 - #pragma pack(1) /* structures must be packed (byte-aligned) */
2.62 - #if defined __TURBOC__
2.63 - #pragma option -a- /* "pack" pragma for older Borland compilers */
2.64 - #endif
2.65 - #endif
2.66 -#endif
2.67 -
2.68 -typedef struct tagAMX_DBG_HDR {
2.69 - int32_t size PACKED; /* size of the debug information chunk */
2.70 - uint16_t magic PACKED; /* signature, must be 0xf1ef */
2.71 - char file_version PACKED; /* file format version */
2.72 - char amx_version PACKED; /* required version of the AMX */
2.73 - int16_t flags PACKED; /* currently unused */
2.74 - int16_t files PACKED; /* number of entries in the "file" table */
2.75 - int16_t lines PACKED; /* number of entries in the "line" table */
2.76 - int16_t symbols PACKED; /* number of entries in the "symbol" table */
2.77 - int16_t tags PACKED; /* number of entries in the "tag" table */
2.78 - int16_t automatons PACKED; /* number of entries in the "automaton" table */
2.79 - int16_t states PACKED; /* number of entries in the "state" table */
2.80 -} PACKED AMX_DBG_HDR;
2.81 -#define AMX_DBG_MAGIC 0xf1ef
2.82 -
2.83 -typedef struct tagAMX_DBG_FILE {
2.84 - ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
2.85 - const char name[1] PACKED; /* ASCII string, zero-terminated */
2.86 -} PACKED AMX_DBG_FILE;
2.87 -
2.88 -typedef struct tagAMX_DBG_LINE {
2.89 - ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
2.90 - int32_t line PACKED; /* line number */
2.91 -} PACKED AMX_DBG_LINE;
2.92 -
2.93 -typedef struct tagAMX_DBG_SYMBOL {
2.94 - ucell address PACKED; /* address in the data segment or relative to the frame */
2.95 - int16_t tag PACKED; /* tag for the symbol */
2.96 - ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
2.97 - ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
2.98 - char ident PACKED; /* kind of symbol (function/variable) */
2.99 - char vclass PACKED; /* class of symbol (global/local) */
2.100 - int16_t dim PACKED; /* number of dimensions */
2.101 - const char name[1] PACKED; /* ASCII string, zero-terminated */
2.102 -} PACKED AMX_DBG_SYMBOL;
2.103 -
2.104 -typedef struct tagAMX_DBG_SYMDIM {
2.105 - int16_t tag PACKED; /* tag for the array dimension */
2.106 - ucell size PACKED; /* size of the array dimension */
2.107 -} PACKED AMX_DBG_SYMDIM;
2.108 -
2.109 -typedef struct tagAMX_DBG_TAG {
2.110 - int16_t tag PACKED; /* tag id */
2.111 - const char name[1] PACKED; /* ASCII string, zero-terminated */
2.112 -} PACKED AMX_DBG_TAG;
2.113 -
2.114 -typedef struct tagAMX_DBG_MACHINE {
2.115 - int16_t automaton PACKED; /* automaton id */
2.116 - ucell address PACKED; /* address of state variable */
2.117 - const char name[1] PACKED; /* ASCII string, zero-terminated */
2.118 -} PACKED AMX_DBG_MACHINE;
2.119 -
2.120 -typedef struct tagAMX_DBG_STATE {
2.121 - int16_t state PACKED; /* state id */
2.122 - int16_t automaton PACKED; /* automaton id */
2.123 - const char name[1] PACKED; /* ASCII string, zero-terminated */
2.124 -} PACKED AMX_DBG_STATE;
2.125 -
2.126 -typedef struct tagAMX_DBG {
2.127 - AMX_DBG_HDR *hdr PACKED; /* points to the AMX_DBG header */
2.128 - AMX_DBG_FILE **filetbl PACKED;
2.129 - AMX_DBG_LINE *linetbl PACKED;
2.130 - AMX_DBG_SYMBOL **symboltbl PACKED;
2.131 - AMX_DBG_TAG **tagtbl PACKED;
2.132 - AMX_DBG_MACHINE **automatontbl PACKED;
2.133 - AMX_DBG_STATE **statetbl PACKED;
2.134 -} PACKED AMX_DBG;
2.135 -
2.136 -#if !defined iVARIABLE
2.137 - #define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
2.138 - #define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
2.139 - #define iARRAY 3
2.140 - #define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
2.141 - #define iFUNCTN 9
2.142 -#endif
2.143 -
2.144 -
2.145 -int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg);
2.146 -int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, FILE *fp);
2.147 -
2.148 -int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename);
2.149 -int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname);
2.150 -int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line);
2.151 -
2.152 -int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address);
2.153 -int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address);
2.154 -int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name);
2.155 -int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name);
2.156 -int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name);
2.157 -int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym);
2.158 -int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim);
2.159 -
2.160 -
2.161 -#if !defined AMX_NO_ALIGN
2.162 - #if defined LINUX || defined __FreeBSD__
2.163 - #pragma pack() /* reset default packing */
2.164 - #elif defined MACOS && defined __MWERKS__
2.165 - #pragma options align=reset
2.166 - #else
2.167 - #pragma pack(pop) /* reset previous packing */
2.168 - #endif
2.169 -#endif
2.170 -
2.171 -#ifdef __cplusplus
2.172 -}
2.173 -#endif
2.174 -
2.175 -#endif /* AMXDBG_H_INCLUDED */
3.1 --- a/compiler-init/libpawnc.c Sat Jul 15 05:02:38 2006 +0000
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,262 +0,0 @@
3.4 -/* LIBPAWNC.C
3.5 - *
3.6 - * A "glue file" for building the Pawn compiler as a DLL or shared library.
3.7 - *
3.8 - * Copyright (c) ITB CompuPhase, 2000-2006
3.9 - *
3.10 - * This software is provided "as-is", without any express or implied warranty.
3.11 - * In no event will the authors be held liable for any damages arising from
3.12 - * the use of this software.
3.13 - *
3.14 - * Permission is granted to anyone to use this software for any purpose,
3.15 - * including commercial applications, and to alter it and redistribute it
3.16 - * freely, subject to the following restrictions:
3.17 - *
3.18 - * 1. The origin of this software must not be misrepresented; you must not
3.19 - * claim that you wrote the original software. If you use this software in
3.20 - * a product, an acknowledgment in the product documentation would be
3.21 - * appreciated but is not required.
3.22 - * 2. Altered source versions must be plainly marked as such, and must not be
3.23 - * misrepresented as being the original software.
3.24 - * 3. This notice may not be removed or altered from any source distribution.
3.25 - *
3.26 - * Version: $Id: libsc.c 3114 2005-03-17 14:48:29Z thiadmer $
3.27 - */
3.28 -#include <assert.h>
3.29 -#include <stdio.h>
3.30 -#include <stdlib.h>
3.31 -#include <string.h>
3.32 -#include <malloc.h>
3.33 -#include "sc.h"
3.34 -#include "memfile.h"
3.35 -
3.36 -/* pc_printf()
3.37 - * Called for general purpose "console" output. This function prints general
3.38 - * purpose messages; errors go through pc_error(). The function is modelled
3.39 - * after printf().
3.40 - */
3.41 -int pc_printf(const char *message,...)
3.42 -{
3.43 - int ret;
3.44 - va_list argptr;
3.45 -
3.46 - va_start(argptr,message);
3.47 - ret=vprintf(message,argptr);
3.48 - va_end(argptr);
3.49 -
3.50 - return ret;
3.51 -}
3.52 -
3.53 -/* pc_error()
3.54 - * Called for producing error output.
3.55 - * number the error number (as documented in the manual)
3.56 - * message a string describing the error with embedded %d and %s tokens
3.57 - * filename the name of the file currently being parsed
3.58 - * firstline the line number at which the expression started on which
3.59 - * the error was found, or -1 if there is no "starting line"
3.60 - * lastline the line number at which the error was detected
3.61 - * argptr a pointer to the first of a series of arguments (for macro
3.62 - * "va_arg")
3.63 - * Return:
3.64 - * If the function returns 0, the parser attempts to continue compilation.
3.65 - * On a non-zero return value, the parser aborts.
3.66 - */
3.67 -int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr)
3.68 -{
3.69 -static char *prefix[3]={ "error", "fatal error", "warning" };
3.70 -
3.71 - if (number!=0) {
3.72 - char *pre;
3.73 -
3.74 - pre=prefix[number/100];
3.75 - if (firstline>=0)
3.76 - fprintf(stderr,"%s(%d -- %d) : %s %03d: ",filename,firstline,lastline,pre,number);
3.77 - else
3.78 - fprintf(stderr,"%s(%d) : %s %03d: ",filename,lastline,pre,number);
3.79 - } /* if */
3.80 - vfprintf(stderr,message,argptr);
3.81 - fflush(stderr);
3.82 - return 0;
3.83 -}
3.84 -
3.85 -/* pc_opensrc()
3.86 - * Opens a source file (or include file) for reading. The "file" does not have
3.87 - * to be a physical file, one might compile from memory.
3.88 - * filename the name of the "file" to read from
3.89 - * Return:
3.90 - * The function must return a pointer, which is used as a "magic cookie" to
3.91 - * all I/O functions. When failing to open the file for reading, the
3.92 - * function must return NULL.
3.93 - * Note:
3.94 - * Several "source files" may be open at the same time. Specifically, one
3.95 - * file can be open for reading and another for writing.
3.96 - */
3.97 -void *pc_opensrc(char *filename)
3.98 -{
3.99 - return fopen(filename,"rt");
3.100 -}
3.101 -
3.102 -/* pc_createsrc()
3.103 - * Creates/overwrites a source file for writing. The "file" does not have
3.104 - * to be a physical file, one might compile from memory.
3.105 - * filename the name of the "file" to create
3.106 - * Return:
3.107 - * The function must return a pointer which is used as a "magic cookie" to
3.108 - * all I/O functions. When failing to open the file for reading, the
3.109 - * function must return NULL.
3.110 - * Note:
3.111 - * Several "source files" may be open at the same time. Specifically, one
3.112 - * file can be open for reading and another for writing.
3.113 - */
3.114 -void *pc_createsrc(char *filename)
3.115 -{
3.116 - return fopen(filename,"wt");
3.117 -}
3.118 -
3.119 -/* pc_closesrc()
3.120 - * Closes a source file (or include file). The "handle" parameter has the
3.121 - * value that pc_opensrc() returned in an earlier call.
3.122 - */
3.123 -void pc_closesrc(void *handle)
3.124 -{
3.125 - assert(handle!=NULL);
3.126 - fclose((FILE*)handle);
3.127 -}
3.128 -
3.129 -/* pc_resetsrc()
3.130 - * "position" may only hold a pointer that was previously obtained from
3.131 - * pc_getpossrc()
3.132 - */
3.133 -void pc_resetsrc(void *handle,void *position)
3.134 -{
3.135 - assert(handle!=NULL);
3.136 - fsetpos((FILE*)handle,(fpos_t *)position);
3.137 -}
3.138 -
3.139 -/* pc_readsrc()
3.140 - * Reads a single line from the source file (or up to a maximum number of
3.141 - * characters if the line in the input file is too long).
3.142 - */
3.143 -char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
3.144 -{
3.145 - return fgets((char*)target,maxchars,(FILE*)handle);
3.146 -}
3.147 -
3.148 -/* pc_writesrc()
3.149 - * Writes to to the source file. There is no automatic line ending; to end a
3.150 - * line, write a "\n".
3.151 - */
3.152 -int pc_writesrc(void *handle,unsigned char *source)
3.153 -{
3.154 - return fputs((char*)source,(FILE*)handle) >= 0;
3.155 -}
3.156 -
3.157 -void *pc_getpossrc(void *handle)
3.158 -{
3.159 - static fpos_t lastpos; /* may need to have a LIFO stack of such positions */
3.160 -
3.161 - fgetpos((FILE*)handle,&lastpos);
3.162 - return &lastpos;
3.163 -}
3.164 -
3.165 -int pc_eofsrc(void *handle)
3.166 -{
3.167 - return feof((FILE*)handle);
3.168 -}
3.169 -
3.170 -/* should return a pointer, which is used as a "magic cookie" to all I/O
3.171 - * functions; return NULL for failure
3.172 - */
3.173 -void *pc_openasm(char *filename)
3.174 -{
3.175 - #if defined __MSDOS__ || defined SC_LIGHT
3.176 - return fopen(filename,"w+t");
3.177 - #else
3.178 - return mfcreate(filename);
3.179 - #endif
3.180 -}
3.181 -
3.182 -void pc_closeasm(void *handle, int deletefile)
3.183 -{
3.184 - #if defined __MSDOS__ || defined SC_LIGHT
3.185 - if (handle!=NULL)
3.186 - fclose((FILE*)handle);
3.187 - if (deletefile)
3.188 - remove(outfname);
3.189 - #else
3.190 - if (handle!=NULL) {
3.191 - if (!deletefile)
3.192 - mfdump((MEMFILE*)handle);
3.193 - mfclose((MEMFILE*)handle);
3.194 - } /* if */
3.195 - #endif
3.196 -}
3.197 -
3.198 -void pc_resetasm(void *handle)
3.199 -{
3.200 - assert(handle!=NULL);
3.201 - #if defined __MSDOS__ || defined SC_LIGHT
3.202 - fflush((FILE*)handle);
3.203 - fseek((FILE*)handle,0,SEEK_SET);
3.204 - #else
3.205 - mfseek((MEMFILE*)handle,0,SEEK_SET);
3.206 - #endif
3.207 -}
3.208 -
3.209 -int pc_writeasm(void *handle,char *string)
3.210 -{
3.211 - #if defined __MSDOS__ || defined SC_LIGHT
3.212 - return fputs(string,(FILE*)handle) >= 0;
3.213 - #else
3.214 - return mfputs((MEMFILE*)handle,string);
3.215 - #endif
3.216 -}
3.217 -
3.218 -char *pc_readasm(void *handle, char *string, int maxchars)
3.219 -{
3.220 - #if defined __MSDOS__ || defined SC_LIGHT
3.221 - return fgets(string,maxchars,(FILE*)handle);
3.222 - #else
3.223 - return mfgets((MEMFILE*)handle,string,maxchars);
3.224 - #endif
3.225 -}
3.226 -
3.227 -extern memfile_t *bin_file;
3.228 -
3.229 -/* Should return a pointer, which is used as a "magic cookie" to all I/O
3.230 - * functions; return NULL for failure.
3.231 - */
3.232 -void *pc_openbin(char *filename)
3.233 -{
3.234 - return memfile_creat(filename, 1);
3.235 -}
3.236 -
3.237 -void pc_closebin(void *handle,int deletefile)
3.238 -{
3.239 - if (deletefile)
3.240 - {
3.241 - memfile_destroy((memfile_t *)handle);
3.242 - bin_file = NULL;
3.243 - } else {
3.244 - bin_file = (memfile_t *)handle;
3.245 - }
3.246 -}
3.247 -
3.248 -/* pc_resetbin()
3.249 - * Can seek to any location in the file.
3.250 - * The offset is always from the start of the file.
3.251 - */
3.252 -void pc_resetbin(void *handle,long offset)
3.253 -{
3.254 - memfile_seek((memfile_t *)handle, offset);
3.255 -}
3.256 -
3.257 -int pc_writebin(void *handle,void *buffer,int size)
3.258 -{
3.259 - return memfile_write((memfile_t *)handle, buffer, size);
3.260 -}
3.261 -
3.262 -long pc_lengthbin(void *handle)
3.263 -{
3.264 - return memfile_tell((memfile_t *)handle);
3.265 -}
4.1 --- a/compiler-init/libpawnc.rc Sat Jul 15 05:02:38 2006 +0000
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,55 +0,0 @@
4.4 -#include <windows.h>
4.5 -#if defined WIN32 || defined _WIN32 || defined __WIN32__
4.6 -# include <winver.h>
4.7 -#else
4.8 -# include <ver.h>
4.9 -#endif
4.10 -#include "svnrev.h"
4.11 -
4.12 -AppIcon ICON "pawn.ico"
4.13 -
4.14 -/* Version information
4.15 - *
4.16 - * All strings MUST have an explicit \0. See the Windows SDK documentation
4.17 - * for details on version information and the VERSIONINFO structure.
4.18 - */
4.19 -#define VERSION SMC_VERSION
4.20 -#define REVISION SMC_REVISION
4.21 -#define BUILD SMC_BUILD
4.22 -#define VERSIONSTR SMC_VERSTRING
4.23 -#define VERSIONNAME "smcomp.exe\0"
4.24 -#define VERSIONDESCRIPTION "SourcePawn Compiler\0"
4.25 -#define VERSIONPRODUCTNAME "smcomp\0"
4.26 -
4.27 -VS_VERSION_INFO VERSIONINFO
4.28 -FILEVERSION VERSION, REVISION, BUILD, 0
4.29 -PRODUCTVERSION VERSION, REVISION, BUILD, 0
4.30 -FILEFLAGSMASK 0x0000003FL
4.31 -FILEFLAGS 0
4.32 -#if defined(WIN32)
4.33 - FILEOS VOS__WINDOWS32
4.34 -#else
4.35 - FILEOS VOS__WINDOWS16
4.36 -#endif
4.37 -FILETYPE VFT_DLL
4.38 -BEGIN
4.39 - BLOCK "StringFileInfo"
4.40 - BEGIN
4.41 - BLOCK "040904E4"
4.42 - BEGIN
4.43 - VALUE "CompanyName", "(C)1998-2006 ITB CompuPhase, AlliedModders LLC\0"
4.44 - VALUE "FileDescription", VERSIONDESCRIPTION
4.45 - VALUE "FileVersion", VERSIONSTR
4.46 - VALUE "InternalName", VERSIONNAME
4.47 - VALUE "LegalCopyright", "(C)1998-2006 ITB CompuPhase, AlliedModders LLC\0"
4.48 - VALUE "OriginalFilename", VERSIONNAME
4.49 - VALUE "ProductName", VERSIONPRODUCTNAME
4.50 - VALUE "ProductVersion", VERSIONSTR
4.51 - END
4.52 - END
4.53 -
4.54 - BLOCK "VarFileInfo"
4.55 - BEGIN
4.56 - VALUE "Translation", 0x409, 1252
4.57 - END
4.58 -END
5.1 --- a/compiler-init/lstring.c Sat Jul 15 05:02:38 2006 +0000
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,124 +0,0 @@
5.4 -/* Safe string copying and concatenation
5.5 - * These routines are originally distributed in two separate files. I have
5.6 - * copied the files verbatim in this single source file, including all comments.
5.7 - * The only change is that the second set of include files is commented out
5.8 - * (there is no need to include the same files twice).
5.9 - */
5.10 -
5.11 -#include "lstring.h"
5.12 -
5.13 -#if !defined HAVE_SAFESTR
5.14 -
5.15 -/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
5.16 -
5.17 -/*
5.18 - * Copyright (c) 1998 Todd C. Miller <[email protected]>
5.19 - *
5.20 - * Permission to use, copy, modify, and distribute this software for any
5.21 - * purpose with or without fee is hereby granted, provided that the above
5.22 - * copyright notice and this permission notice appear in all copies.
5.23 - *
5.24 - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
5.25 - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
5.26 - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
5.27 - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
5.28 - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
5.29 - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
5.30 - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5.31 - */
5.32 -
5.33 -/*
5.34 - #include <sys/types.h> already included through lstring.h
5.35 - */
5.36 -#include <string.h> /* for strlen() */
5.37 -
5.38 -/*
5.39 - * Copy src to string dst of size siz. At most siz-1 characters
5.40 - * will be copied. Always NUL terminates (unless siz == 0).
5.41 - * Returns strlen(src); if retval >= siz, truncation occurred.
5.42 - */
5.43 -size_t
5.44 -strlcpy(char *dst, const char *src, size_t siz)
5.45 -{
5.46 - char *d = dst;
5.47 - const char *s = src;
5.48 - size_t n = siz;
5.49 -
5.50 - /* Copy as many bytes as will fit */
5.51 - if (n != 0 && --n != 0) {
5.52 - do {
5.53 - if ((*d++ = *s++) == 0)
5.54 - break;
5.55 - } while (--n != 0);
5.56 - }
5.57 -
5.58 - /* Not enough room in dst, add NUL and traverse rest of src */
5.59 - if (n == 0) {
5.60 - if (siz != 0)
5.61 - *d = '\0'; /* NUL-terminate dst */
5.62 - while (*s++)
5.63 - ;
5.64 - }
5.65 -
5.66 - return(s - src - 1); /* count does not include NUL */
5.67 -}
5.68 -
5.69 -/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
5.70 -
5.71 -/*
5.72 - * Copyright (c) 1998 Todd C. Miller <[email protected]>
5.73 - *
5.74 - * Permission to use, copy, modify, and distribute this software for any
5.75 - * purpose with or without fee is hereby granted, provided that the above
5.76 - * copyright notice and this permission notice appear in all copies.
5.77 - *
5.78 - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
5.79 - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
5.80 - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
5.81 - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
5.82 - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
5.83 - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
5.84 - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5.85 - */
5.86 -
5.87 -/*
5.88 - #include <sys/types.h> already included
5.89 - #include <string.h> already included
5.90 -*/
5.91 -
5.92 -/*
5.93 - * Appends src to string dst of size siz (unlike strncat, siz is the
5.94 - * full size of dst, not space left). At most siz-1 characters
5.95 - * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
5.96 - * Returns strlen(src) + MIN(siz, strlen(initial dst)).
5.97 - * If retval >= siz, truncation occurred.
5.98 - */
5.99 -size_t
5.100 -strlcat(char *dst, const char *src, size_t siz)
5.101 -{
5.102 - char *d = dst;
5.103 - const char *s = src;
5.104 - size_t n = siz;
5.105 - size_t dlen;
5.106 -
5.107 - /* Find the end of dst and adjust bytes left but don't go past end */
5.108 - while (n-- != 0 && *d != '\0')
5.109 - d++;
5.110 - dlen = d - dst;
5.111 - n = siz - dlen;
5.112 -
5.113 - if (n == 0)
5.114 - return(dlen + strlen(s));
5.115 - while (*s != '\0') {
5.116 - if (n != 1) {
5.117 - *d++ = *s;
5.118 - n--;
5.119 - }
5.120 - s++;
5.121 - }
5.122 - *d = '\0';
5.123 -
5.124 - return(dlen + (s - src)); /* count does not include NUL */
5.125 -}
5.126 -
5.127 -#endif /* #if !defined HAVE_SAFESTR */
6.1 --- a/compiler-init/lstring.h Sat Jul 15 05:02:38 2006 +0000
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,18 +0,0 @@
6.4 -/* prototypes for strlcpy() and strlcat() */
6.5 -
6.6 -#include <stddef.h>
6.7 -
6.8 -#if defined __WATCOMC__ && __WATCOMC__ >= 1240
6.9 - /* OpenWatcom introduced BSD "safe string functions" with version 1.4 */
6.10 - #define HAVE_SAFESTR
6.11 -#endif
6.12 -
6.13 -#if !defined HAVE_SAFESTR
6.14 -
6.15 -size_t
6.16 -strlcpy(char *dst, const char *src, size_t siz);
6.17 -
6.18 -size_t
6.19 -strlcat(char *dst, const char *src, size_t siz);
6.20 -
6.21 -#endif
7.1 --- a/compiler-init/memfile.c Sat Jul 15 05:02:38 2006 +0000
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,105 +0,0 @@
7.4 -#include "memfile.h"
7.5 -#include <string.h>
7.6 -#include "osdefs.h"
7.7 -
7.8 -memfile_t *memfile_creat(const char *name, size_t init)
7.9 -{
7.10 - memfile_t mf;
7.11 - memfile_t *pmf;
7.12 -
7.13 - mf.size = init;
7.14 - mf.base = (char *)malloc(init);
7.15 - mf.usedoffs = 0;
7.16 - if (!mf.base)
7.17 - {
7.18 - return NULL;
7.19 - }
7.20 -
7.21 - mf.offs = 0;
7.22 - mf._static = 0;
7.23 -
7.24 - pmf = (memfile_t *)malloc(sizeof(memfile_t));
7.25 - memcpy(pmf, &mf, sizeof(memfile_t));
7.26 -
7.27 - pmf->name = strdup(name);
7.28 -
7.29 - return pmf;
7.30 -}
7.31 -
7.32 -void memfile_destroy(memfile_t *mf)
7.33 -{
7.34 - if (!mf->_static)
7.35 - {
7.36 - free(mf->name);
7.37 - free(mf->base);
7.38 - free(mf);
7.39 - }
7.40 -}
7.41 -
7.42 -void memfile_seek(memfile_t *mf, long seek)
7.43 -{
7.44 - mf->offs = seek;
7.45 -}
7.46 -
7.47 -long memfile_tell(memfile_t *mf)
7.48 -{
7.49 - return mf->offs;
7.50 -}
7.51 -
7.52 -size_t memfile_read(memfile_t *mf, void *buffer, size_t maxsize)
7.53 -{
7.54 - if (!maxsize || mf->offs >= mf->usedoffs)
7.55 - {
7.56 - return 0;
7.57 - }
7.58 -
7.59 - if (mf->usedoffs - mf->offs < (long)maxsize)
7.60 - {
7.61 - maxsize = mf->usedoffs - mf->offs;
7.62 - if (!maxsize)
7.63 - {
7.64 - return 0;
7.65 - }
7.66 - }
7.67 -
7.68 - memcpy(buffer, mf->base + mf->offs, maxsize);
7.69 -
7.70 - mf->offs += maxsize;
7.71 -
7.72 - return maxsize;
7.73 -}
7.74 -
7.75 -int memfile_write(memfile_t *mf, void *buffer, size_t size)
7.76 -{
7.77 - if (mf->offs + size > mf->size)
7.78 - {
7.79 - size_t newsize = (mf->size + size) * 2;
7.80 - if (mf->_static)
7.81 - {
7.82 - char *oldbase = mf->base;
7.83 - mf->base = (char *)malloc(newsize);
7.84 - if (!mf->base)
7.85 - {
7.86 - return 0;
7.87 - }
7.88 - memcpy(mf->base, oldbase, mf->size);
7.89 - } else {
7.90 - mf->base = (char *)realloc(mf->base, newsize);
7.91 - if (!mf->base)
7.92 - {
7.93 - return 0;
7.94 - }
7.95 - }
7.96 - mf->_static = 0;
7.97 - mf->size = newsize;
7.98 - }
7.99 - memcpy(mf->base + mf->offs, buffer, size);
7.100 - mf->offs += size;
7.101 -
7.102 - if (mf->offs > mf->usedoffs)
7.103 - {
7.104 - mf->usedoffs = mf->offs;
7.105 - }
7.106 -
7.107 - return 1;
7.108 -}
8.1 --- a/compiler-init/memfile.h Sat Jul 15 05:02:38 2006 +0000
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,23 +0,0 @@
8.4 -#ifndef _INCLUDE_MEMFILE_H
8.5 -#define _INCLUDE_MEMFILE_H
8.6 -
8.7 -#include <malloc.h>
8.8 -
8.9 -typedef struct memfile_s
8.10 -{
8.11 - char *name;
8.12 - char *base;
8.13 - long offs;
8.14 - long usedoffs;
8.15 - size_t size;
8.16 - int _static;
8.17 -} memfile_t;
8.18 -
8.19 -memfile_t *memfile_creat(const char *name, size_t init);
8.20 -void memfile_destroy(memfile_t *mf);
8.21 -void memfile_seek(memfile_t *mf, long seek);
8.22 -int memfile_write(memfile_t *mf, void *buffer, size_t size);
8.23 -size_t memfile_read(memfile_t *mf, void *buffer, size_t maxsize);
8.24 -long memfile_tell(memfile_t *mf);
8.25 -
8.26 -#endif //_INCLUDE_MEMFILE_H
9.1 --- a/compiler-init/osdefs.h Sat Jul 15 05:02:38 2006 +0000
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,109 +0,0 @@
9.4 -/* __MSDOS__ set when compiling for DOS (not Windows)
9.5 - * _Windows set when compiling for any version of Microsoft Windows
9.6 - * __WIN32__ set when compiling for Windows95 or WindowsNT (32 bit mode)
9.7 - * __32BIT__ set when compiling in 32-bit "flat" mode (DOS or Windows)
9.8 - *
9.9 - * Copyright 1998-2005, ITB CompuPhase, The Netherlands.
9.10 - * [email protected].
9.11 - */
9.12 -
9.13 -#ifndef _OSDEFS_H
9.14 -#define _OSDEFS_H
9.15 -
9.16 -/* Every compiler uses different "default" macros to indicate the mode
9.17 - * it is in. Throughout the source, we use the Borland C++ macros, so
9.18 - * the macros of Watcom C/C++ and Microsoft Visual C/C++ are mapped to
9.19 - * those of Borland C++.
9.20 - */
9.21 -#if defined(__WATCOMC__)
9.22 -# if defined(__WINDOWS__) || defined(__NT__)
9.23 -# define _Windows 1
9.24 -# endif
9.25 -# ifdef __386__
9.26 -# define __32BIT__ 1
9.27 -# endif
9.28 -# if defined(_Windows) && defined(__32BIT__)
9.29 -# define __WIN32__ 1
9.30 -# endif
9.31 -#elif defined(_MSC_VER)
9.32 -# if defined(_WINDOWS) || defined(_WIN32)
9.33 -# define _Windows 1
9.34 -# endif
9.35 -# ifdef _WIN32
9.36 -# define __WIN32__ 1
9.37 -# define __32BIT__ 1
9.38 -# endif
9.39 -# if _MSC_VER >= 1400
9.40 -# if !defined _CRT_SECURE_NO_DEPRECATE
9.41 -# define _CRT_SECURE_NO_DEPRECATE
9.42 -# endif
9.43 -# define strdup _strdup
9.44 -# define stricmp _stricmp
9.45 -# define access _access
9.46 -# define chdir _chdir
9.47 -# define strdup _strdup
9.48 -# define unlink _unlink
9.49 -# endif
9.50 -#endif
9.51 -
9.52 -#if defined __FreeBSD__
9.53 - #include <sys/endian.h>
9.54 -#elif defined LINUX
9.55 - #include <endian.h>
9.56 -#endif
9.57 -
9.58 -/* Linux NOW has these */
9.59 -#if !defined BIG_ENDIAN
9.60 - #define BIG_ENDIAN 4321
9.61 -#endif
9.62 -#if !defined LITTLE_ENDIAN
9.63 - #define LITTLE_ENDIAN 1234
9.64 -#endif
9.65 -
9.66 -/* educated guess, BYTE_ORDER is undefined, i386 is common => little endian */
9.67 -#if !defined BYTE_ORDER
9.68 - #if defined UCLINUX
9.69 - #define BYTE_ORDER BIG_ENDIAN
9.70 - #else
9.71 - #define BYTE_ORDER LITTLE_ENDIAN
9.72 - #endif
9.73 -#endif
9.74 -
9.75 -#if defined __MSDOS__ || defined __WIN32__ || defined _Windows
9.76 - #define DIRSEP_CHAR '\\'
9.77 -#elif defined macintosh
9.78 - #define DIRSEP_CHAR ':'
9.79 -#else
9.80 - #define DIRSEP_CHAR '/' /* directory separator character */
9.81 -#endif
9.82 -
9.83 -/* _MAX_PATH is sometimes called differently and it may be in limits.h or
9.84 - * stdlib.h instead of stdio.h.
9.85 - */
9.86 -#if !defined _MAX_PATH
9.87 - /* not defined, perhaps stdio.h was not included */
9.88 - #if !defined PATH_MAX
9.89 - #include <stdio.h>
9.90 - #endif
9.91 - #if !defined _MAX_PATH && !defined PATH_MAX
9.92 - /* no _MAX_PATH and no MAX_PATH, perhaps it is in limits.h */
9.93 - #include <limits.h>
9.94 - #endif
9.95 - #if !defined _MAX_PATH && !defined PATH_MAX
9.96 - /* no _MAX_PATH and no MAX_PATH, perhaps it is in stdlib.h */
9.97 - #include <stdlib.h>
9.98 - #endif
9.99 - /* if _MAX_PATH is undefined, try common alternative names */
9.100 - #if !defined _MAX_PATH
9.101 - #if defined MAX_PATH
9.102 - #define _MAX_PATH MAX_PATH
9.103 - #elif defined _POSIX_PATH_MAX
9.104 - #define _MAX_PATH _POSIX_PATH_MAX
9.105 - #else
9.106 - /* everything failed, actually we have a problem here... */
9.107 - #define _MAX_PATH 1024
9.108 - #endif
9.109 - #endif
9.110 -#endif
9.111 -
9.112 -#endif /* _OSDEFS_H */
10.1 Binary file compiler-init/pawn.ico has changed
11.1 --- a/compiler-init/pawncc.c Sat Jul 15 05:02:38 2006 +0000
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,550 +0,0 @@
11.4 -#include <stdio.h>
11.5 -#include <setjmp.h>
11.6 -#include <assert.h>
11.7 -#include <string.h>
11.8 -#include "memfile.h"
11.9 -#include "sp_file.h"
11.10 -#include "amx.h"
11.11 -#include "osdefs.h"
11.12 -#include "zlib/zlib.h"
11.13 -
11.14 -#define NUM_SECTIONS 6
11.15 -
11.16 -int pc_printf(const char *message,...);
11.17 -int pc_compile(int argc, char **argv);
11.18 -void sfwrite(const void *buf, size_t size, size_t count, FILE *fp);
11.19 -
11.20 -memfile_t *bin_file = NULL;
11.21 -jmp_buf brkout;
11.22 -
11.23 -int main(int argc, char *argv[])
11.24 -{
11.25 - if (pc_compile(argc,argv) == 0)
11.26 - {
11.27 - FILE *fp;
11.28 - AMX_HEADER *hdr;
11.29 - sp_file_hdr_t shdr;
11.30 - uint32_t curoffs = 0;
11.31 - uint32_t lastsection = 0;
11.32 - int err;
11.33 - uint8_t i8;
11.34 - uint32_t i;
11.35 - const char *tables[NUM_SECTIONS] = {".code", ".data", ".publics", ".pubvars", ".natives", ".names"};
11.36 - uint32_t offsets[NUM_SECTIONS] = {0,0,0,0,0,0};
11.37 - sp_file_section_t sh;
11.38 -
11.39 - if (bin_file == NULL)
11.40 - {
11.41 - return 0;
11.42 - }
11.43 -
11.44 - hdr = (AMX_HEADER *)bin_file->base;
11.45 - shdr.version = SPFILE_VERSION;
11.46 - shdr.magic = SPFILE_MAGIC;
11.47 -
11.48 - if ((fp=fopen(bin_file->name, "wb")) == NULL)
11.49 - {
11.50 - pc_printf("Error writing to file: %s", bin_file->name);
11.51 - return 1;
11.52 - }
11.53 -
11.54 - if ((err=setjmp(brkout))!=0)
11.55 - {
11.56 - goto write_error;
11.57 - }
11.58 -
11.59 - shdr.sections = NUM_SECTIONS;
11.60 - shdr.stringtab = sizeof(shdr) + (sizeof(sp_file_section_t) * shdr.sections);
11.61 -
11.62 - /**
11.63 - * write the header
11.64 - * unwritten values:
11.65 - * imagesize
11.66 - */
11.67 - sfwrite(&shdr, sizeof(shdr), 1, fp);
11.68 -
11.69 - curoffs = shdr.stringtab;
11.70 -
11.71 - /**
11.72 - * write the sections
11.73 - * unwritten values:
11.74 - * dataoffs
11.75 - * size
11.76 - */
11.77 - for (i8=0; i8<shdr.sections; i8++)
11.78 - {
11.79 - /* set name offset to next in string table */
11.80 - sh.nameoffs = curoffs - shdr.stringtab;
11.81 - /* save offset to this section */
11.82 - offsets[i8] = (uint32_t)ftell(fp) + sizeof(sh.nameoffs);
11.83 - /* update `end of file` offset */
11.84 - curoffs += strlen(tables[i8]) + 1;
11.85 - sfwrite(&sh, sizeof(sh), 1, fp);
11.86 - }
11.87 -
11.88 - /** write the string table */
11.89 - for (i8=0; i8<shdr.sections; i8++)
11.90 - {
11.91 - sfwrite(tables[i8], 1, strlen(tables[i8])+1, fp);
11.92 - }
11.93 -
11.94 - lastsection = curoffs;
11.95 -
11.96 - /**
11.97 - * Begin writing each of our known tables out
11.98 - */
11.99 -
11.100 - if (strcmp(tables[0], ".code") == 0)
11.101 - {
11.102 - sp_file_code_t cod;
11.103 - cell cip;
11.104 - unsigned char *cbase;
11.105 - uint8_t *tbase, *tptr;
11.106 - cell real_codesize;
11.107 - uint8_t op;
11.108 -
11.109 - cod.cellsize = sizeof(cell);
11.110 -
11.111 - cod.codesize = 0;
11.112 - cod.codeversion = hdr->amx_version;
11.113 - cod.flags = 0;
11.114 - if (hdr->flags & AMX_FLAG_DEBUG)
11.115 - {
11.116 - cod.flags |= SP_FILE_DEBUG;
11.117 - }
11.118 - cod.code = sizeof(cod);
11.119 - cod.main = hdr->cip;
11.120 -
11.121 - /* write the code in our newer format */
11.122 - cbase = (unsigned char *)hdr + hdr->cod;
11.123 - real_codesize = hdr->dat - hdr->cod;
11.124 - tbase = (uint8_t *)malloc(real_codesize);
11.125 - tptr = tbase;
11.126 - for (cip = 0; cip < real_codesize;)
11.127 - {
11.128 -#define DBGPARAM(v) ( (v)=*(cell *)(cbase+(int)cip), cip+=sizeof(cell) )
11.129 - op=(uint8_t) *(ucell *)(cbase+(int)cip);
11.130 - cip += sizeof(cell);
11.131 - *tptr++ = op;
11.132 - switch (op)
11.133 - {
11.134 - case OP_PUSH5_C: /* instructions with 5 parameters */
11.135 - case OP_PUSH5:
11.136 - case OP_PUSH5_S:
11.137 - case OP_PUSH5_ADR:
11.138 - {
11.139 - memcpy(tptr, cbase+(int)cip, sizeof(cell)*5);
11.140 - cip += sizeof(cell)*5;
11.141 - tptr += sizeof(cell)*5;
11.142 - break;
11.143 - }
11.144 - case OP_PUSH4_C: /* instructions with 4 parameters */
11.145 - case OP_PUSH4:
11.146 - case OP_PUSH4_S:
11.147 - case OP_PUSH4_ADR:
11.148 - {
11.149 - memcpy(tptr, cbase+(int)cip, sizeof(cell)*4);
11.150 - cip += sizeof(cell)*4;
11.151 - tptr += sizeof(cell)*4;
11.152 - break;
11.153 - }
11.154 - case OP_PUSH3_C: /* instructions with 3 parameters */
11.155 - case OP_PUSH3:
11.156 - case OP_PUSH3_S:
11.157 - case OP_PUSH3_ADR:
11.158 - {
11.159 - memcpy(tptr, cbase+(int)cip, sizeof(cell)*3);
11.160 - cip += sizeof(cell)*3;
11.161 - tptr += sizeof(cell)*3;
11.162 - break;
11.163 - }
11.164 - case OP_PUSH2_C: /* instructions with 2 parameters */
11.165 - case OP_PUSH2:
11.166 - case OP_PUSH2_S:
11.167 - case OP_PUSH2_ADR:
11.168 - case OP_LOAD_BOTH:
11.169 - case OP_LOAD_S_BOTH:
11.170 - case OP_CONST:
11.171 - case OP_CONST_S:
11.172 - case OP_SYSREQ_N:
11.173 - {
11.174 - memcpy(tptr, cbase+(int)cip, sizeof(cell)*2);
11.175 - cip += sizeof(cell)*2;
11.176 - tptr += sizeof(cell)*2;
11.177 - break;
11.178 - }
11.179 - case OP_LOAD_PRI: /* instructions with 1 parameter */
11.180 - case OP_LOAD_ALT:
11.181 - case OP_LOAD_S_PRI:
11.182 - case OP_LOAD_S_ALT:
11.183 - case OP_LREF_PRI:
11.184 - case OP_LREF_ALT:
11.185 - case OP_LREF_S_PRI:
11.186 - case OP_LREF_S_ALT:
11.187 - case OP_LODB_I:
11.188 - case OP_CONST_PRI:
11.189 - case OP_CONST_ALT:
11.190 - case OP_ADDR_PRI:
11.191 - case OP_ADDR_ALT:
11.192 - case OP_STOR_PRI:
11.193 - case OP_STOR_ALT:
11.194 - case OP_STOR_S_PRI:
11.195 - case OP_STOR_S_ALT:
11.196 - case OP_SREF_PRI:
11.197 - case OP_SREF_ALT:
11.198 - case OP_SREF_S_PRI:
11.199 - case OP_SREF_S_ALT:
11.200 - case OP_STRB_I:
11.201 - case OP_LIDX_B:
11.202 - case OP_IDXADDR_B:
11.203 - case OP_ALIGN_PRI:
11.204 - case OP_ALIGN_ALT:
11.205 - case OP_LCTRL:
11.206 - case OP_SCTRL:
11.207 - case OP_PUSH_R:
11.208 - case OP_PUSH_C:
11.209 - case OP_PUSH:
11.210 - case OP_PUSH_S:
11.211 - case OP_STACK:
11.212 - case OP_HEAP:
11.213 - case OP_JREL:
11.214 - case OP_SHL_C_PRI:
11.215 - case OP_SHL_C_ALT:
11.216 - case OP_SHR_C_PRI:
11.217 - case OP_SHR_C_ALT:
11.218 - case OP_ADD_C:
11.219 - case OP_SMUL_C:
11.220 - case OP_ZERO:
11.221 - case OP_ZERO_S:
11.222 - case OP_EQ_C_PRI:
11.223 - case OP_EQ_C_ALT:
11.224 - case OP_INC:
11.225 - case OP_INC_S:
11.226 - case OP_DEC:
11.227 - case OP_DEC_S:
11.228 - case OP_MOVS:
11.229 - case OP_CMPS:
11.230 - case OP_FILL:
11.231 - case OP_HALT:
11.232 - case OP_BOUNDS:
11.233 - case OP_PUSH_ADR:
11.234 - case OP_CALL: /* opcodes that need relocation */
11.235 - case OP_JUMP:
11.236 - case OP_JZER:
11.237 - case OP_JNZ:
11.238 - case OP_JEQ:
11.239 - case OP_JNEQ:
11.240 - case OP_JLESS:
11.241 - case OP_JLEQ:
11.242 - case OP_JGRTR:
11.243 - case OP_JGEQ:
11.244 - case OP_JSLESS:
11.245 - case OP_JSLEQ:
11.246 - case OP_JSGRTR:
11.247 - case OP_JSGEQ:
11.248 - case OP_SWITCH:
11.249 - case OP_SYSREQ_C:
11.250 - {
11.251 - *(cell *)tptr = *(cell *)(cbase + (int)cip);
11.252 - cip += sizeof(cell);
11.253 - tptr += sizeof(cell);
11.254 - break;
11.255 - }
11.256 - case OP_LOAD_I: /* instructions without parameters */
11.257 - case OP_STOR_I:
11.258 - case OP_LIDX:
11.259 - case OP_IDXADDR:
11.260 - case OP_MOVE_PRI:
11.261 - case OP_MOVE_ALT:
11.262 - case OP_XCHG:
11.263 - case OP_PUSH_PRI:
11.264 - case OP_PUSH_ALT:
11.265 - case OP_POP_PRI:
11.266 - case OP_POP_ALT:
11.267 - case OP_PROC:
11.268 - case OP_RET:
11.269 - case OP_RETN:
11.270 - case OP_CALL_PRI:
11.271 - case OP_SHL:
11.272 - case OP_SHR:
11.273 - case OP_SSHR:
11.274 - case OP_SMUL:
11.275 - case OP_SDIV:
11.276 - case OP_SDIV_ALT:
11.277 - case OP_UMUL:
11.278 - case OP_UDIV:
11.279 - case OP_UDIV_ALT:
11.280 - case OP_ADD:
11.281 - case OP_SUB:
11.282 - case OP_SUB_ALT:
11.283 - case OP_AND:
11.284 - case OP_OR:
11.285 - case OP_XOR:
11.286 - case OP_NOT:
11.287 - case OP_NEG:
11.288 - case OP_INVERT:
11.289 - case OP_ZERO_PRI:
11.290 - case OP_ZERO_ALT:
11.291 - case OP_SIGN_PRI:
11.292 - case OP_SIGN_ALT:
11.293 - case OP_EQ:
11.294 - case OP_NEQ:
11.295 - case OP_LESS:
11.296 - case OP_LEQ:
11.297 - case OP_GRTR:
11.298 - case OP_GEQ:
11.299 - case OP_SLESS:
11.300 - case OP_SLEQ:
11.301 - case OP_SGRTR:
11.302 - case OP_SGEQ:
11.303 - case OP_INC_PRI:
11.304 - case OP_INC_ALT:
11.305 - case OP_INC_I:
11.306 - case OP_DEC_PRI:
11.307 - case OP_DEC_ALT:
11.308 - case OP_DEC_I:
11.309 - case OP_SYSREQ_PRI:
11.310 - case OP_JUMP_PRI:
11.311 - case OP_SWAP_PRI:
11.312 - case OP_SWAP_ALT:
11.313 - case OP_NOP:
11.314 - case OP_BREAK:
11.315 - break;
11.316 - case OP_CASETBL:
11.317 - {
11.318 - cell num;
11.319 - DBGPARAM(*(cell *)tptr);
11.320 - num = *(cell *)tptr;
11.321 - tptr += sizeof(cell);
11.322 - memcpy(tptr, cbase+(int)cip, (2*num+1)*sizeof(cell));
11.323 - tptr += (2*num+1) * sizeof(cell);
11.324 - cip += (2*num+1) * sizeof(cell);
11.325 - break;
11.326 - }
11.327 - default:
11.328 - {
11.329 - assert(0);
11.330 - }
11.331 -#undef DBGPARAM
11.332 - }
11.333 - }
11.334 - cod.codesize = (uint32_t)(tptr - tbase);
11.335 - cod.disksize = cod.codesize;
11.336 - cod.compression = SPFILE_COMPRESSION_NONE;
11.337 - sfwrite(&cod, sizeof(cod), 1, fp);
11.338 - sfwrite(tbase, cod.codesize, 1, fp);
11.339 - free(tbase);
11.340 -
11.341 - /* backtrack and write this section's header info */
11.342 - curoffs = (uint32_t)ftell(fp);
11.343 - fseek(fp, offsets[0], SEEK_SET);
11.344 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
11.345 - cod.codesize += sizeof(cod);
11.346 - sfwrite(&cod.codesize, sizeof(uint32_t), 1, fp);
11.347 - fseek(fp, curoffs, SEEK_SET);
11.348 - lastsection = curoffs;
11.349 - }
11.350 -
11.351 - if (strcmp(tables[1], ".data") == 0)
11.352 - {
11.353 - sp_file_data_t dat;
11.354 - unsigned char *dbase;
11.355 - Bytef *cmp_dbase;
11.356 - uLong disksize;
11.357 - int err;
11.358 -
11.359 - dat.datasize = hdr->hea - hdr->dat;
11.360 - dat.memsize = hdr->stp;
11.361 - dat.data = sizeof(dat);
11.362 - dat.compression = SPFILE_COMPRESSION_GZ;
11.363 -
11.364 - if (dat.datasize)
11.365 - {
11.366 - dat.disksize = (uint32_t)compressBound((uLong)dat.datasize);
11.367 -
11.368 - dbase = (unsigned char *)hdr + hdr->dat;
11.369 - cmp_dbase = (Bytef *)malloc(dat.disksize);
11.370 -
11.371 - /* compress */
11.372 - err = compress2(cmp_dbase, &disksize, (Bytef *)dbase, dat.datasize, Z_BEST_COMPRESSION);
11.373 -
11.374 - if (err != Z_OK)
11.375 - {
11.376 - pc_printf("Failed to compress DAT section with error: %d\n", err);
11.377 - pc_printf("Defaulting to no compression.\n");
11.378 - dat.compression = SPFILE_COMPRESSION_NONE;
11.379 - dat.disksize = dat.datasize;
11.380 -
11.381 - /* write header */
11.382 - sfwrite(&dat, sizeof(dat), 1, fp);
11.383 - /* write data */
11.384 - sfwrite(&dbase, dat.datasize, 1, fp);
11.385 - } else {
11.386 - dat.disksize = (uint32_t)disksize;
11.387 -
11.388 - /* write header */
11.389 - sfwrite(&dat, sizeof(dat), 1, fp);
11.390 - /* write data */
11.391 - sfwrite(&cmp_dbase, dat.disksize, 1, fp);
11.392 - }
11.393 -
11.394 - free(cmp_dbase);
11.395 - } else {
11.396 - /* should be 0 */
11.397 - dat.disksize = dat.datasize;
11.398 - sfwrite(&dat, sizeof(dat), 1, fp);
11.399 - }
11.400 -
11.401 - /* backtrack and write this section's header info */
11.402 - curoffs = ftell(fp);
11.403 - fseek(fp, offsets[1], SEEK_SET);
11.404 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
11.405 - disksize += sizeof(dat);
11.406 - sfwrite(&disksize, sizeof(uint32_t),1, fp);
11.407 - fseek(fp, curoffs, SEEK_SET);
11.408 - lastsection = curoffs;
11.409 - }
11.410 -
11.411 - if (strcmp(tables[2], ".publics") == 0)
11.412 - {
11.413 - sp_file_publics_t *pbtbl;
11.414 - AMX_FUNCSTUBNT *stub;
11.415 - uint32_t publics = (hdr->natives - hdr->publics) / hdr->defsize;
11.416 -
11.417 - pbtbl = (sp_file_publics_t *)malloc(sizeof(sp_file_publics_t) * publics);
11.418 - stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->publics);
11.419 -
11.420 - for (i=0; i<publics; i++)
11.421 - {
11.422 - pbtbl[i].address = stub->address;
11.423 - pbtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
11.424 -
11.425 - stub += hdr->defsize;
11.426 - }
11.427 - if (publics)
11.428 - {
11.429 - sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, fp);
11.430 - }
11.431 - free(pbtbl);
11.432 -
11.433 - /* backtrack and write section's header info */
11.434 - curoffs = ftell(fp);
11.435 - fseek(fp, offsets[2], SEEK_SET);
11.436 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
11.437 - publics *= sizeof(sp_file_publics_t);
11.438 - sfwrite(&publics, sizeof(uint32_t), 1, fp);
11.439 - fseek(fp, curoffs, SEEK_SET);
11.440 - lastsection = curoffs;
11.441 - }
11.442 -
11.443 - if (strcmp(tables[3], ".pubvars") == 0)
11.444 - {
11.445 - sp_file_pubvars_t *pbvars;
11.446 - AMX_FUNCSTUBNT *stub;
11.447 - uint32_t pubvars = (hdr->tags - hdr->pubvars) / hdr->defsize;
11.448 -
11.449 - pbvars = (sp_file_pubvars_t *)malloc(sizeof(sp_file_pubvars_t) * pubvars);
11.450 - stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->pubvars);
11.451 -
11.452 - for (i=0; i<pubvars; i++)
11.453 - {
11.454 - pbvars[i].address = stub->address;
11.455 - pbvars[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
11.456 -
11.457 - stub += hdr->defsize;
11.458 - }
11.459 - if (pubvars)
11.460 - {
11.461 - sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, fp);
11.462 - }
11.463 - free(pbvars);
11.464 -
11.465 - /* backtrack and write section's header info */
11.466 - curoffs = ftell(fp);
11.467 - fseek(fp, offsets[3], SEEK_SET);
11.468 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
11.469 - pubvars *= sizeof(sp_file_pubvars_t);
11.470 - sfwrite(&pubvars, sizeof(uint32_t), 1, fp);
11.471 - fseek(fp, curoffs, SEEK_SET);
11.472 - lastsection = curoffs;
11.473 - }
11.474 -
11.475 - if (strcmp(tables[4], ".natives") == 0)
11.476 - {
11.477 - sp_file_natives_t *nvtbl;
11.478 - AMX_FUNCSTUBNT *stub;
11.479 - uint32_t natives = (hdr->libraries - hdr->natives) / hdr->defsize;
11.480 -
11.481 - nvtbl = (sp_file_natives_t *)malloc(sizeof(sp_file_natives_t) * natives);
11.482 - stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->natives);
11.483 -
11.484 - for (i=0; i<natives; i++)
11.485 - {
11.486 - nvtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
11.487 -
11.488 - stub += hdr->defsize;
11.489 - }
11.490 - if (natives)
11.491 - {
11.492 - sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, fp);
11.493 - }
11.494 - free(nvtbl);
11.495 -
11.496 - /* backtrack and write header */
11.497 - curoffs = ftell(fp);
11.498 - fseek(fp, offsets[4], SEEK_SET);
11.499 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
11.500 - natives *= sizeof(sp_file_natives_t);
11.501 - sfwrite(&natives, sizeof(uint32_t), 1, fp);
11.502 - fseek(fp, curoffs, SEEK_SET);
11.503 - lastsection = curoffs;
11.504 - }
11.505 -
11.506 - if (strcmp(tables[5], ".names") == 0)
11.507 - {
11.508 - unsigned char *base;
11.509 - uint32_t namelen;
11.510 -
11.511 - /* write the entire block */
11.512 - base = (unsigned char *)hdr + hdr->nametable + sizeof(uint16_t);
11.513 - /**
11.514 - * note - the name table will be padded to sizeof(cell) bytes.
11.515 - * this may clip at most an extra three bytes in!
11.516 - */
11.517 - namelen = hdr->cod - hdr->nametable;
11.518 - sfwrite(base, namelen, 1, fp);
11.519 -
11.520 - /* backtrack and write header */
11.521 - curoffs = ftell(fp);
11.522 - fseek(fp, offsets[5], SEEK_SET);
11.523 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
11.524 - sfwrite(&namelen, sizeof(uint32_t), 1, fp);
11.525 - fseek(fp, curoffs, SEEK_SET);
11.526 - lastsection = curoffs;
11.527 - }
11.528 -
11.529 - fclose(fp);
11.530 -
11.531 - return 0;
11.532 -
11.533 -write_error:
11.534 - pc_printf("Error writing to file: %s", bin_file->name);
11.535 - unlink(bin_file->name);
11.536 - fclose(fp);
11.537 -
11.538 - memfile_destroy(bin_file);
11.539 - bin_file = NULL;
11.540 -
11.541 - return 1;
11.542 - }
11.543 -
11.544 - return 1;
11.545 -}
11.546 -
11.547 -void sfwrite(const void *buf, size_t size, size_t count, FILE *fp)
11.548 -{
11.549 - if (fwrite(buf, size, count, fp) != count)
11.550 - {
11.551 - longjmp(brkout, 1);
11.552 - }
11.553 -}
12.1 --- a/compiler-init/sc.h Sat Jul 15 05:02:38 2006 +0000
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,813 +0,0 @@
12.4 -/* Pawn compiler
12.5 - *
12.6 - * Drafted after the Small-C compiler Version 2.01, originally created
12.7 - * by Ron Cain, july 1980, and enhanced by James E. Hendrix.
12.8 - *
12.9 - * This version comes close to a complete rewrite.
12.10 - *
12.11 - * Copyright R. Cain, 1980
12.12 - * Copyright J.E. Hendrix, 1982, 1983
12.13 - * Copyright ITB CompuPhase, 1997-2006
12.14 - *
12.15 - * This software is provided "as-is", without any express or implied warranty.
12.16 - * In no event will the authors be held liable for any damages arising from
12.17 - * the use of this software.
12.18 - *
12.19 - * Permission is granted to anyone to use this software for any purpose,
12.20 - * including commercial applications, and to alter it and redistribute it
12.21 - * freely, subject to the following restrictions:
12.22 - *
12.23 - * 1. The origin of this software must not be misrepresented; you must not
12.24 - * claim that you wrote the original software. If you use this software in
12.25 - * a product, an acknowledgment in the product documentation would be
12.26 - * appreciated but is not required.
12.27 - * 2. Altered source versions must be plainly marked as such, and must not be
12.28 - * misrepresented as being the original software.
12.29 - * 3. This notice may not be removed or altered from any source distribution.
12.30 - *
12.31 - * Version: $Id: sc.h 3590 2006-06-24 14:16:39Z thiadmer $
12.32 - */
12.33 -#ifndef SC_H_INCLUDED
12.34 -#define SC_H_INCLUDED
12.35 -#include <limits.h>
12.36 -#include <stdarg.h>
12.37 -#include <stdio.h>
12.38 -#if defined __BORLANDC__ && defined _Windows && !(defined __32BIT__ || defined __WIN32__)
12.39 - /* setjmp() and longjmp() not well supported in 16-bit windows */
12.40 - #include <windows.h>
12.41 - typedef int jmp_buf[9];
12.42 - #define setjmp(b) Catch(b)
12.43 - #define longjmp(b,e) Throw(b,e)
12.44 -#else
12.45 - #include <setjmp.h>
12.46 -#endif
12.47 -#include "osdefs.h"
12.48 -#include "amx.h"
12.49 -
12.50 -/* Note: the "cell" and "ucell" types are defined in AMX.H */
12.51 -
12.52 -#define PUBLIC_CHAR '@' /* character that defines a function "public" */
12.53 -#define CTRL_CHAR '\\' /* default control character */
12.54 -#define sCHARBITS 8 /* size of a packed character */
12.55 -
12.56 -#define sDIMEN_MAX 4 /* maximum number of array dimensions */
12.57 -#define sLINEMAX 1023 /* input line length (in characters) */
12.58 -#define sCOMP_STACK 32 /* maximum nesting of #if .. #endif sections */
12.59 -#define sDEF_LITMAX 500 /* initial size of the literal pool, in "cells" */
12.60 -#define sDEF_AMXSTACK 4096 /* default stack size for AMX files */
12.61 -#define PREPROC_TERM '\x7f'/* termination character for preprocessor expressions (the "DEL" code) */
12.62 -#define sDEF_PREFIX "sourcemod.inc" /* default prefix filename */
12.63 -
12.64 -typedef union {
12.65 - void *pv; /* e.g. a name */
12.66 - int i;
12.67 -} stkitem; /* type of items stored on the compiler stack */
12.68 -
12.69 -typedef struct s_arginfo { /* function argument info */
12.70 - char name[sNAMEMAX+1];
12.71 - char ident; /* iVARIABLE, iREFERENCE, iREFARRAY or iVARARGS */
12.72 - char usage; /* uCONST */
12.73 - int *tags; /* argument tag id. list */
12.74 - int numtags; /* number of tags in the tag list */
12.75 - int dim[sDIMEN_MAX];
12.76 - int idxtag[sDIMEN_MAX];
12.77 - int numdim; /* number of dimensions */
12.78 - unsigned char hasdefault; /* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */
12.79 - union {
12.80 - cell val; /* default value */
12.81 - struct {
12.82 - char *symname; /* name of another symbol */
12.83 - short level; /* indirection level for that symbol */
12.84 - } size; /* used for "sizeof" default value */
12.85 - struct {
12.86 - cell *data; /* values of default array */
12.87 - int size; /* complete length of default array */
12.88 - int arraysize; /* size to reserve on the heap */
12.89 - cell addr; /* address of the default array in the data segment */
12.90 - } array;
12.91 - } defvalue; /* default value, or pointer to default array */
12.92 - int defvalue_tag; /* tag of the default value */
12.93 -} arginfo;
12.94 -
12.95 -/* Equate table, tagname table, library table */
12.96 -typedef struct s_constvalue {
12.97 - struct s_constvalue *next;
12.98 - char name[sNAMEMAX+1];
12.99 - cell value;
12.100 - int index; /* index level, for constants referring to array sizes/tags
12.101 - * automaton id. for states and automatons
12.102 - * tag for enumeration lists */
12.103 -} constvalue;
12.104 -
12.105 -/* Symbol table format
12.106 - *
12.107 - * The symbol name read from the input file is stored in "name", the
12.108 - * value of "addr" is written to the output file. The address in "addr"
12.109 - * depends on the class of the symbol:
12.110 - * global offset into the data segment
12.111 - * local offset relative to the stack frame
12.112 - * label generated hexadecimal number
12.113 - * function offset into code segment
12.114 - */
12.115 -typedef struct s_symbol {
12.116 - struct s_symbol *next;
12.117 - struct s_symbol *parent; /* hierarchical types (multi-dimensional arrays) */
12.118 - char name[sNAMEMAX+1];
12.119 - uint32_t hash; /* value derived from name, for quicker searching */
12.120 - cell addr; /* address or offset (or value for constant, index for native function) */
12.121 - cell codeaddr; /* address (in the code segment) where the symbol declaration starts */
12.122 - char vclass; /* sLOCAL if "addr" refers to a local symbol */
12.123 - char ident; /* see below for possible values */
12.124 - short usage; /* see below for possible values */
12.125 - char flags; /* see below for possible values */
12.126 - int compound; /* compound level (braces nesting level) */
12.127 - int tag; /* tagname id */
12.128 - union {
12.129 - int declared; /* label: how many local variables are declared */
12.130 - struct {
12.131 - int index; /* array & enum: tag of array indices or the enum item */
12.132 - int field; /* enumeration fields, where a size is attached to the field */
12.133 - } tags; /* extra tags */
12.134 - constvalue *lib; /* native function: library it is part of */
12.135 - long stacksize; /* normal/public function: stack requirements */
12.136 - } x; /* 'x' for 'extra' */
12.137 - union {
12.138 - arginfo *arglist; /* types of all parameters for functions */
12.139 - constvalue *enumlist;/* list of names for the "root" of an enumeration */
12.140 - struct {
12.141 - cell length; /* arrays: length (size) */
12.142 - short level; /* number of dimensions below this level */
12.143 - } array;
12.144 - } dim; /* for 'dimension', both functions and arrays */
12.145 - constvalue *states; /* list of state function/state variable ids + addresses */
12.146 - int fnumber; /* static global variables: file number in which the declaration is visible */
12.147 - int lnumber; /* line number (in the current source file) for the declaration */
12.148 - struct s_symbol **refer; /* referrer list, functions that "use" this symbol */
12.149 - int numrefers; /* number of entries in the referrer list */
12.150 - char *documentation; /* optional documentation string */
12.151 -} symbol;
12.152 -
12.153 -
12.154 -/* Possible entries for "ident". These are used in the "symbol", "value"
12.155 - * and arginfo structures. Not every constant is valid for every use.
12.156 - * In an argument list, the list is terminated with a "zero" ident; labels
12.157 - * cannot be passed as function arguments, so the value 0 is overloaded.
12.158 - */
12.159 -#define iLABEL 0
12.160 -#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
12.161 -#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
12.162 -#define iARRAY 3
12.163 -#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
12.164 -#define iARRAYCELL 5 /* array element, cell that must be fetched indirectly */
12.165 -#define iARRAYCHAR 6 /* array element, character from cell from array */
12.166 -#define iEXPRESSION 7 /* expression result, has no address (rvalue) */
12.167 -#define iCONSTEXPR 8 /* constant expression (or constant symbol) */
12.168 -#define iFUNCTN 9
12.169 -#define iREFFUNC 10
12.170 -#define iVARARGS 11 /* function specified ... as argument(s) */
12.171 -
12.172 -/* Possible entries for "usage"
12.173 - *
12.174 - * This byte is used as a serie of bits, the syntax is different for
12.175 - * functions and other symbols:
12.176 - *
12.177 - * VARIABLE
12.178 - * bits: 0 (uDEFINE) the variable is defined in the source file
12.179 - * 1 (uREAD) the variable is "read" (accessed) in the source file
12.180 - * 2 (uWRITTEN) the variable is altered (assigned a value)
12.181 - * 3 (uCONST) the variable is constant (may not be assigned to)
12.182 - * 4 (uPUBLIC) the variable is public
12.183 - * 6 (uSTOCK) the variable is discardable (without warning)
12.184 - *
12.185 - * FUNCTION
12.186 - * bits: 0 (uDEFINE) the function is defined ("implemented") in the source file
12.187 - * 1 (uREAD) the function is invoked in the source file
12.188 - * 2 (uRETVALUE) the function returns a value (or should return a value)
12.189 - * 3 (uPROTOTYPED) the function was prototyped (implicitly via a definition or explicitly)
12.190 - * 4 (uPUBLIC) the function is public
12.191 - * 5 (uNATIVE) the function is native
12.192 - * 6 (uSTOCK) the function is discardable (without warning)
12.193 - * 7 (uMISSING) the function is not implemented in this source file
12.194 - * 8 (uFORWARD) the function is explicitly forwardly declared
12.195 - *
12.196 - * CONSTANT
12.197 - * bits: 0 (uDEFINE) the symbol is defined in the source file
12.198 - * 1 (uREAD) the constant is "read" (accessed) in the source file
12.199 - * 2 (uWRITTEN) redundant, but may be set for constants passed by reference
12.200 - * 3 (uPREDEF) the constant is pre-defined and should be kept between passes
12.201 - * 5 (uENUMROOT) the constant is the "root" of an enumeration
12.202 - * 6 (uENUMFIELD) the constant is a field in a named enumeration
12.203 - */
12.204 -#define uDEFINE 0x001
12.205 -#define uREAD 0x002
12.206 -#define uWRITTEN 0x004
12.207 -#define uRETVALUE 0x004 /* function returns (or should return) a value */
12.208 -#define uCONST 0x008
12.209 -#define uPROTOTYPED 0x008
12.210 -#define uPREDEF 0x008 /* constant is pre-defined */
12.211 -#define uPUBLIC 0x010
12.212 -#define uNATIVE 0x020
12.213 -#define uENUMROOT 0x020
12.214 -#define uSTOCK 0x040
12.215 -#define uENUMFIELD 0x040
12.216 -#define uMISSING 0x080
12.217 -#define uFORWARD 0x100
12.218 -/* uRETNONE is not stored in the "usage" field of a symbol. It is
12.219 - * used during parsing a function, to detect a mix of "return;" and
12.220 - * "return value;" in a few special cases.
12.221 - */
12.222 -#define uRETNONE 0x10
12.223 -
12.224 -#define flgDEPRICATED 0x01 /* symbol is depricated (avoid use) */
12.225 -
12.226 -#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
12.227 -#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
12.228 -
12.229 -#define uMAINFUNC "main"
12.230 -#define uENTRYFUNC "entry"
12.231 -
12.232 -#define sGLOBAL 0 /* global variable/constant class (no states) */
12.233 -#define sLOCAL 1 /* local variable/constant */
12.234 -#define sSTATIC 2 /* global life, local scope */
12.235 -
12.236 -#define sSTATEVAR 3 /* criterion to find variables (sSTATEVAR implies a global variable) */
12.237 -
12.238 -typedef struct s_value {
12.239 - symbol *sym; /* symbol in symbol table, NULL for (constant) expression */
12.240 - cell constval; /* value of the constant expression (if ident==iCONSTEXPR)
12.241 - * also used for the size of a literal array */
12.242 - int tag; /* tag (of the expression) */
12.243 - int cmptag; /* for searching symbols: choose the one with the matching tag */
12.244 - char ident; /* iCONSTEXPR, iVARIABLE, iARRAY, iARRAYCELL,
12.245 - * iEXPRESSION or iREFERENCE */
12.246 - char boolresult; /* boolean result for relational operators */
12.247 - cell *arrayidx; /* last used array indices, for checking self assignment */
12.248 -} value;
12.249 -
12.250 -/* "while" statement queue (also used for "for" and "do - while" loops) */
12.251 -enum {
12.252 - wqBRK, /* used to restore stack for "break" */
12.253 - wqCONT, /* used to restore stack for "continue" */
12.254 - wqLOOP, /* loop start label number */
12.255 - wqEXIT, /* loop exit label number (jump if false) */
12.256 - /* --- */
12.257 - wqSIZE /* "while queue" size */
12.258 -};
12.259 -#define wqTABSZ (24*wqSIZE) /* 24 nested loop statements */
12.260 -
12.261 -enum {
12.262 - statIDLE, /* not compiling yet */
12.263 - statFIRST, /* first pass */
12.264 - statWRITE, /* writing output */
12.265 - statSKIP, /* skipping output */
12.266 -};
12.267 -
12.268 -typedef struct s_stringlist {
12.269 - struct s_stringlist *next;
12.270 - char *line;
12.271 -} stringlist;
12.272 -
12.273 -typedef struct s_stringpair {
12.274 - struct s_stringpair *next;
12.275 - char *first;
12.276 - char *second;
12.277 - int matchlength;
12.278 -} stringpair;
12.279 -
12.280 -/* macros for code generation */
12.281 -#define opcodes(n) ((n)*sizeof(cell)) /* opcode size */
12.282 -#define opargs(n) ((n)*sizeof(cell)) /* size of typical argument */
12.283 -
12.284 -/* Tokens recognized by lex()
12.285 - * Some of these constants are assigned as well to the variable "lastst"
12.286 - */
12.287 -#define tFIRST 256 /* value of first multi-character operator */
12.288 -#define tMIDDLE 280 /* value of last multi-character operator */
12.289 -#define tLAST 326 /* value of last multi-character match-able token */
12.290 -/* multi-character operators */
12.291 -#define taMULT 256 /* *= */
12.292 -#define taDIV 257 /* /= */
12.293 -#define taMOD 258 /* %= */
12.294 -#define taADD 259 /* += */
12.295 -#define taSUB 260 /* -= */
12.296 -#define taSHL 261 /* <<= */
12.297 -#define taSHRU 262 /* >>>= */
12.298 -#define taSHR 263 /* >>= */
12.299 -#define taAND 264 /* &= */
12.300 -#define taXOR 265 /* ^= */
12.301 -#define taOR 266 /* |= */
12.302 -#define tlOR 267 /* || */
12.303 -#define tlAND 268 /* && */
12.304 -#define tlEQ 269 /* == */
12.305 -#define tlNE 270 /* != */
12.306 -#define tlLE 271 /* <= */
12.307 -#define tlGE 272 /* >= */
12.308 -#define tSHL 273 /* << */
12.309 -#define tSHRU 274 /* >>> */
12.310 -#define tSHR 275 /* >> */
12.311 -#define tINC 276 /* ++ */
12.312 -#define tDEC 277 /* -- */
12.313 -#define tELLIPS 278 /* ... */
12.314 -#define tDBLDOT 279 /* .. */
12.315 -#define tDBLCOLON 280 /* :: */
12.316 -/* reserved words (statements) */
12.317 -#define tASSERT 281
12.318 -#define tBREAK 282
12.319 -#define tCASE 283
12.320 -#define tCHAR 284
12.321 -#define tCONST 285
12.322 -#define tCONTINUE 286
12.323 -#define tDEFAULT 287
12.324 -#define tDEFINED 288
12.325 -#define tDO 289
12.326 -#define tELSE 290
12.327 -#define tENUM 291
12.328 -#define tEXIT 292
12.329 -#define tFOR 293
12.330 -#define tFORWARD 294
12.331 -#define tGOTO 295
12.332 -#define tIF 296
12.333 -#define tNATIVE 297
12.334 -#define tNEW 298
12.335 -#define tDECL 299
12.336 -#define tOPERATOR 300
12.337 -#define tPUBLIC 301
12.338 -#define tRETURN 302
12.339 -#define tSIZEOF 303
12.340 -#define tSLEEP 304
12.341 -#define tSTATE 305
12.342 -#define tSTATIC 306
12.343 -#define tSTOCK 307
12.344 -#define tSWITCH 308
12.345 -#define tTAGOF 309
12.346 -#define tWHILE 310
12.347 -/* compiler directives */
12.348 -#define tpASSERT 311 /* #assert */
12.349 -#define tpDEFINE 312
12.350 -#define tpELSE 313 /* #else */
12.351 -#define tpELSEIF 314 /* #elseif */
12.352 -#define tpEMIT 315
12.353 -#define tpENDIF 316
12.354 -#define tpENDINPUT 317
12.355 -#define tpENDSCRPT 318
12.356 -#define tpERROR 319
12.357 -#define tpFILE 320
12.358 -#define tpIF 321 /* #if */
12.359 -#define tINCLUDE 322
12.360 -#define tpLINE 323
12.361 -#define tpPRAGMA 324
12.362 -#define tpTRYINCLUDE 325
12.363 -#define tpUNDEF 326
12.364 -/* semicolon is a special case, because it can be optional */
12.365 -#define tTERM 327 /* semicolon or newline */
12.366 -#define tENDEXPR 328 /* forced end of expression */
12.367 -/* other recognized tokens */
12.368 -#define tNUMBER 329 /* integer number */
12.369 -#define tRATIONAL 330 /* rational number */
12.370 -#define tSYMBOL 331
12.371 -#define tLABEL 332
12.372 -#define tSTRING 333
12.373 -#define tEXPR 334 /* for assigment to "lastst" only */
12.374 -
12.375 -/* (reversed) evaluation of staging buffer */
12.376 -#define sSTARTREORDER 0x01
12.377 -#define sENDREORDER 0x02
12.378 -#define sEXPRSTART 0x80 /* top bit set, rest is free */
12.379 -#define sMAXARGS 127 /* relates to the bit pattern of sEXPRSTART */
12.380 -
12.381 -#define sDOCSEP 0x01 /* to separate documentation comments between functions */
12.382 -
12.383 -/* codes for ffabort() */
12.384 -#define xEXIT 1 /* exit code in PRI */
12.385 -#define xASSERTION 2 /* abort caused by failing assertion */
12.386 -#define xSTACKERROR 3 /* stack/heap overflow */
12.387 -#define xBOUNDSERROR 4 /* array index out of bounds */
12.388 -#define xMEMACCESS 5 /* data access error */
12.389 -#define xINVINSTR 6 /* invalid instruction */
12.390 -#define xSTACKUNDERFLOW 7 /* stack underflow */
12.391 -#define xHEAPUNDERFLOW 8 /* heap underflow */
12.392 -#define xCALLBACKERR 9 /* no, or invalid, callback */
12.393 -#define xSLEEP 12 /* sleep, exit code in PRI, tag in ALT */
12.394 -
12.395 -/* Miscellaneous */
12.396 -#if !defined TRUE
12.397 - #define FALSE 0
12.398 - #define TRUE 1
12.399 -#endif
12.400 -#define sIN_CSEG 1 /* if parsing CODE */
12.401 -#define sIN_DSEG 2 /* if parsing DATA */
12.402 -#define sCHKBOUNDS 1 /* bit position in "debug" variable: check bounds */
12.403 -#define sSYMBOLIC 2 /* bit position in "debug" variable: symbolic info */
12.404 -#define sRESET 0 /* reset error flag */
12.405 -#define sFORCESET 1 /* force error flag on */
12.406 -#define sEXPRMARK 2 /* mark start of expression */
12.407 -#define sEXPRRELEASE 3 /* mark end of expression */
12.408 -#define sSETPOS 4 /* set line number for the error */
12.409 -
12.410 -enum {
12.411 - sOPTIMIZE_NONE, /* no optimization */
12.412 - sOPTIMIZE_NOMACRO, /* no macro instructions */
12.413 - sOPTIMIZE_DEFAULT, /* full optimization */
12.414 - /* ----- */
12.415 - sOPTIMIZE_NUMBER
12.416 -};
12.417 -
12.418 -typedef enum s_regid {
12.419 - sPRI, /* indicates the primary register */
12.420 - sALT, /* indicates the secundary register */
12.421 -} regid;
12.422 -
12.423 -typedef enum s_optmark {
12.424 - sEXPR, /* end of expression (for expressions that form a statement) */
12.425 - sPARM, /* end of parameter (in a function parameter list) */
12.426 - sLDECL, /* start of local declaration (variable) */
12.427 -} optmark;
12.428 -
12.429 -#define suSLEEP_INSTR 0x01 /* the "sleep" instruction was used */
12.430 -
12.431 -#if INT_MAX<0x8000u
12.432 - #define PUBLICTAG 0x8000u
12.433 - #define FIXEDTAG 0x4000u
12.434 -#else
12.435 - #define PUBLICTAG 0x80000000Lu
12.436 - #define FIXEDTAG 0x40000000Lu
12.437 -#endif
12.438 -#define TAGMASK (~PUBLICTAG)
12.439 -#define CELL_MAX (((ucell)1 << (sizeof(cell)*8-1)) - 1)
12.440 -
12.441 -
12.442 -/* interface functions */
12.443 -#if defined __cplusplus
12.444 - extern "C" {
12.445 -#endif
12.446 -
12.447 -/*
12.448 - * Functions you call from the "driver" program
12.449 - */
12.450 -int pc_compile(int argc, char **argv);
12.451 -int pc_addconstant(char *name,cell value,int tag);
12.452 -int pc_addtag(char *name);
12.453 -int pc_enablewarning(int number,int enable);
12.454 -
12.455 -/*
12.456 - * Functions called from the compiler (to be implemented by you)
12.457 - */
12.458 -
12.459 -/* general console output */
12.460 -int pc_printf(const char *message,...);
12.461 -
12.462 -/* error report function */
12.463 -int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr);
12.464 -
12.465 -/* input from source file */
12.466 -void *pc_opensrc(char *filename); /* reading only */
12.467 -void *pc_createsrc(char *filename);
12.468 -void pc_closesrc(void *handle); /* never delete */
12.469 -void pc_resetsrc(void *handle,void *position); /* reset to a position marked earlier */
12.470 -char *pc_readsrc(void *handle,unsigned char *target,int maxchars);
12.471 -int pc_writesrc(void *handle,unsigned char *source);
12.472 -void *pc_getpossrc(void *handle); /* mark the current position */
12.473 -int pc_eofsrc(void *handle);
12.474 -
12.475 -/* output to intermediate (.ASM) file */
12.476 -void *pc_openasm(char *filename); /* read/write */
12.477 -void pc_closeasm(void *handle,int deletefile);
12.478 -void pc_resetasm(void *handle);
12.479 -int pc_writeasm(void *handle,char *str);
12.480 -char *pc_readasm(void *handle,char *target,int maxchars);
12.481 -
12.482 -/* output to binary (.AMX) file */
12.483 -void *pc_openbin(char *filename);
12.484 -void pc_closebin(void *handle,int deletefile);
12.485 -void pc_resetbin(void *handle,long offset);
12.486 -int pc_writebin(void *handle,void *buffer,int size);
12.487 -long pc_lengthbin(void *handle); /* return the length of the file */
12.488 -
12.489 -#if defined __cplusplus
12.490 - }
12.491 -#endif
12.492 -
12.493 -
12.494 -/* by default, functions and variables used in throughout the compiler
12.495 - * files are "external"
12.496 - */
12.497 -#if !defined SC_FUNC
12.498 - #define SC_FUNC
12.499 -#endif
12.500 -#if !defined SC_VDECL
12.501 - #define SC_VDECL extern
12.502 -#endif
12.503 -#if !defined SC_VDEFINE
12.504 - #define SC_VDEFINE
12.505 -#endif
12.506 -
12.507 -/* function prototypes in SC1.C */
12.508 -SC_FUNC void set_extension(char *filename,char *extension,int force);
12.509 -SC_FUNC symbol *fetchfunc(char *name,int tag);
12.510 -SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag);
12.511 -SC_FUNC char *funcdisplayname(char *dest,char *funcname);
12.512 -SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr);
12.513 -SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,int index);
12.514 -SC_FUNC constvalue *find_constval(constvalue *table,char *name,int index);
12.515 -SC_FUNC void delete_consttable(constvalue *table);
12.516 -SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag);
12.517 -SC_FUNC void exporttag(int tag);
12.518 -SC_FUNC void sc_attachdocumentation(symbol *sym);
12.519 -
12.520 -/* function prototypes in SC2.C */
12.521 -#define PUSHSTK_P(v) { stkitem s_; s_.pv=(v); pushstk(s_); }
12.522 -#define PUSHSTK_I(v) { stkitem s_; s_.i=(v); pushstk(s_); }
12.523 -#define POPSTK_P() (popstk().pv)
12.524 -#define POPSTK_I() (popstk().i)
12.525 -SC_FUNC void pushstk(stkitem val);
12.526 -SC_FUNC stkitem popstk(void);
12.527 -SC_FUNC void clearstk(void);
12.528 -SC_FUNC int plungequalifiedfile(char *name); /* explicit path included */
12.529 -SC_FUNC int plungefile(char *name,int try_currentpath,int try_includepaths); /* search through "include" paths */
12.530 -SC_FUNC void preprocess(void);
12.531 -SC_FUNC void lexinit(void);
12.532 -SC_FUNC int lex(cell *lexvalue,char **lexsym);
12.533 -SC_FUNC void lexpush(void);
12.534 -SC_FUNC void lexclr(int clreol);
12.535 -SC_FUNC int matchtoken(int token);
12.536 -SC_FUNC int tokeninfo(cell *val,char **str);
12.537 -SC_FUNC int needtoken(int token);
12.538 -SC_FUNC void litadd(cell value);
12.539 -SC_FUNC void litinsert(cell value,int pos);
12.540 -SC_FUNC int alphanum(char c);
12.541 -SC_FUNC int ishex(char c);
12.542 -SC_FUNC void delete_symbol(symbol *root,symbol *sym);
12.543 -SC_FUNC void delete_symbols(symbol *root,int level,int del_labels,int delete_functions);
12.544 -SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom);
12.545 -SC_FUNC void markusage(symbol *sym,int usage);
12.546 -SC_FUNC uint32_t namehash(const char *name);
12.547 -SC_FUNC symbol *findglb(const char *name,int filter);
12.548 -SC_FUNC symbol *findloc(const char *name);
12.549 -SC_FUNC symbol *findconst(const char *name,int *matchtag);
12.550 -SC_FUNC symbol *finddepend(const symbol *parent);
12.551 -SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,
12.552 - int usage);
12.553 -SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
12.554 - int dim[],int numdim,int idxtag[]);
12.555 -SC_FUNC int getlabel(void);
12.556 -SC_FUNC char *itoh(ucell val);
12.557 -
12.558 -/* function prototypes in SC3.C */
12.559 -SC_FUNC int check_userop(void (*oper)(void),int tag1,int tag2,int numparam,
12.560 - value *lval,int *resulttag);
12.561 -SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce);
12.562 -SC_FUNC int expression(cell *val,int *tag,symbol **symptr,int chkfuncresult);
12.563 -SC_FUNC int sc_getstateid(constvalue **automaton,constvalue **state);
12.564 -SC_FUNC cell array_totalsize(symbol *sym);
12.565 -
12.566 -/* function prototypes in SC4.C */
12.567 -SC_FUNC void writeleader(symbol *root);
12.568 -SC_FUNC void writetrailer(void);
12.569 -SC_FUNC void begcseg(void);
12.570 -SC_FUNC void begdseg(void);
12.571 -SC_FUNC void setline(int chkbounds);
12.572 -SC_FUNC void setfiledirect(char *name);
12.573 -SC_FUNC void setlinedirect(int line);
12.574 -SC_FUNC void setlabel(int index);
12.575 -SC_FUNC void markexpr(optmark type,const char *name,cell offset);
12.576 -SC_FUNC void startfunc(char *fname);
12.577 -SC_FUNC void endfunc(void);
12.578 -SC_FUNC void alignframe(int numbytes);
12.579 -SC_FUNC void rvalue(value *lval);
12.580 -SC_FUNC void address(symbol *ptr,regid reg);
12.581 -SC_FUNC void store(value *lval);
12.582 -SC_FUNC void loadreg(cell address,regid reg);
12.583 -SC_FUNC void storereg(cell address,regid reg);
12.584 -SC_FUNC void memcopy(cell size);
12.585 -SC_FUNC void copyarray(symbol *sym,cell size);
12.586 -SC_FUNC void fillarray(symbol *sym,cell size,cell value);
12.587 -SC_FUNC void ldconst(cell val,regid reg);
12.588 -SC_FUNC void moveto1(void);
12.589 -SC_FUNC void pushreg(regid reg);
12.590 -SC_FUNC void pushval(cell val);
12.591 -SC_FUNC void popreg(regid reg);
12.592 -SC_FUNC void swap1(void);
12.593 -SC_FUNC void ffswitch(int label);
12.594 -SC_FUNC void ffcase(cell value,char *labelname,int newtable);
12.595 -SC_FUNC void ffcall(symbol *sym,const char *label,int numargs);
12.596 -SC_FUNC void ffret(int remparams);
12.597 -SC_FUNC void ffabort(int reason);
12.598 -SC_FUNC void ffbounds(cell size);
12.599 -SC_FUNC void jumplabel(int number);
12.600 -SC_FUNC void defstorage(void);
12.601 -SC_FUNC void modstk(int delta);
12.602 -SC_FUNC void setstk(cell value);
12.603 -SC_FUNC void modheap(int delta);
12.604 -SC_FUNC void setheap_pri(void);
12.605 -SC_FUNC void setheap(cell value);
12.606 -SC_FUNC void cell2addr(void);
12.607 -SC_FUNC void cell2addr_alt(void);
12.608 -SC_FUNC void addr2cell(void);
12.609 -SC_FUNC void char2addr(void);
12.610 -SC_FUNC void charalign(void);
12.611 -SC_FUNC void addconst(cell value);
12.612 -
12.613 -/* Code generation functions for arithmetic operators.
12.614 - *
12.615 - * Syntax: o[u|s|b]_name
12.616 - * | | | +--- name of operator
12.617 - * | | +----- underscore
12.618 - * | +--------- "u"nsigned operator, "s"igned operator or "b"oth
12.619 - * +------------- "o"perator
12.620 - */
12.621 -SC_FUNC void os_mult(void); /* multiplication (signed) */
12.622 -SC_FUNC void os_div(void); /* division (signed) */
12.623 -SC_FUNC void os_mod(void); /* modulus (signed) */
12.624 -SC_FUNC void ob_add(void); /* addition */
12.625 -SC_FUNC void ob_sub(void); /* subtraction */
12.626 -SC_FUNC void ob_sal(void); /* shift left (arithmetic) */
12.627 -SC_FUNC void os_sar(void); /* shift right (arithmetic, signed) */
12.628 -SC_FUNC void ou_sar(void); /* shift right (logical, unsigned) */
12.629 -SC_FUNC void ob_or(void); /* bitwise or */
12.630 -SC_FUNC void ob_xor(void); /* bitwise xor */
12.631 -SC_FUNC void ob_and(void); /* bitwise and */
12.632 -SC_FUNC void ob_eq(void); /* equality */
12.633 -SC_FUNC void ob_ne(void); /* inequality */
12.634 -SC_FUNC void relop_prefix(void);
12.635 -SC_FUNC void relop_suffix(void);
12.636 -SC_FUNC void os_le(void); /* less or equal (signed) */
12.637 -SC_FUNC void os_ge(void); /* greater or equal (signed) */
12.638 -SC_FUNC void os_lt(void); /* less (signed) */
12.639 -SC_FUNC void os_gt(void); /* greater (signed) */
12.640 -
12.641 -SC_FUNC void lneg(void);
12.642 -SC_FUNC void neg(void);
12.643 -SC_FUNC void invert(void);
12.644 -SC_FUNC void nooperation(void);
12.645 -SC_FUNC void inc(value *lval);
12.646 -SC_FUNC void dec(value *lval);
12.647 -SC_FUNC void jmp_ne0(int number);
12.648 -SC_FUNC void jmp_eq0(int number);
12.649 -SC_FUNC void outval(cell val,int newline);
12.650 -
12.651 -/* function prototypes in SC5.C */
12.652 -SC_FUNC int error(int number,...);
12.653 -SC_FUNC void errorset(int code,int line);
12.654 -
12.655 -/* function prototypes in SC6.C */
12.656 -SC_FUNC int assemble(FILE *fout,FILE *fin);
12.657 -
12.658 -/* function prototypes in SC7.C */
12.659 -SC_FUNC void stgbuffer_cleanup(void);
12.660 -SC_FUNC void stgmark(char mark);
12.661 -SC_FUNC void stgwrite(const char *st);
12.662 -SC_FUNC void stgout(int index);
12.663 -SC_FUNC void stgdel(int index,cell code_index);
12.664 -SC_FUNC int stgget(int *index,cell *code_index);
12.665 -SC_FUNC void stgset(int onoff);
12.666 -SC_FUNC int phopt_init(void);
12.667 -SC_FUNC int phopt_cleanup(void);
12.668 -
12.669 -/* function prototypes in SCLIST.C */
12.670 -SC_FUNC char* duplicatestring(const char* sourcestring);
12.671 -SC_FUNC stringpair *insert_alias(char *name,char *alias);
12.672 -SC_FUNC stringpair *find_alias(char *name);
12.673 -SC_FUNC int lookup_alias(char *target,char *name);
12.674 -SC_FUNC void delete_aliastable(void);
12.675 -SC_FUNC stringlist *insert_path(char *path);
12.676 -SC_FUNC char *get_path(int index);
12.677 -SC_FUNC void delete_pathtable(void);
12.678 -SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen);
12.679 -SC_FUNC int get_subst(int index,char **pattern,char **substitution);
12.680 -SC_FUNC stringpair *find_subst(char *name,int length);
12.681 -SC_FUNC int delete_subst(char *name,int length);
12.682 -SC_FUNC void delete_substtable(void);
12.683 -SC_FUNC stringlist *insert_sourcefile(char *string);
12.684 -SC_FUNC char *get_sourcefile(int index);
12.685 -SC_FUNC void delete_sourcefiletable(void);
12.686 -SC_FUNC stringlist *insert_docstring(char *string);
12.687 -SC_FUNC char *get_docstring(int index);
12.688 -SC_FUNC void delete_docstring(int index);
12.689 -SC_FUNC void delete_docstringtable(void);
12.690 -SC_FUNC stringlist *insert_autolist(char *string);
12.691 -SC_FUNC char *get_autolist(int index);
12.692 -SC_FUNC void delete_autolisttable(void);
12.693 -SC_FUNC stringlist *insert_dbgfile(const char *filename);
12.694 -SC_FUNC stringlist *insert_dbgline(int linenr);
12.695 -SC_FUNC stringlist *insert_dbgsymbol(symbol *sym);
12.696 -SC_FUNC char *get_dbgstring(int index);
12.697 -SC_FUNC void delete_dbgstringtable(void);
12.698 -
12.699 -/* function prototypes in SCMEMFILE.C */
12.700 -#if !defined tMEMFILE
12.701 - typedef unsigned char MEMFILE;
12.702 - #define tMEMFILE 1
12.703 -#endif
12.704 -MEMFILE *mfcreate(char *filename);
12.705 -void mfclose(MEMFILE *mf);
12.706 -int mfdump(MEMFILE *mf);
12.707 -long mflength(MEMFILE *mf);
12.708 -long mfseek(MEMFILE *mf,long offset,int whence);
12.709 -unsigned int mfwrite(MEMFILE *mf,unsigned char *buffer,unsigned int size);
12.710 -unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size);
12.711 -char *mfgets(MEMFILE *mf,char *string,unsigned int size);
12.712 -int mfputs(MEMFILE *mf,char *string);
12.713 -
12.714 -/* function prototypes in SCI18N.C */
12.715 -#define MAXCODEPAGE 12
12.716 -SC_FUNC int cp_path(const char *root,const char *directory);
12.717 -SC_FUNC int cp_set(const char *name);
12.718 -SC_FUNC cell cp_translate(const unsigned char *string,const unsigned char **endptr);
12.719 -SC_FUNC cell get_utf8_char(const unsigned char *string,const unsigned char **endptr);
12.720 -SC_FUNC int scan_utf8(FILE *fp,const char *filename);
12.721 -
12.722 -/* function prototypes in SCSTATE.C */
12.723 -SC_FUNC constvalue *automaton_add(const char *name);
12.724 -SC_FUNC constvalue *automaton_find(const char *name);
12.725 -SC_FUNC constvalue *automaton_findid(int id);
12.726 -SC_FUNC constvalue *state_add(const char *name,int fsa_id);
12.727 -SC_FUNC constvalue *state_find(const char *name,int fsa_id);
12.728 -SC_FUNC constvalue *state_findid(int id);
12.729 -SC_FUNC void state_buildlist(int **list,int *listsize,int *count,int stateid);
12.730 -SC_FUNC int state_addlist(int *list,int count,int fsa_id);
12.731 -SC_FUNC void state_deletetable(void);
12.732 -SC_FUNC int state_getfsa(int listid);
12.733 -SC_FUNC int state_count(int listid);
12.734 -SC_FUNC int state_inlist(int listid,int state);
12.735 -SC_FUNC int state_listitem(int listid,int index);
12.736 -SC_FUNC void state_conflict(symbol *root);
12.737 -SC_FUNC int state_conflict_id(int listid1,int listid2);
12.738 -
12.739 -/* external variables (defined in scvars.c) */
12.740 -#if !defined SC_SKIP_VDECL
12.741 -SC_VDECL symbol loctab; /* local symbol table */
12.742 -SC_VDECL symbol glbtab; /* global symbol table */
12.743 -SC_VDECL cell *litq; /* the literal queue */
12.744 -SC_VDECL unsigned char pline[]; /* the line read from the input file */
12.745 -SC_VDECL const unsigned char *lptr;/* points to the current position in "pline" */
12.746 -SC_VDECL constvalue tagname_tab;/* tagname table */
12.747 -SC_VDECL constvalue libname_tab;/* library table (#pragma library "..." syntax) */
12.748 -SC_VDECL constvalue *curlibrary;/* current library */
12.749 -SC_VDECL int pc_addlibtable; /* is the library table added to the AMX file? */
12.750 -SC_VDECL symbol *curfunc; /* pointer to current function */
12.751 -SC_VDECL char *inpfname; /* name of the file currently read from */
12.752 -SC_VDECL char outfname[]; /* intermediate (assembler) file name */
12.753 -SC_VDECL char binfname[]; /* binary file name */
12.754 -SC_VDECL char errfname[]; /* error file name */
12.755 -SC_VDECL char sc_ctrlchar; /* the control character (or escape character) */
12.756 -SC_VDECL char sc_ctrlchar_org;/* the default control character */
12.757 -SC_VDECL int litidx; /* index to literal table */
12.758 -SC_VDECL int litmax; /* current size of the literal table */
12.759 -SC_VDECL int stgidx; /* index to the staging buffer */
12.760 -SC_VDECL int sc_labnum; /* number of (internal) labels */
12.761 -SC_VDECL int staging; /* true if staging output */
12.762 -SC_VDECL cell declared; /* number of local cells declared */
12.763 -SC_VDECL cell glb_declared; /* number of global cells declared */
12.764 -SC_VDECL cell code_idx; /* number of bytes with generated code */
12.765 -SC_VDECL int ntv_funcid; /* incremental number of native function */
12.766 -SC_VDECL int errnum; /* number of errors */
12.767 -SC_VDECL int warnnum; /* number of warnings */
12.768 -SC_VDECL int sc_debug; /* debug/optimization options (bit field) */
12.769 -SC_VDECL int sc_packstr; /* strings are packed by default? */
12.770 -SC_VDECL int sc_asmfile; /* create .ASM file? */
12.771 -SC_VDECL int sc_listing; /* create .LST file? */
12.772 -SC_VDECL int sc_compress; /* compress bytecode? */
12.773 -SC_VDECL int sc_needsemicolon;/* semicolon required to terminate expressions? */
12.774 -SC_VDECL int sc_dataalign; /* data alignment value */
12.775 -SC_VDECL int sc_alignnext; /* must frame of the next function be aligned? */
12.776 -SC_VDECL int pc_docexpr; /* must expression be attached to documentation comment? */
12.777 -SC_VDECL int curseg; /* 1 if currently parsing CODE, 2 if parsing DATA */
12.778 -SC_VDECL cell pc_stksize; /* stack size */
12.779 -SC_VDECL cell pc_amxlimit; /* abstract machine size limit (code + data, or only code) */
12.780 -SC_VDECL cell pc_amxram; /* abstract machine data size limit */
12.781 -SC_VDECL int freading; /* is there an input file ready for reading? */
12.782 -SC_VDECL int fline; /* the line number in the current file */
12.783 -SC_VDECL short fnumber; /* number of files in the file table (debugging) */
12.784 -SC_VDECL short fcurrent; /* current file being processed (debugging) */
12.785 -SC_VDECL short sc_intest; /* true if inside a test */
12.786 -SC_VDECL int sideeffect; /* true if an expression causes a side-effect */
12.787 -SC_VDECL int stmtindent; /* current indent of the statement */
12.788 -SC_VDECL int indent_nowarn; /* skip warning "217 loose indentation" */
12.789 -SC_VDECL int sc_tabsize; /* number of spaces that a TAB represents */
12.790 -SC_VDECL short sc_allowtags; /* allow/detect tagnames in lex() */
12.791 -SC_VDECL int sc_status; /* read/write status */
12.792 -SC_VDECL int sc_rationaltag; /* tag for rational numbers */
12.793 -SC_VDECL int rational_digits; /* number of fractional digits */
12.794 -SC_VDECL int sc_allowproccall;/* allow/detect tagnames in lex() */
12.795 -SC_VDECL short sc_is_utf8; /* is this source file in UTF-8 encoding */
12.796 -SC_VDECL char *pc_depricate; /* if non-NULL, mark next declaration as depricated */
12.797 -SC_VDECL int sc_curstates; /* ID of the current state list */
12.798 -SC_VDECL int pc_optimize; /* (peephole) optimization level */
12.799 -SC_VDECL int pc_memflags; /* special flags for the stack/heap usage */
12.800 -
12.801 -SC_VDECL constvalue sc_automaton_tab; /* automaton table */
12.802 -SC_VDECL constvalue sc_state_tab; /* state table */
12.803 -
12.804 -SC_VDECL FILE *inpf; /* file read from (source or include) */
12.805 -SC_VDECL FILE *inpf_org; /* main source file */
12.806 -SC_VDECL FILE *outf; /* file written to */
12.807 -
12.808 -SC_VDECL jmp_buf errbuf; /* target of longjmp() on a fatal error */
12.809 -
12.810 -#if !defined SC_LIGHT
12.811 - SC_VDECL int sc_makereport; /* generate a cross-reference report */
12.812 -#endif
12.813 -
12.814 -#endif /* SC_SKIP_VDECL */
12.815 -
12.816 -#endif /* SC_H_INCLUDED */
13.1 --- a/compiler-init/sc1.c Sat Jul 15 05:02:38 2006 +0000
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,5653 +0,0 @@
13.4 -/* Pawn compiler
13.5 - *
13.6 - * Function and variable definition and declaration, statement parser.
13.7 - *
13.8 - * Copyright (c) ITB CompuPhase, 1997-2006
13.9 - *
13.10 - * This software is provided "as-is", without any express or implied warranty.
13.11 - * In no event will the authors be held liable for any damages arising from
13.12 - * the use of this software.
13.13 - *
13.14 - * Permission is granted to anyone to use this software for any purpose,
13.15 - * including commercial applications, and to alter it and redistribute it
13.16 - * freely, subject to the following restrictions:
13.17 - *
13.18 - * 1. The origin of this software must not be misrepresented; you must not
13.19 - * claim that you wrote the original software. If you use this software in
13.20 - * a product, an acknowledgment in the product documentation would be
13.21 - * appreciated but is not required.
13.22 - * 2. Altered source versions must be plainly marked as such, and must not be
13.23 - * misrepresented as being the original software.
13.24 - * 3. This notice may not be removed or altered from any source distribution.
13.25 - *
13.26 - * Version: $Id: sc1.c 3591 2006-06-25 14:30:07Z thiadmer $
13.27 - */
13.28 -#include <assert.h>
13.29 -#include <ctype.h>
13.30 -#include <limits.h>
13.31 -#include <stdarg.h>
13.32 -#include <stdio.h>
13.33 -#include <stdlib.h>
13.34 -#include <string.h>
13.35 -
13.36 -#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
13.37 - #include <conio.h>
13.38 - #include <io.h>
13.39 -#endif
13.40 -
13.41 -#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
13.42 - #include <sclinux.h>
13.43 - #include <binreloc.h> /* from BinReloc, see www.autopackage.org */
13.44 -#endif
13.45 -
13.46 -#if defined FORTIFY
13.47 - #include <alloc/fortify.h>
13.48 -#endif
13.49 -
13.50 -#if defined __BORLANDC__ || defined __WATCOMC__
13.51 - #include <dos.h>
13.52 - static unsigned total_drives; /* dummy variable */
13.53 - #define dos_setdrive(i) _dos_setdrive(i,&total_drives)
13.54 -#elif defined _MSC_VER && defined _WIN32
13.55 - #include <direct.h> /* for _chdrive() */
13.56 - #define dos_setdrive(i) _chdrive(i)
13.57 -#endif
13.58 -#if defined __BORLANDC__
13.59 - #include <dir.h> /* for chdir() */
13.60 -#elif defined __WATCOMC__
13.61 - #include <direct.h> /* for chdir() */
13.62 -#endif
13.63 -#if defined __WIN32__ || defined _WIN32 || defined _Windows
13.64 - #include <windows.h>
13.65 -#endif
13.66 -
13.67 -#include <time.h>
13.68 -
13.69 -#include "lstring.h"
13.70 -#include "sc.h"
13.71 -#include "svnrev.h"
13.72 -#define VERSION_STR "3.2." SVN_REVSTR
13.73 -#define VERSION_INT 0x0302
13.74 -
13.75 -static void resetglobals(void);
13.76 -static void initglobals(void);
13.77 -static char *get_extension(char *filename);
13.78 -static void setopt(int argc,char **argv,char *oname,char *ename,char *pname,
13.79 - char *rname,char *codepage);
13.80 -static void setconfig(char *root);
13.81 -static void setcaption(void);
13.82 -static void about(void);
13.83 -static void setconstants(void);
13.84 -static void parse(void);
13.85 -static void dumplits(void);
13.86 -static void dumpzero(int count);
13.87 -static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst);
13.88 -static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,
13.89 - int stock,int fconst);
13.90 -static int declloc(int fstatic);
13.91 -static void decl_const(int table);
13.92 -static void decl_enum(int table);
13.93 -static cell needsub(int *tag,constvalue **enumroot);
13.94 -static void initials(int ident,int tag,cell *size,int dim[],int numdim,
13.95 - constvalue *enumroot);
13.96 -static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
13.97 - int startlit,int counteddim[],constvalue *lastdim,
13.98 - constvalue *enumroot,int *errorfound);
13.99 -static cell initvector(int ident,int tag,cell size,int fillzero,
13.100 - constvalue *enumroot,int *errorfound);
13.101 -static cell init(int ident,int *tag,int *errorfound);
13.102 -static int getstates(const char *funcname);
13.103 -static void attachstatelist(symbol *sym, int state_id);
13.104 -static void funcstub(int fnative);
13.105 -static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock);
13.106 -static int declargs(symbol *sym,int chkshadow);
13.107 -static void doarg(char *name,int ident,int offset,int tags[],int numtags,
13.108 - int fpublic,int fconst,int chkshadow,arginfo *arg);
13.109 -static void make_report(symbol *root,FILE *log,char *sourcefile);
13.110 -static void reduce_referrers(symbol *root);
13.111 -static long max_stacksize(symbol *root,int *recursion);
13.112 -static int testsymbols(symbol *root,int level,int testlabs,int testconst);
13.113 -static void destructsymbols(symbol *root,int level);
13.114 -static constvalue *find_constval_byval(constvalue *table,cell val);
13.115 -static void statement(int *lastindent,int allow_decl);
13.116 -static void compound(int stmt_sameline);
13.117 -static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
13.118 - int *tag,symbol **symptr,int chkfuncresult);
13.119 -static void doassert(void);
13.120 -static void doexit(void);
13.121 -static void test(int label,int parens,int invert);
13.122 -static void doif(void);
13.123 -static void dowhile(void);
13.124 -static void dodo(void);
13.125 -static void dofor(void);
13.126 -static void doswitch(void);
13.127 -static void dogoto(void);
13.128 -static void dolabel(void);
13.129 -static symbol *fetchlab(char *name);
13.130 -static void doreturn(void);
13.131 -static void dobreak(void);
13.132 -static void docont(void);
13.133 -static void dosleep(void);
13.134 -static void dostate(void);
13.135 -static void addwhile(int *ptr);
13.136 -static void delwhile(void);
13.137 -static int *readwhile(void);
13.138 -static void inst_datetime_defines(void);
13.139 -
13.140 -static int norun = 0; /* the compiler never ran */
13.141 -static int autozero = 1; /* if 1 will zero out the variable, if 0 omit the zeroing */
13.142 -static int lastst = 0; /* last executed statement type */
13.143 -static int nestlevel = 0; /* number of active (open) compound statements */
13.144 -static int rettype = 0; /* the type that a "return" expression should have */
13.145 -static int skipinput = 0; /* number of lines to skip from the first input file */
13.146 -static int optproccall = TRUE; /* support "procedure call" */
13.147 -static int verbosity = 1; /* verbosity level, 0=quiet, 1=normal, 2=verbose */
13.148 -static int sc_reparse = 0; /* needs 3th parse because of changed prototypes? */
13.149 -static int sc_parsenum = 0; /* number of the extra parses */
13.150 -static int wq[wqTABSZ]; /* "while queue", internal stack for nested loops */
13.151 -static int *wqptr; /* pointer to next entry */
13.152 -#if !defined SC_LIGHT
13.153 - static char sc_rootpath[_MAX_PATH];
13.154 - static char *sc_documentation=NULL;/* main documentation */
13.155 -#endif
13.156 -#if defined __WIN32__ || defined _WIN32 || defined _Windows
13.157 - static HWND hwndFinish = 0;
13.158 -#endif
13.159 -
13.160 -/* "main" of the compiler
13.161 - */
13.162 -#if defined __cplusplus
13.163 - extern "C"
13.164 -#endif
13.165 -int pc_compile(int argc, char *argv[])
13.166 -{
13.167 - int entry,i,jmpcode;
13.168 - int retcode;
13.169 - char incfname[_MAX_PATH];
13.170 - char reportname[_MAX_PATH];
13.171 - char codepage[MAXCODEPAGE+1];
13.172 - FILE *binf;
13.173 - void *inpfmark;
13.174 - int lcl_packstr,lcl_needsemicolon,lcl_tabsize;
13.175 - #if !defined SC_LIGHT
13.176 - int hdrsize=0;
13.177 - #endif
13.178 - char *ptr;
13.179 -
13.180 - /* set global variables to their initial value */
13.181 - binf=NULL;
13.182 - initglobals();
13.183 - errorset(sRESET,0);
13.184 - errorset(sEXPRRELEASE,0);
13.185 - lexinit();
13.186 -
13.187 - /* make sure that we clean up on a fatal error; do this before the first
13.188 - * call to error(). */
13.189 - if ((jmpcode=setjmp(errbuf))!=0)
13.190 - goto cleanup;
13.191 -
13.192 - /* allocate memory for fixed tables */
13.193 - inpfname=(char*)malloc(_MAX_PATH);
13.194 - if (inpfname==NULL)
13.195 - error(103); /* insufficient memory */
13.196 - litq=(cell*)malloc(litmax*sizeof(cell));
13.197 - if (litq==NULL)
13.198 - error(103); /* insufficient memory */
13.199 - if (!phopt_init())
13.200 - error(103); /* insufficient memory */
13.201 -
13.202 - setopt(argc,argv,outfname,errfname,incfname,reportname,codepage);
13.203 - strcpy(binfname,outfname);
13.204 - ptr=get_extension(binfname);
13.205 - if (ptr!=NULL && stricmp(ptr,".asm")==0)
13.206 - set_extension(binfname,".smx",TRUE);
13.207 - else
13.208 - set_extension(binfname,".smx",FALSE);
13.209 - /* set output names that depend on the input name */
13.210 - if (sc_listing)
13.211 - set_extension(outfname,".lst",TRUE);
13.212 - else
13.213 - set_extension(outfname,".asm",TRUE);
13.214 - if (strlen(errfname)!=0)
13.215 - remove(errfname); /* delete file on startup */
13.216 - else if (verbosity>0)
13.217 - setcaption();
13.218 - setconfig(argv[0]); /* the path to the include and codepage files */
13.219 - sc_ctrlchar_org=sc_ctrlchar;
13.220 - lcl_packstr=sc_packstr;
13.221 - lcl_needsemicolon=sc_needsemicolon;
13.222 - lcl_tabsize=sc_tabsize;
13.223 - #if !defined NO_CODEPAGE
13.224 - if (!cp_set(codepage)) /* set codepage */
13.225 - error(108); /* codepage mapping file not found */
13.226 - #endif
13.227 - /* optionally create a temporary input file that is a collection of all
13.228 - * input files
13.229 - */
13.230 - assert(get_sourcefile(0)!=NULL); /* there must be at least one source file */
13.231 - if (get_sourcefile(1)!=NULL) {
13.232 - /* there are at least two or more source files */
13.233 - char *tname,*sname;
13.234 - FILE *ftmp,*fsrc;
13.235 - int fidx;
13.236 - #if defined __WIN32__ || defined _WIN32
13.237 - tname=_tempnam(NULL,"pawn");
13.238 - #elif defined __MSDOS__ || defined _Windows
13.239 - tname=tempnam(NULL,"pawn");
13.240 - #elif defined(MACOS) && !defined(__MACH__)
13.241 - /* tempnam is not supported for the Macintosh CFM build. */
13.242 - error(104,get_sourcefile(1));
13.243 - tname=NULL;
13.244 - sname=NULL;
13.245 - #else
13.246 - tname=tempnam(NULL,"pawn");
13.247 - #endif
13.248 - ftmp=(FILE*)pc_createsrc(tname);
13.249 - for (fidx=0; (sname=get_sourcefile(fidx))!=NULL; fidx++) {
13.250 - unsigned char tstring[128];
13.251 - fsrc=(FILE*)pc_opensrc(sname);
13.252 - if (fsrc==NULL) {
13.253 - strcpy(inpfname,sname); /* avoid invalid filename */
13.254 - error(100,sname);
13.255 - } /* if */
13.256 - pc_writesrc(ftmp,(unsigned char*)"#file ");
13.257 - pc_writesrc(ftmp,(unsigned char*)sname);
13.258 - pc_writesrc(ftmp,(unsigned char*)"\n");
13.259 - while (!pc_eofsrc(fsrc)) {
13.260 - pc_readsrc(fsrc,tstring,sizeof tstring);
13.261 - pc_writesrc(ftmp,tstring);
13.262 - } /* while */
13.263 - pc_closesrc(fsrc);
13.264 - } /* for */
13.265 - pc_closesrc(ftmp);
13.266 - strcpy(inpfname,tname);
13.267 - free(tname);
13.268 - } else {
13.269 - strcpy(inpfname,get_sourcefile(0));
13.270 - } /* if */
13.271 - inpf_org=(FILE*)pc_opensrc(inpfname);
13.272 - if (inpf_org==NULL)
13.273 - error(100,inpfname);
13.274 - freading=TRUE;
13.275 - outf=(FILE*)pc_openasm(outfname); /* first write to assembler file (may be temporary) */
13.276 - if (outf==NULL)
13.277 - error(101,outfname);
13.278 - /* immediately open the binary file, for other programs to check */
13.279 - if (sc_asmfile || sc_listing) {
13.280 - binf=NULL;
13.281 - } else {
13.282 - binf=(FILE*)pc_openbin(binfname);
13.283 - if (binf==NULL)
13.284 - error(101,binfname);
13.285 - } /* if */
13.286 - setconstants(); /* set predefined constants and tagnames */
13.287 - for (i=0; i<skipinput; i++) /* skip lines in the input file */
13.288 - if (pc_readsrc(inpf_org,pline,sLINEMAX)!=NULL)
13.289 - fline++; /* keep line number up to date */
13.290 - skipinput=fline;
13.291 - sc_status=statFIRST;
13.292 - /* write starting options (from the command line or the configuration file) */
13.293 - if (sc_listing) {
13.294 - char string[150];
13.295 - sprintf(string,"#pragma ctrlchar 0x%02x\n"
13.296 - "#pragma pack %s\n"
13.297 - "#pragma semicolon %s\n"
13.298 - "#pragma tabsize %d\n",
13.299 - sc_ctrlchar,
13.300 - sc_packstr ? "true" : "false",
13.301 - sc_needsemicolon ? "true" : "false",
13.302 - sc_tabsize);
13.303 - pc_writeasm(outf,string);
13.304 - setfiledirect(inpfname);
13.305 - } /* if */
13.306 - /* do the first pass through the file (or possibly two or more "first passes") */
13.307 - sc_parsenum=0;
13.308 - inpfmark=pc_getpossrc(inpf_org);
13.309 - do {
13.310 - /* reset "defined" flag of all functions and global variables */
13.311 - reduce_referrers(&glbtab);
13.312 - delete_symbols(&glbtab,0,TRUE,FALSE);
13.313 - #if !defined NO_DEFINE
13.314 - delete_substtable();
13.315 - inst_datetime_defines();
13.316 - #endif
13.317 - resetglobals();
13.318 - sc_ctrlchar=sc_ctrlchar_org;
13.319 - sc_packstr=lcl_packstr;
13.320 - sc_needsemicolon=lcl_needsemicolon;
13.321 - sc_tabsize=lcl_tabsize;
13.322 - errorset(sRESET,0);
13.323 - /* reset the source file */
13.324 - inpf=inpf_org;
13.325 - freading=TRUE;
13.326 - pc_resetsrc(inpf,inpfmark); /* reset file position */
13.327 - fline=skipinput; /* reset line number */
13.328 - sc_reparse=FALSE; /* assume no extra passes */
13.329 - sc_status=statFIRST; /* resetglobals() resets it to IDLE */
13.330 -
13.331 - if (strlen(incfname)>0) {
13.332 - if (strcmp(incfname,sDEF_PREFIX)==0) {
13.333 - plungefile(incfname,FALSE,TRUE); /* parse "default.inc" */
13.334 - } else {
13.335 - if (!plungequalifiedfile(incfname)) /* parse "prefix" include file */
13.336 - error(100,incfname); /* cannot read from ... (fatal error) */
13.337 - } /* if */
13.338 - } /* if */
13.339 - preprocess(); /* fetch first line */
13.340 - parse(); /* process all input */
13.341 - sc_parsenum++;
13.342 - } while (sc_reparse);
13.343 -
13.344 - /* second (or third) pass */
13.345 - sc_status=statWRITE; /* set, to enable warnings */
13.346 - state_conflict(&glbtab);
13.347 -
13.348 - /* write a report, if requested */
13.349 - #if !defined SC_LIGHT
13.350 - if (sc_makereport) {
13.351 - FILE *frep=stdout;
13.352 - if (strlen(reportname)>0)
13.353 - frep=fopen(reportname,"wb"); /* avoid translation of \n to \r\n in DOS/Windows */
13.354 - if (frep!=NULL) {
13.355 - make_report(&glbtab,frep,get_sourcefile(0));
13.356 - if (strlen(reportname)>0)
13.357 - fclose(frep);
13.358 - } /* if */
13.359 - if (sc_documentation!=NULL) {
13.360 - free(sc_documentation);
13.361 - sc_documentation=NULL;
13.362 - } /* if */
13.363 - } /* if */
13.364 - #endif
13.365 - if (sc_listing)
13.366 - goto cleanup;
13.367 -
13.368 - /* ??? for re-parsing the listing file instead of the original source
13.369 - * file (and doing preprocessing twice):
13.370 - * - close input file, close listing file
13.371 - * - re-open listing file for reading (inpf)
13.372 - * - open assembler file (outf)
13.373 - */
13.374 -
13.375 - /* reset "defined" flag of all functions and global variables */
13.376 - reduce_referrers(&glbtab);
13.377 - delete_symbols(&glbtab,0,TRUE,FALSE);
13.378 - #if !defined NO_DEFINE
13.379 - delete_substtable();
13.380 - inst_datetime_defines();
13.381 - #endif
13.382 - resetglobals();
13.383 - sc_ctrlchar=sc_ctrlchar_org;
13.384 - sc_packstr=lcl_packstr;
13.385 - sc_needsemicolon=lcl_needsemicolon;
13.386 - sc_tabsize=lcl_tabsize;
13.387 - errorset(sRESET,0);
13.388 - /* reset the source file */
13.389 - inpf=inpf_org;
13.390 - freading=TRUE;
13.391 - pc_resetsrc(inpf,inpfmark); /* reset file position */
13.392 - fline=skipinput; /* reset line number */
13.393 - lexinit(); /* clear internal flags of lex() */
13.394 - sc_status=statWRITE; /* allow to write --this variable was reset by resetglobals() */
13.395 - writeleader(&glbtab);
13.396 - insert_dbgfile(inpfname);
13.397 - if (strlen(incfname)>0) {
13.398 - if (strcmp(incfname,sDEF_PREFIX)==0)
13.399 - plungefile(incfname,FALSE,TRUE); /* parse "default.inc" (again) */
13.400 - else
13.401 - plungequalifiedfile(incfname); /* parse implicit include file (again) */
13.402 - } /* if */
13.403 - preprocess(); /* fetch first line */
13.404 - parse(); /* process all input */
13.405 - /* inpf is already closed when readline() attempts to pop of a file */
13.406 - writetrailer(); /* write remaining stuff */
13.407 -
13.408 - entry=testsymbols(&glbtab,0,TRUE,FALSE); /* test for unused or undefined
13.409 - * functions and variables */
13.410 - if (!entry)
13.411 - error(13); /* no entry point (no public functions) */
13.412 -
13.413 -cleanup:
13.414 - if (inpf!=NULL) /* main source file is not closed, do it now */
13.415 - pc_closesrc(inpf);
13.416 - /* write the binary file (the file is already open) */
13.417 - if (!(sc_asmfile || sc_listing) && errnum==0 && jmpcode==0) {
13.418 - assert(binf!=NULL);
13.419 - pc_resetasm(outf); /* flush and loop back, for reading */
13.420 - #if !defined SC_LIGHT
13.421 - hdrsize=
13.422 - #endif
13.423 - assemble(binf,outf); /* assembler file is now input */
13.424 - } /* if */
13.425 - if (outf!=NULL) {
13.426 - pc_closeasm(outf,!(sc_asmfile || sc_listing));
13.427 - outf=NULL;
13.428 - } /* if */
13.429 - if (binf!=NULL) {
13.430 - pc_closebin(binf,errnum!=0);
13.431 - binf=NULL;
13.432 - } /* if */
13.433 -
13.434 - #if !defined SC_LIGHT
13.435 - if (errnum==0 && strlen(errfname)==0) {
13.436 - int recursion;
13.437 - long stacksize=max_stacksize(&glbtab,&recursion);
13.438 - int flag_exceed=0;
13.439 - if (pc_amxlimit>0) {
13.440 - long totalsize=hdrsize+code_idx;
13.441 - if (pc_amxram==0)
13.442 - totalsize+=(glb_declared+pc_stksize)*sizeof(cell);
13.443 - if (totalsize>=pc_amxlimit)
13.444 - flag_exceed=1;
13.445 - } /* if */
13.446 - if (pc_amxram>0 && (glb_declared+pc_stksize)*sizeof(cell)>=(unsigned long)pc_amxram)
13.447 - flag_exceed=1;
13.448 - if (!norun && (sc_debug & sSYMBOLIC)!=0 || verbosity>=2 || stacksize+32>=(long)pc_stksize || flag_exceed) {
13.449 - pc_printf("Header size: %8ld bytes\n", (long)hdrsize);
13.450 - pc_printf("Code size: %8ld bytes\n", (long)code_idx);
13.451 - pc_printf("Data size: %8ld bytes\n", (long)glb_declared*sizeof(cell));
13.452 - pc_printf("Stack/heap size: %8ld bytes; ", (long)pc_stksize*sizeof(cell));
13.453 - pc_printf("estimated max. usage");
13.454 - if (recursion)
13.455 - pc_printf(" is unknown, due to recursion\n");
13.456 - else if ((pc_memflags & suSLEEP_INSTR)!=0)
13.457 - pc_printf(" is unknown, due to the \"sleep\" instruction\n");
13.458 - else
13.459 - pc_printf("=%ld cells (%ld bytes)\n",stacksize,stacksize*sizeof(cell));
13.460 - pc_printf("Total requirements:%8ld bytes\n", (long)hdrsize+(long)code_idx+(long)glb_declared*sizeof(cell)+(long)pc_stksize*sizeof(cell));
13.461 - } /* if */
13.462 - if (flag_exceed)
13.463 - error(106,pc_amxlimit+pc_amxram); /* this causes a jump back to label "cleanup" */
13.464 - } /* if */
13.465 - #endif
13.466 -
13.467 - if (inpfname!=NULL) {
13.468 - if (get_sourcefile(1)!=NULL)
13.469 - remove(inpfname); /* the "input file" was in fact a temporary file */
13.470 - free(inpfname);
13.471 - } /* if */
13.472 - if (litq!=NULL)
13.473 - free(litq);
13.474 - phopt_cleanup();
13.475 - stgbuffer_cleanup();
13.476 - clearstk();
13.477 - assert(jmpcode!=0 || loctab.next==NULL);/* on normal flow, local symbols
13.478 - * should already have been deleted */
13.479 - delete_symbols(&loctab,0,TRUE,TRUE); /* delete local variables if not yet
13.480 - * done (i.e. on a fatal error) */
13.481 - delete_symbols(&glbtab,0,TRUE,TRUE);
13.482 - delete_consttable(&tagname_tab);
13.483 - delete_consttable(&libname_tab);
13.484 - delete_consttable(&sc_automaton_tab);
13.485 - delete_consttable(&sc_state_tab);
13.486 - state_deletetable();
13.487 - delete_aliastable();
13.488 - delete_pathtable();
13.489 - delete_sourcefiletable();
13.490 - delete_dbgstringtable();
13.491 - #if !defined NO_DEFINE
13.492 - delete_substtable();
13.493 - #endif
13.494 - #if !defined SC_LIGHT
13.495 - delete_docstringtable();
13.496 - if (sc_documentation!=NULL)
13.497 - free(sc_documentation);
13.498 - #endif
13.499 - delete_autolisttable();
13.500 - if (errnum!=0) {
13.501 - if (strlen(errfname)==0)
13.502 - pc_printf("\n%d Error%s.\n",errnum,(errnum>1) ? "s" : "");
13.503 - retcode=1;
13.504 - } else if (warnnum!=0){
13.505 - if (strlen(errfname)==0)
13.506 - pc_printf("\n%d Warning%s.\n",warnnum,(warnnum>1) ? "s" : "");
13.507 - retcode=0; /* use "0", so that MAKE and similar tools continue */
13.508 - } else {
13.509 - retcode=jmpcode;
13.510 - if (retcode==0 && verbosity>=2)
13.511 - pc_printf("\nDone.\n");
13.512 - } /* if */
13.513 - #if defined __WIN32__ || defined _WIN32 || defined _Windows
13.514 - if (IsWindow(hwndFinish))
13.515 - PostMessageA(hwndFinish,RegisterWindowMessageA("PawnNotify"),retcode,0L);
13.516 - #endif
13.517 - #if defined FORTIFY
13.518 - Fortify_ListAllMemory();
13.519 - #endif
13.520 - return retcode;
13.521 -}
13.522 -
13.523 -#if defined __cplusplus
13.524 - extern "C"
13.525 -#endif
13.526 -int pc_addconstant(char *name,cell value,int tag)
13.527 -{
13.528 - errorset(sFORCESET,0); /* make sure error engine is silenced */
13.529 - sc_status=statIDLE;
13.530 - add_constant(name,value,sGLOBAL,tag);
13.531 - return 1;
13.532 -}
13.533 -
13.534 -static void inst_datetime_defines(void)
13.535 -{
13.536 - char date[64];
13.537 - char ltime[64];
13.538 - time_t td;
13.539 - struct tm *curtime;
13.540 -
13.541 - time(&td);
13.542 - curtime = localtime(&td);
13.543 - strftime(date, 31, "\"%m/%d%Y\"", curtime);
13.544 - strftime(ltime, 31, "\"%H:%M:%S\"", curtime);
13.545 -
13.546 - insert_subst("__DATE__", date, 8);
13.547 - insert_subst("__TIME__", ltime, 8);
13.548 -}
13.549 -
13.550 -#if defined __cplusplus
13.551 - extern "C"
13.552 -#endif
13.553 -int pc_addtag(char *name)
13.554 -{
13.555 - cell val;
13.556 - constvalue *ptr;
13.557 - int last,tag;
13.558 -
13.559 - if (name==NULL) {
13.560 - /* no tagname was given, check for one */
13.561 - if (lex(&val,&name)!=tLABEL) {
13.562 - lexpush();
13.563 - return 0; /* untagged */
13.564 - } /* if */
13.565 - } /* if */
13.566 -
13.567 - assert(strchr(name,':')==NULL); /* colon should already have been stripped */
13.568 - last=0;
13.569 - ptr=tagname_tab.next;
13.570 - while (ptr!=NULL) {
13.571 - tag=(int)(ptr->value & TAGMASK);
13.572 - if (strcmp(name,ptr->name)==0)
13.573 - return tag; /* tagname is known, return its sequence number */
13.574 - tag &= (int)~FIXEDTAG;
13.575 - if (tag>last)
13.576 - last=tag;
13.577 - ptr=ptr->next;
13.578 - } /* while */
13.579 -
13.580 - /* tagname currently unknown, add it */
13.581 - tag=last+1; /* guaranteed not to exist already */
13.582 - if (isupper(*name))
13.583 - tag |= (int)FIXEDTAG;
13.584 - append_constval(&tagname_tab,name,(cell)tag,0);
13.585 - return tag;
13.586 -}
13.587 -
13.588 -static void resetglobals(void)
13.589 -{
13.590 - /* reset the subset of global variables that is modified by the first pass */
13.591 - curfunc=NULL; /* pointer to current function */
13.592 - lastst=0; /* last executed statement type */
13.593 - nestlevel=0; /* number of active (open) compound statements */
13.594 - rettype=0; /* the type that a "return" expression should have */
13.595 - litidx=0; /* index to literal table */
13.596 - stgidx=0; /* index to the staging buffer */
13.597 - sc_labnum=0; /* top value of (internal) labels */
13.598 - staging=0; /* true if staging output */
13.599 - declared=0; /* number of local cells declared */
13.600 - glb_declared=0; /* number of global cells declared */
13.601 - code_idx=0; /* number of bytes with generated code */
13.602 - ntv_funcid=0; /* incremental number of native function */
13.603 - curseg=0; /* 1 if currently parsing CODE, 2 if parsing DATA */
13.604 - freading=FALSE; /* no input file ready yet */
13.605 - fline=0; /* the line number in the current file */
13.606 - fnumber=0; /* the file number in the file table (debugging) */
13.607 - fcurrent=0; /* current file being processed (debugging) */
13.608 - sc_intest=FALSE; /* true if inside a test */
13.609 - sideeffect=0; /* true if an expression causes a side-effect */
13.610 - stmtindent=0; /* current indent of the statement */
13.611 - indent_nowarn=FALSE; /* do not skip warning "217 loose indentation" */
13.612 - sc_allowtags=TRUE; /* allow/detect tagnames */
13.613 - sc_status=statIDLE;
13.614 - sc_allowproccall=FALSE;
13.615 - pc_addlibtable=TRUE; /* by default, add a "library table" to the output file */
13.616 - sc_alignnext=FALSE;
13.617 - pc_docexpr=FALSE;
13.618 - pc_depricate=NULL;
13.619 - sc_curstates=0;
13.620 - pc_memflags=0;
13.621 -}
13.622 -
13.623 -static void initglobals(void)
13.624 -{
13.625 - resetglobals();
13.626 -
13.627 - sc_asmfile=FALSE; /* do not create .ASM file */
13.628 - sc_listing=FALSE; /* do not create .LST file */
13.629 - skipinput=0; /* number of lines to skip from the first input file */
13.630 - sc_ctrlchar=CTRL_CHAR;/* the escape character */
13.631 - litmax=sDEF_LITMAX; /* current size of the literal table */
13.632 - errnum=0; /* number of errors */
13.633 - warnnum=0; /* number of warnings */
13.634 - optproccall=FALSE; /* sourcemod: do not support "procedure call" */
13.635 - verbosity=1; /* verbosity level, no copyright banner */
13.636 - sc_debug=sCHKBOUNDS|sSYMBOLIC; /* sourcemod: full debug stuff */
13.637 - pc_optimize=sOPTIMIZE_DEFAULT; /* sourcemod: full optimization */
13.638 - sc_packstr=FALSE; /* strings are unpacked by default */
13.639 - sc_compress=FALSE; /* always disable compact encoding! */
13.640 - sc_needsemicolon=FALSE;/* semicolon required to terminate expressions? */
13.641 - sc_dataalign=sizeof(cell);
13.642 - pc_stksize=sDEF_AMXSTACK;/* default stack size */
13.643 - pc_amxlimit=0; /* no limit on size of the abstract machine */
13.644 - pc_amxram=0; /* no limit on data size of the abstract machine */
13.645 - sc_tabsize=8; /* assume a TAB is 8 spaces */
13.646 - sc_rationaltag=0; /* assume no support for rational numbers */
13.647 - rational_digits=0; /* number of fractional digits */
13.648 -
13.649 - outfname[0]='\0'; /* output file name */
13.650 - errfname[0]='\0'; /* error file name */
13.651 - inpf=NULL; /* file read from */
13.652 - inpfname=NULL; /* pointer to name of the file currently read from */
13.653 - outf=NULL; /* file written to */
13.654 - litq=NULL; /* the literal queue */
13.655 - glbtab.next=NULL; /* clear global variables/constants table */
13.656 - loctab.next=NULL; /* " local " / " " */
13.657 - tagname_tab.next=NULL;/* tagname table */
13.658 - libname_tab.next=NULL;/* library table (#pragma library "..." syntax) */
13.659 -
13.660 - pline[0]='\0'; /* the line read from the input file */
13.661 - lptr=NULL; /* points to the current position in "pline" */
13.662 - curlibrary=NULL; /* current library */
13.663 - inpf_org=NULL; /* main source file */
13.664 -
13.665 - wqptr=wq; /* initialize while queue pointer */
13.666 -
13.667 -#if !defined SC_LIGHT
13.668 - sc_documentation=NULL;
13.669 - sc_makereport=FALSE; /* do not generate a cross-reference report */
13.670 -#endif
13.671 -}
13.672 -
13.673 -static char *get_extension(char *filename)
13.674 -{
13.675 - char *ptr;
13.676 -
13.677 - assert(filename!=NULL);
13.678 - ptr=strrchr(filename,'.');
13.679 - if (ptr!=NULL) {
13.680 - /* ignore extension on a directory or at the start of the filename */
13.681 - if (strchr(ptr,DIRSEP_CHAR)!=NULL || ptr==filename || *(ptr-1)==DIRSEP_CHAR)
13.682 - ptr=NULL;
13.683 - } /* if */
13.684 - return ptr;
13.685 -}
13.686 -
13.687 -/* set_extension
13.688 - * Set the default extension, or force an extension. To erase the
13.689 - * extension of a filename, set "extension" to an empty string.
13.690 - */
13.691 -SC_FUNC void set_extension(char *filename,char *extension,int force)
13.692 -{
13.693 - char *ptr;
13.694 -
13.695 - assert(extension!=NULL && (*extension=='\0' || *extension=='.'));
13.696 - assert(filename!=NULL);
13.697 - ptr=get_extension(filename);
13.698 - if (force && ptr!=NULL)
13.699 - *ptr='\0'; /* set zero terminator at the position of the period */
13.700 - if (force || ptr==NULL)
13.701 - strcat(filename,extension);
13.702 -}
13.703 -
13.704 -static const char *option_value(const char *optptr)
13.705 -{
13.706 - return (*(optptr+1)=='=' || *(optptr+1)==':') ? optptr+2 : optptr+1;
13.707 -}
13.708 -
13.709 -static int toggle_option(const char *optptr, int option)
13.710 -{
13.711 - switch (*option_value(optptr)) {
13.712 - case '\0':
13.713 - option=!option;
13.714 - break;
13.715 - case '-':
13.716 - option=FALSE;
13.717 - break;
13.718 - case '+':
13.719 - option=TRUE;
13.720 - break;
13.721 - default:
13.722 - about();
13.723 - } /* switch */
13.724 - return option;
13.725 -}
13.726 -
13.727 -/* Parsing command line options is indirectly recursive: parseoptions()
13.728 - * calls parserespf() to handle options in a a response file and
13.729 - * parserespf() calls parseoptions() at its turn after having created
13.730 - * an "option list" from the contents of the file.
13.731 - */
13.732 -static void parserespf(char *filename,char *oname,char *ename,char *pname,
13.733 - char *rname, char *codepage);
13.734 -
13.735 -static void parseoptions(int argc,char **argv,char *oname,char *ename,char *pname,
13.736 - char *rname, char *codepage)
13.737 -{
13.738 - char str[_MAX_PATH],*name;
13.739 - const char *ptr;
13.740 - int arg,i,isoption;
13.741 -
13.742 - for (arg=1; arg<argc; arg++) {
13.743 - #if DIRSEP_CHAR=='/'
13.744 - isoption= argv[arg][0]=='-';
13.745 - #else
13.746 - isoption= argv[arg][0]=='/' || argv[arg][0]=='-';
13.747 - #endif
13.748 - if (isoption) {
13.749 - ptr=&argv[arg][1];
13.750 - switch (*ptr) {
13.751 - case 'A':
13.752 - i=atoi(option_value(ptr));
13.753 - if ((i % sizeof(cell))==0)
13.754 - sc_dataalign=i;
13.755 - else
13.756 - about();
13.757 - break;
13.758 - case 'a':
13.759 - if (*(ptr+1)!='\0')
13.760 - about();
13.761 - sc_asmfile=TRUE; /* skip last pass of making binary file */
13.762 - if (verbosity>1)
13.763 - verbosity=1;
13.764 - break;
13.765 -#if 0 /* not allowed in SourceMod */
13.766 - case 'C':
13.767 - #if AMX_COMPACTMARGIN > 2
13.768 - sc_compress=toggle_option(ptr,sc_compress);
13.769 - #else
13.770 - about();
13.771 - #endif
13.772 - break;
13.773 -#endif
13.774 - case 'c':
13.775 - strlcpy(codepage,option_value(ptr),MAXCODEPAGE); /* set name of codepage */
13.776 - break;
13.777 -#if defined dos_setdrive
13.778 - case 'D': /* set active directory */
13.779 - ptr=option_value(ptr);
13.780 - if (ptr[1]==':')
13.781 - dos_setdrive(toupper(*ptr)-'A'+1); /* set active drive */
13.782 - chdir(ptr);
13.783 - break;
13.784 -#endif
13.785 -#if 0 /* not allowed to change for SourceMod */
13.786 - case 'd':
13.787 - switch (*option_value(ptr)) {
13.788 - case '0':
13.789 - sc_debug=0;
13.790 - break;
13.791 - case '1':
13.792 - sc_debug=sCHKBOUNDS; /* assertions and bounds checking */
13.793 - break;
13.794 - case '2':
13.795 - sc_debug=sCHKBOUNDS | sSYMBOLIC; /* also symbolic info */
13.796 - break;
13.797 - case '3':
13.798 - sc_debug=sCHKBOUNDS | sSYMBOLIC;
13.799 - pc_optimize=sOPTIMIZE_NONE;
13.800 - /* also avoid peephole optimization */
13.801 - break;
13.802 - default:
13.803 - about();
13.804 - } /* switch */
13.805 - break;
13.806 -#endif
13.807 - case 'e':
13.808 - strlcpy(ename,option_value(ptr),_MAX_PATH); /* set name of error file */
13.809 - break;
13.810 -#if defined __WIN32__ || defined _WIN32 || defined _Windows
13.811 - case 'H':
13.812 - hwndFinish=(HWND)atoi(option_value(ptr));
13.813 - if (!IsWindow(hwndFinish))
13.814 - hwndFinish=(HWND)0;
13.815 - break;
13.816 -#endif
13.817 - case 'i':
13.818 - strlcpy(str,option_value(ptr),sizeof str); /* set name of include directory */
13.819 - i=strlen(str);
13.820 - if (i>0) {
13.821 - if (str[i-1]!=DIRSEP_CHAR) {
13.822 - str[i]=DIRSEP_CHAR;
13.823 - str[i+1]='\0';
13.824 - } /* if */
13.825 - insert_path(str);
13.826 - } /* if */
13.827 - break;
13.828 - case 'l':
13.829 - if (*(ptr+1)!='\0')
13.830 - about();
13.831 - sc_listing=TRUE; /* skip second pass & code generation */
13.832 - break;
13.833 - case 'o':
13.834 - strlcpy(oname,option_value(ptr),_MAX_PATH); /* set name of (binary) output file */
13.835 - break;
13.836 - case 'O':
13.837 - pc_optimize=*option_value(ptr) - '0';
13.838 - if (pc_optimize<sOPTIMIZE_NONE || pc_optimize>=sOPTIMIZE_NUMBER || pc_optimize==sOPTIMIZE_NOMACRO)
13.839 - about();
13.840 - break;
13.841 - case 'p':
13.842 - strlcpy(pname,option_value(ptr),_MAX_PATH); /* set name of implicit include file */
13.843 - break;
13.844 -#if !defined SC_LIGHT
13.845 - case 'r':
13.846 - strlcpy(rname,option_value(ptr),_MAX_PATH); /* set name of report file */
13.847 - sc_makereport=TRUE;
13.848 - if (strlen(rname)>0) {
13.849 - set_extension(rname,".xml",FALSE);
13.850 - } else if ((name=get_sourcefile(0))!=NULL) {
13.851 - assert(strlen(rname)==0);
13.852 - assert(strlen(name)<_MAX_PATH);
13.853 - if ((ptr=strrchr(name,DIRSEP_CHAR))!=NULL)
13.854 - ptr++; /* strip path */
13.855 - else
13.856 - ptr=name;
13.857 - assert(strlen(ptr)<_MAX_PATH);
13.858 - strcpy(rname,ptr);
13.859 - set_extension(rname,".xml",TRUE);
13.860 - } /* if */
13.861 - break;
13.862 -#endif
13.863 - case 'S':
13.864 - i=atoi(option_value(ptr));
13.865 - if (i>32)
13.866 - pc_stksize=(cell)i; /* stack size has minimum size */
13.867 - else
13.868 - about();
13.869 - break;
13.870 - case 's':
13.871 - skipinput=atoi(option_value(ptr));
13.872 - break;
13.873 - case 't':
13.874 - sc_tabsize=atoi(option_value(ptr));
13.875 - break;
13.876 - case 'v':
13.877 - verbosity= isdigit(*option_value(ptr)) ? atoi(option_value(ptr)) : 2;
13.878 - if (sc_asmfile && verbosity>1)
13.879 - verbosity=1;
13.880 - break;
13.881 - case 'w':
13.882 - i=(int)strtol(option_value(ptr),(char **)&ptr,10);
13.883 - if (*ptr=='-')
13.884 - pc_enablewarning(i,0);
13.885 - else if (*ptr=='+')
13.886 - pc_enablewarning(i,1);
13.887 - else if (*ptr=='\0')
13.888 - pc_enablewarning(i,2);
13.889 - break;
13.890 - case 'X':
13.891 - if (*(ptr+1)=='D') {
13.892 - i=atoi(option_value(ptr+1));
13.893 - if (i>64)
13.894 - pc_amxram=(cell)i; /* abstract machine data/stack has minimum size */
13.895 - else
13.896 - about();
13.897 - } else {
13.898 - i=atoi(option_value(ptr));
13.899 - if (i>64)
13.900 - pc_amxlimit=(cell)i;/* abstract machine has minimum size */
13.901 - else
13.902 - about();
13.903 - } /* if */
13.904 - break;
13.905 - case '\\': /* use \ instead for escape characters */
13.906 - sc_ctrlchar='\\';
13.907 - break;
13.908 - case '^': /* use ^ instead for escape characters */
13.909 - sc_ctrlchar='^';
13.910 - break;
13.911 - case ';':
13.912 - sc_needsemicolon=toggle_option(ptr,sc_needsemicolon);
13.913 - break;
13.914 -#if 0 /* not allowed to change in SourceMod */
13.915 - case '(':
13.916 - optproccall=!toggle_option(ptr,!optproccall);
13.917 - break;
13.918 -#endif
13.919 - default: /* wrong option */
13.920 - about();
13.921 - } /* switch */
13.922 - } else if (argv[arg][0]=='@') {
13.923 - #if !defined SC_LIGHT
13.924 - parserespf(&argv[arg][1],oname,ename,pname,rname,codepage);
13.925 - #endif
13.926 - } else if ((ptr=strchr(argv[arg],'='))!=NULL) {
13.927 - i=(int)(ptr-argv[arg]);
13.928 - if (i>sNAMEMAX) {
13.929 - i=sNAMEMAX;
13.930 - error(200,argv[arg],sNAMEMAX); /* symbol too long, truncated to sNAMEMAX chars */
13.931 - } /* if */
13.932 - strlcpy(str,argv[arg],i+1); /* str holds symbol name */
13.933 - i=atoi(ptr+1);
13.934 - add_constant(str,i,sGLOBAL,0);
13.935 - } else {
13.936 - strlcpy(str,argv[arg],sizeof(str)-5); /* -5 because default extension is ".psrc" */
13.937 - set_extension(str,".psrc",FALSE);
13.938 - insert_sourcefile(str);
13.939 - /* The output name is the first input name with a different extension,
13.940 - * but it is stored in a different directory
13.941 - */
13.942 - if (strlen(oname)==0) {
13.943 - if ((ptr=strrchr(str,DIRSEP_CHAR))!=NULL)
13.944 - ptr++; /* strip path */
13.945 - else
13.946 - ptr=str;
13.947 - assert(strlen(ptr)<_MAX_PATH);
13.948 - strcpy(oname,ptr);
13.949 - } /* if */
13.950 - set_extension(oname,".asm",TRUE);
13.951 -#if !defined SC_LIGHT
13.952 - if (sc_makereport && strlen(rname)==0) {
13.953 - if ((ptr=strrchr(str,DIRSEP_CHAR))!=NULL)
13.954 - ptr++; /* strip path */
13.955 - else
13.956 - ptr=str;
13.957 - assert(strlen(ptr)<_MAX_PATH);
13.958 - strcpy(rname,ptr);
13.959 - set_extension(rname,".xml",TRUE);
13.960 - } /* if */
13.961 -#endif
13.962 - } /* if */
13.963 - } /* for */
13.964 -}
13.965 -
13.966 -#if !defined SC_LIGHT
13.967 -static void parserespf(char *filename,char *oname,char *ename,char *pname,
13.968 - char *rname,char *codepage)
13.969 -{
13.970 -#define MAX_OPTIONS 100
13.971 - FILE *fp;
13.972 - char *string, *ptr, **argv;
13.973 - int argc;
13.974 - long size;
13.975 -
13.976 - if ((fp=fopen(filename,"r"))==NULL)
13.977 - error(100,filename); /* error reading input file */
13.978 - /* load the complete file into memory */
13.979 - fseek(fp,0L,SEEK_END);
13.980 - size=ftell(fp);
13.981 - fseek(fp,0L,SEEK_SET);
13.982 - assert(size<INT_MAX);
13.983 - if ((string=(char *)malloc((int)size+1))==NULL)
13.984 - error(103); /* insufficient memory */
13.985 - /* fill with zeros; in MS-DOS, fread() may collapse CR/LF pairs to
13.986 - * a single '\n', so the string size may be smaller than the file
13.987 - * size. */
13.988 - memset(string,0,(int)size+1);
13.989 - fread(string,1,(int)size,fp);
13.990 - fclose(fp);
13.991 - /* allocate table for option pointers */
13.992 - if ((argv=(char **)malloc(MAX_OPTIONS*sizeof(char*)))==NULL)
13.993 - error(103); /* insufficient memory */
13.994 - /* fill the options table */
13.995 - ptr=strtok(string," \t\r\n");
13.996 - for (argc=1; argc<MAX_OPTIONS && ptr!=NULL; argc++) {
13.997 - /* note: the routine skips argv[0], for compatibility with main() */
13.998 - argv[argc]=ptr;
13.999 - ptr=strtok(NULL," \t\r\n");
13.1000 - } /* for */
13.1001 - if (ptr!=NULL)
13.1002 - error(102,"option table"); /* table overflow */
13.1003 - /* parse the option table */
13.1004 - parseoptions(argc,argv,oname,ename,pname,rname,codepage);
13.1005 - /* free allocated memory */
13.1006 - free(argv);
13.1007 - free(string);
13.1008 -}
13.1009 -#endif
13.1010 -
13.1011 -static void setopt(int argc,char **argv,char *oname,char *ename,char *pname,
13.1012 - char *rname,char *codepage)
13.1013 -{
13.1014 - delete_sourcefiletable(); /* make sure it is empty */
13.1015 - *oname='\0';
13.1016 - *ename='\0';
13.1017 - *pname='\0';
13.1018 - *rname='\0';
13.1019 - *codepage='\0';
13.1020 - strcpy(pname,sDEF_PREFIX);
13.1021 -
13.1022 - #if 0 /* needed to test with BoundsChecker for DOS (it does not pass
13.1023 - * through arguments) */
13.1024 - insert_sourcefile("test.p");
13.1025 - strcpy(oname,"test.asm");
13.1026 - #endif
13.1027 -
13.1028 - #if !defined SC_LIGHT
13.1029 - /* first parse a "config" file with default options */
13.1030 - if (argv[0]!=NULL) {
13.1031 - char cfgfile[_MAX_PATH];
13.1032 - char *ext;
13.1033 - strcpy(cfgfile,argv[0]);
13.1034 - if ((ext=strrchr(cfgfile,DIRSEP_CHAR))!=NULL) {
13.1035 - *(ext+1)='\0'; /* strip the program filename */
13.1036 - strcat(cfgfile,"pawn.cfg");
13.1037 - } else {
13.1038 - strcpy(cfgfile,"pawn.cfg");
13.1039 - } /* if */
13.1040 - if (access(cfgfile,4)==0)
13.1041 - parserespf(cfgfile,oname,ename,pname,rname,codepage);
13.1042 - } /* if */
13.1043 - #endif
13.1044 - parseoptions(argc,argv,oname,ename,pname,rname,codepage);
13.1045 - if (get_sourcefile(0)==NULL)
13.1046 - about();
13.1047 -}
13.1048 -
13.1049 -#if defined __BORLANDC__ || defined __WATCOMC__
13.1050 - #pragma argsused
13.1051 -#endif
13.1052 -static void setconfig(char *root)
13.1053 -{
13.1054 - #if defined macintosh
13.1055 - insert_path(":include:");
13.1056 - #else
13.1057 - char path[_MAX_PATH];
13.1058 - char *ptr,*base;
13.1059 - int len;
13.1060 -
13.1061 - /* add the default "include" directory */
13.1062 - #if defined __WIN32__ || defined _WIN32
13.1063 - GetModuleFileNameA(NULL,path,_MAX_PATH);
13.1064 - #elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
13.1065 - /* see www.autopackage.org for the BinReloc module */
13.1066 - br_init_lib(NULL);
13.1067 - ptr=br_find_exe("spcomp");
13.1068 - strlcpy(path,ptr,sizeof path);
13.1069 - free(ptr);
13.1070 - #else
13.1071 - if (root!=NULL)
13.1072 - strlcpy(path,root,sizeof path); /* path + filename (hopefully) */
13.1073 - #endif
13.1074 - #if defined __MSDOS__
13.1075 - /* strip the options (appended to the path + filename) */
13.1076 - if ((ptr=strpbrk(path," \t/"))!=NULL)
13.1077 - *ptr='\0';
13.1078 - #endif
13.1079 - /* terminate just behind last \ or : */
13.1080 - if ((ptr=strrchr(path,DIRSEP_CHAR))!=NULL || (ptr=strchr(path,':'))!=NULL) {
13.1081 - /* If there is no "\" or ":", the string probably does not contain the
13.1082 - * path; so we just don't add it to the list in that case
13.1083 - */
13.1084 - *(ptr+1)='\0';
13.1085 - base=ptr;
13.1086 - strcat(path,"include");
13.1087 - len=strlen(path);
13.1088 - path[len]=DIRSEP_CHAR;
13.1089 - path[len+1]='\0';
13.1090 - /* see if it exists */
13.1091 - if (access(path,0)!=0 && *base==DIRSEP_CHAR) {
13.1092 - /* There is no "include" directory below the directory where the compiler
13.1093 - * is found. This typically means that the compiler is in a "bin" sub-directory
13.1094 - * and the "include" is below the *parent*. So find the parent...
13.1095 - */
13.1096 - *base='\0';
13.1097 - if ((ptr=strrchr(path,DIRSEP_CHAR))!=NULL) {
13.1098 - *(ptr+1)='\0';
13.1099 - strcat(path,"include");
13.1100 - len=strlen(path);
13.1101 - path[len]=DIRSEP_CHAR;
13.1102 - path[len+1]='\0';
13.1103 - } else {
13.1104 - *base=DIRSEP_CHAR;
13.1105 - } /* if */
13.1106 - } /* if */
13.1107 - insert_path(path);
13.1108 - /* same for the codepage root */
13.1109 - #if !defined NO_CODEPAGE
13.1110 - *ptr='\0';
13.1111 - if (!cp_path(path,"codepage"))
13.1112 - error(109,path); /* codepage path */
13.1113 - #endif
13.1114 - /* also copy the root path (for the XML documentation) */
13.1115 - #if !defined SC_LIGHT
13.1116 - *ptr='\0';
13.1117 - strcpy(sc_rootpath,path);
13.1118 - #endif
13.1119 - } /* if */
13.1120 - #endif /* macintosh */
13.1121 -}
13.1122 -
13.1123 -static void setcaption(void)
13.1124 -{
13.1125 - pc_printf("SourcePawn Compiler " SMC_VERSTRING "\n");
13.1126 - pc_printf("Copyright (c) 1997-2006, ITB CompuPhase, (C)2004-2006 AlliedModders, LLC\n\n");
13.1127 -}
13.1128 -
13.1129 -static void about(void)
13.1130 -{
13.1131 - if (strlen(errfname)==0) {
13.1132 - setcaption();
13.1133 - pc_printf("Usage: pawncc <filename> [filename...] [options]\n\n");
13.1134 - pc_printf("Options:\n");
13.1135 - pc_printf(" -A<num> alignment in bytes of the data segment and the stack\n");
13.1136 - pc_printf(" -a output assembler code\n");
13.1137 -#if 0 /* not toggleable in SourceMod */
13.1138 - pc_printf(" -C[+/-] compact encoding for output file (default=%c)\n", sc_compress ? '+' : '-');
13.1139 -#endif
13.1140 - pc_printf(" -c<name> codepage name or number; e.g. 1252 for Windows Latin-1\n");
13.1141 -#if defined dos_setdrive
13.1142 - pc_printf(" -Dpath active directory path\n");
13.1143 -#endif
13.1144 -#if 0 /* not used for SourceMod */
13.1145 - pc_printf(" -d<num> debugging level (default=-d%d)\n",sc_debug);
13.1146 - pc_printf(" 0 no symbolic information, no run-time checks\n");
13.1147 - pc_printf(" 1 run-time checks, no symbolic information\n");
13.1148 - pc_printf(" 2 full debug information and dynamic checking\n");
13.1149 - pc_printf(" 3 same as -d2, but implies -O0\n");
13.1150 -#endif
13.1151 - pc_printf(" -e<name> set name of error file (quiet compile)\n");
13.1152 -#if defined __WIN32__ || defined _WIN32 || defined _Windows
13.1153 - pc_printf(" -H<hwnd> window handle to send a notification message on finish\n");
13.1154 -#endif
13.1155 - pc_printf(" -i<name> path for include files\n");
13.1156 - pc_printf(" -l create list file (preprocess only)\n");
13.1157 - pc_printf(" -o<name> set base name of (P-code) output file\n");
13.1158 - pc_printf(" -O<num> optimization level (default=-O%d)\n",pc_optimize);
13.1159 - pc_printf(" 0 no optimization\n");
13.1160 -#if 0 /* not used for SourceMod */
13.1161 - pc_printf(" 1 JIT-compatible optimizations only\n");
13.1162 -#endif
13.1163 - pc_printf(" 2 full optimizations\n");
13.1164 - pc_printf(" -p<name> set name of \"prefix\" file\n");
13.1165 -#if !defined SC_LIGHT
13.1166 - pc_printf(" -r[name] write cross reference report to console or to specified file\n");
13.1167 -#endif
13.1168 - pc_printf(" -S<num> stack/heap size in cells (default=%d)\n",(int)pc_stksize);
13.1169 - pc_printf(" -s<num> skip lines from the input file\n");
13.1170 - pc_printf(" -t<num> TAB indent size (in character positions, default=%d)\n",sc_tabsize);
13.1171 - pc_printf(" -v<num> verbosity level; 0=quiet, 1=normal, 2=verbose (default=%d)\n",verbosity);
13.1172 - pc_printf(" -w<num> disable a specific warning by its number\n");
13.1173 - pc_printf(" -X<num> abstract machine size limit in bytes\n");
13.1174 - pc_printf(" -XD<num> abstract machine data/stack size limit in bytes\n");
13.1175 - pc_printf(" -\\ use '\\' for escape characters\n");
13.1176 - pc_printf(" -^ use '^' for escape characters\n");
13.1177 - pc_printf(" -;[+/-] require a semicolon to end each statement (default=%c)\n", sc_needsemicolon ? '+' : '-');
13.1178 -#if 0 /* not allowed in SourceMod */
13.1179 - pc_printf(" -([+/-] require parantheses for function invocation (default=%c)\n", optproccall ? '-' : '+');
13.1180 -#endif
13.1181 - pc_printf(" sym=val define constant \"sym\" with value \"val\"\n");
13.1182 - pc_printf(" sym= define constant \"sym\" with value 0\n");
13.1183 -#if defined __WIN32__ || defined _WIN32 || defined _Windows || defined __MSDOS__
13.1184 - pc_printf("\nOptions may start with a dash or a slash; the options \"-d0\" and \"/d0\" are\n");
13.1185 - pc_printf("equivalent.\n");
13.1186 -#endif
13.1187 - pc_printf("\nOptions with a value may optionally separate the value from the option letter\n");
13.1188 - pc_printf("with a colon (\":\") or an equal sign (\"=\"). That is, the options \"-d0\", \"-d=0\"\n");
13.1189 - pc_printf("and \"-d:0\" are all equivalent.\n");
13.1190 - } /* if */
13.1191 - norun = 1;
13.1192 - longjmp(errbuf,3); /* user abort */
13.1193 -}
13.1194 -
13.1195 -static void setconstants(void)
13.1196 -{
13.1197 - int debug;
13.1198 -
13.1199 - assert(sc_status==statIDLE);
13.1200 - append_constval(&tagname_tab,"_",0,0);/* "untagged" */
13.1201 - append_constval(&tagname_tab,"bool",1,0);
13.1202 -
13.1203 - add_constant("true",1,sGLOBAL,1); /* boolean flags */
13.1204 - add_constant("false",0,sGLOBAL,1);
13.1205 - add_constant("EOS",0,sGLOBAL,0); /* End Of String, or '\0' */
13.1206 - #if PAWN_CELL_SIZE==16
13.1207 - add_constant("cellbits",16,sGLOBAL,0);
13.1208 - #if defined _I16_MAX
13.1209 - add_constant("cellmax",_I16_MAX,sGLOBAL,0);
13.1210 - add_constant("cellmin",_I16_MIN,sGLOBAL,0);
13.1211 - #else
13.1212 - add_constant("cellmax",SHRT_MAX,sGLOBAL,0);
13.1213 - add_constant("cellmin",SHRT_MIN,sGLOBAL,0);
13.1214 - #endif
13.1215 - #elif PAWN_CELL_SIZE==32
13.1216 - add_constant("cellbits",32,sGLOBAL,0);
13.1217 - #if defined _I32_MAX
13.1218 - add_constant("cellmax",_I32_MAX,sGLOBAL,0);
13.1219 - add_constant("cellmin",_I32_MIN,sGLOBAL,0);
13.1220 - #else
13.1221 - add_constant("cellmax",LONG_MAX,sGLOBAL,0);
13.1222 - add_constant("cellmin",LONG_MIN,sGLOBAL,0);
13.1223 - #endif
13.1224 - #elif PAWN_CELL_SIZE==64
13.1225 - #if !defined _I64_MIN
13.1226 - #define _I64_MIN (-9223372036854775807ULL - 1)
13.1227 - #define _I64_MAX 9223372036854775807ULL
13.1228 - #endif
13.1229 - add_constant("cellbits",64,sGLOBAL,0);
13.1230 - add_constant("cellmax",_I64_MAX,sGLOBAL,0);
13.1231 - add_constant("cellmin",_I64_MIN,sGLOBAL,0);
13.1232 - #else
13.1233 - #error Unsupported cell size
13.1234 - #endif
13.1235 - add_constant("charbits",sCHARBITS,sGLOBAL,0);
13.1236 - add_constant("charmin",0,sGLOBAL,0);
13.1237 - add_constant("charmax",~(-1 << sCHARBITS) - 1,sGLOBAL,0);
13.1238 - add_constant("ucharmax",(1 << (sizeof(cell)-1)*8)-1,sGLOBAL,0);
13.1239 -
13.1240 - add_constant("__Pawn",VERSION_INT,sGLOBAL,0);
13.1241 -
13.1242 - debug=0;
13.1243 - if ((sc_debug & (sCHKBOUNDS | sSYMBOLIC))==(sCHKBOUNDS | sSYMBOLIC))
13.1244 - debug=2;
13.1245 - else if ((sc_debug & sCHKBOUNDS)==sCHKBOUNDS)
13.1246 - debug=1;
13.1247 - add_constant("debug",debug,sGLOBAL,0);
13.1248 -
13.1249 - append_constval(&sc_automaton_tab,"",0,0); /* anonymous automaton */
13.1250 -}
13.1251 -
13.1252 -static int getclassspec(int initialtok,int *fpublic,int *fstatic,int *fstock,int *fconst)
13.1253 -{
13.1254 - int tok,err;
13.1255 - cell val;
13.1256 - char *str;
13.1257 -
13.1258 - assert(fconst!=NULL);
13.1259 - assert(fstock!=NULL);
13.1260 - assert(fstatic!=NULL);
13.1261 - assert(fpublic!=NULL);
13.1262 - *fconst=FALSE;
13.1263 - *fstock=FALSE;
13.1264 - *fstatic=FALSE;
13.1265 - *fpublic=FALSE;
13.1266 - switch (initialtok) {
13.1267 - case tCONST:
13.1268 - *fconst=TRUE;
13.1269 - break;
13.1270 - case tSTOCK:
13.1271 - *fstock=TRUE;
13.1272 - break;
13.1273 - case tSTATIC:
13.1274 - *fstatic=TRUE;
13.1275 - break;
13.1276 - case tPUBLIC:
13.1277 - *fpublic=TRUE;
13.1278 - break;
13.1279 - } /* switch */
13.1280 -
13.1281 - err=0;
13.1282 - do {
13.1283 - tok=lex(&val,&str); /* read in (new) token */
13.1284 - switch (tok) {
13.1285 - case tCONST:
13.1286 - if (*fconst)
13.1287 - err=42; /* invalid combination of class specifiers */
13.1288 - *fconst=TRUE;
13.1289 - break;
13.1290 - case tSTOCK:
13.1291 - if (*fstock)
13.1292 - err=42; /* invalid combination of class specifiers */
13.1293 - *fstock=TRUE;
13.1294 - break;
13.1295 - case tSTATIC:
13.1296 - if (*fstatic)
13.1297 - err=42; /* invalid combination of class specifiers */
13.1298 - *fstatic=TRUE;
13.1299 - break;
13.1300 - case tPUBLIC:
13.1301 - if (*fpublic)
13.1302 - err=42; /* invalid combination of class specifiers */
13.1303 - *fpublic=TRUE;
13.1304 - break;
13.1305 - default:
13.1306 - lexpush();
13.1307 - tok=0; /* force break out of loop */
13.1308 - } /* switch */
13.1309 - } while (tok && err==0);
13.1310 -
13.1311 - /* extra checks */
13.1312 - if (*fstatic && *fpublic) {
13.1313 - err=42; /* invalid combination of class specifiers */
13.1314 - *fstatic=*fpublic=FALSE;
13.1315 - } /* if */
13.1316 -
13.1317 - if (err)
13.1318 - error(err);
13.1319 - return err==0;
13.1320 -}
13.1321 -
13.1322 -/* parse - process all input text
13.1323 - *
13.1324 - * At this level, only static declarations and function definitions are legal.
13.1325 - */
13.1326 -static void parse(void)
13.1327 -{
13.1328 - int tok,fconst,fstock,fstatic,fpublic;
13.1329 - cell val;
13.1330 - char *str;
13.1331 -
13.1332 - while (freading){
13.1333 - /* first try whether a declaration possibly is native or public */
13.1334 - tok=lex(&val,&str); /* read in (new) token */
13.1335 - switch (tok) {
13.1336 - case 0:
13.1337 - /* ignore zero's */
13.1338 - break;
13.1339 - case tNEW:
13.1340 - if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst))
13.1341 - declglb(NULL,0,fpublic,fstatic,fstock,fconst);
13.1342 - break;
13.1343 - case tSTATIC:
13.1344 - /* This can be a static function or a static global variable; we know
13.1345 - * which of the two as soon as we have parsed up to the point where an
13.1346 - * opening paranthesis of a function would be expected. To back out after
13.1347 - * deciding it was a declaration of a static variable after all, we have
13.1348 - * to store the symbol name and tag.
13.1349 - */
13.1350 - if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
13.1351 - assert(!fpublic);
13.1352 - declfuncvar(fpublic,fstatic,fstock,fconst);
13.1353 - } /* if */
13.1354 - break;
13.1355 - case tCONST:
13.1356 - decl_const(sGLOBAL);
13.1357 - break;
13.1358 - case tENUM:
13.1359 - decl_enum(sGLOBAL);
13.1360 - break;
13.1361 - case tPUBLIC:
13.1362 - /* This can be a public function or a public variable; see the comment
13.1363 - * above (for static functions/variables) for details.
13.1364 - */
13.1365 - if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
13.1366 - assert(!fstatic);
13.1367 - declfuncvar(fpublic,fstatic,fstock,fconst);
13.1368 - } /* if */
13.1369 - break;
13.1370 - case tSTOCK:
13.1371 - /* This can be a stock function or a stock *global*) variable; see the
13.1372 - * comment above (for static functions/variables) for details.
13.1373 - */
13.1374 - if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
13.1375 - assert(fstock);
13.1376 - declfuncvar(fpublic,fstatic,fstock,fconst);
13.1377 - } /* if */
13.1378 - break;
13.1379 - case tLABEL:
13.1380 - case tSYMBOL:
13.1381 - case tOPERATOR:
13.1382 - lexpush();
13.1383 - if (!newfunc(NULL,-1,FALSE,FALSE,FALSE)) {
13.1384 - error(10); /* illegal function or declaration */
13.1385 - lexclr(TRUE); /* drop the rest of the line */
13.1386 - litidx=0; /* drop the literal queue too */
13.1387 - } /* if */
13.1388 - break;
13.1389 - case tNATIVE:
13.1390 - funcstub(TRUE); /* create a dummy function */
13.1391 - break;
13.1392 - case tFORWARD:
13.1393 - funcstub(FALSE);
13.1394 - break;
13.1395 - case '}':
13.1396 - error(54); /* unmatched closing brace */
13.1397 - break;
13.1398 - case '{':
13.1399 - error(55); /* start of function body without function header */
13.1400 - break;
13.1401 - default:
13.1402 - if (freading) {
13.1403 - error(10); /* illegal function or declaration */
13.1404 - lexclr(TRUE); /* drop the rest of the line */
13.1405 - litidx=0; /* drop any literal arrays (strings) */
13.1406 - } /* if */
13.1407 - } /* switch */
13.1408 - } /* while */
13.1409 -}
13.1410 -
13.1411 -/* dumplits
13.1412 - *
13.1413 - * Dump the literal pool (strings etc.)
13.1414 - *
13.1415 - * Global references: litidx (referred to only)
13.1416 - */
13.1417 -static void dumplits(void)
13.1418 -{
13.1419 - int j,k;
13.1420 -
13.1421 - k=0;
13.1422 - while (k<litidx){
13.1423 - /* should be in the data segment */
13.1424 - assert(curseg==2);
13.1425 - defstorage();
13.1426 - j=16; /* 16 values per line */
13.1427 - while (j && k<litidx){
13.1428 - outval(litq[k], FALSE);
13.1429 - stgwrite(" ");
13.1430 - k++;
13.1431 - j--;
13.1432 - if (j==0 || k>=litidx)
13.1433 - stgwrite("\n"); /* force a newline after 10 dumps */
13.1434 - /* Note: stgwrite() buffers a line until it is complete. It recognizes
13.1435 - * the end of line as a sequence of "\n\0", so something like "\n\t"
13.1436 - * so should not be passed to stgwrite().
13.1437 - */
13.1438 - } /* while */
13.1439 - } /* while */
13.1440 -}
13.1441 -
13.1442 -/* dumpzero
13.1443 - *
13.1444 - * Dump zero's for default initial values
13.1445 - */
13.1446 -static void dumpzero(int count)
13.1447 -{
13.1448 - int i;
13.1449 -
13.1450 - if (count<=0)
13.1451 - return;
13.1452 - assert(curseg==2);
13.1453 - defstorage();
13.1454 - i=0;
13.1455 - while (count-- > 0) {
13.1456 - outval(0, FALSE);
13.1457 - i=(i+1) % 16;
13.1458 - stgwrite((i==0 || count==0) ? "\n" : " ");
13.1459 - if (i==0 && count>0)
13.1460 - defstorage();
13.1461 - } /* while */
13.1462 -}
13.1463 -
13.1464 -static void aligndata(int numbytes)
13.1465 -{
13.1466 - assert(numbytes % sizeof(cell) == 0); /* alignment must be a multiple of
13.1467 - * the cell size */
13.1468 - assert(numbytes!=0);
13.1469 -
13.1470 - if ((((glb_declared+litidx)*sizeof(cell)) % numbytes)!=0) {
13.1471 - while ((((glb_declared+litidx)*sizeof(cell)) % numbytes)!=0)
13.1472 - litadd(0);
13.1473 - } /* if */
13.1474 -
13.1475 -}
13.1476 -
13.1477 -#if !defined SC_LIGHT
13.1478 -/* sc_attachdocumentation()
13.1479 - * appends documentation comments to the passed-in symbol, or to a global
13.1480 - * string if "sym" is NULL.
13.1481 - */
13.1482 -void sc_attachdocumentation(symbol *sym)
13.1483 -{
13.1484 - int line;
13.1485 - size_t length;
13.1486 - char *str,*doc;
13.1487 -
13.1488 - if (!sc_makereport || sc_status!=statFIRST || sc_parsenum>0) {
13.1489 - /* just clear the entire table */
13.1490 - delete_docstringtable();
13.1491 - return;
13.1492 - } /* if */
13.1493 - /* in the case of state functions, multiple documentation sections may
13.1494 - * appear; we should concatenate these
13.1495 - * (with forward declarations, this is also already the case, so the assertion
13.1496 - * below is invalid)
13.1497 - */
13.1498 - // assert(sym==NULL || sym->documentation==NULL || sym->states!=NULL);
13.1499 -
13.1500 - /* first check the size */
13.1501 - length=0;
13.1502 - for (line=0; (str=get_docstring(line))!=NULL && *str!=sDOCSEP; line++) {
13.1503 - if (length>0)
13.1504 - length++; /* count 1 extra for a separating space */
13.1505 - length+=strlen(str);
13.1506 - } /* for */
13.1507 - if (sym==NULL && sc_documentation!=NULL) {
13.1508 - length += strlen(sc_documentation) + 1 + 4; /* plus 4 for "<p/>" */
13.1509 - assert(length>strlen(sc_documentation));
13.1510 - } /* if */
13.1511 -
13.1512 - if (length>0) {
13.1513 - /* allocate memory for the documentation */
13.1514 - if (sym!=NULL && sym->documentation!=NULL)
13.1515 - length+=strlen(sym->documentation) + 1 + 4;/* plus 4 for "<p/>" */
13.1516 - doc=(char*)malloc((length+1)*sizeof(char));
13.1517 - if (doc!=NULL) {
13.1518 - /* initialize string or concatenate */
13.1519 - if (sym==NULL && sc_documentation!=NULL) {
13.1520 - strcpy(doc,sc_documentation);
13.1521 - strcat(doc,"<p/>");
13.1522 - } else if (sym!=NULL && sym->documentation!=NULL) {
13.1523 - strcpy(doc,sym->documentation);
13.1524 - strcat(doc,"<p/>");
13.1525 - free(sym->documentation);
13.1526 - sym->documentation=NULL;
13.1527 - } else {
13.1528 - doc[0]='\0';
13.1529 - } /* if */
13.1530 - /* collect all documentation */
13.1531 - while ((str=get_docstring(0))!=NULL && *str!=sDOCSEP) {
13.1532 - if (doc[0]!='\0')
13.1533 - strcat(doc," ");
13.1534 - strcat(doc,str);
13.1535 - delete_docstring(0);
13.1536 - } /* while */
13.1537 - if (str!=NULL) {
13.1538 - /* also delete the separator */
13.1539 - assert(*str==sDOCSEP);
13.1540 - delete_docstring(0);
13.1541 - } /* if */
13.1542 - if (sym!=NULL) {
13.1543 - assert(sym->documentation==NULL);
13.1544 - sym->documentation=doc;
13.1545 - } else {
13.1546 - if (sc_documentation!=NULL)
13.1547 - free(sc_documentation);
13.1548 - sc_documentation=doc;
13.1549 - } /* if */
13.1550 - } /* if */
13.1551 - } else {
13.1552 - /* delete an empty separator, if present */
13.1553 - if ((str=get_docstring(0))!=NULL && *str==sDOCSEP)
13.1554 - delete_docstring(0);
13.1555 - } /* if */
13.1556 -}
13.1557 -
13.1558 -static void insert_docstring_separator(void)
13.1559 -{
13.1560 - char sep[2]={sDOCSEP,'\0'};
13.1561 - insert_docstring(sep);
13.1562 -}
13.1563 -#else
13.1564 - #define sc_attachdocumentation(s) (void)(s)
13.1565 - #define insert_docstring_separator()
13.1566 -#endif
13.1567 -
13.1568 -static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst)
13.1569 -{
13.1570 - char name[sNAMEMAX+11];
13.1571 - int tok,tag;
13.1572 - char *str;
13.1573 - cell val;
13.1574 - int invalidfunc;
13.1575 -
13.1576 - tag=pc_addtag(NULL);
13.1577 - tok=lex(&val,&str);
13.1578 - /* if we arrived here, this may not be a declaration of a native function
13.1579 - * or variable
13.1580 - */
13.1581 - if (tok==tNATIVE) {
13.1582 - error(42); /* invalid combination of class specifiers */
13.1583 - return;
13.1584 - } /* if */
13.1585 -
13.1586 - if (tok!=tSYMBOL && tok!=tOPERATOR) {
13.1587 - lexpush();
13.1588 - needtoken(tSYMBOL);
13.1589 - lexclr(TRUE); /* drop the rest of the line */
13.1590 - litidx=0; /* drop the literal queue too */
13.1591 - return;
13.1592 - } /* if */
13.1593 - if (tok==tOPERATOR) {
13.1594 - lexpush(); /* push "operator" keyword back (for later analysis) */
13.1595 - if (!newfunc(NULL,tag,fpublic,fstatic,fstock)) {
13.1596 - error(10); /* illegal function or declaration */
13.1597 - lexclr(TRUE); /* drop the rest of the line */
13.1598 - litidx=0; /* drop the literal queue too */
13.1599 - } /* if */
13.1600 - } else {
13.1601 - /* so tok is tSYMBOL */
13.1602 - assert(strlen(str)<=sNAMEMAX);
13.1603 - strcpy(name,str);
13.1604 - /* only variables can be "const" or both "public" and "stock" */
13.1605 - invalidfunc= fconst || (fpublic && fstock);
13.1606 - if (invalidfunc || !newfunc(name,tag,fpublic,fstatic,fstock)) {
13.1607 - /* if not a function, try a global variable */
13.1608 - declglb(name,tag,fpublic,fstatic,fstock,fconst);
13.1609 - } /* if */
13.1610 - } /* if */
13.1611 -}
13.1612 -
13.1613 -/* declglb - declare global symbols
13.1614 - *
13.1615 - * Declare a static (global) variable. Global variables are stored in
13.1616 - * the DATA segment.
13.1617 - *
13.1618 - * global references: glb_declared (altered)
13.1619 - */
13.1620 -static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fstock,int fconst)
13.1621 -{
13.1622 - int ident,tag,ispublic;
13.1623 - int idxtag[sDIMEN_MAX];
13.1624 - char name[sNAMEMAX+1];
13.1625 - cell val,size,cidx;
13.1626 - ucell address;
13.1627 - int glb_incr;
13.1628 - char *str;
13.1629 - int dim[sDIMEN_MAX];
13.1630 - int numdim;
13.1631 - short filenum;
13.1632 - symbol *sym;
13.1633 - constvalue *enumroot;
13.1634 - #if !defined NDEBUG
13.1635 - cell glbdecl=0;
13.1636 - #endif
13.1637 -
13.1638 - assert(!fpublic || !fstatic); /* may not both be set */
13.1639 - insert_docstring_separator(); /* see comment in newfunc() */
13.1640 - filenum=fcurrent; /* save file number at the start of the declaration */
13.1641 - do {
13.1642 - size=1; /* single size (no array) */
13.1643 - numdim=0; /* no dimensions */
13.1644 - ident=iVARIABLE;
13.1645 - if (firstname!=NULL) {
13.1646 - assert(strlen(firstname)<=sNAMEMAX);
13.1647 - strcpy(name,firstname); /* save symbol name */
13.1648 - tag=firsttag;
13.1649 - firstname=NULL;
13.1650 - } else {
13.1651 - tag=pc_addtag(NULL);
13.1652 - if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
13.1653 - error(20,str); /* invalid symbol name */
13.1654 - assert(strlen(str)<=sNAMEMAX);
13.1655 - strcpy(name,str); /* save symbol name */
13.1656 - } /* if */
13.1657 - ispublic=fpublic;
13.1658 - if (name[0]==PUBLIC_CHAR) {
13.1659 - ispublic=TRUE; /* implicitly public variable */
13.1660 - assert(!fstatic);
13.1661 - } /* if */
13.1662 - while (matchtoken('[')) {
13.1663 - ident=iARRAY;
13.1664 - if (numdim == sDIMEN_MAX) {
13.1665 - error(53); /* exceeding maximum number of dimensions */
13.1666 - return;
13.1667 - } /* if */
13.1668 - size=needsub(&idxtag[numdim],&enumroot); /* get size; size==0 for "var[]" */
13.1669 - #if INT_MAX < LONG_MAX
13.1670 - if (size > INT_MAX)
13.1671 - error(105); /* overflow, exceeding capacity */
13.1672 - #endif
13.1673 - if (ispublic)
13.1674 - error(56,name); /* arrays cannot be public */
13.1675 - dim[numdim++]=(int)size;
13.1676 - } /* while */
13.1677 - assert(sc_curstates==0);
13.1678 - sc_curstates=getstates(name);
13.1679 - if (sc_curstates<0) {
13.1680 - error(85,name); /* empty state list on declaration */
13.1681 - sc_curstates=0;
13.1682 - } else if (sc_curstates>0 && ispublic) {
13.1683 - error(88,name); /* public variables may not have states */
13.1684 - sc_curstates=0;
13.1685 - } /* if */
13.1686 - sym=findconst(name,NULL);
13.1687 - if (sym==NULL) {
13.1688 - sym=findglb(name,sSTATEVAR);
13.1689 - /* if a global variable without states is found and this declaration has
13.1690 - * states, the declaration is okay
13.1691 - */
13.1692 - if (sym!=NULL && sym->states==NULL && sc_curstates>0)
13.1693 - sym=NULL; /* set to NULL, we found the global variable */
13.1694 - if (sc_curstates>0 && findglb(name,sGLOBAL)!=NULL)
13.1695 - error(233,name); /* state variable shadows a global variable */
13.1696 - } /* if */
13.1697 - /* we have either:
13.1698 - * a) not found a matching variable (or rejected it, because it was a shadow)
13.1699 - * b) found a global variable and we were looking for that global variable
13.1700 - * c) found a state variable in the automaton that we were looking for
13.1701 - */
13.1702 - assert(sym==NULL
13.1703 - || sym->states==NULL && sc_curstates==0
13.1704 - || sym->states!=NULL && sym->next!=NULL && sym->states->next->index==sc_curstates);
13.1705 - /* a state variable may only have a single id in its list (so either this
13.1706 - * variable has no states, or it has a single list)
13.1707 - */
13.1708 - assert(sym==NULL || sym->states==NULL || sym->states->next->next==NULL);
13.1709 - /* it is okay for the (global) variable to exist, as long as it belongs to
13.1710 - * a different automaton
13.1711 - */
13.1712 - if (sym!=NULL && (sym->usage & uDEFINE)!=0)
13.1713 - error(21,name); /* symbol already defined */
13.1714 - /* if this variable is never used (which can be detected only in the
13.1715 - * second stage), shut off code generation
13.1716 - */
13.1717 - cidx=0; /* only to avoid a compiler warning */
13.1718 - if (sc_status==statWRITE && sym!=NULL && (sym->usage & (uREAD | uWRITTEN))==0) {
13.1719 - sc_status=statSKIP;
13.1720 - cidx=code_idx;
13.1721 - #if !defined NDEBUG
13.1722 - glbdecl=glb_declared;
13.1723 - #endif
13.1724 - } /* if */
13.1725 - begdseg(); /* real (initialized) data in data segment */
13.1726 - assert(litidx==0); /* literal queue should be empty */
13.1727 - if (sc_alignnext) {
13.1728 - litidx=0;
13.1729 - aligndata(sc_dataalign);
13.1730 - dumplits(); /* dump the literal queue */
13.1731 - sc_alignnext=FALSE;
13.1732 - litidx=0; /* global initial data is dumped, so restart at zero */
13.1733 - } /* if */
13.1734 - assert(litidx==0); /* literal queue should be empty (again) */
13.1735 - initials(ident,tag,&size,dim,numdim,enumroot);/* stores values in the literal queue */
13.1736 - assert(size>=litidx);
13.1737 - if (numdim==1)
13.1738 - dim[0]=(int)size;
13.1739 - /* before dumping the initial values (or zeros) check whether this variable
13.1740 - * overlaps another
13.1741 - */
13.1742 - if (sc_curstates>0) {
13.1743 - unsigned char *map;
13.1744 -
13.1745 - if (litidx!=0)
13.1746 - error(89,name); /* state variables may not be initialized */
13.1747 - /* find an appropriate address for the state variable */
13.1748 - /* assume that it cannot be found */
13.1749 - address=sizeof(cell)*glb_declared;
13.1750 - glb_incr=(int)size;
13.1751 - /* use a memory map in which every cell occupies one bit */
13.1752 - if (glb_declared>0 && (map=(unsigned char*)malloc((glb_declared+7)/8))!=NULL) {
13.1753 - int fsa=state_getfsa(sc_curstates);
13.1754 - symbol *sweep;
13.1755 - cell sweepsize,addr;
13.1756 - memset(map,0,(glb_declared+7)/8);
13.1757 - assert(fsa>=0);
13.1758 - /* fill in all variables belonging to this automaton */
13.1759 - for (sweep=glbtab.next; sweep!=NULL; sweep=sweep->next) {
13.1760 - if (sweep->parent!=NULL || sweep->states==NULL || sweep==sym)
13.1761 - continue; /* hierarchical type, or no states, or same as this variable */
13.1762 - if (sweep->ident!=iVARIABLE && sweep->ident!=iARRAY)
13.1763 - continue; /* a function or a constant */
13.1764 - if ((sweep->usage & uDEFINE)==0)
13.1765 - continue; /* undefined variable, ignore */
13.1766 - if (fsa!=state_getfsa(sweep->states->next->index))
13.1767 - continue; /* wrong automaton */
13.1768 - /* when arrived here, this is a global variable, with states and
13.1769 - * belonging to the same automaton as the variable we are declaring
13.1770 - */
13.1771 - sweepsize=(sweep->ident==iVARIABLE) ? 1 : array_totalsize(sweep);
13.1772 - assert(sweep->addr % sizeof(cell) == 0);
13.1773 - addr=sweep->addr/sizeof(cell);
13.1774 - /* mark this address range */
13.1775 - while (sweepsize-->0) {
13.1776 - map[addr/8] |= (unsigned char)(1 << (addr % 8));
13.1777 - addr++;
13.1778 - } /* while */
13.1779 - } /* for */
13.1780 - /* go over it again, clearing any ranges that have conflicts */
13.1781 - for (sweep=glbtab.next; sweep!=NULL; sweep=sweep->next) {
13.1782 - if (sweep->parent!=NULL || sweep->states==NULL || sweep==sym)
13.1783 - continue; /* hierarchical type, or no states, or same as this variable */
13.1784 - if (sweep->ident!=iVARIABLE && sweep->ident!=iARRAY)
13.1785 - continue; /* a function or a constant */
13.1786 - if ((sweep->usage & uDEFINE)==0)
13.1787 - continue; /* undefined variable, ignore */
13.1788 - if (fsa!=state_getfsa(sweep->states->next->index))
13.1789 - continue; /* wrong automaton */
13.1790 - /* when arrived here, this is a global variable, with states and
13.1791 - * belonging to the same automaton as the variable we are declaring
13.1792 - */
13.1793 - /* if the lists of states of the existing variable and the new
13.1794 - * variable have a non-empty intersection, this is not a suitable
13.1795 - * overlap point -> wipe the address range
13.1796 - */
13.1797 - if (state_conflict_id(sc_curstates,sweep->states->next->index)) {
13.1798 - sweepsize=(sweep->ident==iVARIABLE) ? 1 : array_totalsize(sweep);
13.1799 - assert(sweep->addr % sizeof(cell) == 0);
13.1800 - addr=sweep->addr/sizeof(cell);
13.1801 - /* mark this address range */
13.1802 - while (sweepsize-->0) {
13.1803 - map[addr/8] &= (unsigned char)(~(1 << (addr % 8)));
13.1804 - addr++;
13.1805 - } /* while */
13.1806 - } /* if */
13.1807 - } /* for */
13.1808 - /* now walk through the map and find a starting point that is big enough */
13.1809 - sweepsize=0;
13.1810 - for (addr=0; addr<glb_declared; addr++) {
13.1811 - if ((map[addr/8] & (1 << (addr % 8)))==0)
13.1812 - continue;
13.1813 - for (sweepsize=addr+1; sweepsize<glb_declared; sweepsize++) {
13.1814 - if ((map[sweepsize/8] & (1 << (sweepsize % 8)))==0)
13.1815 - break; /* zero bit found, skip this range */
13.1816 - if (sweepsize-addr>=size)
13.1817 - break; /* fitting range found, no need to search further */
13.1818 - } /* for */
13.1819 - if (sweepsize-addr>=size)
13.1820 - break; /* fitting range found, no need to search further */
13.1821 - addr=sweepsize;
13.1822 - } /* for */
13.1823 - free(map);
13.1824 - if (sweepsize-addr>=size) {
13.1825 - address=sizeof(cell)*addr; /* fitting range found, set it */
13.1826 - glb_incr=0;
13.1827 - } /* if */
13.1828 - } /* if */
13.1829 - } else {
13.1830 - address=sizeof(cell)*glb_declared;
13.1831 - glb_incr=(int)size;
13.1832 - } /* if */
13.1833 - if (address==sizeof(cell)*glb_declared) {
13.1834 - dumplits(); /* dump the literal queue */
13.1835 - dumpzero((int)size-litidx);
13.1836 - } /* if */
13.1837 - litidx=0;
13.1838 - if (sym==NULL) { /* define only if not yet defined */
13.1839 - sym=addvariable(name,address,ident,sGLOBAL,tag,dim,numdim,idxtag);
13.1840 - if (sc_curstates>0)
13.1841 - attachstatelist(sym,sc_curstates);
13.1842 - } else { /* if declared but not yet defined, adjust the variable's address */
13.1843 - assert(sym->states==NULL && sc_curstates==0
13.1844 - || sym->states->next!=NULL && sym->states->next->index==sc_curstates && sym->states->next->next==NULL);
13.1845 - sym->addr=address;
13.1846 - sym->codeaddr=code_idx;
13.1847 - sym->usage|=uDEFINE;
13.1848 - } /* if */
13.1849 - assert(sym!=NULL);
13.1850 - sc_curstates=0;
13.1851 - if (ispublic)
13.1852 - sym->usage|=uPUBLIC;
13.1853 - if (fconst)
13.1854 - sym->usage|=uCONST;
13.1855 - if (fstock)
13.1856 - sym->usage|=uSTOCK;
13.1857 - if (fstatic)
13.1858 - sym->fnumber=filenum;
13.1859 - sc_attachdocumentation(sym);/* attach any documenation to the variable */
13.1860 - if (sc_status==statSKIP) {
13.1861 - sc_status=statWRITE;
13.1862 - code_idx=cidx;
13.1863 - assert(glb_declared==glbdecl);
13.1864 - } else {
13.1865 - glb_declared+=glb_incr; /* add total number of cells (if added to the end) */
13.1866 - } /* if */
13.1867 - } while (matchtoken(',')); /* enddo */ /* more? */
13.1868 - needtoken(tTERM); /* if not comma, must be semicolumn */
13.1869 -}
13.1870 -
13.1871 -/* declloc - declare local symbols
13.1872 - *
13.1873 - * Declare local (automatic) variables. Since these variables are relative
13.1874 - * to the STACK, there is no switch to the DATA segment. These variables
13.1875 - * cannot be initialized either.
13.1876 - *
13.1877 - * global references: declared (altered)
13.1878 - * funcstatus (referred to only)
13.1879 - */
13.1880 -static int declloc(int fstatic)
13.1881 -{
13.1882 - int ident,tag;
13.1883 - int idxtag[sDIMEN_MAX];
13.1884 - char name[sNAMEMAX+1];
13.1885 - symbol *sym;
13.1886 - constvalue *enumroot;
13.1887 - cell val,size;
13.1888 - char *str;
13.1889 - value lval = {0};
13.1890 - int cur_lit=0;
13.1891 - int dim[sDIMEN_MAX];
13.1892 - int numdim;
13.1893 - int fconst;
13.1894 - int staging_start;
13.1895 -
13.1896 - fconst=matchtoken(tCONST);
13.1897 - do {
13.1898 - ident=iVARIABLE;
13.1899 - size=1;
13.1900 - numdim=0; /* no dimensions */
13.1901 - tag=pc_addtag(NULL);
13.1902 - if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
13.1903 - error(20,str); /* invalid symbol name */
13.1904 - assert(strlen(str)<=sNAMEMAX);
13.1905 - strcpy(name,str); /* save symbol name */
13.1906 - if (name[0]==PUBLIC_CHAR)
13.1907 - error(56,name); /* local variables cannot be public */
13.1908 - /* Note: block locals may be named identical to locals at higher
13.1909 - * compound blocks (as with standard C); so we must check (and add)
13.1910 - * the "nesting level" of local variables to verify the
13.1911 - * multi-definition of symbols.
13.1912 - */
13.1913 - if ((sym=findloc(name))!=NULL && sym->compound==nestlevel)
13.1914 - error(21,name); /* symbol already defined */
13.1915 - /* Although valid, a local variable whose name is equal to that
13.1916 - * of a global variable or to that of a local variable at a lower
13.1917 - * level might indicate a bug.
13.1918 - */
13.1919 - if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name,sGLOBAL)!=NULL)
13.1920 - error(219,name); /* variable shadows another symbol */
13.1921 - while (matchtoken('[')){
13.1922 - ident=iARRAY;
13.1923 - if (numdim == sDIMEN_MAX) {
13.1924 - error(53); /* exceeding maximum number of dimensions */
13.1925 - return ident;
13.1926 - } /* if */
13.1927 - size=needsub(&idxtag[numdim],&enumroot); /* get size; size==0 for "var[]" */
13.1928 - #if INT_MAX < LONG_MAX
13.1929 - if (size > INT_MAX)
13.1930 - error(105); /* overflow, exceeding capacity */
13.1931 - #endif
13.1932 - dim[numdim++]=(int)size;
13.1933 - } /* while */
13.1934 - if (getstates(name))
13.1935 - error(88,name); /* local variables may not have states */
13.1936 - if (ident==iARRAY || fstatic) {
13.1937 - if (sc_alignnext) {
13.1938 - aligndata(sc_dataalign);
13.1939 - sc_alignnext=FALSE;
13.1940 - } /* if */
13.1941 - cur_lit=litidx; /* save current index in the literal table */
13.1942 - initials(ident,tag,&size,dim,numdim,enumroot);
13.1943 - if (size==0)
13.1944 - return ident; /* error message already given */
13.1945 - if (numdim==1)
13.1946 - dim[0]=(int)size;
13.1947 - } /* if */
13.1948 - /* reserve memory (on the stack) for the variable */
13.1949 - if (fstatic) {
13.1950 - /* write zeros for uninitialized fields */
13.1951 - while (litidx<cur_lit+size)
13.1952 - litadd(0);
13.1953 - sym=addvariable(name,(cur_lit+glb_declared)*sizeof(cell),ident,sSTATIC,
13.1954 - tag,dim,numdim,idxtag);
13.1955 - } else {
13.1956 - declared+=(int)size; /* variables are put on stack, adjust "declared" */
13.1957 - sym=addvariable(name,-declared*sizeof(cell),ident,sLOCAL,tag,
13.1958 - dim,numdim,idxtag);
13.1959 - if (ident==iVARIABLE) {
13.1960 - assert(!staging);
13.1961 - stgset(TRUE); /* start stage-buffering */
13.1962 - assert(stgidx==0);
13.1963 - staging_start=stgidx;
13.1964 - } /* if */
13.1965 - markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */
13.1966 - modstk(-(int)size*sizeof(cell));
13.1967 - assert(curfunc!=NULL);
13.1968 - assert((curfunc->usage & uNATIVE)==0);
13.1969 - if (curfunc->x.stacksize<declared+1)
13.1970 - curfunc->x.stacksize=declared+1; /* +1 for PROC opcode */
13.1971 - } /* if */
13.1972 - /* now that we have reserved memory for the variable, we can proceed
13.1973 - * to initialize it */
13.1974 - assert(sym!=NULL); /* we declared it, it must be there */
13.1975 - sym->compound=nestlevel; /* for multiple declaration/shadowing check */
13.1976 - if (fconst)
13.1977 - sym->usage|=uCONST;
13.1978 - if (!fstatic) { /* static variables already initialized */
13.1979 - if (ident==iVARIABLE) {
13.1980 - /* simple variable, also supports initialization */
13.1981 - int ctag = tag; /* set to "tag" by default */
13.1982 - int explicit_init=FALSE;/* is the variable explicitly initialized? */
13.1983 - if (matchtoken('=')) {
13.1984 - if (!autozero)
13.1985 - error(10);
13.1986 - doexpr(FALSE,FALSE,FALSE,FALSE,&ctag,NULL,TRUE);
13.1987 - explicit_init=TRUE;
13.1988 - } else {
13.1989 - if (autozero)
13.1990 - ldconst(0,sPRI); /* uninitialized variable, set to zero */
13.1991 - } /* if */
13.1992 - if (autozero) {
13.1993 - /* now try to save the value (still in PRI) in the variable */
13.1994 - lval.sym=sym;
13.1995 - lval.ident=iVARIABLE;
13.1996 - lval.constval=0;
13.1997 - lval.tag=tag;
13.1998 - check_userop(NULL,ctag,lval.tag,2,NULL,&ctag);
13.1999 - store(&lval);
13.2000 - markexpr(sEXPR,NULL,0); /* full expression ends after the store */
13.2001 - }
13.2002 - assert(staging); /* end staging phase (optimize expression) */
13.2003 - stgout(staging_start);
13.2004 - stgset(FALSE);
13.2005 - if (!matchtag(tag,ctag,TRUE))
13.2006 - error(213); /* tag mismatch */
13.2007 - /* if the variable was not explicitly initialized, reset the
13.2008 - * "uWRITTEN" flag that store() set */
13.2009 - if (!explicit_init)
13.2010 - sym->usage &= ~uWRITTEN;
13.2011 - } else {
13.2012 - /* an array */
13.2013 - assert(cur_lit>=0 && cur_lit<=litidx && litidx<=litmax);
13.2014 - assert(size>0 && size>=sym->dim.array.length);
13.2015 - assert(numdim>1 || size==sym->dim.array.length);
13.2016 - if (autozero) {
13.2017 - /* final literal values that are zero make no sense to put in the literal
13.2018 - * pool, because values get zero-initialized anyway; we check for this,
13.2019 - * because users often explicitly initialize strings to ""
13.2020 - */
13.2021 - while (litidx>cur_lit && litq[litidx-1]==0)
13.2022 - litidx--;
13.2023 - /* if the array is not completely filled, set all values to zero first */
13.2024 - if (litidx-cur_lit<size && (ucell)size<CELL_MAX)
13.2025 - fillarray(sym,size*sizeof(cell),0);
13.2026 - }
13.2027 - if (cur_lit<litidx) {
13.2028 - /* check whether the complete array is set to a single value; if
13.2029 - * it is, more compact code can be generated */
13.2030 - cell first=litq[cur_lit];
13.2031 - int i;
13.2032 - for (i=cur_lit; i<litidx && litq[i]==first; i++)
13.2033 - /* nothing */;
13.2034 - if (i==litidx) {
13.2035 - /* all values are the same */
13.2036 - fillarray(sym,(litidx-cur_lit)*sizeof(cell),first);
13.2037 - litidx=cur_lit; /* reset literal table */
13.2038 - } else {
13.2039 - /* copy the literals to the array */
13.2040 - ldconst((cur_lit+glb_declared)*sizeof(cell),sPRI);
13.2041 - copyarray(sym,(litidx-cur_lit)*sizeof(cell));
13.2042 - } /* if */
13.2043 - } /* if */
13.2044 - } /* if */
13.2045 - } /* if */
13.2046 - } while (matchtoken(',')); /* enddo */ /* more? */
13.2047 - needtoken(tTERM); /* if not comma, must be semicolumn */
13.2048 - return ident;
13.2049 -}
13.2050 -
13.2051 -/* this function returns the maximum value for a cell in case of an error
13.2052 - * (invalid dimension).
13.2053 - */
13.2054 -static cell calc_arraysize(int dim[],int numdim,int cur)
13.2055 -{
13.2056 - cell subsize;
13.2057 - ucell newsize;
13.2058 -
13.2059 - /* the return value is in cells, not bytes */
13.2060 - assert(cur>=0 && cur<=numdim);
13.2061 - if (cur==numdim)
13.2062 - return 0;
13.2063 - subsize=calc_arraysize(dim,numdim,cur+1);
13.2064 - newsize=dim[cur]+dim[cur]*subsize;
13.2065 - if ((ucell)subsize>=CELL_MAX || newsize>=CELL_MAX || newsize<(ucell)subsize
13.2066 - || newsize*sizeof(cell)>=CELL_MAX)
13.2067 - return CELL_MAX;
13.2068 - return newsize;
13.2069 -}
13.2070 -
13.2071 -static cell adjust_indirectiontables(int dim[],int numdim,int cur,cell increment,
13.2072 - int startlit,constvalue *lastdim,int *skipdim)
13.2073 -{
13.2074 -static int base;
13.2075 - int d;
13.2076 - cell accum;
13.2077 -
13.2078 - assert(cur>=0 && cur<numdim);
13.2079 - assert(increment>=0);
13.2080 - assert(cur>0 && startlit==-1 || startlit>=0 && startlit<=litidx);
13.2081 - if (cur==0)
13.2082 - base=startlit;
13.2083 - if (cur==numdim-1)
13.2084 - return 0;
13.2085 - /* 2 or more dimensions left, fill in an indirection vector */
13.2086 - assert(dim[cur]>0);
13.2087 - if (dim[cur+1]>0) {
13.2088 - for (d=0; d<dim[cur]; d++)
13.2089 - litq[base++]=(dim[cur]+d*(dim[cur+1]-1)+increment) * sizeof(cell);
13.2090 - accum=dim[cur]*(dim[cur+1]-1);
13.2091 - } else {
13.2092 - /* final dimension is variable length */
13.2093 - constvalue *ld;
13.2094 - assert(dim[cur+1]==0);
13.2095 - assert(lastdim!=NULL);
13.2096 - assert(skipdim!=NULL);
13.2097 - accum=0;
13.2098 - /* skip the final dimension sizes for all earlier major dimensions */
13.2099 - for (d=0,ld=lastdim->next; d<*skipdim; d++,ld=ld->next) {
13.2100 - assert(ld!=NULL);
13.2101 - } /* for */
13.2102 - for (d=0; d<dim[cur]; d++) {
13.2103 - assert(ld!=NULL);
13.2104 - assert(strtol(ld->name,NULL,16)==d);
13.2105 - litq[base++]=(dim[cur]+accum+increment) * sizeof(cell);
13.2106 - accum+=ld->value-1;
13.2107 - *skipdim+=1;
13.2108 - ld=ld->next;
13.2109 - } /* for */
13.2110 - } /* if */
13.2111 - /* create the indirection tables for the lower level */
13.2112 - if (cur+2<numdim) { /* are there at least 2 dimensions below this one? */
13.2113 - increment+=(dim[cur]-1)*dim[cur+1]; /* this many indirection tables follow */
13.2114 - for (d=0; d<dim[cur]; d++)
13.2115 - increment+=adjust_indirectiontables(dim,numdim,cur+1,increment,-1,lastdim,skipdim);
13.2116 - } /* if */
13.2117 - return accum;
13.2118 -}
13.2119 -
13.2120 -/* initials
13.2121 - *
13.2122 - * Initialize global objects and local arrays.
13.2123 - * size==array cells (count), if 0 on input, the routine counts the number of elements
13.2124 - * tag==required tagname id (not the returned tag)
13.2125 - *
13.2126 - * Global references: litidx (altered)
13.2127 - */
13.2128 -static void initials(int ident,int tag,cell *size,int dim[],int numdim,
13.2129 - constvalue *enumroot)
13.2130 -{
13.2131 - int ctag;
13.2132 - cell tablesize;
13.2133 - int curlit=litidx;
13.2134 - int err=0;
13.2135 -
13.2136 - if (!matchtoken('=')) {
13.2137 - assert(ident!=iARRAY || numdim>0);
13.2138 - if (ident==iARRAY && dim[numdim-1]==0) {
13.2139 - /* declared as "myvar[];" which is senseless (note: this *does* make
13.2140 - * sense in the case of a iREFARRAY, which is a function parameter)
13.2141 - */
13.2142 - error(9); /* array has zero length -> invalid size */
13.2143 - } /* if */
13.2144 - if (ident==iARRAY) {
13.2145 - assert(numdim>0 && numdim<=sDIMEN_MAX);
13.2146 - *size=calc_arraysize(dim,numdim,0);
13.2147 - if (*size==(cell)CELL_MAX) {
13.2148 - error(9); /* array is too big -> invalid size */
13.2149 - return;
13.2150 - } /* if */
13.2151 - /* first reserve space for the indirection vectors of the array, then
13.2152 - * adjust it to contain the proper values
13.2153 - * (do not use dumpzero(), as it bypasses the literal queue)
13.2154 - */
13.2155 - for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
13.2156 - litadd(0);
13.2157 - if (dim[numdim-1]!=0) /* error 9 has already been given */
13.2158 - adjust_indirectiontables(dim,numdim,0,0,curlit,NULL,NULL);
13.2159 - } /* if */
13.2160 - return;
13.2161 - } /* if */
13.2162 -
13.2163 - if (ident==iVARIABLE) {
13.2164 - assert(*size==1);
13.2165 - init(ident,&ctag,NULL);
13.2166 - if (!matchtag(tag,ctag,TRUE))
13.2167 - error(213); /* tag mismatch */
13.2168 - } else {
13.2169 - assert(numdim>0);
13.2170 - if (numdim==1) {
13.2171 - *size=initvector(ident,tag,dim[0],FALSE,enumroot,NULL);
13.2172 - } else {
13.2173 - int errorfound=FALSE;
13.2174 - int counteddim[sDIMEN_MAX];
13.2175 - int idx;
13.2176 - constvalue lastdim={NULL,"",0,0}; /* sizes of the final dimension */
13.2177 - int skipdim=0;
13.2178 -
13.2179 - if (dim[numdim-1]!=0)
13.2180 - *size=calc_arraysize(dim,numdim,0); /* calc. full size, if known */
13.2181 - /* already reserve space for the indirection tables (for an array with
13.2182 - * known dimensions)
13.2183 - * (do not use dumpzero(), as it bypasses the literal queue)
13.2184 - */
13.2185 - for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
13.2186 - litadd(0);
13.2187 - /* now initialize the sub-arrays */
13.2188 - memset(counteddim,0,sizeof counteddim);
13.2189 - initarray(ident,tag,dim,numdim,0,curlit,counteddim,&lastdim,enumroot,&errorfound);
13.2190 - /* check the specified array dimensions with the initialler counts */
13.2191 - for (idx=0; idx<numdim-1; idx++) {
13.2192 - if (dim[idx]==0) {
13.2193 - dim[idx]=counteddim[idx];
13.2194 - } else if (counteddim[idx]<dim[idx]) {
13.2195 - error(52); /* array is not fully initialized */
13.2196 - err++;
13.2197 - } else if (counteddim[idx]>dim[idx]) {
13.2198 - error(18); /* initialization data exceeds declared size */
13.2199 - err++;
13.2200 - } /* if */
13.2201 - } /* for */
13.2202 - /* after all arrays have been initalized, we know the (major) dimensions
13.2203 - * of the array and we can properly adjust the indirection vectors
13.2204 - */
13.2205 - if (err==0)
13.2206 - adjust_indirectiontables(dim,numdim,0,0,curlit,&lastdim,&skipdim);
13.2207 - delete_consttable(&lastdim); /* clear list of minor dimension sizes */
13.2208 - } /* if */
13.2209 - } /* if */
13.2210 -
13.2211 - if (*size==0)
13.2212 - *size=litidx-curlit; /* number of elements defined */
13.2213 -}
13.2214 -
13.2215 -static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
13.2216 - int startlit,int counteddim[],constvalue *lastdim,
13.2217 - constvalue *enumroot,int *errorfound)
13.2218 -{
13.2219 - cell dsize,totalsize;
13.2220 - int idx,abortparse;
13.2221 -
13.2222 - assert(cur>=0 && cur<numdim);
13.2223 - assert(startlit>=0);
13.2224 - assert(cur+2<=numdim);/* there must be 2 dimensions or more to do */
13.2225 - assert(errorfound!=NULL && *errorfound==FALSE);
13.2226 - totalsize=0;
13.2227 - needtoken('{');
13.2228 - for (idx=0,abortparse=FALSE; !abortparse; idx++) {
13.2229 - /* In case the major dimension is zero, we need to store the offset
13.2230 - * to the newly detected sub-array into the indirection table; i.e.
13.2231 - * this table needs to be expanded and updated.
13.2232 - * In the current design, the indirection vectors for a multi-dimensional
13.2233 - * array are adjusted after parsing all initiallers. Hence, it is only
13.2234 - * necessary at this point to reserve space for an extra cell in the
13.2235 - * indirection vector.
13.2236 - */
13.2237 - if (dim[cur]==0) {
13.2238 - litinsert(0,startlit);
13.2239 - } else if (idx>=dim[cur]) {
13.2240 - error(18); /* initialization data exceeds array size */
13.2241 - break;
13.2242 - } /* if */
13.2243 - if (cur+2<numdim) {
13.2244 - dsize=initarray(ident,tag,dim,numdim,cur+1,startlit,counteddim,
13.2245 - lastdim,enumroot,errorfound);
13.2246 - } else {
13.2247 - dsize=initvector(ident,tag,dim[cur+1],TRUE,enumroot,errorfound);
13.2248 - /* The final dimension may be variable length. We need to keep the
13.2249 - * lengths of the final dimensions in order to set the indirection
13.2250 - * vectors for the next-to-last dimension.
13.2251 - */
13.2252 - append_constval(lastdim,itoh(idx),dsize,0);
13.2253 - } /* if */
13.2254 - totalsize+=dsize;
13.2255 - if (*errorfound || !matchtoken(','))
13.2256 - abortparse=TRUE;
13.2257 - } /* for */
13.2258 - needtoken('}');
13.2259 - assert(counteddim!=NULL);
13.2260 - if (counteddim[cur]>0) {
13.2261 - if (idx<counteddim[cur])
13.2262 - error(52); /* array is not fully initialized */
13.2263 - else if (idx>counteddim[cur])
13.2264 - error(18); /* initialization data exceeds declared size */
13.2265 - } /* if */
13.2266 - counteddim[cur]=idx;
13.2267 -
13.2268 - return totalsize+dim[cur]; /* size of sub-arrays + indirection vector */
13.2269 -}
13.2270 -
13.2271 -/* initvector
13.2272 - * Initialize a single dimensional array
13.2273 - */
13.2274 -static cell initvector(int ident,int tag,cell size,int fillzero,
13.2275 - constvalue *enumroot,int *errorfound)
13.2276 -{
13.2277 - cell prev1=0,prev2=0;
13.2278 - int ellips=FALSE,hadtoken=0;
13.2279 - int curlit=litidx;
13.2280 - int rtag,ctag;
13.2281 -
13.2282 - assert(ident==iARRAY || ident==iREFARRAY);
13.2283 - if ((hadtoken=matchtoken('{')) && autozero) {
13.2284 - constvalue *enumfield=(enumroot!=NULL) ? enumroot->next : NULL;
13.2285 - do {
13.2286 - int fieldlit=litidx;
13.2287 - int matchbrace,i;
13.2288 - if (matchtoken('}')) { /* to allow for trailing ',' after the initialization */
13.2289 - lexpush();
13.2290 - break;
13.2291 - } /* if */
13.2292 - if ((ellips=matchtoken(tELLIPS))!=0)
13.2293 - break;
13.2294 - /* for enumeration fields, allow another level of braces ("{...}") */
13.2295 - matchbrace=0; /* preset */
13.2296 - ellips=0;
13.2297 - if (enumfield!=NULL)
13.2298 - matchbrace=matchtoken('{');
13.2299 - for ( ;; ) {
13.2300 - prev2=prev1;
13.2301 - prev1=init(ident,&ctag,errorfound);
13.2302 - if (!matchbrace)
13.2303 - break;
13.2304 - if ((ellips=matchtoken(tELLIPS))!=0)
13.2305 - break;
13.2306 - if (!matchtoken(',')) {
13.2307 - needtoken('}');
13.2308 - break;
13.2309 - } /* for */
13.2310 - } /* for */
13.2311 - /* if this array is based on an enumeration, fill the "field" up with
13.2312 - * zeros, and toggle the tag
13.2313 - */
13.2314 - if (enumroot!=NULL && enumfield==NULL)
13.2315 - error(227); /* more initiallers than enum fields */
13.2316 - rtag=tag; /* preset, may be overridden by enum field tag */
13.2317 - if (enumfield!=NULL) {
13.2318 - cell step;
13.2319 - int cmptag=enumfield->index;
13.2320 - symbol *symfield=findconst(enumfield->name,&cmptag);
13.2321 - if (cmptag>1)
13.2322 - error(91,enumfield->name); /* ambiguous constant, needs tag override */
13.2323 - assert(symfield!=NULL);
13.2324 - assert(fieldlit<litidx);
13.2325 - if (litidx-fieldlit>symfield->dim.array.length)
13.2326 - error(228); /* length of initialler exceeds size of the enum field */
13.2327 - if (ellips) {
13.2328 - step=prev1-prev2;
13.2329 - } else {
13.2330 - step=0;
13.2331 - prev1=0;
13.2332 - } /* if */
13.2333 - for (i=litidx-fieldlit; i<symfield->dim.array.length; i++) {
13.2334 - prev1+=step;
13.2335 - litadd(prev1);
13.2336 - } /* for */
13.2337 - rtag=symfield->x.tags.index; /* set the expected tag to the index tag */
13.2338 - enumfield=enumfield->next;
13.2339 - } /* if */
13.2340 - if (!matchtag(rtag,ctag,TRUE))
13.2341 - error(213); /* tag mismatch */
13.2342 - } while (matchtoken(',')); /* do */
13.2343 - needtoken('}');
13.2344 - } else {
13.2345 - if (hadtoken && !autozero)
13.2346 - error(10);
13.2347 - init(ident,&ctag,errorfound);
13.2348 - if (!matchtag(tag,ctag,TRUE))
13.2349 - error(213); /* tagname mismatch */
13.2350 - } /* if */
13.2351 - /* fill up the literal queue with a series */
13.2352 - if (ellips) {
13.2353 - cell step=((litidx-curlit)==1) ? (cell)0 : prev1-prev2;
13.2354 - if (size==0 || (litidx-curlit)==0)
13.2355 - error(41); /* invalid ellipsis, array size unknown */
13.2356 - else if ((litidx-curlit)==(int)size)
13.2357 - error(18); /* initialisation data exceeds declared size */
13.2358 - while ((litidx-curlit)<(int)size) {
13.2359 - prev1+=step;
13.2360 - litadd(prev1);
13.2361 - } /* while */
13.2362 - } /* if */
13.2363 - if (fillzero && size>0) {
13.2364 - while ((litidx-curlit)<(int)size)
13.2365 - litadd(0);
13.2366 - } /* if */
13.2367 - if (size==0) {
13.2368 - size=litidx-curlit; /* number of elements defined */
13.2369 - } else if (litidx-curlit>(int)size) { /* e.g. "myvar[3]={1,2,3,4};" */
13.2370 - error(18); /* initialisation data exceeds declared size */
13.2371 - litidx=(int)size+curlit; /* avoid overflow in memory moves */
13.2372 - } /* if */
13.2373 - return size;
13.2374 -}
13.2375 -
13.2376 -/* init
13.2377 - *
13.2378 - * Evaluate one initializer.
13.2379 - */
13.2380 -static cell init(int ident,int *tag,int *errorfound)
13.2381 -{
13.2382 - cell i = 0;
13.2383 -
13.2384 - if (matchtoken(tSTRING)){
13.2385 - /* lex() automatically stores strings in the literal table (and
13.2386 - * increases "litidx") */
13.2387 - if (ident==iVARIABLE) {
13.2388 - error(6); /* must be assigned to an array */
13.2389 - litidx=1; /* reset literal queue */
13.2390 - } /* if */
13.2391 - *tag=0;
13.2392 - } else if (constexpr(&i,tag,NULL)){
13.2393 - litadd(i); /* store expression result in literal table */
13.2394 - } else {
13.2395 - if (errorfound!=NULL)
13.2396 - *errorfound=TRUE;
13.2397 - } /* if */
13.2398 - return i;
13.2399 -}
13.2400 -
13.2401 -/* needsub
13.2402 - *
13.2403 - * Get required array size
13.2404 - */
13.2405 -static cell needsub(int *tag,constvalue **enumroot)
13.2406 -{
13.2407 - cell val;
13.2408 - symbol *sym;
13.2409 -
13.2410 - assert(tag!=NULL);
13.2411 - *tag=0;
13.2412 - if (enumroot!=NULL)
13.2413 - *enumroot=NULL; /* preset */
13.2414 - if (matchtoken(']')) /* we have already seen "[" */
13.2415 - return 0; /* zero size (like "char msg[]") */
13.2416 -
13.2417 - constexpr(&val,tag,&sym); /* get value (must be constant expression) */
13.2418 - if (val<0) {
13.2419 - error(9); /* negative array size is invalid; assumed zero */
13.2420 - val=0;
13.2421 - } /* if */
13.2422 - needtoken(']');
13.2423 -
13.2424 - if (enumroot!=NULL) {
13.2425 - /* get the field list for an enumeration */
13.2426 - assert(*enumroot==NULL);/* should have been preset */
13.2427 - assert(sym==NULL || sym->ident==iCONSTEXPR);
13.2428 - if (sym!=NULL && (sym->usage & uENUMROOT)==uENUMROOT) {
13.2429 - assert(sym->dim.enumlist!=NULL);
13.2430 - *enumroot=sym->dim.enumlist;
13.2431 - } /* if */
13.2432 - } /* if */
13.2433 -
13.2434 - return val; /* return array size */
13.2435 -}
13.2436 -
13.2437 -/* decl_const - declare a single constant
13.2438 - *
13.2439 - */
13.2440 -static void decl_const(int vclass)
13.2441 -{
13.2442 - char constname[sNAMEMAX+1];
13.2443 - cell val;
13.2444 - char *str;
13.2445 - int tag,exprtag;
13.2446 - int symbolline;
13.2447 - symbol *sym;
13.2448 -
13.2449 - insert_docstring_separator(); /* see comment in newfunc() */
13.2450 - tag=pc_addtag(NULL);
13.2451 - if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
13.2452 - error(20,str); /* invalid symbol name */
13.2453 - symbolline=fline; /* save line where symbol was found */
13.2454 - strcpy(constname,str); /* save symbol name */
13.2455 - needtoken('=');
13.2456 - constexpr(&val,&exprtag,NULL);/* get value */
13.2457 - needtoken(tTERM);
13.2458 - /* add_constant() checks for duplicate definitions */
13.2459 - if (!matchtag(tag,exprtag,FALSE)) {
13.2460 - /* temporarily reset the line number to where the symbol was defined */
13.2461 - int orgfline=fline;
13.2462 - fline=symbolline;
13.2463 - error(213); /* tagname mismatch */
13.2464 - fline=orgfline;
13.2465 - } /* if */
13.2466 - sym=add_constant(constname,val,vclass,tag);
13.2467 - if (sym!=NULL)
13.2468 - sc_attachdocumentation(sym);/* attach any documenation to the function */
13.2469 -}
13.2470 -
13.2471 -/* decl_enum - declare enumerated constants
13.2472 - *
13.2473 - */
13.2474 -static void decl_enum(int vclass)
13.2475 -{
13.2476 - char enumname[sNAMEMAX+1],constname[sNAMEMAX+1];
13.2477 - cell val,value,size;
13.2478 - char *str;
13.2479 - int tag,explicittag;
13.2480 - cell increment,multiplier;
13.2481 - constvalue *enumroot;
13.2482 - symbol *enumsym;
13.2483 -
13.2484 - /* get an explicit tag, if any (we need to remember whether an explicit
13.2485 - * tag was passed, even if that explicit tag was "_:", so we cannot call
13.2486 - * pc_addtag() here
13.2487 - */
13.2488 - if (lex(&val,&str)==tLABEL) {
13.2489 - tag=pc_addtag(str);
13.2490 - explicittag=TRUE;
13.2491 - } else {
13.2492 - lexpush();
13.2493 - tag=0;
13.2494 - explicittag=FALSE;
13.2495 - } /* if */
13.2496 -
13.2497 - /* get optional enum name (also serves as a tag if no explicit tag was set) */
13.2498 - if (lex(&val,&str)==tSYMBOL) { /* read in (new) token */
13.2499 - strcpy(enumname,str); /* save enum name (last constant) */
13.2500 - if (!explicittag)
13.2501 - tag=pc_addtag(enumname);
13.2502 - } else {
13.2503 - lexpush(); /* analyze again */
13.2504 - enumname[0]='\0';
13.2505 - } /* if */
13.2506 -
13.2507 - /* get increment and multiplier */
13.2508 - increment=1;
13.2509 - multiplier=1;
13.2510 - if (matchtoken('(')) {
13.2511 - if (matchtoken(taADD)) {
13.2512 - constexpr(&increment,NULL,NULL);
13.2513 - } else if (matchtoken(taMULT)) {
13.2514 - constexpr(&multiplier,NULL,NULL);
13.2515 - } else if (matchtoken(taSHL)) {
13.2516 - constexpr(&val,NULL,NULL);
13.2517 - while (val-->0)
13.2518 - multiplier*=2;
13.2519 - } /* if */
13.2520 - needtoken(')');
13.2521 - } /* if */
13.2522 -
13.2523 - if (strlen(enumname)>0) {
13.2524 - /* already create the root symbol, so the fields can have it as their "parent" */
13.2525 - enumsym=add_constant(enumname,0,vclass,tag);
13.2526 - if (enumsym!=NULL)
13.2527 - enumsym->usage |= uENUMROOT;
13.2528 - /* start a new list for the element names */
13.2529 - if ((enumroot=(constvalue*)malloc(sizeof(constvalue)))==NULL)
13.2530 - error(103); /* insufficient memory (fatal error) */
13.2531 - memset(enumroot,0,sizeof(constvalue));
13.2532 - } else {
13.2533 - enumsym=NULL;
13.2534 - enumroot=NULL;
13.2535 - } /* if */
13.2536 -
13.2537 - needtoken('{');
13.2538 - /* go through all constants */
13.2539 - value=0; /* default starting value */
13.2540 - do {
13.2541 - int idxtag,fieldtag;
13.2542 - symbol *sym;
13.2543 - if (matchtoken('}')) { /* quick exit if '}' follows ',' */
13.2544 - lexpush();
13.2545 - break;
13.2546 - } /* if */
13.2547 - idxtag=pc_addtag(NULL); /* optional explicit item tag */
13.2548 - if (needtoken(tSYMBOL)) { /* read in (new) token */
13.2549 - tokeninfo(&val,&str); /* get the information */
13.2550 - strcpy(constname,str); /* save symbol name */
13.2551 - } else {
13.2552 - constname[0]='\0';
13.2553 - } /* if */
13.2554 - size=increment; /* default increment of 'val' */
13.2555 - fieldtag=0; /* default field tag */
13.2556 - if (matchtoken('[')) {
13.2557 - constexpr(&size,&fieldtag,NULL); /* get size */
13.2558 - needtoken(']');
13.2559 - } /* if */
13.2560 - if (matchtoken('='))
13.2561 - constexpr(&value,NULL,NULL); /* get value */
13.2562 - /* add_constant() checks whether a variable (global or local) or
13.2563 - * a constant with the same name already exists
13.2564 - */
13.2565 - sym=add_constant(constname,value,vclass,tag);
13.2566 - if (sym==NULL)
13.2567 - continue; /* error message already given */
13.2568 - /* set the item tag and the item size, for use in indexing arrays */
13.2569 - sym->x.tags.index=idxtag;
13.2570 - sym->x.tags.field=fieldtag;
13.2571 - sym->dim.array.length=size;
13.2572 - sym->dim.array.level=0;
13.2573 - sym->parent=enumsym;
13.2574 - /* add the constant to a separate list as well */
13.2575 - if (enumroot!=NULL) {
13.2576 - sym->usage |= uENUMFIELD;
13.2577 - append_constval(enumroot,constname,value,tag);
13.2578 - } /* if */
13.2579 - if (multiplier==1)
13.2580 - value+=size;
13.2581 - else
13.2582 - value*=size*multiplier;
13.2583 - } while (matchtoken(','));
13.2584 - needtoken('}'); /* terminates the constant list */
13.2585 - matchtoken(';'); /* eat an optional ; */
13.2586 -
13.2587 - /* set the enum name to the "next" value (typically the last value plus one) */
13.2588 - if (enumsym!=NULL) {
13.2589 - assert((enumsym->usage & uENUMROOT)!=0);
13.2590 - enumsym->addr=value;
13.2591 - /* assign the constant list */
13.2592 - assert(enumroot!=NULL);
13.2593 - enumsym->dim.enumlist=enumroot;
13.2594 - sc_attachdocumentation(enumsym); /* attach any documenation to the enumeration */
13.2595 - } /* if */
13.2596 -}
13.2597 -
13.2598 -static int getstates(const char *funcname)
13.2599 -{
13.2600 - char fsaname[sNAMEMAX+1],statename[sNAMEMAX+1];
13.2601 - cell val;
13.2602 - char *str;
13.2603 - constvalue *automaton;
13.2604 - constvalue *state;
13.2605 - int fsa,islabel;
13.2606 - int *list;
13.2607 - int count,listsize,state_id;
13.2608 -
13.2609 - if (!matchtoken('<'))
13.2610 - return 0;
13.2611 - if (matchtoken('>'))
13.2612 - return -1; /* special construct: all other states (fall-back) */
13.2613 -
13.2614 - count=0;
13.2615 - listsize=0;
13.2616 - list=NULL;
13.2617 - fsa=-1;
13.2618 -
13.2619 - do {
13.2620 - if (!(islabel=matchtoken(tLABEL)) && !needtoken(tSYMBOL))
13.2621 - break;
13.2622 - tokeninfo(&val,&str);
13.2623 - assert(strlen(str)<sizeof fsaname);
13.2624 - strcpy(fsaname,str); /* assume this is the name of the automaton */
13.2625 - if (islabel || matchtoken(':')) {
13.2626 - /* token is an automaton name, add the name and get a new token */
13.2627 - if (!needtoken(tSYMBOL))
13.2628 - break;
13.2629 - tokeninfo(&val,&str);
13.2630 - assert(strlen(str)<sizeof statename);
13.2631 - strcpy(statename,str);
13.2632 - } else {
13.2633 - /* the token was the state name (part of an anynymous automaton) */
13.2634 - assert(strlen(fsaname)<sizeof statename);
13.2635 - strcpy(statename,fsaname);
13.2636 - fsaname[0]='\0';
13.2637 - } /* if */
13.2638 - if (fsa<0 || fsaname[0]!='\0') {
13.2639 - automaton=automaton_add(fsaname);
13.2640 - assert(automaton!=NULL);
13.2641 - if (fsa>=0 && automaton->index!=fsa)
13.2642 - error(83,funcname); /* multiple automatons for a single function/variable */
13.2643 - fsa=automaton->index;
13.2644 - } /* if */
13.2645 - state=state_add(statename,fsa);
13.2646 - /* add this state to the state combination list (it will be attached to the
13.2647 - * automaton later) */
13.2648 - state_buildlist(&list,&listsize,&count,(int)state->value);
13.2649 - } while (matchtoken(','));
13.2650 - needtoken('>');
13.2651 -
13.2652 - if (count>0) {
13.2653 - assert(automaton!=NULL);
13.2654 - assert(fsa>=0);
13.2655 - state_id=state_addlist(list,count,fsa);
13.2656 - assert(state_id>0);
13.2657 - } else {
13.2658 - /* error is already given */
13.2659 - state_id=0;
13.2660 - } /* if */
13.2661 - if (list!=NULL)
13.2662 - free(list);
13.2663 -
13.2664 - return state_id;
13.2665 -}
13.2666 -
13.2667 -static void attachstatelist(symbol *sym, int state_id)
13.2668 -{
13.2669 - assert(sym!=NULL);
13.2670 - if ((sym->usage & uDEFINE)!=0 && (sym->states==NULL || state_id==0))
13.2671 - error(21,sym->name); /* function already defined, either without states or the current definition has no states */
13.2672 -
13.2673 - if (state_id!=0) {
13.2674 - /* add the state list id */
13.2675 - constvalue *stateptr;
13.2676 - if (sym->states==NULL) {
13.2677 - if ((sym->states=(constvalue*)malloc(sizeof(constvalue)))==NULL)
13.2678 - error(103); /* insufficient memory (fatal error) */
13.2679 - memset(sym->states,0,sizeof(constvalue));
13.2680 - } /* if */
13.2681 - /* see whether the id already exists (add new state only if it does not
13.2682 - * yet exist
13.2683 - */
13.2684 - assert(sym->states!=NULL);
13.2685 - for (stateptr=sym->states->next; stateptr!=NULL && stateptr->index!=state_id; stateptr=stateptr->next)
13.2686 - /* nothing */;
13.2687 - assert(state_id<=SHRT_MAX);
13.2688 - if (stateptr==NULL)
13.2689 - append_constval(sym->states,"",code_idx,(short)state_id);
13.2690 - else if (stateptr->value==0)
13.2691 - stateptr->value=code_idx;
13.2692 - else
13.2693 - error(84,sym->name);
13.2694 - /* also check for another conflicting situation: a fallback function
13.2695 - * without any states
13.2696 - */
13.2697 - if (state_id==-1 && sc_status!=statFIRST) {
13.2698 - /* in the second round, all states should have been accumulated */
13.2699 - assert(sym->states!=NULL);
13.2700 - for (stateptr=sym->states->next; stateptr!=NULL && stateptr->index==-1; stateptr=stateptr->next)
13.2701 - /* nothing */;
13.2702 - if (stateptr==NULL)
13.2703 - error(85,sym->name); /* no states are defined for this function */
13.2704 - } /* if */
13.2705 - } /* if */
13.2706 -}
13.2707 -
13.2708 -/*
13.2709 - * Finds a function in the global symbol table or creates a new entry.
13.2710 - * It does some basic processing and error checking.
13.2711 - */
13.2712 -SC_FUNC symbol *fetchfunc(char *name,int tag)
13.2713 -{
13.2714 - symbol *sym;
13.2715 -
13.2716 - if ((sym=findglb(name,sGLOBAL))!=0) { /* already in symbol table? */
13.2717 - if (sym->ident!=iFUNCTN) {
13.2718 - error(21,name); /* yes, but not as a function */
13.2719 - return NULL; /* make sure the old symbol is not damaged */
13.2720 - } else if ((sym->usage & uNATIVE)!=0) {
13.2721 - error(21,name); /* yes, and it is a native */
13.2722 - } /* if */
13.2723 - assert(sym->vclass==sGLOBAL);
13.2724 - if ((sym->usage & uPROTOTYPED)!=0 && sym->tag!=tag)
13.2725 - error(25); /* mismatch from earlier prototype */
13.2726 - if ((sym->usage & uDEFINE)==0) {
13.2727 - /* as long as the function stays undefined, update the address and the tag */
13.2728 - if (sym->states==NULL)
13.2729 - sym->addr=code_idx;
13.2730 - sym->tag=tag;
13.2731 - } /* if */
13.2732 - } else {
13.2733 - /* don't set the "uDEFINE" flag; it may be a prototype */
13.2734 - sym=addsym(name,code_idx,iFUNCTN,sGLOBAL,tag,0);
13.2735 - assert(sym!=NULL); /* fatal error 103 must be given on error */
13.2736 - /* assume no arguments */
13.2737 - sym->dim.arglist=(arginfo*)malloc(1*sizeof(arginfo));
13.2738 - sym->dim.arglist[0].ident=0;
13.2739 - /* set library ID to NULL (only for native functions) */
13.2740 - sym->x.lib=NULL;
13.2741 - /* set the required stack size to zero (only for non-native functions) */
13.2742 - sym->x.stacksize=1; /* 1 for PROC opcode */
13.2743 - } /* if */
13.2744 - if (pc_depricate!=NULL) {
13.2745 - assert(sym!=NULL);
13.2746 - sym->flags|=flgDEPRICATED;
13.2747 - if (sc_status==statWRITE) {
13.2748 - if (sym->documentation!=NULL) {
13.2749 - free(sym->documentation);
13.2750 - sym->documentation=NULL;
13.2751 - } /* if */
13.2752 - sym->documentation=pc_depricate;
13.2753 - } else {
13.2754 - free(pc_depricate);
13.2755 - } /* if */
13.2756 - pc_depricate=NULL;
13.2757 - } /* if */
13.2758 -
13.2759 - return sym;
13.2760 -}
13.2761 -
13.2762 -/* This routine adds symbolic information for each argument.
13.2763 - */
13.2764 -static void define_args(void)
13.2765 -{
13.2766 - symbol *sym;
13.2767 -
13.2768 - /* At this point, no local variables have been declared. All
13.2769 - * local symbols are function arguments.
13.2770 - */
13.2771 - sym=loctab.next;
13.2772 - while (sym!=NULL) {
13.2773 - assert(sym->ident!=iLABEL);
13.2774 - assert(sym->vclass==sLOCAL);
13.2775 - markexpr(sLDECL,sym->name,sym->addr); /* mark for better optimization */
13.2776 - sym=sym->next;
13.2777 - } /* while */
13.2778 -}
13.2779 -
13.2780 -static int operatorname(char *name)
13.2781 -{
13.2782 - int opertok;
13.2783 - char *str;
13.2784 - cell val;
13.2785 -
13.2786 - assert(name!=NULL);
13.2787 -
13.2788 - /* check the operator */
13.2789 - opertok=lex(&val,&str);
13.2790 - switch (opertok) {
13.2791 - case '+':
13.2792 - case '-':
13.2793 - case '*':
13.2794 - case '/':
13.2795 - case '%':
13.2796 - case '>':
13.2797 - case '<':
13.2798 - case '!':
13.2799 - case '~':
13.2800 - case '=':
13.2801 - name[0]=(char)opertok;
13.2802 - name[1]='\0';
13.2803 - break;
13.2804 - case tINC:
13.2805 - strcpy(name,"++");
13.2806 - break;
13.2807 - case tDEC:
13.2808 - strcpy(name,"--");
13.2809 - break;
13.2810 - case tlEQ:
13.2811 - strcpy(name,"==");
13.2812 - break;
13.2813 - case tlNE:
13.2814 - strcpy(name,"!=");
13.2815 - break;
13.2816 - case tlLE:
13.2817 - strcpy(name,"<=");
13.2818 - break;
13.2819 - case tlGE:
13.2820 - strcpy(name,">=");
13.2821 - break;
13.2822 - default:
13.2823 - name[0]='\0';
13.2824 - error(7); /* operator cannot be redefined (or bad operator name) */
13.2825 - return 0;
13.2826 - } /* switch */
13.2827 -
13.2828 - return opertok;
13.2829 -}
13.2830 -
13.2831 -static int operatoradjust(int opertok,symbol *sym,char *opername,int resulttag)
13.2832 -{
13.2833 - int tags[2]={0,0};
13.2834 - int count=0;
13.2835 - arginfo *arg;
13.2836 - char tmpname[sNAMEMAX+1];
13.2837 - symbol *oldsym;
13.2838 -
13.2839 - if (opertok==0)
13.2840 - return TRUE;
13.2841 -
13.2842 - assert(sym!=NULL && sym->ident==iFUNCTN && sym->dim.arglist!=NULL);
13.2843 - /* count arguments and save (first two) tags */
13.2844 - while (arg=&sym->dim.arglist[count], arg->ident!=0) {
13.2845 - if (count<2) {
13.2846 - if (arg->numtags>1)
13.2847 - error(65,count+1); /* function argument may only have a single tag */
13.2848 - else if (arg->numtags==1)
13.2849 - tags[count]=arg->tags[0];
13.2850 - } /* if */
13.2851 - if (opertok=='~' && count==0) {
13.2852 - if (arg->ident!=iREFARRAY)
13.2853 - error(73,arg->name);/* must be an array argument */
13.2854 - } else {
13.2855 - if (arg->ident!=iVARIABLE)
13.2856 - error(66,arg->name);/* must be non-reference argument */
13.2857 - } /* if */
13.2858 - if (arg->hasdefault)
13.2859 - error(59,arg->name); /* arguments of an operator may not have a default value */
13.2860 - count++;
13.2861 - } /* while */
13.2862 -
13.2863 - /* for '!', '++' and '--', count must be 1
13.2864 - * for '-', count may be 1 or 2
13.2865 - * for '=', count must be 1, and the resulttag is also important
13.2866 - * for all other (binary) operators and the special '~' operator, count must be 2
13.2867 - */
13.2868 - switch (opertok) {
13.2869 - case '!':
13.2870 - case '=':
13.2871 - case tINC:
13.2872 - case tDEC:
13.2873 - if (count!=1)
13.2874 - error(62); /* number or placement of the operands does not fit the operator */
13.2875 - break;
13.2876 - case '-':
13.2877 - if (count!=1 && count!=2)
13.2878 - error(62); /* number or placement of the operands does not fit the operator */
13.2879 - break;
13.2880 - default:
13.2881 - if (count!=2)
13.2882 - error(62); /* number or placement of the operands does not fit the operator */
13.2883 - } /* switch */
13.2884 -
13.2885 - if (tags[0]==0 && (opertok!='=' && tags[1]==0 || opertok=='=' && resulttag==0))
13.2886 - error(64); /* cannot change predefined operators */
13.2887 -
13.2888 - /* change the operator name */
13.2889 - assert(strlen(opername)>0);
13.2890 - operator_symname(tmpname,opername,tags[0],tags[1],count,resulttag);
13.2891 - if ((oldsym=findglb(tmpname,sGLOBAL))!=NULL) {
13.2892 - int i;
13.2893 - if ((oldsym->usage & uDEFINE)!=0) {
13.2894 - char errname[2*sNAMEMAX+16];
13.2895 - funcdisplayname(errname,tmpname);
13.2896 - error(21,errname); /* symbol already defined */
13.2897 - } /* if */
13.2898 - sym->usage|=oldsym->usage; /* copy flags from the previous definition */
13.2899 - for (i=0; i<oldsym->numrefers; i++)
13.2900 - if (oldsym->refer[i]!=NULL)
13.2901 - refer_symbol(sym,oldsym->refer[i]);
13.2902 - delete_symbol(&glbtab,oldsym);
13.2903 - } /* if */
13.2904 - strcpy(sym->name,tmpname);
13.2905 - sym->hash=namehash(sym->name);/* calculate new hash */
13.2906 -
13.2907 - /* operators should return a value, except the '~' operator */
13.2908 - if (opertok!='~')
13.2909 - sym->usage |= uRETVALUE;
13.2910 -
13.2911 - return TRUE;
13.2912 -}
13.2913 -
13.2914 -static int check_operatortag(int opertok,int resulttag,char *opername)
13.2915 -{
13.2916 - assert(opername!=NULL && strlen(opername)>0);
13.2917 - switch (opertok) {
13.2918 - case '!':
13.2919 - case '<':
13.2920 - case '>':
13.2921 - case tlEQ:
13.2922 - case tlNE:
13.2923 - case tlLE:
13.2924 - case tlGE:
13.2925 - if (resulttag!=pc_addtag("bool")) {
13.2926 - error(63,opername,"bool:"); /* operator X requires a "bool:" result tag */
13.2927 - return FALSE;
13.2928 - } /* if */
13.2929 - break;
13.2930 - case '~':
13.2931 - if (resulttag!=0) {
13.2932 - error(63,opername,"_:"); /* operator "~" requires a "_:" result tag */
13.2933 - return FALSE;
13.2934 - } /* if */
13.2935 - break;
13.2936 - } /* switch */
13.2937 - return TRUE;
13.2938 -}
13.2939 -
13.2940 -static char *tag2str(char *dest,int tag)
13.2941 -{
13.2942 - tag &= TAGMASK;
13.2943 - assert(tag>=0);
13.2944 - sprintf(dest,"0%x",tag);
13.2945 - return isdigit(dest[1]) ? &dest[1] : dest;
13.2946 -}
13.2947 -
13.2948 -SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag)
13.2949 -{
13.2950 - char tagstr1[10], tagstr2[10];
13.2951 - int opertok;
13.2952 -
13.2953 - assert(numtags>=1 && numtags<=2);
13.2954 - opertok= (opername[1]=='\0') ? opername[0] : 0;
13.2955 - if (opertok=='=')
13.2956 - sprintf(symname,"%s%s%s",tag2str(tagstr1,resulttag),opername,tag2str(tagstr2,tag1));
13.2957 - else if (numtags==1 || opertok=='~')
13.2958 - sprintf(symname,"%s%s",opername,tag2str(tagstr1,tag1));
13.2959 - else
13.2960 - sprintf(symname,"%s%s%s",tag2str(tagstr1,tag1),opername,tag2str(tagstr2,tag2));
13.2961 - return symname;
13.2962 -}
13.2963 -
13.2964 -static int parse_funcname(char *fname,int *tag1,int *tag2,char *opname)
13.2965 -{
13.2966 - char *ptr,*name;
13.2967 - int unary;
13.2968 -
13.2969 - /* tags are only positive, so if the function name starts with a '-',
13.2970 - * the operator is an unary '-' or '--' operator.
13.2971 - */
13.2972 - if (*fname=='-') {
13.2973 - *tag1=0;
13.2974 - unary=TRUE;
13.2975 - ptr=fname;
13.2976 - } else {
13.2977 - *tag1=(int)strtol(fname,&ptr,16);
13.2978 - unary= ptr==fname; /* unary operator if it doesn't start with a tag name */
13.2979 - } /* if */
13.2980 - assert(!unary || *tag1==0);
13.2981 - assert(*ptr!='\0');
13.2982 - for (name=opname; !isdigit(*ptr); )
13.2983 - *name++ = *ptr++;
13.2984 - *name='\0';
13.2985 - *tag2=(int)strtol(ptr,NULL,16);
13.2986 - return unary;
13.2987 -}
13.2988 -
13.2989 -static constvalue *find_tag_byval(int tag)
13.2990 -{
13.2991 - constvalue *tagsym;
13.2992 - tagsym=find_constval_byval(&tagname_tab,tag & ~PUBLICTAG);
13.2993 - if (tagsym==NULL)
13.2994 - tagsym=find_constval_byval(&tagname_tab,tag | PUBLICTAG);
13.2995 - return tagsym;
13.2996 -}
13.2997 -
13.2998 -SC_FUNC char *funcdisplayname(char *dest,char *funcname)
13.2999 -{
13.3000 - int tags[2];
13.3001 - char opname[10];
13.3002 - constvalue *tagsym[2];
13.3003 - int unary;
13.3004 -
13.3005 - if (isalpha(*funcname) || *funcname=='_' || *funcname==PUBLIC_CHAR || *funcname=='\0') {
13.3006 - if (dest!=funcname)
13.3007 - strcpy(dest,funcname);
13.3008 - return dest;
13.3009 - } /* if */
13.3010 -
13.3011 - unary=parse_funcname(funcname,&tags[0],&tags[1],opname);
13.3012 - tagsym[1]=find_tag_byval(tags[1]);
13.3013 - assert(tagsym[1]!=NULL);
13.3014 - if (unary) {
13.3015 - sprintf(dest,"operator%s(%s:)",opname,tagsym[1]->name);
13.3016 - } else {
13.3017 - tagsym[0]=find_tag_byval(tags[0]);
13.3018 - assert(tagsym[0]!=NULL);
13.3019 - /* special case: the assignment operator has the return value as the 2nd tag */
13.3020 - if (opname[0]=='=' && opname[1]=='\0')
13.3021 - sprintf(dest,"%s:operator%s(%s:)",tagsym[0]->name,opname,tagsym[1]->name);
13.3022 - else
13.3023 - sprintf(dest,"operator%s(%s:,%s:)",opname,tagsym[0]->name,tagsym[1]->name);
13.3024 - } /* if */
13.3025 - return dest;
13.3026 -}
13.3027 -
13.3028 -static void funcstub(int fnative)
13.3029 -{
13.3030 - int tok,tag,fpublic;
13.3031 - char *str;
13.3032 - cell val,size;
13.3033 - char symbolname[sNAMEMAX+1];
13.3034 - int idxtag[sDIMEN_MAX];
13.3035 - int dim[sDIMEN_MAX];
13.3036 - int numdim;
13.3037 - symbol *sym,*sub;
13.3038 - int opertok;
13.3039 -
13.3040 - opertok=0;
13.3041 - lastst=0;
13.3042 - litidx=0; /* clear the literal pool */
13.3043 - assert(loctab.next==NULL); /* local symbol table should be empty */
13.3044 -
13.3045 - tag=pc_addtag(NULL); /* get the tag of the return value */
13.3046 - numdim=0;
13.3047 - while (matchtoken('[')) {
13.3048 - /* the function returns an array, get this tag for the index and the array
13.3049 - * dimensions
13.3050 - */
13.3051 - if (numdim == sDIMEN_MAX) {
13.3052 - error(53); /* exceeding maximum number of dimensions */
13.3053 - return;
13.3054 - } /* if */
13.3055 - size=needsub(&idxtag[numdim],NULL); /* get size; size==0 for "var[]" */
13.3056 - if (size==0)
13.3057 - error(9); /* invalid array size */
13.3058 - #if INT_MAX < LONG_MAX
13.3059 - if (size > INT_MAX)
13.3060 - error(105); /* overflow, exceeding capacity */
13.3061 - #endif
13.3062 - dim[numdim++]=(int)size;
13.3063 - } /* while */
13.3064 -
13.3065 - tok=lex(&val,&str);
13.3066 - fpublic=(tok==tPUBLIC) || (tok==tSYMBOL && str[0]==PUBLIC_CHAR);
13.3067 - if (fnative) {
13.3068 - if (fpublic || tok==tSTOCK || tok==tSTATIC || tok==tSYMBOL && *str==PUBLIC_CHAR)
13.3069 - error(42); /* invalid combination of class specifiers */
13.3070 - } else {
13.3071 - if (tok==tPUBLIC || tok==tSTOCK || tok==tSTATIC)
13.3072 - tok=lex(&val,&str);
13.3073 - } /* if */
13.3074 -
13.3075 - if (tok==tOPERATOR) {
13.3076 - opertok=operatorname(symbolname);
13.3077 - if (opertok==0)
13.3078 - return; /* error message already given */
13.3079 - check_operatortag(opertok,tag,symbolname);
13.3080 - } else {
13.3081 - if (tok!=tSYMBOL && freading) {
13.3082 - error(10); /* illegal function or declaration */
13.3083 - return;
13.3084 - } /* if */
13.3085 - strcpy(symbolname,str);
13.3086 - } /* if */
13.3087 - needtoken('('); /* only functions may be native/forward */
13.3088 -
13.3089 - sym=fetchfunc(symbolname,tag);/* get a pointer to the function entry */
13.3090 - if (sym==NULL)
13.3091 - return;
13.3092 - if (fnative) {
13.3093 - sym->usage=(char)(uNATIVE | uRETVALUE | uDEFINE | (sym->usage & uPROTOTYPED));
13.3094 - sym->x.lib=curlibrary;
13.3095 - } else if (fpublic) {
13.3096 - sym->usage|=uPUBLIC;
13.3097 - } /* if */
13.3098 - sym->usage|=uFORWARD;
13.3099 -
13.3100 - declargs(sym,FALSE);
13.3101 - /* "declargs()" found the ")" */
13.3102 - sc_attachdocumentation(sym); /* attach any documenation to the function */
13.3103 - if (!operatoradjust(opertok,sym,symbolname,tag))
13.3104 - sym->usage &= ~uDEFINE;
13.3105 -
13.3106 - if (getstates(symbolname)!=0) {
13.3107 - if (fnative || opertok!=0)
13.3108 - error(82); /* native functions and operators may not have states */
13.3109 - else
13.3110 - error(231); /* ignoring state specifications on forward declarations */
13.3111 - } /* if */
13.3112 -
13.3113 - /* for a native operator, also need to specify an "exported" function name;
13.3114 - * for a native function, this is optional
13.3115 - */
13.3116 - if (fnative) {
13.3117 - if (opertok!=0) {
13.3118 - needtoken('=');
13.3119 - lexpush(); /* push back, for matchtoken() to retrieve again */
13.3120 - } /* if */
13.3121 - if (matchtoken('=')) {
13.3122 - /* allow number or symbol */
13.3123 - if (matchtoken(tSYMBOL)) {
13.3124 - tokeninfo(&val,&str);
13.3125 - insert_alias(sym->name,str);
13.3126 - } else {
13.3127 - constexpr(&val,NULL,NULL);
13.3128 - sym->addr=val;
13.3129 - /* At the moment, I have assumed that this syntax is only valid if
13.3130 - * val < 0. To properly mix "normal" native functions and indexed
13.3131 - * native functions, one should use negative indices anyway.
13.3132 - * Special code for a negative index in sym->addr exists in SC4.C
13.3133 - * (ffcall()) and in SC6.C (the loops for counting the number of native
13.3134 - * variables and for writing them).
13.3135 - */
13.3136 - } /* if */
13.3137 - } /* if */
13.3138 - } /* if */
13.3139 - needtoken(tTERM);
13.3140 -
13.3141 - /* attach the array to the function symbol */
13.3142 - if (numdim>0) {
13.3143 - assert(sym!=NULL);
13.3144 - sub=addvariable(symbolname,0,iARRAY,sGLOBAL,tag,dim,numdim,idxtag);
13.3145 - sub->parent=sym;
13.3146 - } /* if */
13.3147 -
13.3148 - litidx=0; /* clear the literal pool */
13.3149 - delete_symbols(&loctab,0,TRUE,TRUE);/* clear local variables queue */
13.3150 -}
13.3151 -
13.3152 -/* newfunc - begin a function
13.3153 - *
13.3154 - * This routine is called from "parse" and tries to make a function
13.3155 - * out of the following text
13.3156 - *
13.3157 - * Global references: funcstatus,lastst,litidx
13.3158 - * rettype (altered)
13.3159 - * curfunc (altered)
13.3160 - * declared (altered)
13.3161 - * glb_declared (altered)
13.3162 - * sc_alignnext (altered)
13.3163 - */
13.3164 -static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock)
13.3165 -{
13.3166 - symbol *sym;
13.3167 - int argcnt,tok,tag,funcline;
13.3168 - int opertok,opererror;
13.3169 - char symbolname[sNAMEMAX+1];
13.3170 - char *str;
13.3171 - cell val,cidx,glbdecl;
13.3172 - short filenum;
13.3173 - int state_id;
13.3174 -
13.3175 - assert(litidx==0); /* literal queue should be empty */
13.3176 - litidx=0; /* clear the literal pool (should already be empty) */
13.3177 - opertok=0;
13.3178 - lastst=0; /* no statement yet */
13.3179 - cidx=0; /* just to avoid compiler warnings */
13.3180 - glbdecl=0;
13.3181 - assert(loctab.next==NULL); /* local symbol table should be empty */
13.3182 - filenum=fcurrent; /* save file number at the start of the declaration */
13.3183 -
13.3184 - if (firstname!=NULL) {
13.3185 - assert(strlen(firstname)<=sNAMEMAX);
13.3186 - strcpy(symbolname,firstname); /* save symbol name */
13.3187 - tag=firsttag;
13.3188 - } else {
13.3189 - tag= (firsttag>=0) ? firsttag : pc_addtag(NULL);
13.3190 - tok=lex(&val,&str);
13.3191 - assert(!fpublic);
13.3192 - if (tok==tNATIVE || tok==tPUBLIC && stock)
13.3193 - error(42); /* invalid combination of class specifiers */
13.3194 - if (tok==tOPERATOR) {
13.3195 - opertok=operatorname(symbolname);
13.3196 - if (opertok==0)
13.3197 - return TRUE; /* error message already given */
13.3198 - check_operatortag(opertok,tag,symbolname);
13.3199 - } else {
13.3200 - if (tok!=tSYMBOL && freading) {
13.3201 - error(20,str); /* invalid symbol name */
13.3202 - return FALSE;
13.3203 - } /* if */
13.3204 - assert(strlen(str)<=sNAMEMAX);
13.3205 - strcpy(symbolname,str);
13.3206 - } /* if */
13.3207 - } /* if */
13.3208 - /* check whether this is a function or a variable declaration */
13.3209 - if (!matchtoken('('))
13.3210 - return FALSE;
13.3211 - /* so it is a function, proceed */
13.3212 - funcline=fline; /* save line at which the function is defined */
13.3213 - if (symbolname[0]==PUBLIC_CHAR) {
13.3214 - fpublic=TRUE; /* implicitly public function */
13.3215 - if (stock)
13.3216 - error(42); /* invalid combination of class specifiers */
13.3217 - } /* if */
13.3218 - sym=fetchfunc(symbolname,tag);/* get a pointer to the function entry */
13.3219 - if (sym==NULL || (sym->usage & uNATIVE)!=0)
13.3220 - return TRUE; /* it was recognized as a function declaration, but not as a valid one */
13.3221 - if (fpublic)
13.3222 - sym->usage|=uPUBLIC;
13.3223 - if (fstatic)
13.3224 - sym->fnumber=filenum;
13.3225 - /* if the function was used before being declared, and it has a tag for the
13.3226 - * result, add a third pass (as second "skimming" parse) because the function
13.3227 - * result may have been used with user-defined operators, which have now
13.3228 - * been incorrectly flagged (as the return tag was unknown at the time of
13.3229 - * the call)
13.3230 - */
13.3231 - if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD && sym->tag!=0) {
13.3232 - int curstatus=sc_status;
13.3233 - sc_status=statWRITE; /* temporarily set status to WRITE, so the warning isn't blocked */
13.3234 -#if 0 /* SourceMod - silly, should be removed in first pass, so removed */
13.3235 - error(208);
13.3236 -#endif
13.3237 - sc_status=curstatus;
13.3238 - sc_reparse=TRUE; /* must add another pass to "initial scan" phase */
13.3239 - } /* if */
13.3240 -#if 0 /* Not used for SourceMod */
13.3241 - /* we want public functions to be explicitly prototyped, as they are called
13.3242 - * from the outside
13.3243 - */
13.3244 - if (fpublic && (sym->usage & uFORWARD)==0)
13.3245 - error(235,symbolname);
13.3246 -#endif
13.3247 - /* declare all arguments */
13.3248 - argcnt=declargs(sym,TRUE);
13.3249 - opererror=!operatoradjust(opertok,sym,symbolname,tag);
13.3250 - if (strcmp(symbolname,uMAINFUNC)==0 || strcmp(symbolname,uENTRYFUNC)==0) {
13.3251 - if (argcnt>0)
13.3252 - error(5); /* "main()" and "entry()" functions may not have any arguments */
13.3253 - sym->usage|=uREAD; /* "main()" is the program's entry point: always used */
13.3254 - } /* if */
13.3255 - state_id=getstates(symbolname);
13.3256 - if (state_id>0 && (opertok!=0 || strcmp(symbolname,uMAINFUNC)==0))
13.3257 - error(82); /* operators may not have states, main() may neither */
13.3258 - attachstatelist(sym,state_id);
13.3259 - /* "declargs()" found the ")"; if a ";" appears after this, it was a
13.3260 - * prototype */
13.3261 - if (matchtoken(';')) {
13.3262 - sym->usage|=uFORWARD;
13.3263 - if (!sc_needsemicolon)
13.3264 - error(218); /* old style prototypes used with optional semicolumns */
13.3265 - delete_symbols(&loctab,0,TRUE,TRUE); /* prototype is done; forget everything */
13.3266 - return TRUE;
13.3267 - } /* if */
13.3268 - /* so it is not a prototype, proceed */
13.3269 - /* if this is a function that is not referred to (this can only be detected
13.3270 - * in the second stage), shut code generation off */
13.3271 - if (sc_status==statWRITE && (sym->usage & uREAD)==0 && !fpublic) {
13.3272 - sc_status=statSKIP;
13.3273 - cidx=code_idx;
13.3274 - glbdecl=glb_declared;
13.3275 - } /* if */
13.3276 - if ((sym->flags & flgDEPRICATED)!=0) {
13.3277 - char *ptr= (sym->documentation!=NULL) ? sym->documentation : "";
13.3278 - error(234,symbolname,ptr); /* depricated (probably a public function) */
13.3279 - } /* if */
13.3280 - begcseg();
13.3281 - sym->usage|=uDEFINE; /* set the definition flag */
13.3282 - if (stock)
13.3283 - sym->usage|=uSTOCK;
13.3284 - if (opertok!=0 && opererror)
13.3285 - sym->usage &= ~uDEFINE;
13.3286 - /* if the function has states, dump the label to the start of the function */
13.3287 - if (state_id!=0) {
13.3288 - constvalue *ptr=sym->states->next;
13.3289 - while (ptr!=NULL) {
13.3290 - assert(sc_status!=statWRITE || strlen(ptr->name)>0);
13.3291 - if (ptr->index==state_id) {
13.3292 - setlabel((int)strtol(ptr->name,NULL,16));
13.3293 - break;
13.3294 - } /* if */
13.3295 - ptr=ptr->next;
13.3296 - } /* while */
13.3297 - } /* if */
13.3298 - startfunc(sym->name); /* creates stack frame */
13.3299 - insert_dbgline(funcline);
13.3300 - setline(FALSE);
13.3301 - if (sc_alignnext) {
13.3302 - alignframe(sc_dataalign);
13.3303 - sc_alignnext=FALSE;
13.3304 - } /* if */
13.3305 - declared=0; /* number of local cells */
13.3306 - rettype=(sym->usage & uRETVALUE); /* set "return type" variable */
13.3307 - curfunc=sym;
13.3308 - define_args(); /* add the symbolic info for the function arguments */
13.3309 - #if !defined SC_LIGHT
13.3310 - if (matchtoken('{')) {
13.3311 - lexpush();
13.3312 - } else {
13.3313 - /* Insert a separator so that comments following the statement will not
13.3314 - * be attached to this function; they should be attached to the next
13.3315 - * function. This is not a problem for functions having a compound block,
13.3316 - * because the closing brace is an explicit "end token" for the function.
13.3317 - * With single statement functions, the preprocessor may overread the
13.3318 - * source code before the parser determines an "end of statement".
13.3319 - */
13.3320 - insert_docstring_separator();
13.3321 - } /* if */
13.3322 - #endif
13.3323 - sc_curstates=state_id;/* set state id, for accessing global state variables */
13.3324 - statement(NULL,FALSE);
13.3325 - sc_curstates=0;
13.3326 - if ((rettype & uRETVALUE)!=0)
13.3327 - sym->usage|=uRETVALUE;
13.3328 - if (declared!=0) {
13.3329 - /* This happens only in a very special (and useless) case, where a function
13.3330 - * has only a single statement in its body (no compound block) and that
13.3331 - * statement declares a new variable
13.3332 - */
13.3333 - modstk((int)declared*sizeof(cell)); /* remove all local variables */
13.3334 - declared=0;
13.3335 - } /* if */
13.3336 - if ((lastst!=tRETURN) && (lastst!=tGOTO)){
13.3337 - ldconst(0,sPRI);
13.3338 - ffret(strcmp(sym->name,uENTRYFUNC)!=0);
13.3339 - if ((sym->usage & uRETVALUE)!=0) {
13.3340 - char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
13.3341 - funcdisplayname(symname,sym->name);
13.3342 - error(209,symname); /* function should return a value */
13.3343 - } /* if */
13.3344 - } /* if */
13.3345 - endfunc();
13.3346 - sym->codeaddr=code_idx;
13.3347 - sc_attachdocumentation(sym); /* attach collected documenation to the function */
13.3348 - if (litidx) { /* if there are literals defined */
13.3349 - glb_declared+=litidx;
13.3350 - begdseg(); /* flip to DATA segment */
13.3351 - dumplits(); /* dump literal strings */
13.3352 - litidx=0;
13.3353 - } /* if */
13.3354 - testsymbols(&loctab,0,TRUE,TRUE); /* test for unused arguments and labels */
13.3355 - delete_symbols(&loctab,0,TRUE,TRUE); /* clear local variables queue */
13.3356 - assert(loctab.next==NULL);
13.3357 - curfunc=NULL;
13.3358 - if (sc_status==statSKIP) {
13.3359 - sc_status=statWRITE;
13.3360 - code_idx=cidx;
13.3361 - glb_declared=glbdecl;
13.3362 - } /* if */
13.3363 - return TRUE;
13.3364 -}
13.3365 -
13.3366 -static int argcompare(arginfo *a1,arginfo *a2)
13.3367 -{
13.3368 - int result,level,i;
13.3369 -
13.3370 -#if 0 /* SourceMod uses case insensitive args for forwards */
13.3371 - result= strcmp(a1->name,a2->name)==0; /* name */
13.3372 -#else
13.3373 - result=1;
13.3374 -#endif
13.3375 - if (result)
13.3376 - result= a1->ident==a2->ident; /* type/class */
13.3377 - if (result)
13.3378 - result= a1->usage==a2->usage; /* "const" flag */
13.3379 - if (result)
13.3380 - result= a1->numtags==a2->numtags; /* tags (number and names) */
13.3381 - for (i=0; result && i<a1->numtags; i++)
13.3382 - result= a1->tags[i]==a2->tags[i];
13.3383 - if (result)
13.3384 - result= a1->numdim==a2->numdim; /* array dimensions & index tags */
13.3385 - for (level=0; result && level<a1->numdim; level++)
13.3386 - result= a1->dim[level]==a2->dim[level];
13.3387 - for (level=0; result && level<a1->numdim; level++)
13.3388 - result= a1->idxtag[level]==a2->idxtag[level];
13.3389 - if (result)
13.3390 - result= a1->hasdefault==a2->hasdefault; /* availability of default value */
13.3391 - if (a1->hasdefault) {
13.3392 - if (a1->ident==iREFARRAY) {
13.3393 - if (result)
13.3394 - result= a1->defvalue.array.size==a2->defvalue.array.size;
13.3395 - if (result)
13.3396 - result= a1->defvalue.array.arraysize==a2->defvalue.array.arraysize;
13.3397 - /* ??? should also check contents of the default array (these troubles
13.3398 - * go away in a 2-pass compiler that forbids double declarations, but
13.3399 - * Pawn currently does not forbid them) */
13.3400 - } else {
13.3401 - if (result) {
13.3402 - if ((a1->hasdefault & uSIZEOF)!=0 || (a1->hasdefault & uTAGOF)!=0)
13.3403 - result= a1->hasdefault==a2->hasdefault
13.3404 - && strcmp(a1->defvalue.size.symname,a2->defvalue.size.symname)==0
13.3405 - && a1->defvalue.size.level==a2->defvalue.size.level;
13.3406 - else
13.3407 - result= a1->defvalue.val==a2->defvalue.val;
13.3408 - } /* if */
13.3409 - } /* if */
13.3410 - if (result)
13.3411 - result= a1->defvalue_tag==a2->defvalue_tag;
13.3412 - } /* if */
13.3413 - return result;
13.3414 -}
13.3415 -
13.3416 -/* declargs()
13.3417 - *
13.3418 - * This routine adds an entry in the local symbol table for each argument
13.3419 - * found in the argument list. It returns the number of arguments.
13.3420 - */
13.3421 -static int declargs(symbol *sym,int chkshadow)
13.3422 -{
13.3423 - #define MAXTAGS 16
13.3424 - char *ptr;
13.3425 - int argcnt,oldargcnt,tok,tags[MAXTAGS],numtags;
13.3426 - cell val;
13.3427 - arginfo arg, *arglist;
13.3428 - char name[sNAMEMAX+1];
13.3429 - int ident,fpublic,fconst;
13.3430 - int idx;
13.3431 -
13.3432 - /* if the function is already defined earlier, get the number of arguments
13.3433 - * of the existing definition
13.3434 - */
13.3435 - oldargcnt=0;
13.3436 - if ((sym->usage & uPROTOTYPED)!=0)
13.3437 - while (sym->dim.arglist[oldargcnt].ident!=0)
13.3438 - oldargcnt++;
13.3439 - argcnt=0; /* zero aruments up to now */
13.3440 - ident=iVARIABLE;
13.3441 - numtags=0;
13.3442 - fconst=FALSE;
13.3443 - fpublic= (sym->usage & uPUBLIC)!=0;
13.3444 - /* the '(' parantheses has already been parsed */
13.3445 - if (!matchtoken(')')){
13.3446 - do { /* there are arguments; process them */
13.3447 - /* any legal name increases argument count (and stack offset) */
13.3448 - tok=lex(&val,&ptr);
13.3449 - switch (tok) {
13.3450 - case 0:
13.3451 - /* nothing */
13.3452 - break;
13.3453 - case '&':
13.3454 - if (ident!=iVARIABLE || numtags>0)
13.3455 - error(1,"-identifier-","&");
13.3456 - ident=iREFERENCE;
13.3457 - break;
13.3458 - case tCONST:
13.3459 - if (ident!=iVARIABLE || numtags>0)
13.3460 - error(1,"-identifier-","const");
13.3461 - fconst=TRUE;
13.3462 - break;
13.3463 - case tLABEL:
13.3464 - if (numtags>0)
13.3465 - error(1,"-identifier-","-tagname-");
13.3466 - tags[0]=pc_addtag(ptr);
13.3467 - numtags=1;
13.3468 - break;
13.3469 - case '{':
13.3470 - if (numtags>0)
13.3471 - error(1,"-identifier-","-tagname-");
13.3472 - numtags=0;
13.3473 - while (numtags<MAXTAGS) {
13.3474 - if (!matchtoken('_') && !needtoken(tSYMBOL))
13.3475 - break;
13.3476 - tokeninfo(&val,&ptr);
13.3477 - tags[numtags++]=pc_addtag(ptr);
13.3478 - if (matchtoken('}'))
13.3479 - break;
13.3480 - needtoken(',');
13.3481 - } /* for */
13.3482 - needtoken(':');
13.3483 - tok=tLABEL; /* for outer loop: flag that we have seen a tagname */
13.3484 - break;
13.3485 - case tSYMBOL:
13.3486 - if (argcnt>=sMAXARGS)
13.3487 - error(45); /* too many function arguments */
13.3488 - strcpy(name,ptr); /* save symbol name */
13.3489 - if (name[0]==PUBLIC_CHAR)
13.3490 - error(56,name); /* function arguments cannot be public */
13.3491 - if (numtags==0)
13.3492 - tags[numtags++]=0; /* default tag */
13.3493 - /* Stack layout:
13.3494 - * base + 0*sizeof(cell) == previous "base"
13.3495 - * base + 1*sizeof(cell) == function return address
13.3496 - * base + 2*sizeof(cell) == number of arguments
13.3497 - * base + 3*sizeof(cell) == first argument of the function
13.3498 - * So the offset of each argument is "(argcnt+3) * sizeof(cell)".
13.3499 - */
13.3500 - doarg(name,ident,(argcnt+3)*sizeof(cell),tags,numtags,fpublic,fconst,chkshadow,&arg);
13.3501 - if (fpublic && arg.hasdefault)
13.3502 - error(59,name); /* arguments of a public function may not have a default value */
13.3503 - if ((sym->usage & uPROTOTYPED)==0) {
13.3504 - /* redimension the argument list, add the entry */
13.3505 - sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
13.3506 - if (sym->dim.arglist==0)
13.3507 - error(103); /* insufficient memory */
13.3508 - memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
13.3509 - sym->dim.arglist[argcnt]=arg;
13.3510 - } else {
13.3511 - /* check the argument with the earlier definition */
13.3512 - if (argcnt>oldargcnt || !argcompare(&sym->dim.arglist[argcnt],&arg))
13.3513 - error(25); /* function definition does not match prototype */
13.3514 - /* may need to free default array argument and the tag list */
13.3515 - if (arg.ident==iREFARRAY && arg.hasdefault)
13.3516 - free(arg.defvalue.array.data);
13.3517 - else if (arg.ident==iVARIABLE
13.3518 - && ((arg.hasdefault & uSIZEOF)!=0 || (arg.hasdefault & uTAGOF)!=0))
13.3519 - free(arg.defvalue.size.symname);
13.3520 - free(arg.tags);
13.3521 - } /* if */
13.3522 - argcnt++;
13.3523 - ident=iVARIABLE;
13.3524 - numtags=0;
13.3525 - fconst=FALSE;
13.3526 - break;
13.3527 - case tELLIPS:
13.3528 - if (ident!=iVARIABLE)
13.3529 - error(10); /* illegal function or declaration */
13.3530 - if (numtags==0)
13.3531 - tags[numtags++]=0; /* default tag */
13.3532 - if ((sym->usage & uPROTOTYPED)==0) {
13.3533 - /* redimension the argument list, add the entry iVARARGS */
13.3534 - sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
13.3535 - if (sym->dim.arglist==0)
13.3536 - error(103); /* insufficient memory */
13.3537 - memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
13.3538 - sym->dim.arglist[argcnt].ident=iVARARGS;
13.3539 - sym->dim.arglist[argcnt].hasdefault=FALSE;
13.3540 - sym->dim.arglist[argcnt].defvalue.val=0;
13.3541 - sym->dim.arglist[argcnt].defvalue_tag=0;
13.3542 - sym->dim.arglist[argcnt].numtags=numtags;
13.3543 - sym->dim.arglist[argcnt].tags=(int*)malloc(numtags*sizeof tags[0]);
13.3544 - if (sym->dim.arglist[argcnt].tags==NULL)
13.3545 - error(103); /* insufficient memory */
13.3546 - memcpy(sym->dim.arglist[argcnt].tags,tags,numtags*sizeof tags[0]);
13.3547 - } else {
13.3548 - if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
13.3549 - error(25); /* function definition does not match prototype */
13.3550 - } /* if */
13.3551 - argcnt++;
13.3552 - break;
13.3553 - default:
13.3554 - error(10); /* illegal function or declaration */
13.3555 - } /* switch */
13.3556 - } while (tok=='&' || tok==tLABEL || tok==tCONST
13.3557 - || tok!=tELLIPS && matchtoken(',')); /* more? */
13.3558 - /* if the next token is not ",", it should be ")" */
13.3559 - needtoken(')');
13.3560 - } /* if */
13.3561 - /* resolve any "sizeof" arguments (now that all arguments are known) */
13.3562 - assert(sym->dim.arglist!=NULL);
13.3563 - arglist=sym->dim.arglist;
13.3564 - for (idx=0; idx<argcnt && arglist[idx].ident!=0; idx++) {
13.3565 - if ((arglist[idx].hasdefault & uSIZEOF)!=0 || (arglist[idx].hasdefault & uTAGOF)!=0) {
13.3566 - int altidx;
13.3567 - /* Find the argument with the name mentioned after the "sizeof". Note
13.3568 - * that we cannot use findloc here because we need the arginfo struct,
13.3569 - * not the symbol.
13.3570 - */
13.3571 - ptr=arglist[idx].defvalue.size.symname;
13.3572 - assert(ptr!=NULL);
13.3573 - for (altidx=0; altidx<argcnt && strcmp(ptr,arglist[altidx].name)!=0; altidx++)
13.3574 - /* nothing */;
13.3575 - if (altidx>=argcnt) {
13.3576 - error(17,ptr); /* undefined symbol */
13.3577 - } else {
13.3578 - assert(arglist[idx].defvalue.size.symname!=NULL);
13.3579 - /* check the level against the number of dimensions */
13.3580 - if (arglist[idx].defvalue.size.level>0
13.3581 - && arglist[idx].defvalue.size.level>=arglist[altidx].numdim)
13.3582 - error(28,arglist[idx].name); /* invalid subscript */
13.3583 - /* check the type of the argument whose size to take; for a iVARIABLE
13.3584 - * or a iREFERENCE, this is always 1 (so the code is redundant)
13.3585 - */
13.3586 - assert(arglist[altidx].ident!=iVARARGS);
13.3587 - if (arglist[altidx].ident!=iREFARRAY && (arglist[idx].hasdefault & uSIZEOF)!=0) {
13.3588 - if ((arglist[idx].hasdefault & uTAGOF)!=0) {
13.3589 - error(81,arglist[idx].name); /* cannot take "tagof" an indexed array */
13.3590 - } else {
13.3591 - assert(arglist[altidx].ident==iVARIABLE || arglist[altidx].ident==iREFERENCE);
13.3592 - error(223,ptr); /* redundant sizeof */
13.3593 - } /* if */
13.3594 - } /* if */
13.3595 - } /* if */
13.3596 - } /* if */
13.3597 - } /* for */
13.3598 -
13.3599 - sym->usage|=uPROTOTYPED;
13.3600 - errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
13.3601 - return argcnt;
13.3602 -}
13.3603 -
13.3604 -/* doarg - declare one argument type
13.3605 - *
13.3606 - * this routine is called from "declargs()" and adds an entry in the local
13.3607 - * symbol table for one argument.
13.3608 - *
13.3609 - * "fpublic" indicates whether the function for this argument list is public.
13.3610 - * The arguments themselves are never public.
13.3611 - */
13.3612 -static void doarg(char *name,int ident,int offset,int tags[],int numtags,
13.3613 - int fpublic,int fconst,int chkshadow,arginfo *arg)
13.3614 -{
13.3615 - symbol *argsym;
13.3616 - constvalue *enumroot;
13.3617 - cell size;
13.3618 -
13.3619 - strcpy(arg->name,name);
13.3620 - arg->hasdefault=FALSE; /* preset (most common case) */
13.3621 - arg->defvalue.val=0; /* clear */
13.3622 - arg->defvalue_tag=0;
13.3623 - arg->numdim=0;
13.3624 - if (matchtoken('[')) {
13.3625 - if (ident==iREFERENCE)
13.3626 - error(67,name); /* illegal declaration ("&name[]" is unsupported) */
13.3627 - do {
13.3628 - if (arg->numdim == sDIMEN_MAX) {
13.3629 - error(53); /* exceeding maximum number of dimensions */
13.3630 - return;
13.3631 - } /* if */
13.3632 - size=needsub(&arg->idxtag[arg->numdim],&enumroot);/* may be zero here, it is a pointer anyway */
13.3633 - #if INT_MAX < LONG_MAX
13.3634 - if (size > INT_MAX)
13.3635 - error(105); /* overflow, exceeding capacity */
13.3636 - #endif
13.3637 - arg->dim[arg->numdim]=(int)size;
13.3638 - arg->numdim+=1;
13.3639 - } while (matchtoken('['));
13.3640 - ident=iREFARRAY; /* "reference to array" (is a pointer) */
13.3641 - if (matchtoken('=')) {
13.3642 - lexpush(); /* initials() needs the "=" token again */
13.3643 - assert(litidx==0); /* at the start of a function, this is reset */
13.3644 - assert(numtags>0);
13.3645 - initials(ident,tags[0],&size,arg->dim,arg->numdim,enumroot);
13.3646 - assert(size>=litidx);
13.3647 - /* allocate memory to hold the initial values */
13.3648 - arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell));
13.3649 - if (arg->defvalue.array.data!=NULL) {
13.3650 - int i;
13.3651 - memcpy(arg->defvalue.array.data,litq,litidx*sizeof(cell));
13.3652 - arg->hasdefault=TRUE; /* argument has default value */
13.3653 - arg->defvalue.array.size=litidx;
13.3654 - arg->defvalue.array.addr=-1;
13.3655 - /* calulate size to reserve on the heap */
13.3656 - arg->defvalue.array.arraysize=1;
13.3657 - for (i=0; i<arg->numdim; i++)
13.3658 - arg->defvalue.array.arraysize*=arg->dim[i];
13.3659 - if (arg->defvalue.array.arraysize < arg->defvalue.array.size)
13.3660 - arg->defvalue.array.arraysize = arg->defvalue.array.size;
13.3661 - } /* if */
13.3662 - litidx=0; /* reset */
13.3663 - } /* if */
13.3664 - } else {
13.3665 - if (matchtoken('=')) {
13.3666 - unsigned char size_tag_token;
13.3667 - assert(ident==iVARIABLE || ident==iREFERENCE);
13.3668 - arg->hasdefault=TRUE; /* argument has a default value */
13.3669 - size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0);
13.3670 - if (size_tag_token==0)
13.3671 - size_tag_token=(unsigned char)(matchtoken(tTAGOF) ? uTAGOF : 0);
13.3672 - if (size_tag_token!=0) {
13.3673 - int paranthese;
13.3674 - if (ident==iREFERENCE)
13.3675 - error(66,name); /* argument may not be a reference */
13.3676 - paranthese=0;
13.3677 - while (matchtoken('('))
13.3678 - paranthese++;
13.3679 - if (needtoken(tSYMBOL)) {
13.3680 - /* save the name of the argument whose size id to take */
13.3681 - char *name;
13.3682 - cell val;
13.3683 - tokeninfo(&val,&name);
13.3684 - if ((arg->defvalue.size.symname=duplicatestring(name)) == NULL)
13.3685 - error(103); /* insufficient memory */
13.3686 - arg->defvalue.size.level=0;
13.3687 - if (size_tag_token==uSIZEOF) {
13.3688 - while (matchtoken('[')) {
13.3689 - arg->defvalue.size.level+=(short)1;
13.3690 - needtoken(']');
13.3691 - } /* while */
13.3692 - } /* if */
13.3693 - if (ident==iVARIABLE) /* make sure we set this only if not a reference */
13.3694 - arg->hasdefault |= size_tag_token; /* uSIZEOF or uTAGOF */
13.3695 - } /* if */
13.3696 - while (paranthese--)
13.3697 - needtoken(')');
13.3698 - } else {
13.3699 - constexpr(&arg->defvalue.val,&arg->defvalue_tag,NULL);
13.3700 - assert(numtags>0);
13.3701 - if (!matchtag(tags[0],arg->defvalue_tag,TRUE))
13.3702 - error(213); /* tagname mismatch */
13.3703 - } /* if */
13.3704 - } /* if */
13.3705 - } /* if */
13.3706 - arg->ident=(char)ident;
13.3707 - arg->usage=(char)(fconst ? uCONST : 0);
13.3708 - arg->numtags=numtags;
13.3709 - arg->tags=(int*)malloc(numtags*sizeof tags[0]);
13.3710 - if (arg->tags==NULL)
13.3711 - error(103); /* insufficient memory */
13.3712 - memcpy(arg->tags,tags,numtags*sizeof tags[0]);
13.3713 - argsym=findloc(name);
13.3714 - if (argsym!=NULL) {
13.3715 - error(21,name); /* symbol already defined */
13.3716 - } else {
13.3717 - if (chkshadow && (argsym=findglb(name,sSTATEVAR))!=NULL && argsym->ident!=iFUNCTN)
13.3718 - error(219,name); /* variable shadows another symbol */
13.3719 - /* add details of type and address */
13.3720 - assert(numtags>0);
13.3721 - argsym=addvariable(name,offset,ident,sLOCAL,tags[0],
13.3722 - arg->dim,arg->numdim,arg->idxtag);
13.3723 - argsym->compound=0;
13.3724 - if (ident==iREFERENCE)
13.3725 - argsym->usage|=uREAD; /* because references are passed back */
13.3726 - if (fpublic)
13.3727 - argsym->usage|=uREAD; /* arguments of public functions are always "used" */
13.3728 - if (fconst)
13.3729 - argsym->usage|=uCONST;
13.3730 - } /* if */
13.3731 -}
13.3732 -
13.3733 -static int count_referrers(symbol *entry)
13.3734 -{
13.3735 - int i,count;
13.3736 -
13.3737 - count=0;
13.3738 - for (i=0; i<entry->numrefers; i++)
13.3739 - if (entry->refer[i]!=NULL)
13.3740 - count++;
13.3741 - return count;
13.3742 -}
13.3743 -
13.3744 -#if !defined SC_LIGHT
13.3745 -static int find_xmltag(char *source,char *xmltag,char *xmlparam,char *xmlvalue,
13.3746 - char **outer_start,int *outer_length,
13.3747 - char **inner_start,int *inner_length)
13.3748 -{
13.3749 - char *ptr,*inner_end;
13.3750 - int xmltag_len,xmlparam_len,xmlvalue_len;
13.3751 - int match;
13.3752 -
13.3753 - assert(source!=NULL);
13.3754 - assert(xmltag!=NULL);
13.3755 - assert(outer_start!=NULL);
13.3756 - assert(outer_length!=NULL);
13.3757 - assert(inner_start!=NULL);
13.3758 - assert(inner_length!=NULL);
13.3759 -
13.3760 - /* both NULL or both non-NULL */
13.3761 - assert(xmlvalue!=NULL && xmlparam!=NULL || xmlvalue==NULL && xmlparam==NULL);
13.3762 -
13.3763 - xmltag_len=strlen(xmltag);
13.3764 - xmlparam_len= (xmlparam!=NULL) ? strlen(xmlparam) : 0;
13.3765 - xmlvalue_len= (xmlvalue!=NULL) ? strlen(xmlvalue) : 0;
13.3766 - ptr=source;
13.3767 - /* find an opening '<' */
13.3768 - while ((ptr=strchr(ptr,'<'))!=NULL) {
13.3769 - *outer_start=ptr; /* be optimistic... */
13.3770 - match=FALSE; /* ...and pessimistic at the same time */
13.3771 - ptr++; /* skip '<' */
13.3772 - while (*ptr!='\0' && *ptr<=' ')
13.3773 - ptr++; /* skip white space */
13.3774 - if (strncmp(ptr,xmltag,xmltag_len)==0 && (*(ptr+xmltag_len)<=' ' || *(ptr+xmltag_len)=='>')) {
13.3775 - /* xml tag found, optionally check the parameter */
13.3776 - ptr+=xmltag_len;
13.3777 - while (*ptr!='\0' && *ptr<=' ')
13.3778 - ptr++; /* skip white space */
13.3779 - if (xmlparam!=NULL) {
13.3780 - if (strncmp(ptr,xmlparam,xmlparam_len)==0 && (*(ptr+xmlparam_len)<=' ' || *(ptr+xmlparam_len)=='=')) {
13.3781 - ptr+=xmlparam_len;
13.3782 - while (*ptr!='\0' && *ptr<=' ')
13.3783 - ptr++; /* skip white space */
13.3784 - if (*ptr=='=') {
13.3785 - ptr++; /* skip '=' */
13.3786 - while (*ptr!='\0' && *ptr<=' ')
13.3787 - ptr++; /* skip white space */
13.3788 - if (*ptr=='"' || *ptr=='\'')
13.3789 - ptr++; /* skip " or ' */
13.3790 - assert(xmlvalue!=NULL);
13.3791 - if (strncmp(ptr,xmlvalue,xmlvalue_len)==0
13.3792 - && (*(ptr+xmlvalue_len)<=' '
13.3793 - || *(ptr+xmlvalue_len)=='>'
13.3794 - || *(ptr+xmlvalue_len)=='"'
13.3795 - || *(ptr+xmlvalue_len)=='\''))
13.3796 - match=TRUE; /* found it */
13.3797 - } /* if */
13.3798 - } /* if */
13.3799 - } else {
13.3800 - match=TRUE; /* don't check the parameter */
13.3801 - } /* if */
13.3802 - } /* if */
13.3803 - if (match) {
13.3804 - /* now find the end of the opening tag */
13.3805 - while (*ptr!='\0' && *ptr!='>')
13.3806 - ptr++;
13.3807 - if (*ptr=='>')
13.3808 - ptr++;
13.3809 - while (*ptr!='\0' && *ptr<=' ')
13.3810 - ptr++; /* skip white space */
13.3811 - *inner_start=ptr;
13.3812 - /* find the start of the closing tag (assume no nesting) */
13.3813 - while ((ptr=strchr(ptr,'<'))!=NULL) {
13.3814 - inner_end=ptr;
13.3815 - ptr++; /* skip '<' */
13.3816 - while (*ptr!='\0' && *ptr<=' ')
13.3817 - ptr++; /* skip white space */
13.3818 - if (*ptr=='/') {
13.3819 - ptr++; /* skip / */
13.3820 - while (*ptr!='\0' && *ptr<=' ')
13.3821 - ptr++; /* skip white space */
13.3822 - if (strncmp(ptr,xmltag,xmltag_len)==0 && (*(ptr+xmltag_len)<=' ' || *(ptr+xmltag_len)=='>')) {
13.3823 - /* find the end of the closing tag */
13.3824 - while (*ptr!='\0' && *ptr!='>')
13.3825 - ptr++;
13.3826 - if (*ptr=='>')
13.3827 - ptr++;
13.3828 - /* set the lengths of the inner and outer segment */
13.3829 - assert(*inner_start!=NULL);
13.3830 - *inner_length=(int)(inner_end-*inner_start);
13.3831 - assert(*outer_start!=NULL);
13.3832 - *outer_length=(int)(ptr-*outer_start);
13.3833 - break; /* break out of the loop */
13.3834 - } /* if */
13.3835 - } /* if */
13.3836 - } /* while */
13.3837 - return TRUE;
13.3838 - } /* if */
13.3839 - } /* while */
13.3840 - return FALSE; /* not found */
13.3841 -}
13.3842 -
13.3843 -static char *xmlencode(char *dest,char *source)
13.3844 -{
13.3845 - char temp[2*sNAMEMAX+20],*ptr;
13.3846 -
13.3847 - /* replace < by < and such; normally, such a symbol occurs at most once in
13.3848 - * a symbol name (e.g. "operator<")
13.3849 - */
13.3850 - ptr=temp;
13.3851 - while (*source!='\0') {
13.3852 - switch (*source) {
13.3853 - case '<':
13.3854 - strcpy(ptr,"<");
13.3855 - ptr+=4;
13.3856 - break;
13.3857 - case '>':
13.3858 - strcpy(ptr,">");
13.3859 - ptr+=4;
13.3860 - break;
13.3861 - case '&':
13.3862 - strcpy(ptr,"&");
13.3863 - ptr+=5;
13.3864 - break;
13.3865 - default:
13.3866 - *ptr++=*source;
13.3867 - } /* switch */
13.3868 - source++;
13.3869 - } /* while */
13.3870 - *ptr='\0';
13.3871 - strcpy(dest,temp);
13.3872 - return dest;
13.3873 -}
13.3874 -
13.3875 -static void make_report(symbol *root,FILE *log,char *sourcefile)
13.3876 -{
13.3877 - char symname[_MAX_PATH];
13.3878 - int i,arg;
13.3879 - symbol *sym,*ref;
13.3880 - constvalue *tagsym;
13.3881 - constvalue *enumroot;
13.3882 - char *ptr;
13.3883 -
13.3884 - /* adapt the installation directory */
13.3885 - strcpy(symname,sc_rootpath);
13.3886 - #if DIRSEP_CHAR=='\\'
13.3887 - while ((ptr=strchr(symname,':'))!=NULL)
13.3888 - *ptr='|';
13.3889 - while ((ptr=strchr(symname,DIRSEP_CHAR))!=NULL)
13.3890 - *ptr='/';
13.3891 - #endif
13.3892 -
13.3893 - /* the XML header */
13.3894 - fprintf(log,"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
13.3895 - fprintf(log,"<?xml-stylesheet href=\"file:///%s/xml/pawndoc.xsl\" type=\"text/xsl\"?>\n",symname);
13.3896 - fprintf(log,"<doc source=\"%s\">\n",sourcefile);
13.3897 - ptr=strrchr(sourcefile,DIRSEP_CHAR);
13.3898 - if (ptr!=NULL)
13.3899 - ptr++;
13.3900 - else
13.3901 - ptr=sourcefile;
13.3902 - fprintf(log,"\t<assembly>\n\t\t<name>%s</name>\n\t</assembly>\n",ptr);
13.3903 -
13.3904 - /* attach the global documentation, if any */
13.3905 - if (sc_documentation!=NULL) {
13.3906 - fprintf(log,"\n\t<!-- general -->\n");
13.3907 - fprintf(log,"\t<general>\n\t\t");
13.3908 - fputs(sc_documentation,log);
13.3909 - fprintf(log,"\n\t</general>\n\n");
13.3910 - } /* if */
13.3911 -
13.3912 - /* use multiple passes to print constants variables and functions in
13.3913 - * separate sections
13.3914 - */
13.3915 - fprintf(log,"\t<members>\n");
13.3916 -
13.3917 - fprintf(log,"\n\t\t<!-- enumerations -->\n");
13.3918 - for (sym=root->next; sym!=NULL; sym=sym->next) {
13.3919 - if (sym->parent!=NULL)
13.3920 - continue; /* hierarchical data type */
13.3921 - assert(sym->ident==iCONSTEXPR || sym->ident==iVARIABLE
13.3922 - || sym->ident==iARRAY || sym->ident==iFUNCTN);
13.3923 - if (sym->ident!=iCONSTEXPR || (sym->usage & uENUMROOT)==0)
13.3924 - continue;
13.3925 - if ((sym->usage & uREAD)==0)
13.3926 - continue;
13.3927 - fprintf(log,"\t\t<member name=\"T:%s\" value=\"%ld\">\n",funcdisplayname(symname,sym->name),sym->addr);
13.3928 - if (sym->tag!=0) {
13.3929 - tagsym=find_tag_byval(sym->tag);
13.3930 - assert(tagsym!=NULL);
13.3931 - fprintf(log,"\t\t\t<tagname value=\"%s\"/>\n",tagsym->name);
13.3932 - } /* if */
13.3933 - /* browse through all fields */
13.3934 - if ((enumroot=sym->dim.enumlist)!=NULL) {
13.3935 - enumroot=enumroot->next; /* skip root */
13.3936 - while (enumroot!=NULL) {
13.3937 - fprintf(log,"\t\t\t<member name=\"C:%s\" value=\"%ld\">\n",funcdisplayname(symname,enumroot->name),enumroot->value);
13.3938 - /* find the constant with this name and get the tag */
13.3939 - ref=findglb(enumroot->name,sGLOBAL);
13.3940 - if (ref!=NULL) {
13.3941 - if (ref->x.tags.index!=0) {
13.3942 - tagsym=find_tag_byval(ref->x.tags.index);
13.3943 - assert(tagsym!=NULL);
13.3944 - fprintf(log,"\t\t\t\t<tagname value=\"%s\"/>\n",tagsym->name);
13.3945 - } /* if */
13.3946 - if (ref->dim.array.length!=1)
13.3947 - fprintf(log,"\t\t\t\t<size value=\"%ld\"/>\n",(long)ref->dim.array.length);
13.3948 - } /* if */
13.3949 - fprintf(log,"\t\t\t</member>\n");
13.3950 - enumroot=enumroot->next;
13.3951 - } /* while */
13.3952 - } /* if */
13.3953 - assert(sym->refer!=NULL);
13.3954 - for (i=0; i<sym->numrefers; i++) {
13.3955 - if ((ref=sym->refer[i])!=NULL)
13.3956 - fprintf(log,"\t\t\t<referrer name=\"%s\"/>\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
13.3957 - } /* for */
13.3958 - if (sym->documentation!=NULL)
13.3959 - fprintf(log,"\t\t\t%s\n",sym->documentation);
13.3960 - fprintf(log,"\t\t</member>\n");
13.3961 - } /* for */
13.3962 -
13.3963 - fprintf(log,"\n\t\t<!-- constants -->\n");
13.3964 - for (sym=root->next; sym!=NULL; sym=sym->next) {
13.3965 - if (sym->parent!=NULL)
13.3966 - continue; /* hierarchical data type */
13.3967 - assert(sym->ident==iCONSTEXPR || sym->ident==iVARIABLE
13.3968 - || sym->ident==iARRAY || sym->ident==iFUNCTN);
13.3969 - if (sym->ident!=iCONSTEXPR)
13.3970 - continue;
13.3971 - if ((sym->usage & uREAD)==0 || (sym->usage & (uENUMFIELD | uENUMROOT))!=0)
13.3972 - continue;
13.3973 - fprintf(log,"\t\t<member name=\"C:%s\" value=\"%ld\">\n",funcdisplayname(symname,sym->name),sym->addr);
13.3974 - if (sym->tag!=0) {
13.3975 - tagsym=find_tag_byval(sym->tag);
13.3976 - assert(tagsym!=NULL);
13.3977 - fprintf(log,"\t\t\t<tagname value=\"%s\"/>\n",tagsym->name);
13.3978 - } /* if */
13.3979 - assert(sym->refer!=NULL);
13.3980 - for (i=0; i<sym->numrefers; i++) {
13.3981 - if ((ref=sym->refer[i])!=NULL)
13.3982 - fprintf(log,"\t\t\t<referrer name=\"%s\"/>\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
13.3983 - } /* for */
13.3984 - if (sym->documentation!=NULL)
13.3985 - fprintf(log,"\t\t\t%s\n",sym->documentation);
13.3986 - fprintf(log,"\t\t</member>\n");
13.3987 - } /* for */
13.3988 -
13.3989 - fprintf(log,"\n\t\t<!-- variables -->\n");
13.3990 - for (sym=root->next; sym!=NULL; sym=sym->next) {
13.3991 - if (sym->parent!=NULL)
13.3992 - continue; /* hierarchical data type */
13.3993 - if (sym->ident!=iVARIABLE && sym->ident!=iARRAY)
13.3994 - continue;
13.3995 - fprintf(log,"\t\t<member name=\"F:%s\">\n",funcdisplayname(symname,sym->name));
13.3996 - if (sym->tag!=0) {
13.3997 - tagsym=find_tag_byval(sym->tag);
13.3998 - assert(tagsym!=NULL);
13.3999 - fprintf(log,"\t\t\t<tagname value=\"%s\"/>\n",tagsym->name);
13.4000 - } /* if */
13.4001 - assert(sym->refer!=NULL);
13.4002 - if ((sym->usage & uPUBLIC)!=0)
13.4003 - fprintf(log,"\t\t\t<attribute name=\"public\"/>\n");
13.4004 - for (i=0; i<sym->numrefers; i++) {
13.4005 - if ((ref=sym->refer[i])!=NULL)
13.4006 - fprintf(log,"\t\t\t<referrer name=\"%s\"/>\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
13.4007 - } /* for */
13.4008 - if (sym->documentation!=NULL)
13.4009 - fprintf(log,"\t\t\t%s\n",sym->documentation);
13.4010 - fprintf(log,"\t\t</member>\n");
13.4011 - } /* for */
13.4012 -
13.4013 - fprintf(log,"\n\t\t<!-- functions -->\n");
13.4014 - for (sym=root->next; sym!=NULL; sym=sym->next) {
13.4015 - if (sym->parent!=NULL)
13.4016 - continue; /* hierarchical data type */
13.4017 - if (sym->ident!=iFUNCTN)
13.4018 - continue;
13.4019 - if ((sym->usage & (uREAD | uNATIVE))==uNATIVE)
13.4020 - continue; /* unused native function */
13.4021 - funcdisplayname(symname,sym->name);
13.4022 - xmlencode(symname,symname);
13.4023 - fprintf(log,"\t\t<member name=\"M:%s\" syntax=\"%s(",symname,symname);
13.4024 - /* print only the names of the parameters between the parentheses */
13.4025 - assert(sym->dim.arglist!=NULL);
13.4026 - for (arg=0; sym->dim.arglist[arg].ident!=0; arg++) {
13.4027 - int dim;
13.4028 - if (arg>0)
13.4029 - fprintf(log,", ");
13.4030 - switch (sym->dim.arglist[arg].ident) {
13.4031 - case iVARIABLE:
13.4032 - fprintf(log,"%s",sym->dim.arglist[arg].name);
13.4033 - break;
13.4034 - case iREFERENCE:
13.4035 - fprintf(log,"&%s",sym->dim.arglist[arg].name);
13.4036 - break;
13.4037 - case iREFARRAY:
13.4038 - fprintf(log,"%s",sym->dim.arglist[arg].name);
13.4039 - for (dim=0; dim<sym->dim.arglist[arg].numdim;dim++)
13.4040 - fprintf(log,"[]");
13.4041 - break;
13.4042 - case iVARARGS:
13.4043 - fprintf(log,"...");
13.4044 - break;
13.4045 - } /* switch */
13.4046 - } /* for */
13.4047 - /* ??? should also print an "array return" size */
13.4048 - fprintf(log,")\">\n");
13.4049 - if (sym->tag!=0) {
13.4050 - tagsym=find_tag_byval(sym->tag);
13.4051 - assert(tagsym!=NULL);
13.4052 - fprintf(log,"\t\t\t<tagname value=\"%s\"/>\n",tagsym->name);
13.4053 - } /* if */
13.4054 - /* check whether this function is called from the outside */
13.4055 - if ((sym->usage & uNATIVE)!=0)
13.4056 - fprintf(log,"\t\t\t<attribute name=\"native\"/>\n");
13.4057 - if ((sym->usage & uPUBLIC)!=0)
13.4058 - fprintf(log,"\t\t\t<attribute name=\"public\"/>\n");
13.4059 - if (strcmp(sym->name,uMAINFUNC)==0 || strcmp(sym->name,uENTRYFUNC)==0)
13.4060 - fprintf(log,"\t\t\t<attribute name=\"entry\"/>\n");
13.4061 - if ((sym->usage & uNATIVE)==0)
13.4062 - fprintf(log,"\t\t\t<stacksize value=\"%ld\"/>\n",(long)sym->x.stacksize);
13.4063 - if (sym->states!=NULL) {
13.4064 - constvalue *stlist=sym->states->next;
13.4065 - assert(stlist!=NULL); /* there should be at least one state item */
13.4066 - while (stlist!=NULL && stlist->index==-1)
13.4067 - stlist=stlist->next;
13.4068 - assert(stlist!=NULL); /* state id should be found */
13.4069 - i=state_getfsa(stlist->index);
13.4070 - assert(i>=0); /* automaton 0 exists */
13.4071 - stlist=automaton_findid(i);
13.4072 - assert(stlist!=NULL); /* automaton should be found */
13.4073 - fprintf(log,"\t\t\t<automaton name=\"%s\"/>\n", strlen(stlist->name)>0 ? stlist->name : "(anonymous)");
13.4074 - //??? dump state decision table
13.4075 - } /* if */
13.4076 - assert(sym->refer!=NULL);
13.4077 - for (i=0; i<sym->numrefers; i++)
13.4078 - if ((ref=sym->refer[i])!=NULL)
13.4079 - fprintf(log,"\t\t\t<referrer name=\"%s\"/>\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
13.4080 - /* print all symbols that are required for this function to compile */
13.4081 - for (ref=root->next; ref!=NULL; ref=ref->next) {
13.4082 - if (ref==sym)
13.4083 - continue;
13.4084 - for (i=0; i<ref->numrefers; i++)
13.4085 - if (ref->refer[i]==sym)
13.4086 - fprintf(log,"\t\t\t<dependency name=\"%s\"/>\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
13.4087 - } /* for */
13.4088 - /* print parameter list, with tag & const information, plus descriptions */
13.4089 - assert(sym->dim.arglist!=NULL);
13.4090 - for (arg=0; sym->dim.arglist[arg].ident!=0; arg++) {
13.4091 - int dim,paraminfo;
13.4092 - char *outer_start,*inner_start;
13.4093 - int outer_length,inner_length;
13.4094 - if (sym->dim.arglist[arg].ident==iVARARGS)
13.4095 - fprintf(log,"\t\t\t<param name=\"...\">\n");
13.4096 - else
13.4097 - fprintf(log,"\t\t\t<param name=\"%s\">\n",sym->dim.arglist[arg].name);
13.4098 - /* print the tag name(s) for each parameter */
13.4099 - assert(sym->dim.arglist[arg].numtags>0);
13.4100 - assert(sym->dim.arglist[arg].tags!=NULL);
13.4101 - paraminfo=(sym->dim.arglist[arg].numtags>1 || sym->dim.arglist[arg].tags[0]!=0)
13.4102 - || sym->dim.arglist[arg].ident==iREFERENCE
13.4103 - || sym->dim.arglist[arg].ident==iREFARRAY;
13.4104 - if (paraminfo)
13.4105 - fprintf(log,"\t\t\t\t<paraminfo>");
13.4106 - if (sym->dim.arglist[arg].numtags>1 || sym->dim.arglist[arg].tags[0]!=0) {
13.4107 - assert(paraminfo);
13.4108 - if (sym->dim.arglist[arg].numtags>1)
13.4109 - fprintf(log," {");
13.4110 - for (i=0; i<sym->dim.arglist[arg].numtags; i++) {
13.4111 - if (i>0)
13.4112 - fprintf(log,",");
13.4113 - tagsym=find_tag_byval(sym->dim.arglist[arg].tags[i]);
13.4114 - assert(tagsym!=NULL);
13.4115 - fprintf(log,"%s",tagsym->name);
13.4116 - } /* for */
13.4117 - if (sym->dim.arglist[arg].numtags>1)
13.4118 - fprintf(log,"}");
13.4119 - } /* if */
13.4120 - switch (sym->dim.arglist[arg].ident) {
13.4121 - case iREFERENCE:
13.4122 - fprintf(log," &");
13.4123 - break;
13.4124 - case iREFARRAY:
13.4125 - fprintf(log," ");
13.4126 - for (dim=0; dim<sym->dim.arglist[arg].numdim; dim++) {
13.4127 - if (sym->dim.arglist[arg].dim[dim]==0) {
13.4128 - fprintf(log,"[]");
13.4129 - } else {
13.4130 - //??? find index tag
13.4131 - fprintf(log,"[%d]",sym->dim.arglist[arg].dim[dim]);
13.4132 - } /* if */
13.4133 - } /* for */
13.4134 - break;
13.4135 - } /* switch */
13.4136 - if (paraminfo)
13.4137 - fprintf(log," </paraminfo>\n");
13.4138 - /* print the user description of the parameter (parse through
13.4139 - * sym->documentation)
13.4140 - */
13.4141 - if (sym->documentation!=NULL
13.4142 - && find_xmltag(sym->documentation, "param", "name", sym->dim.arglist[arg].name,
13.4143 - &outer_start, &outer_length, &inner_start, &inner_length))
13.4144 - {
13.4145 - char *tail;
13.4146 - fprintf(log,"\t\t\t\t%.*s\n",inner_length,inner_start);
13.4147 - /* delete from documentation string */
13.4148 - tail=outer_start+outer_length;
13.4149 - memmove(outer_start,tail,strlen(tail)+1);
13.4150 - } /* if */
13.4151 - fprintf(log,"\t\t\t</param>\n");
13.4152 - } /* for */
13.4153 - if (sym->documentation!=NULL)
13.4154 - fprintf(log,"\t\t\t%s\n",sym->documentation);
13.4155 - fprintf(log,"\t\t</member>\n");
13.4156 - } /* for */
13.4157 -
13.4158 - fprintf(log,"\n\t</members>\n");
13.4159 - fprintf(log,"</doc>\n");
13.4160 -}
13.4161 -#endif
13.4162 -
13.4163 -/* Every symbol has a referrer list, that contains the functions that use
13.4164 - * the symbol. Now, if function "apple" is accessed by functions "banana" and
13.4165 - * "citron", but neither function "banana" nor "citron" are used by anyone
13.4166 - * else, then, by inference, function "apple" is not used either.
13.4167 - */
13.4168 -static void reduce_referrers(symbol *root)
13.4169 -{
13.4170 - int i,restart;
13.4171 - symbol *sym,*ref;
13.4172 -
13.4173 - do {
13.4174 - restart=0;
13.4175 - for (sym=root->next; sym!=NULL; sym=sym->next) {
13.4176 - if (sym->parent!=NULL)
13.4177 - continue; /* hierarchical data type */
13.4178 - if (sym->ident==iFUNCTN
13.4179 - && (sym->usage & uNATIVE)==0
13.4180 - && (sym->usage & uPUBLIC)==0 && strcmp(sym->name,uMAINFUNC)!=0 && strcmp(sym->name,uENTRYFUNC)!=0
13.4181 - && count_referrers(sym)==0)
13.4182 - {
13.4183 - sym->usage&=~(uREAD | uWRITTEN); /* erase usage bits if there is no referrer */
13.4184 - /* find all symbols that are referred by this symbol */
13.4185 - for (ref=root->next; ref!=NULL; ref=ref->next) {
13.4186 - if (ref->parent!=NULL)
13.4187 - continue; /* hierarchical data type */
13.4188 - assert(ref->refer!=NULL);
13.4189 - for (i=0; i<ref->numrefers && ref->refer[i]!=sym; i++)
13.4190 - /* nothing */;
13.4191 - if (i<ref->numrefers) {
13.4192 - assert(ref->refer[i]==sym);
13.4193 - ref->refer[i]=NULL;
13.4194 - restart++;
13.4195 - } /* if */
13.4196 - } /* for */
13.4197 - } else if ((sym->ident==iVARIABLE || sym->ident==iARRAY)
13.4198 - && (sym->usage & uPUBLIC)==0
13.4199 - && sym->parent==NULL
13.4200 - && count_referrers(sym)==0)
13.4201 - {
13.4202 - sym->usage&=~(uREAD | uWRITTEN); /* erase usage bits if there is no referrer */
13.4203 - } /* if */
13.4204 - } /* for */
13.4205 - /* after removing a symbol, check whether more can be removed */
13.4206 - } while (restart>0);
13.4207 -}
13.4208 -
13.4209 -#if !defined SC_LIGHT
13.4210 -static long max_stacksize_recurse(symbol *sourcesym,symbol *sym,long basesize,int *pubfuncparams,int *recursion)
13.4211 -{
13.4212 - long size,maxsize;
13.4213 - int i;
13.4214 -
13.4215 - assert(sym!=NULL);
13.4216 - assert(sym->ident==iFUNCTN);
13.4217 - assert((sym->usage & uNATIVE)==0);
13.4218 - assert(recursion!=NULL);
13.4219 -
13.4220 - maxsize=sym->x.stacksize;
13.4221 - for (i=0; i<sym->numrefers; i++) {
13.4222 - if (sym->refer[i]!=NULL) {
13.4223 - assert(sym->refer[i]->ident==iFUNCTN);
13.4224 - assert((sym->refer[i]->usage & uNATIVE)==0); /* a native function cannot refer to a user-function */
13.4225 - if (sym->refer[i]==sourcesym) { /* recursion detection */
13.4226 - *recursion=1;
13.4227 - break; /* recursion was detected, quit loop */
13.4228 - } /* if */
13.4229 - size=max_stacksize_recurse(sourcesym,sym->refer[i],sym->x.stacksize,pubfuncparams,recursion);
13.4230 - if (maxsize<size)
13.4231 - maxsize=size;
13.4232 - } /* if */
13.4233 - } /* for */
13.4234 -
13.4235 - if ((sym->usage & uPUBLIC)!=0) {
13.4236 - /* Find out how many parameters a public function has, then see if this
13.4237 - * is bigger than some maximum
13.4238 - */
13.4239 - arginfo *arg=sym->dim.arglist;
13.4240 - int count=0;
13.4241 - assert(arg!=0);
13.4242 - while (arg->ident!=0) {
13.4243 - count++;
13.4244 - arg++;
13.4245 - } /* while */
13.4246 - assert(pubfuncparams!=0);
13.4247 - if (count>*pubfuncparams)
13.4248 - *pubfuncparams=count;
13.4249 - } /* if */
13.4250 -
13.4251 - return maxsize+basesize;
13.4252 -}
13.4253 -
13.4254 -static long max_stacksize(symbol *root,int *recursion)
13.4255 -{
13.4256 - /* Loop over all non-native functions. For each function, loop
13.4257 - * over all of its referrers, accumulating the stack requirements.
13.4258 - * Detect (indirect) recursion with a "mark-and-sweep" algorithm.
13.4259 - * I (mis-)use the "compound" field of the symbol structure for
13.4260 - * the marker, as this field is unused for functions.
13.4261 - *
13.4262 - * Note that the stack is shared with the heap. A host application
13.4263 - * may "eat" cells from the heap as well, through amx_Allot(). The
13.4264 - * stack requirements are thus only an estimate.
13.4265 - */
13.4266 - long size,maxsize;
13.4267 - int maxparams;
13.4268 - symbol *sym;
13.4269 -
13.4270 - assert(root!=NULL);
13.4271 - assert(recursion!=NULL);
13.4272 - #if !defined NDEBUG
13.4273 - for (sym=root->next; sym!=NULL; sym=sym->next)
13.4274 - if (sym->ident==iFUNCTN)
13.4275 - assert(sym->compound==0);
13.4276 - #endif
13.4277 -
13.4278 - maxsize=0;
13.4279 - maxparams=0;
13.4280 - *recursion=0; /* assume no recursion */
13.4281 - for (sym=root->next; sym!=NULL; sym=sym->next) {
13.4282 - /* drop out if this is not a user-implemented function */
13.4283 - if (sym->ident!=iFUNCTN || (sym->usage & uNATIVE)!=0)
13.4284 - continue;
13.4285 - /* accumulate stack size for this symbol */
13.4286 - size=max_stacksize_recurse(sym,sym,0L,&maxparams,recursion);
13.4287 - assert(size>=0);
13.4288 - if (maxsize<size)
13.4289 - maxsize=size;
13.4290 - } /* for */
13.4291 -
13.4292 - maxsize++; /* +1 because a zero cell is always pushed on top
13.4293 - * of the stack to catch stack overwrites */
13.4294 - return maxsize+(maxparams+1);/* +1 because # of parameters is always pushed on entry */
13.4295 -}
13.4296 -#endif
13.4297 -
13.4298 -/* testsymbols - test for unused local or global variables
13.4299 - *
13.4300 - * "Public" functions are excluded from the check, since these
13.4301 - * may be exported to other object modules.
13.4302 - * Labels are excluded from the check if the argument 'testlabs'
13.4303 - * is 0. Thus, labels are not tested until the end of the function.
13.4304 - * Constants may also be excluded (convenient for global constants).
13.4305 - *
13.4306 - * When the nesting level drops below "level", the check stops.
13.4307 - *
13.4308 - * The function returns whether there is an "entry" point for the file.
13.4309 - * This flag will only be 1 when browsing the global symbol table.
13.4310 - */
13.4311 -static int testsymbols(symbol *root,int level,int testlabs,int testconst)
13.4312 -{
13.4313 - char symname[2*sNAMEMAX+16];
13.4314 - int entry=FALSE;
13.4315 -
13.4316 - symbol *sym=root->next;
13.4317 - while (sym!=NULL && sym->compound>=level) {
13.4318 - switch (sym->ident) {
13.4319 - case iLABEL:
13.4320 - if (testlabs) {
13.4321 - if ((sym->usage & uDEFINE)==0) {
13.4322 - error(19,sym->name); /* not a label: ... */
13.4323 - } else if ((sym->usage & uREAD)==0) {
13.4324 - errorset(sSETPOS,sym->lnumber);
13.4325 - error(203,sym->name); /* symbol isn't used: ... */
13.4326 - } /* if */
13.4327 - } /* if */
13.4328 - break;
13.4329 - case iFUNCTN:
13.4330 - if ((sym->usage & (uDEFINE | uREAD | uNATIVE | uSTOCK | uPUBLIC))==uDEFINE) {
13.4331 - funcdisplayname(symname,sym->name);
13.4332 - if (strlen(symname)>0)
13.4333 - error(203,symname); /* symbol isn't used ... (and not public/native/stock) */
13.4334 - } /* if */
13.4335 - if ((sym->usage & uPUBLIC)!=0 || strcmp(sym->name,uMAINFUNC)==0)
13.4336 - entry=TRUE; /* there is an entry point */
13.4337 - /* also mark the function to the debug information */
13.4338 - if (((sym->usage & uREAD)!=0 || (sym->usage & uPUBLIC)!=0) && (sym->usage & uNATIVE)==0)
13.4339 - insert_dbgsymbol(sym);
13.4340 - break;
13.4341 - case iCONSTEXPR:
13.4342 - if (testconst && (sym->usage & uREAD)==0) {
13.4343 - errorset(sSETPOS,sym->lnumber);
13.4344 - error(203,sym->name); /* symbol isn't used: ... */
13.4345 - } /* if */
13.4346 - break;
13.4347 - default:
13.4348 - /* a variable */
13.4349 - if (sym->parent!=NULL)
13.4350 - break; /* hierarchical data type */
13.4351 - if ((sym->usage & (uWRITTEN | uREAD | uSTOCK))==0) {
13.4352 - if (testconst)
13.4353 - errorset(sSETPOS,sym->lnumber);
13.4354 - error(203,sym->name,sym->lnumber); /* symbol isn't used (and not stock) */
13.4355 - } else if ((sym->usage & (uREAD | uSTOCK | uPUBLIC))==0) {
13.4356 - errorset(sSETPOS,sym->lnumber);
13.4357 - error(204,sym->name); /* value assigned to symbol is never used */
13.4358 -#if 0 // ??? not sure whether it is a good idea to force people use "const"
13.4359 - } else if ((sym->usage & (uWRITTEN | uPUBLIC | uCONST))==0 && sym->ident==iREFARRAY) {
13.4360 - errorset(sSETPOS,sym->lnumber);
13.4361 - error(214,sym->name); /* make array argument "const" */
13.4362 -#endif
13.4363 - } /* if */
13.4364 - /* also mark the variable (local or global) to the debug information */
13.4365 - if ((sym->usage & (uWRITTEN | uREAD))!=0 && (sym->usage & uNATIVE)==0)
13.4366 - insert_dbgsymbol(sym);
13.4367 - } /* if */
13.4368 - sym=sym->next;
13.4369 - } /* while */
13.4370 -
13.4371 - return entry;
13.4372 -}
13.4373 -
13.4374 -static cell calc_array_datasize(symbol *sym, cell *offset)
13.4375 -{
13.4376 - cell length;
13.4377 -
13.4378 - assert(sym!=NULL);
13.4379 - assert(sym->ident==iARRAY || sym->ident==iREFARRAY);
13.4380 - length=sym->dim.array.length;
13.4381 - if (sym->dim.array.level > 0) {
13.4382 - cell sublength=calc_array_datasize(finddepend(sym),offset);
13.4383 - if (offset!=NULL)
13.4384 - *offset=length*(*offset+sizeof(cell));
13.4385 - if (sublength>0)
13.4386 - length*=length*sublength;
13.4387 - else
13.4388 - length=0;
13.4389 - } else {
13.4390 - if (offset!=NULL)
13.4391 - *offset=0;
13.4392 - } /* if */
13.4393 - return length;
13.4394 -}
13.4395 -
13.4396 -static void destructsymbols(symbol *root,int level)
13.4397 -{
13.4398 - cell offset=0;
13.4399 - int savepri=FALSE;
13.4400 - symbol *sym=root->next;
13.4401 - while (sym!=NULL && sym->compound>=level) {
13.4402 - if (sym->ident==iVARIABLE || sym->ident==iARRAY) {
13.4403 - char symbolname[16];
13.4404 - symbol *opsym;
13.4405 - cell elements;
13.4406 - /* check that the '~' operator is defined for this tag */
13.4407 - operator_symname(symbolname,"~",sym->tag,0,1,0);
13.4408 - if ((opsym=findglb(symbolname,sGLOBAL))!=NULL) {
13.4409 - /* save PRI, in case of a return statment */
13.4410 - if (!savepri) {
13.4411 - pushreg(sPRI); /* right-hand operand is in PRI */
13.4412 - savepri=TRUE;
13.4413 - } /* if */
13.4414 - /* if the variable is an array, get the number of elements */
13.4415 - if (sym->ident==iARRAY) {
13.4416 - elements=calc_array_datasize(sym,&offset);
13.4417 - /* "elements" can be zero when the variable is declared like
13.4418 - * new mytag: myvar[2][] = { {1, 2}, {3, 4} }
13.4419 - * one should declare all dimensions!
13.4420 - */
13.4421 - if (elements==0)
13.4422 - error(46,sym->name); /* array size is unknown */
13.4423 - } else {
13.4424 - elements=1;
13.4425 - offset=0;
13.4426 - } /* if */
13.4427 - pushval(elements);
13.4428 - /* call the '~' operator */
13.4429 - address(sym,sPRI);
13.4430 - addconst(offset); /* add offset to array data to the address */
13.4431 - pushreg(sPRI);
13.4432 - pushval(2*sizeof(cell));/* 2 parameters */
13.4433 - assert(opsym->ident==iFUNCTN);
13.4434 - ffcall(opsym,NULL,1);
13.4435 - if (sc_status!=statSKIP)
13.4436 - markusage(opsym,uREAD); /* do not mark as "used" when this call itself is skipped */
13.4437 - if ((opsym->usage & uNATIVE)!=0 && opsym->x.lib!=NULL)
13.4438 - opsym->x.lib->value += 1; /* increment "usage count" of the library */
13.4439 - } /* if */
13.4440 - } /* if */
13.4441 - sym=sym->next;
13.4442 - } /* while */
13.4443 - /* restore PRI, if it was saved */
13.4444 - if (savepri)
13.4445 - popreg(sPRI);
13.4446 -}
13.4447 -
13.4448 -static constvalue *insert_constval(constvalue *prev,constvalue *next,const char *name,cell val,
13.4449 - int index)
13.4450 -{
13.4451 - constvalue *cur;
13.4452 -
13.4453 - if ((cur=(constvalue*)malloc(sizeof(constvalue)))==NULL)
13.4454 - error(103); /* insufficient memory (fatal error) */
13.4455 - memset(cur,0,sizeof(constvalue));
13.4456 - if (name!=NULL) {
13.4457 - assert(strlen(name)<sNAMEMAX);
13.4458 - strcpy(cur->name,name);
13.4459 - } /* if */
13.4460 - cur->value=val;
13.4461 - cur->index=index;
13.4462 - cur->next=next;
13.4463 - prev->next=cur;
13.4464 - return cur;
13.4465 -}
13.4466 -
13.4467 -SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,int index)
13.4468 -{
13.4469 - constvalue *cur,*prev;
13.4470 -
13.4471 - /* find the end of the constant table */
13.4472 - for (prev=table, cur=table->next; cur!=NULL; prev=cur, cur=cur->next)
13.4473 - /* nothing */;
13.4474 - return insert_constval(prev,NULL,name,val,index);
13.4475 -}
13.4476 -
13.4477 -SC_FUNC constvalue *find_constval(constvalue *table,char *name,int index)
13.4478 -{
13.4479 - constvalue *ptr = table->next;
13.4480 -
13.4481 - while (ptr!=NULL) {
13.4482 - if (strcmp(name,ptr->name)==0 && ptr->index==index)
13.4483 - return ptr;
13.4484 - ptr=ptr->next;
13.4485 - } /* while */
13.4486 - return NULL;
13.4487 -}
13.4488 -
13.4489 -static constvalue *find_constval_byval(constvalue *table,cell val)
13.4490 -{
13.4491 - constvalue *ptr = table->next;
13.4492 -
13.4493 - while (ptr!=NULL) {
13.4494 - if (ptr->value==val)
13.4495 - return ptr;
13.4496 - ptr=ptr->next;
13.4497 - } /* while */
13.4498 - return NULL;
13.4499 -}
13.4500 -
13.4501 -#if 0 /* never used */
13.4502 -static int delete_constval(constvalue *table,char *name)
13.4503 -{
13.4504 - constvalue *prev = table;
13.4505 - constvalue *cur = prev->next;
13.4506 -
13.4507 - while (cur!=NULL) {
13.4508 - if (strcmp(name,cur->name)==0) {
13.4509 - prev->next=cur->next;
13.4510 - free(cur);
13.4511 - return TRUE;
13.4512 - } /* if */
13.4513 - prev=cur;
13.4514 - cur=cur->next;
13.4515 - } /* while */
13.4516 - return FALSE;
13.4517 -}
13.4518 -#endif
13.4519 -
13.4520 -SC_FUNC void delete_consttable(constvalue *table)
13.4521 -{
13.4522 - constvalue *cur=table->next, *next;
13.4523 -
13.4524 - while (cur!=NULL) {
13.4525 - next=cur->next;
13.4526 - free(cur);
13.4527 - cur=next;
13.4528 - } /* while */
13.4529 - memset(table,0,sizeof(constvalue));
13.4530 -}
13.4531 -
13.4532 -/* add_constant
13.4533 - *
13.4534 - * Adds a symbol to the symbol table. Returns NULL on failure.
13.4535 - */
13.4536 -SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag)
13.4537 -{
13.4538 - symbol *sym;
13.4539 -
13.4540 - /* Test whether a global or local symbol with the same name exists. Since
13.4541 - * constants are stored in the symbols table, this also finds previously
13.4542 - * defind constants. */
13.4543 - sym=findglb(name,sSTATEVAR);
13.4544 - if (!sym)
13.4545 - sym=findloc(name);
13.4546 - if (sym) {
13.4547 - int redef=0;
13.4548 - if (sym->ident!=iCONSTEXPR)
13.4549 - redef=1; /* redefinition a function/variable to a constant is not allowed */
13.4550 - if ((sym->usage & uENUMFIELD)!=0) {
13.4551 - /* enum field, special case if it has a different tag and the new symbol is also an enum field */
13.4552 - constvalue *tagid;
13.4553 - symbol *tagsym;
13.4554 - if (sym->tag==tag)
13.4555 - redef=1; /* enumeration field is redefined (same tag) */
13.4556 - tagid=find_tag_byval(tag);
13.4557 - if (tagid==NULL) {
13.4558 - redef=1; /* new constant does not have a tag */
13.4559 - } else {
13.4560 - tagsym=findconst(tagid->name,NULL);
13.4561 - if (tagsym==NULL || (tagsym->usage & uENUMROOT)==0)
13.4562 - redef=1; /* new constant is not an enumeration field */
13.4563 - } /* if */
13.4564 - /* in this particular case (enumeration field that is part of a different
13.4565 - * enum, and non-conflicting with plain constants) we want to be able to
13.4566 - * redefine it
13.4567 - */
13.4568 - if (!redef)
13.4569 - goto redef_enumfield;
13.4570 - } else if (sym->tag!=tag) {
13.4571 - redef=1; /* redefinition of a constant (non-enum) to a different tag is not allowed */
13.4572 - } /* if */
13.4573 - if (redef) {
13.4574 - error(21,name); /* symbol already defined */
13.4575 - return NULL;
13.4576 - } else if (sym->addr!=val) {
13.4577 - error(201,name); /* redefinition of constant (different value) */
13.4578 - sym->addr=val; /* set new value */
13.4579 - } /* if */
13.4580 - /* silently ignore redefinitions of constants with the same value & tag */
13.4581 - return sym;
13.4582 - } /* if */
13.4583 -
13.4584 - /* constant doesn't exist yet (or is allowed to be redefined) */
13.4585 -redef_enumfield:
13.4586 - sym=addsym(name,val,iCONSTEXPR,vclass,tag,uDEFINE);
13.4587 - assert(sym!=NULL); /* fatal error 103 must be given on error */
13.4588 - if (sc_status == statIDLE)
13.4589 - sym->usage |= uPREDEF;
13.4590 - return sym;
13.4591 -}
13.4592 -
13.4593 -/* statement - The Statement Parser
13.4594 - *
13.4595 - * This routine is called whenever the parser needs to know what statement
13.4596 - * it encounters (i.e. whenever program syntax requires a statement).
13.4597 - */
13.4598 -static void statement(int *lastindent,int allow_decl)
13.4599 -{
13.4600 - int tok;
13.4601 - cell val;
13.4602 - char *st;
13.4603 -
13.4604 - if (!freading) {
13.4605 - error(36); /* empty statement */
13.4606 - return;
13.4607 - } /* if */
13.4608 - errorset(sRESET,0);
13.4609 -
13.4610 - tok=lex(&val,&st);
13.4611 - if (tok!='{') {
13.4612 - insert_dbgline(fline);
13.4613 - setline(TRUE);
13.4614 - } /* if */
13.4615 - /* lex() has set stmtindent */
13.4616 - if (lastindent!=NULL && tok!=tLABEL) {
13.4617 - if (*lastindent>=0 && *lastindent!=stmtindent && !indent_nowarn && sc_tabsize>0)
13.4618 - error(217); /* loose indentation */
13.4619 - *lastindent=stmtindent;
13.4620 - indent_nowarn=FALSE; /* if warning was blocked, re-enable it */
13.4621 - } /* if */
13.4622 - switch (tok) {
13.4623 - case 0:
13.4624 - /* nothing */
13.4625 - break;
13.4626 - case tNEW:
13.4627 - if (allow_decl) {
13.4628 - autozero=1;
13.4629 - declloc(FALSE);
13.4630 - lastst=tNEW;
13.4631 - } else {
13.4632 - error(3); /* declaration only valid in a block */
13.4633 - } /* if */
13.4634 - break;
13.4635 - case tDECL:
13.4636 - if (allow_decl) {
13.4637 - autozero=0;
13.4638 - declloc(FALSE);
13.4639 - lastst=tDECL;
13.4640 - } else {
13.4641 - error(3); /* declaration only valid in a block */
13.4642 - } /* if */
13.4643 - break;
13.4644 - case tSTATIC:
13.4645 - if (allow_decl) {
13.4646 - declloc(TRUE);
13.4647 - lastst=tNEW;
13.4648 - } else {
13.4649 - error(3); /* declaration only valid in a block */
13.4650 - } /* if */
13.4651 - break;
13.4652 - case '{':
13.4653 - tok=fline;
13.4654 - if (!matchtoken('}')) /* {} is the empty statement */
13.4655 - compound(tok==fline);
13.4656 - /* lastst (for "last statement") does not change */
13.4657 - break;
13.4658 - case ';':
13.4659 - error(36); /* empty statement */
13.4660 - break;
13.4661 - case tIF:
13.4662 - doif();
13.4663 - lastst=tIF;
13.4664 - break;
13.4665 - case tWHILE:
13.4666 - dowhile();
13.4667 - lastst=tWHILE;
13.4668 - break;
13.4669 - case tDO:
13.4670 - dodo();
13.4671 - lastst=tDO;
13.4672 - break;
13.4673 - case tFOR:
13.4674 - dofor();
13.4675 - lastst=tFOR;
13.4676 - break;
13.4677 - case tSWITCH:
13.4678 - doswitch();
13.4679 - lastst=tSWITCH;
13.4680 - break;
13.4681 - case tCASE:
13.4682 - case tDEFAULT:
13.4683 - error(14); /* not in switch */
13.4684 - break;
13.4685 - case tGOTO:
13.4686 - dogoto();
13.4687 - lastst=tGOTO;
13.4688 - break;
13.4689 - case tLABEL:
13.4690 - dolabel();
13.4691 - lastst=tLABEL;
13.4692 - break;
13.4693 - case tRETURN:
13.4694 - doreturn();
13.4695 - lastst=tRETURN;
13.4696 - break;
13.4697 - case tBREAK:
13.4698 - dobreak();
13.4699 - lastst=tBREAK;
13.4700 - break;
13.4701 - case tCONTINUE:
13.4702 - docont();
13.4703 - lastst=tCONTINUE;
13.4704 - break;
13.4705 - case tEXIT:
13.4706 - doexit();
13.4707 - lastst=tEXIT;
13.4708 - break;
13.4709 - case tASSERT:
13.4710 - doassert();
13.4711 - lastst=tASSERT;
13.4712 - break;
13.4713 - case tSLEEP:
13.4714 - dosleep();
13.4715 - lastst=tSLEEP;
13.4716 - break;
13.4717 - case tSTATE:
13.4718 - dostate();
13.4719 - lastst=tSTATE;
13.4720 - break;
13.4721 - case tCONST:
13.4722 - decl_const(sLOCAL);
13.4723 - break;
13.4724 - case tENUM:
13.4725 - decl_enum(sLOCAL);
13.4726 - break;
13.4727 - default: /* non-empty expression */
13.4728 - sc_allowproccall=optproccall;
13.4729 - lexpush(); /* analyze token later */
13.4730 - doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE);
13.4731 - needtoken(tTERM);
13.4732 - lastst=tEXPR;
13.4733 - sc_allowproccall=FALSE;
13.4734 - } /* switch */
13.4735 -}
13.4736 -
13.4737 -static void compound(int stmt_sameline)
13.4738 -{
13.4739 - int indent=-1;
13.4740 - cell save_decl=declared;
13.4741 - int count_stmt=0;
13.4742 - int block_start=fline; /* save line where the compound block started */
13.4743 -
13.4744 - /* if there is more text on this line, we should adjust the statement indent */
13.4745 - if (stmt_sameline) {
13.4746 - int i;
13.4747 - const unsigned char *p=lptr;
13.4748 - /* go back to the opening brace */
13.4749 - while (*p!='{') {
13.4750 - assert(p>pline);
13.4751 - p--;
13.4752 - } /* while */
13.4753 - assert(*p=='{'); /* it should be found */
13.4754 - /* go forward, skipping white-space */
13.4755 - p++;
13.4756 - while (*p<=' ' && *p!='\0')
13.4757 - p++;
13.4758 - assert(*p!='\0'); /* a token should be found */
13.4759 - stmtindent=0;
13.4760 - for (i=0; i<(int)(p-pline); i++)
13.4761 - if (pline[i]=='\t' && sc_tabsize>0)
13.4762 - stmtindent += (int)(sc_tabsize - (stmtindent+sc_tabsize) % sc_tabsize);
13.4763 - else
13.4764 - stmtindent++;
13.4765 - } /* if */
13.4766 -
13.4767 - nestlevel+=1; /* increase compound statement level */
13.4768 - while (matchtoken('}')==0){ /* repeat until compound statement is closed */
13.4769 - if (!freading){
13.4770 - error(30,block_start); /* compound block not closed at end of file */
13.4771 - break;
13.4772 - } else {
13.4773 - if (count_stmt>0 && (lastst==tRETURN || lastst==tBREAK || lastst==tCONTINUE))
13.4774 - error(225); /* unreachable code */
13.4775 - statement(&indent,TRUE); /* do a statement */
13.4776 - count_stmt++;
13.4777 - } /* if */
13.4778 - } /* while */
13.4779 - if (lastst!=tRETURN)
13.4780 - destructsymbols(&loctab,nestlevel);
13.4781 - if (lastst!=tRETURN && lastst!=tGOTO)
13.4782 - modstk((int)(declared-save_decl)*sizeof(cell)); /* delete local variable space */
13.4783 - testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
13.4784 - declared=save_decl;
13.4785 - delete_symbols(&loctab,nestlevel,FALSE,TRUE); /* erase local symbols, but
13.4786 - * retain block local labels
13.4787 - * (within the function) */
13.4788 - nestlevel-=1; /* decrease compound statement level */
13.4789 -}
13.4790 -
13.4791 -/* doexpr
13.4792 - *
13.4793 - * Global references: stgidx (referred to only)
13.4794 - */
13.4795 -static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
13.4796 - int *tag,symbol **symptr,int chkfuncresult)
13.4797 -{
13.4798 - int index,ident;
13.4799 - int localstaging=FALSE;
13.4800 - cell val;
13.4801 -
13.4802 - if (!staging) {
13.4803 - stgset(TRUE); /* start stage-buffering */
13.4804 - localstaging=TRUE;
13.4805 - assert(stgidx==0);
13.4806 - } /* if */
13.4807 - index=stgidx;
13.4808 - errorset(sEXPRMARK,0);
13.4809 - do {
13.4810 - /* on second round through, mark the end of the previous expression */
13.4811 - if (index!=stgidx)
13.4812 - markexpr(sEXPR,NULL,0);
13.4813 - sideeffect=FALSE;
13.4814 - ident=expression(&val,tag,symptr,chkfuncresult);
13.4815 - if (!allowarray && (ident==iARRAY || ident==iREFARRAY))
13.4816 - error(33,"-unknown-"); /* array must be indexed */
13.4817 - if (chkeffect && !sideeffect)
13.4818 - error(215); /* expression has no effect */
13.4819 - sc_allowproccall=FALSE; /* cannot use "procedure call" syntax anymore */
13.4820 - } while (comma && matchtoken(',')); /* more? */
13.4821 - if (mark_endexpr)
13.4822 - markexpr(sEXPR,NULL,0); /* optionally, mark the end of the expression */
13.4823 - errorset(sEXPRRELEASE,0);
13.4824 - if (localstaging) {
13.4825 - stgout(index);
13.4826 - stgset(FALSE); /* stop staging */
13.4827 - } /* if */
13.4828 - return ident;
13.4829 -}
13.4830 -
13.4831 -/* constexpr
13.4832 - */
13.4833 -SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr)
13.4834 -{
13.4835 - int ident,index;
13.4836 - cell cidx;
13.4837 -
13.4838 - stgset(TRUE); /* start stage-buffering */
13.4839 - stgget(&index,&cidx); /* mark position in code generator */
13.4840 - errorset(sEXPRMARK,0);
13.4841 - ident=expression(val,tag,symptr,FALSE);
13.4842 - stgdel(index,cidx); /* scratch generated code */
13.4843 - stgset(FALSE); /* stop stage-buffering */
13.4844 - if (ident!=iCONSTEXPR) {
13.4845 - error(8); /* must be constant expression */
13.4846 - if (val!=NULL)
13.4847 - *val=0;
13.4848 - if (tag!=NULL)
13.4849 - *tag=0;
13.4850 - if (symptr!=NULL)
13.4851 - *symptr=NULL;
13.4852 - } /* if */
13.4853 - errorset(sEXPRRELEASE,0);
13.4854 - return (ident==iCONSTEXPR);
13.4855 -}
13.4856 -
13.4857 -/* test
13.4858 - *
13.4859 - * In the case a "simple assignment" operator ("=") is used within a test,
13.4860 - * the warning "possibly unintended assignment" is displayed. This routine
13.4861 - * sets the global variable "sc_intest" to true, it is restored upon termination.
13.4862 - * In the case the assignment was intended, use parantheses around the
13.4863 - * expression to avoid the warning; primary() sets "sc_intest" to 0.
13.4864 - *
13.4865 - * Global references: sc_intest (altered, but restored upon termination)
13.4866 - */
13.4867 -static void test(int label,int parens,int invert)
13.4868 -{
13.4869 - int index,tok;
13.4870 - cell cidx;
13.4871 - int ident,tag;
13.4872 - cell constval;
13.4873 - symbol *sym;
13.4874 - int localstaging=FALSE;
13.4875 -
13.4876 - if (!staging) {
13.4877 - stgset(TRUE); /* start staging */
13.4878 - localstaging=TRUE;
13.4879 - #if !defined NDEBUG
13.4880 - stgget(&index,&cidx); /* should start at zero if started locally */
13.4881 - assert(index==0);
13.4882 - #endif
13.4883 - } /* if */
13.4884 -
13.4885 - PUSHSTK_I(sc_intest);
13.4886 - sc_intest=TRUE;
13.4887 - if (parens)
13.4888 - needtoken('(');
13.4889 - do {
13.4890 - stgget(&index,&cidx); /* mark position (of last expression) in
13.4891 - * code generator */
13.4892 - ident=expression(&constval,&tag,&sym,TRUE);
13.4893 - tok=matchtoken(',');
13.4894 - if (tok)
13.4895 - markexpr(sEXPR,NULL,0);
13.4896 - } while (tok); /* do */
13.4897 - if (parens)
13.4898 - needtoken(')');
13.4899 - if (ident==iARRAY || ident==iREFARRAY) {
13.4900 - char *ptr=(sym->name!=NULL) ? sym->name : "-unknown-";
13.4901 - error(33,ptr); /* array must be indexed */
13.4902 - } /* if */
13.4903 - if (ident==iCONSTEXPR) { /* constant expression */
13.4904 - sc_intest=(short)POPSTK_I();/* restore stack */
13.4905 - stgdel(index,cidx);
13.4906 - if (constval) { /* code always executed */
13.4907 - error(206); /* redundant test: always non-zero */
13.4908 - } else {
13.4909 - error(205); /* redundant code: never executed */
13.4910 - jumplabel(label);
13.4911 - } /* if */
13.4912 - if (localstaging) {
13.4913 - stgout(0); /* write "jumplabel" code */
13.4914 - stgset(FALSE); /* stop staging */
13.4915 - } /* if */
13.4916 - return;
13.4917 - } /* if */
13.4918 - if (tag!=0 && tag!=pc_addtag("bool"))
13.4919 - if (check_userop(lneg,tag,0,1,NULL,&tag))
13.4920 - invert= !invert; /* user-defined ! operator inverted result */
13.4921 - if (invert)
13.4922 - jmp_ne0(label); /* jump to label if true (different from 0) */
13.4923 - else
13.4924 - jmp_eq0(label); /* jump to label if false (equal to 0) */
13.4925 - markexpr(sEXPR,NULL,0); /* end expression (give optimizer a chance) */
13.4926 - sc_intest=(short)POPSTK_I(); /* double typecast to avoid warning with Microsoft C */
13.4927 - if (localstaging) {
13.4928 - stgout(0); /* output queue from the very beginning (see
13.4929 - * assert() when localstaging is set to TRUE) */
13.4930 - stgset(FALSE); /* stop staging */
13.4931 - } /* if */
13.4932 -}
13.4933 -
13.4934 -static void doif(void)
13.4935 -{
13.4936 - int flab1,flab2;
13.4937 - int ifindent;
13.4938 -
13.4939 - ifindent=stmtindent; /* save the indent of the "if" instruction */
13.4940 - flab1=getlabel(); /* get label number for false branch */
13.4941 - test(flab1,TRUE,FALSE); /* get expression, branch to flab1 if false */
13.4942 - statement(NULL,FALSE); /* if true, do a statement */
13.4943 - if (matchtoken(tELSE)==0){ /* if...else ? */
13.4944 - setlabel(flab1); /* no, simple if..., print false label */
13.4945 - } else {
13.4946 - /* to avoid the "dangling else" error, we want a warning if the "else"
13.4947 - * has a lower indent than the matching "if" */
13.4948 - if (stmtindent<ifindent && sc_tabsize>0)
13.4949 - error(217); /* loose indentation */
13.4950 - flab2=getlabel();
13.4951 - if ((lastst!=tRETURN) && (lastst!=tGOTO))
13.4952 - jumplabel(flab2);
13.4953 - setlabel(flab1); /* print false label */
13.4954 - statement(NULL,FALSE); /* do "else" clause */
13.4955 - setlabel(flab2); /* print true label */
13.4956 - } /* endif */
13.4957 -}
13.4958 -
13.4959 -static void dowhile(void)
13.4960 -{
13.4961 - int wq[wqSIZE]; /* allocate local queue */
13.4962 -
13.4963 - addwhile(wq); /* add entry to queue for "break" */
13.4964 - setlabel(wq[wqLOOP]); /* loop label */
13.4965 - /* The debugger uses the "break" opcode to be able to "break" out of
13.4966 - * a loop. To make sure that each loop has a break opcode, even for the
13.4967 - * tiniest loop, set it below the top of the loop
13.4968 - */
13.4969 - setline(TRUE);
13.4970 - test(wq[wqEXIT],TRUE,FALSE); /* branch to wq[wqEXIT] if false */
13.4971 - statement(NULL,FALSE); /* if so, do a statement */
13.4972 - jumplabel(wq[wqLOOP]); /* and loop to "while" start */
13.4973 - setlabel(wq[wqEXIT]); /* exit label */
13.4974 - delwhile(); /* delete queue entry */
13.4975 -}
13.4976 -
13.4977 -/*
13.4978 - * Note that "continue" will in this case not jump to the top of the loop, but
13.4979 - * to the end: just before the TRUE-or-FALSE testing code.
13.4980 - */
13.4981 -static void dodo(void)
13.4982 -{
13.4983 - int wq[wqSIZE],top;
13.4984 -
13.4985 - addwhile(wq); /* see "dowhile" for more info */
13.4986 - top=getlabel(); /* make a label first */
13.4987 - setlabel(top); /* loop label */
13.4988 - statement(NULL,FALSE);
13.4989 - needtoken(tWHILE);
13.4990 - setlabel(wq[wqLOOP]); /* "continue" always jumps to WQLOOP. */
13.4991 - setline(TRUE);
13.4992 - test(wq[wqEXIT],TRUE,FALSE);
13.4993 - jumplabel(top);
13.4994 - setlabel(wq[wqEXIT]);
13.4995 - delwhile();
13.4996 - needtoken(tTERM);
13.4997 -}
13.4998 -
13.4999 -static void dofor(void)
13.5000 -{
13.5001 - int wq[wqSIZE],skiplab;
13.5002 - cell save_decl;
13.5003 - int save_nestlevel,index;
13.5004 - int *ptr;
13.5005 -
13.5006 - save_decl=declared;
13.5007 - save_nestlevel=nestlevel;
13.5008 -
13.5009 - addwhile(wq);
13.5010 - skiplab=getlabel();
13.5011 - needtoken('(');
13.5012 - if (matchtoken(';')==0) {
13.5013 - /* new variable declarations are allowed here */
13.5014 - if (matchtoken(tNEW)) {
13.5015 - /* The variable in expr1 of the for loop is at a
13.5016 - * 'compound statement' level of it own.
13.5017 - */
13.5018 - nestlevel++;
13.5019 - autozero=1;
13.5020 - declloc(FALSE); /* declare local variable */
13.5021 - } else {
13.5022 - doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 1 */
13.5023 - needtoken(';');
13.5024 - } /* if */
13.5025 - } /* if */
13.5026 - /* Adjust the "declared" field in the "while queue", in case that
13.5027 - * local variables were declared in the first expression of the
13.5028 - * "for" loop. These are deleted in separately, so a "break" or a "continue"
13.5029 - * must ignore these fields.
13.5030 - */
13.5031 - ptr=readwhile();
13.5032 - assert(ptr!=NULL);
13.5033 - ptr[wqBRK]=(int)declared;
13.5034 - ptr[wqCONT]=(int)declared;
13.5035 - jumplabel(skiplab); /* skip expression 3 1st time */
13.5036 - setlabel(wq[wqLOOP]); /* "continue" goes to this label: expr3 */
13.5037 - setline(TRUE);
13.5038 - /* Expressions 2 and 3 are reversed in the generated code: expression 3
13.5039 - * precedes expression 2. When parsing, the code is buffered and marks for
13.5040 - * the start of each expression are insterted in the buffer.
13.5041 - */
13.5042 - assert(!staging);
13.5043 - stgset(TRUE); /* start staging */
13.5044 - assert(stgidx==0);
13.5045 - index=stgidx;
13.5046 - stgmark(sSTARTREORDER);
13.5047 - stgmark((char)(sEXPRSTART+0)); /* mark start of 2nd expression in stage */
13.5048 - setlabel(skiplab); /* jump to this point after 1st expression */
13.5049 - if (matchtoken(';')==0) {
13.5050 - test(wq[wqEXIT],FALSE,FALSE); /* expression 2 (jump to wq[wqEXIT] if false) */
13.5051 - needtoken(';');
13.5052 - } /* if */
13.5053 - stgmark((char)(sEXPRSTART+1)); /* mark start of 3th expression in stage */
13.5054 - if (matchtoken(')')==0) {
13.5055 - doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 3 */
13.5056 - needtoken(')');
13.5057 - } /* if */
13.5058 - stgmark(sENDREORDER); /* mark end of reversed evaluation */
13.5059 - stgout(index);
13.5060 - stgset(FALSE); /* stop staging */
13.5061 - statement(NULL,FALSE);
13.5062 - jumplabel(wq[wqLOOP]);
13.5063 - setlabel(wq[wqEXIT]);
13.5064 - delwhile();
13.5065 -
13.5066 - assert(nestlevel>=save_nestlevel);
13.5067 - if (nestlevel>save_nestlevel) {
13.5068 - /* Clean up the space and the symbol table for the local
13.5069 - * variable in "expr1".
13.5070 - */
13.5071 - destructsymbols(&loctab,nestlevel);
13.5072 - modstk((int)(declared-save_decl)*sizeof(cell));
13.5073 - testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
13.5074 - declared=save_decl;
13.5075 - delete_symbols(&loctab,nestlevel,FALSE,TRUE);
13.5076 - nestlevel=save_nestlevel; /* reset 'compound statement' nesting level */
13.5077 - } /* if */
13.5078 -}
13.5079 -
13.5080 -/* The switch statement is incompatible with its C sibling:
13.5081 - * 1. the cases are not drop through
13.5082 - * 2. only one instruction may appear below each case, use a compound
13.5083 - * instruction to execute multiple instructions
13.5084 - * 3. the "case" keyword accepts a comma separated list of values to
13.5085 - * match, it also accepts a range using the syntax "1 .. 4"
13.5086 - *
13.5087 - * SWITCH param
13.5088 - * PRI = expression result
13.5089 - * param = table offset (code segment)
13.5090 - *
13.5091 - */
13.5092 -static void doswitch(void)
13.5093 -{
13.5094 - int lbl_table,lbl_exit,lbl_case;
13.5095 - int tok,swdefault,casecount;
13.5096 - cell val;
13.5097 - char *str;
13.5098 - constvalue caselist = { NULL, "", 0, 0}; /* case list starts empty */
13.5099 - constvalue *cse,*csp;
13.5100 - char labelname[sNAMEMAX+1];
13.5101 -
13.5102 - needtoken('(');
13.5103 - doexpr(TRUE,FALSE,FALSE,FALSE,NULL,NULL,TRUE);/* evaluate switch expression */
13.5104 - needtoken(')');
13.5105 - /* generate the code for the switch statement, the label is the address
13.5106 - * of the case table (to be generated later).
13.5107 - */
13.5108 - lbl_table=getlabel();
13.5109 - lbl_case=0; /* just to avoid a compiler warning */
13.5110 - ffswitch(lbl_table);
13.5111 -
13.5112 - needtoken('{');
13.5113 - lbl_exit=getlabel(); /* get label number for jumping out of switch */
13.5114 - swdefault=FALSE;
13.5115 - casecount=0;
13.5116 - do {
13.5117 - tok=lex(&val,&str); /* read in (new) token */
13.5118 - switch (tok) {
13.5119 - case tCASE:
13.5120 - if (swdefault!=FALSE)
13.5121 - error(15); /* "default" case must be last in switch statement */
13.5122 - lbl_case=getlabel();
13.5123 - PUSHSTK_I(sc_allowtags);
13.5124 - sc_allowtags=FALSE; /* do not allow tagnames here */
13.5125 - do {
13.5126 - casecount++;
13.5127 -
13.5128 - /* ??? enforce/document that, in a switch, a statement cannot start
13.5129 - * with a label. Then, you can search for:
13.5130 - * * the first semicolon (marks the end of a statement)
13.5131 - * * an opening brace (marks the start of a compound statement)
13.5132 - * and search for the right-most colon before that statement
13.5133 - * Now, by replacing the ':' by a special COLON token, you can
13.5134 - * parse all expressions until that special token.
13.5135 - */
13.5136 -
13.5137 - constexpr(&val,NULL,NULL);
13.5138 - /* Search the insertion point (the table is kept in sorted order, so
13.5139 - * that advanced abstract machines can sift the case table with a
13.5140 - * binary search). Check for duplicate case values at the same time.
13.5141 - */
13.5142 - for (csp=&caselist, cse=caselist.next;
13.5143 - cse!=NULL && cse->value<val;
13.5144 - csp=cse, cse=cse->next)
13.5145 - /* nothing */;
13.5146 - if (cse!=NULL && cse->value==val)
13.5147 - error(40,val); /* duplicate "case" label */
13.5148 - /* Since the label is stored as a string in the "constvalue", the
13.5149 - * size of an identifier must be at least 8, as there are 8
13.5150 - * hexadecimal digits in a 32-bit number.
13.5151 - */
13.5152 - #if sNAMEMAX < 8
13.5153 - #error Length of identifier (sNAMEMAX) too small.
13.5154 - #endif
13.5155 - assert(csp!=NULL);
13.5156 - assert(csp->next==cse);
13.5157 - insert_constval(csp,cse,itoh(lbl_case),val,0);
13.5158 - if (matchtoken(tDBLDOT)) {
13.5159 - cell end;
13.5160 - constexpr(&end,NULL,NULL);
13.5161 - if (end<=val)
13.5162 - error(50); /* invalid range */
13.5163 - while (++val<=end) {
13.5164 - casecount++;
13.5165 - /* find the new insertion point */
13.5166 - for (csp=&caselist, cse=caselist.next;
13.5167 - cse!=NULL && cse->value<val;
13.5168 - csp=cse, cse=cse->next)
13.5169 - /* nothing */;
13.5170 - if (cse!=NULL && cse->value==val)
13.5171 - error(40,val); /* duplicate "case" label */
13.5172 - assert(csp!=NULL);
13.5173 - assert(csp->next==cse);
13.5174 - insert_constval(csp,cse,itoh(lbl_case),val,0);
13.5175 - } /* if */
13.5176 - } /* if */
13.5177 - } while (matchtoken(','));
13.5178 - needtoken(':'); /* ':' ends the case */
13.5179 - sc_allowtags=(short)POPSTK_I(); /* reset */
13.5180 - setlabel(lbl_case);
13.5181 - statement(NULL,FALSE);
13.5182 - jumplabel(lbl_exit);
13.5183 - break;
13.5184 - case tDEFAULT:
13.5185 - if (swdefault!=FALSE)
13.5186 - error(16); /* multiple defaults in switch */
13.5187 - lbl_case=getlabel();
13.5188 - setlabel(lbl_case);
13.5189 - needtoken(':');
13.5190 - swdefault=TRUE;
13.5191 - statement(NULL,FALSE);
13.5192 - /* Jump to lbl_exit, even thouh this is the last clause in the
13.5193 - * switch, because the jump table is generated between the last
13.5194 - * clause of the switch and the exit label.
13.5195 - */
13.5196 - jumplabel(lbl_exit);
13.5197 - break;
13.5198 - case '}':
13.5199 - /* nothing, but avoid dropping into "default" */
13.5200 - break;
13.5201 - default:
13.5202 - error(2);
13.5203 - indent_nowarn=TRUE; /* disable this check */
13.5204 - tok='}'; /* break out of the loop after an error */
13.5205 - } /* switch */
13.5206 - } while (tok!='}');
13.5207 -
13.5208 - #if !defined NDEBUG
13.5209 - /* verify that the case table is sorted (unfortunatly, duplicates can
13.5210 - * occur; there really shouldn't be duplicate cases, but the compiler
13.5211 - * may not crash or drop into an assertion for a user error). */
13.5212 - for (cse=caselist.next; cse!=NULL && cse->next!=NULL; cse=cse->next)
13.5213 - assert(cse->value <= cse->next->value);
13.5214 - #endif
13.5215 - /* generate the table here, before lbl_exit (general jump target) */
13.5216 - setlabel(lbl_table);
13.5217 - assert(swdefault==FALSE || swdefault==TRUE);
13.5218 - if (swdefault==FALSE) {
13.5219 - /* store lbl_exit as the "none-matched" label in the switch table */
13.5220 - strcpy(labelname,itoh(lbl_exit));
13.5221 - } else {
13.5222 - /* lbl_case holds the label of the "default" clause */
13.5223 - strcpy(labelname,itoh(lbl_case));
13.5224 - } /* if */
13.5225 - ffcase(casecount,labelname,TRUE);
13.5226 - /* generate the rest of the table */
13.5227 - for (cse=caselist.next; cse!=NULL; cse=cse->next)
13.5228 - ffcase(cse->value,cse->name,FALSE);
13.5229 -
13.5230 - setlabel(lbl_exit);
13.5231 - delete_consttable(&caselist); /* clear list of case labels */
13.5232 -}
13.5233 -
13.5234 -static void doassert(void)
13.5235 -{
13.5236 - int flab1,index;
13.5237 - cell cidx;
13.5238 -
13.5239 - if ((sc_debug & sCHKBOUNDS)!=0) {
13.5240 - flab1=getlabel(); /* get label number for "OK" branch */
13.5241 - test(flab1,FALSE,TRUE); /* get expression and branch to flab1 if true */
13.5242 - insert_dbgline(fline); /* make sure we can find the correct line number */
13.5243 - ffabort(xASSERTION);
13.5244 - setlabel(flab1);
13.5245 - } else {
13.5246 - stgset(TRUE); /* start staging */
13.5247 - stgget(&index,&cidx); /* mark position in code generator */
13.5248 - do {
13.5249 - expression(NULL,NULL,NULL,FALSE);
13.5250 - stgdel(index,cidx); /* just scrap the code */
13.5251 - } while (matchtoken(','));
13.5252 - stgset(FALSE); /* stop staging */
13.5253 - } /* if */
13.5254 - needtoken(tTERM);
13.5255 -}
13.5256 -
13.5257 -static void dogoto(void)
13.5258 -{
13.5259 - char *st;
13.5260 - cell val;
13.5261 - symbol *sym;
13.5262 -
13.5263 - if (lex(&val,&st)==tSYMBOL) {
13.5264 - sym=fetchlab(st);
13.5265 - jumplabel((int)sym->addr);
13.5266 - sym->usage|=uREAD; /* set "uREAD" bit */
13.5267 - // ??? if the label is defined (check sym->usage & uDEFINE), check
13.5268 - // sym->compound (nesting level of the label) against nestlevel;
13.5269 - // if sym->compound < nestlevel, call the destructor operator
13.5270 - } else {
13.5271 - error(20,st); /* illegal symbol name */
13.5272 - } /* if */
13.5273 - needtoken(tTERM);
13.5274 -}
13.5275 -
13.5276 -static void dolabel(void)
13.5277 -{
13.5278 - char *st;
13.5279 - cell val;
13.5280 - symbol *sym;
13.5281 -
13.5282 - tokeninfo(&val,&st); /* retrieve label name again */
13.5283 - if (find_constval(&tagname_tab,st,0)!=NULL)
13.5284 - error(221,st); /* label name shadows tagname */
13.5285 - sym=fetchlab(st);
13.5286 - setlabel((int)sym->addr);
13.5287 - /* since one can jump around variable declarations or out of compound
13.5288 - * blocks, the stack must be manually adjusted
13.5289 - */
13.5290 - setstk(-declared*sizeof(cell));
13.5291 - sym->usage|=uDEFINE; /* label is now defined */
13.5292 -}
13.5293 -
13.5294 -/* fetchlab
13.5295 - *
13.5296 - * Finds a label from the (local) symbol table or adds one to it.
13.5297 - * Labels are local in scope.
13.5298 - *
13.5299 - * Note: The "_usage" bit is set to zero. The routines that call "fetchlab()"
13.5300 - * must set this bit accordingly.
13.5301 - */
13.5302 -static symbol *fetchlab(char *name)
13.5303 -{
13.5304 - symbol *sym;
13.5305 -
13.5306 - sym=findloc(name); /* labels are local in scope */
13.5307 - if (sym){
13.5308 - if (sym->ident!=iLABEL)
13.5309 - error(19,sym->name); /* not a label: ... */
13.5310 - } else {
13.5311 - sym=addsym(name,getlabel(),iLABEL,sLOCAL,0,0);
13.5312 - assert(sym!=NULL); /* fatal error 103 must be given on error */
13.5313 - sym->x.declared=(int)declared;
13.5314 - sym->compound=nestlevel;
13.5315 - } /* if */
13.5316 - return sym;
13.5317 -}
13.5318 -
13.5319 -/* doreturn
13.5320 - *
13.5321 - * Global references: rettype (altered)
13.5322 - */
13.5323 -static void doreturn(void)
13.5324 -{
13.5325 - int tag,ident;
13.5326 - int level;
13.5327 - symbol *sym,*sub;
13.5328 -
13.5329 - if (!matchtoken(tTERM)) {
13.5330 - /* "return <value>" */
13.5331 - if ((rettype & uRETNONE)!=0)
13.5332 - error(78); /* mix "return;" and "return value;" */
13.5333 - ident=doexpr(TRUE,FALSE,TRUE,TRUE,&tag,&sym,TRUE);
13.5334 - needtoken(tTERM);
13.5335 - /* see if this function already has a sub type (an array attached) */
13.5336 - sub=finddepend(curfunc);
13.5337 - assert(sub==NULL || sub->ident==iREFARRAY);
13.5338 - if ((rettype & uRETVALUE)!=0) {
13.5339 - int retarray=(ident==iARRAY || ident==iREFARRAY);
13.5340 - /* there was an earlier "return" statement in this function */
13.5341 - if (sub==NULL && retarray || sub!=NULL && !retarray)
13.5342 - error(79); /* mixing "return array;" and "return value;" */
13.5343 - if (retarray && (curfunc->usage & uPUBLIC)!=0)
13.5344 - error(90,curfunc->name); /* public function may not return array */
13.5345 - } /* if */
13.5346 - rettype|=uRETVALUE; /* function returns a value */
13.5347 - /* check tagname with function tagname */
13.5348 - assert(curfunc!=NULL);
13.5349 - if (!matchtag(curfunc->tag,tag,TRUE))
13.5350 - error(213); /* tagname mismatch */
13.5351 - if (ident==iARRAY || ident==iREFARRAY) {
13.5352 - int dim[sDIMEN_MAX],numdim;
13.5353 - cell arraysize;
13.5354 - assert(sym!=NULL);
13.5355 - if (sub!=NULL) {
13.5356 - assert(sub->ident==iREFARRAY);
13.5357 - /* this function has an array attached already; check that the current
13.5358 - * "return" statement returns exactly the same array
13.5359 - */
13.5360 - level=sym->dim.array.level;
13.5361 - if (sub->dim.array.level!=level) {
13.5362 - error(48); /* array dimensions must match */
13.5363 - } else {
13.5364 - for (numdim=0; numdim<=level; numdim++) {
13.5365 - dim[numdim]=(int)sub->dim.array.length;
13.5366 - if (sym->dim.array.length!=dim[numdim])
13.5367 - error(47); /* array sizes must match */
13.5368 - if (numdim<level) {
13.5369 - sym=finddepend(sym);
13.5370 - sub=finddepend(sub);
13.5371 - assert(sym!=NULL && sub!=NULL);
13.5372 - /* ^^^ both arrays have the same dimensions (this was checked
13.5373 - * earlier) so the dependend should always be found
13.5374 - */
13.5375 - } /* if */
13.5376 - } /* for */
13.5377 - } /* if */
13.5378 - } else {
13.5379 - int idxtag[sDIMEN_MAX];
13.5380 - int argcount;
13.5381 - /* this function does not yet have an array attached; clone the
13.5382 - * returned symbol beneath the current function
13.5383 - */
13.5384 - sub=sym;
13.5385 - assert(sub!=NULL);
13.5386 - level=sub->dim.array.level;
13.5387 - for (numdim=0; numdim<=level; numdim++) {
13.5388 - dim[numdim]=(int)sub->dim.array.length;
13.5389 - idxtag[numdim]=sub->x.tags.index;
13.5390 - if (numdim<level) {
13.5391 - sub=finddepend(sub);
13.5392 - assert(sub!=NULL);
13.5393 - } /* if */
13.5394 - /* check that all dimensions are known */
13.5395 - if (dim[numdim]<=0)
13.5396 - error(46,sym->name);
13.5397 - } /* for */
13.5398 - /* the address of the array is stored in a hidden parameter; the address
13.5399 - * of this parameter is 1 + the number of parameters (times the size of
13.5400 - * a cell) + the size of the stack frame and the return address
13.5401 - * base + 0*sizeof(cell) == previous "base"
13.5402 - * base + 1*sizeof(cell) == function return address
13.5403 - * base + 2*sizeof(cell) == number of arguments
13.5404 - * base + 3*sizeof(cell) == first argument of the function
13.5405 - * ...
13.5406 - * base + ((n-1)+3)*sizeof(cell) == last argument of the function
13.5407 - * base + (n+3)*sizeof(cell) == hidden parameter with array address
13.5408 - */
13.5409 - assert(curfunc!=NULL);
13.5410 - assert(curfunc->dim.arglist!=NULL);
13.5411 - for (argcount=0; curfunc->dim.arglist[argcount].ident!=0; argcount++)
13.5412 - /* nothing */;
13.5413 - sub=addvariable(curfunc->name,(argcount+3)*sizeof(cell),iREFARRAY,sGLOBAL,curfunc->tag,dim,numdim,idxtag);
13.5414 - sub->parent=curfunc;
13.5415 - } /* if */
13.5416 - /* get the hidden parameter, copy the array (the array is on the heap;
13.5417 - * it stays on the heap for the moment, and it is removed -usually- at
13.5418 - * the end of the expression/statement, see expression() in SC3.C)
13.5419 - */
13.5420 - address(sub,sALT); /* ALT = destination */
13.5421 - arraysize=calc_arraysize(dim,numdim,0);
13.5422 - memcopy(arraysize*sizeof(cell)); /* source already in PRI */
13.5423 - /* moveto1(); is not necessary, callfunction() does a popreg() */
13.5424 - } /* if */
13.5425 - } else {
13.5426 - /* this return statement contains no expression */
13.5427 - ldconst(0,sPRI);
13.5428 - if ((rettype & uRETVALUE)!=0) {
13.5429 - char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
13.5430 - assert(curfunc!=NULL);
13.5431 - funcdisplayname(symname,curfunc->name);
13.5432 - error(209,symname); /* function should return a value */
13.5433 - } /* if */
13.5434 - rettype|=uRETNONE; /* function does not return anything */
13.5435 - } /* if */
13.5436 - destructsymbols(&loctab,0); /* call destructor for *all* locals */
13.5437 - modstk((int)declared*sizeof(cell)); /* end of function, remove *all*
13.5438 - * local variables */
13.5439 - ffret(strcmp(curfunc->name,uENTRYFUNC)!=0);
13.5440 -}
13.5441 -
13.5442 -static void dobreak(void)
13.5443 -{
13.5444 - int *ptr;
13.5445 -
13.5446 - ptr=readwhile(); /* readwhile() gives an error if not in loop */
13.5447 - needtoken(tTERM);
13.5448 - if (ptr==NULL)
13.5449 - return;
13.5450 - destructsymbols(&loctab,nestlevel);
13.5451 - modstk(((int)declared-ptr[wqBRK])*sizeof(cell));
13.5452 - jumplabel(ptr[wqEXIT]);
13.5453 -}
13.5454 -
13.5455 -static void docont(void)
13.5456 -{
13.5457 - int *ptr;
13.5458 -
13.5459 - ptr=readwhile(); /* readwhile() gives an error if not in loop */
13.5460 - needtoken(tTERM);
13.5461 - if (ptr==NULL)
13.5462 - return;
13.5463 - destructsymbols(&loctab,nestlevel);
13.5464 - modstk(((int)declared-ptr[wqCONT])*sizeof(cell));
13.5465 - jumplabel(ptr[wqLOOP]);
13.5466 -}
13.5467 -
13.5468 -SC_FUNC void exporttag(int tag)
13.5469 -{
13.5470 - /* find the tag by value in the table, then set the top bit to mark it
13.5471 - * "public"
13.5472 - */
13.5473 - if (tag!=0 && (tag & PUBLICTAG)==0) {
13.5474 - constvalue *ptr;
13.5475 - for (ptr=tagname_tab.next; ptr!=NULL && tag!=(int)(ptr->value & TAGMASK); ptr=ptr->next)
13.5476 - /* nothing */;
13.5477 - if (ptr!=NULL)
13.5478 - ptr->value |= PUBLICTAG;
13.5479 - } /* if */
13.5480 -}
13.5481 -
13.5482 -static void doexit(void)
13.5483 -{
13.5484 - int tag=0;
13.5485 -
13.5486 - if (matchtoken(tTERM)==0){
13.5487 - doexpr(TRUE,FALSE,FALSE,TRUE,&tag,NULL,TRUE);
13.5488 - needtoken(tTERM);
13.5489 - } else {
13.5490 - ldconst(0,sPRI);
13.5491 - } /* if */
13.5492 - ldconst(tag,sALT);
13.5493 - exporttag(tag);
13.5494 - destructsymbols(&loctab,0); /* call destructor for *all* locals */
13.5495 - ffabort(xEXIT);
13.5496 -}
13.5497 -
13.5498 -static void dosleep(void)
13.5499 -{
13.5500 - int tag=0;
13.5501 -
13.5502 - if (matchtoken(tTERM)==0){
13.5503 - doexpr(TRUE,FALSE,FALSE,TRUE,&tag,NULL,TRUE);
13.5504 - needtoken(tTERM);
13.5505 - } else {
13.5506 - ldconst(0,sPRI);
13.5507 - } /* if */
13.5508 - ldconst(tag,sALT);
13.5509 - exporttag(tag);
13.5510 - ffabort(xSLEEP);
13.5511 -
13.5512 - /* for stack usage checking, mark the use of the sleep instruction */
13.5513 - pc_memflags |= suSLEEP_INSTR;
13.5514 -}
13.5515 -
13.5516 -static void dostate(void)
13.5517 -{
13.5518 - char name[sNAMEMAX+1];
13.5519 - constvalue *automaton;
13.5520 - constvalue *state;
13.5521 - constvalue *stlist;
13.5522 - int flabel;
13.5523 - symbol *sym;
13.5524 - #if !defined SC_LIGHT
13.5525 - int length,index,listid,listindex,stateindex;
13.5526 - char *doc;
13.5527 - #endif
13.5528 -
13.5529 - /* check for an optional condition */
13.5530 - if (matchtoken('(')) {
13.5531 - flabel=getlabel(); /* get label number for "false" branch */
13.5532 - pc_docexpr=TRUE; /* attach expression as a documentation string */
13.5533 - test(flabel,FALSE,FALSE); /* get expression, branch to flabel if false */
13.5534 - pc_docexpr=FALSE;
13.5535 - needtoken(')');
13.5536 - } else {
13.5537 - flabel=-1;
13.5538 - } /* if */
13.5539 -
13.5540 - if (!sc_getstateid(&automaton,&state)) {
13.5541 - delete_autolisttable();
13.5542 - return;
13.5543 - } /* if */
13.5544 - needtoken(tTERM);
13.5545 -
13.5546 - /* store the new state id */
13.5547 - assert(state!=NULL);
13.5548 - ldconst(state->value,sPRI);
13.5549 - assert(automaton!=NULL);
13.5550 - assert(automaton->index==0 && automaton->name[0]=='\0' || automaton->index>0);
13.5551 - storereg(automaton->value,sPRI);
13.5552 -
13.5553 - /* find the optional entry() function for the state */
13.5554 - sym=findglb(uENTRYFUNC,sGLOBAL);
13.5555 - if (sc_status==statWRITE && sym!=NULL && sym->ident==iFUNCTN && sym->states!=NULL) {
13.5556 - for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) {
13.5557 - assert(strlen(stlist->name)!=0);
13.5558 - if (state_getfsa(stlist->index)==automaton->index && state_inlist(stlist->index,(int)state->value))
13.5559 - break; /* found! */
13.5560 - } /* for */
13.5561 - assert(stlist==NULL || state_inlist(stlist->index,state->value));
13.5562 - if (stlist!=NULL) {
13.5563 - /* the label to jump to is in stlist->name */
13.5564 - ffcall(sym,stlist->name,0);
13.5565 - } /* if */
13.5566 - } /* if */
13.5567 -
13.5568 - if (flabel>=0)
13.5569 - setlabel(flabel); /* condition was false, jump around the state switch */
13.5570 -
13.5571 - #if !defined SC_LIGHT
13.5572 - /* mark for documentation */
13.5573 - if (sc_status==statFIRST) {
13.5574 - char *str;
13.5575 - /* get the last list id attached to the function, this contains the source states */
13.5576 - assert(curfunc!=NULL);
13.5577 - if (curfunc->states!=NULL) {
13.5578 - stlist=curfunc->states->next;
13.5579 - assert(stlist!=NULL);
13.5580 - while (stlist->next!=NULL)
13.5581 - stlist=stlist->next;
13.5582 - listid=stlist->index;
13.5583 - } else {
13.5584 - listid=-1;
13.5585 - } /* if */
13.5586 - listindex=0;
13.5587 - length=strlen(name)+70; /* +70 for the fixed part "<transition ... />\n" */
13.5588 - /* see if there are any condition strings to attach */
13.5589 - for (index=0; (str=get_autolist(index))!=NULL; index++)
13.5590 - length+=strlen(str);
13.5591 - if ((doc=(char*)malloc(length*sizeof(char)))!=NULL) {
13.5592 - do {
13.5593 - sprintf(doc,"<transition target=\"%s\"",name);
13.5594 - if (listid>=0) {
13.5595 - /* get the source state */
13.5596 - stateindex=state_listitem(listid,listindex);
13.5597 - state=state_findid(stateindex);
13.5598 - assert(state!=NULL);
13.5599 - sprintf(doc+strlen(doc)," source=\"%s\"",state->name);
13.5600 - } /* if */
13.5601 - if (get_autolist(0)!=NULL) {
13.5602 - /* add the condition */
13.5603 - strcat(doc," condition=\"");
13.5604 - for (index=0; (str=get_autolist(index))!=NULL; index++) {
13.5605 - /* remove the ')' token that may be appended before detecting that the expression has ended */
13.5606 - if (*str!=')' || *(str+1)!='\0' || get_autolist(index+1)!=NULL)
13.5607 - strcat(doc,str);
13.5608 - } /* for */
13.5609 - strcat(doc,"\"");
13.5610 - } /* if */
13.5611 - strcat(doc,"/>\n");
13.5612 - insert_docstring(doc);
13.5613 - } while (listid>=0 && ++listindex<state_count(listid));
13.5614 - free(doc);
13.5615 - } /* if */
13.5616 - } /* if */
13.5617 - #endif
13.5618 - delete_autolisttable();
13.5619 -}
13.5620 -
13.5621 -
13.5622 -static void addwhile(int *ptr)
13.5623 -{
13.5624 - int k;
13.5625 -
13.5626 - ptr[wqBRK]=(int)declared; /* stack pointer (for "break") */
13.5627 - ptr[wqCONT]=(int)declared; /* for "continue", possibly adjusted later */
13.5628 - ptr[wqLOOP]=getlabel();
13.5629 - ptr[wqEXIT]=getlabel();
13.5630 - if (wqptr>=(wq+wqTABSZ-wqSIZE))
13.5631 - error(102,"loop table"); /* loop table overflow (too many active loops)*/
13.5632 - k=0;
13.5633 - while (k<wqSIZE){ /* copy "ptr" to while queue table */
13.5634 - *wqptr=*ptr;
13.5635 - wqptr+=1;
13.5636 - ptr+=1;
13.5637 - k+=1;
13.5638 - } /* while */
13.5639 -}
13.5640 -
13.5641 -static void delwhile(void)
13.5642 -{
13.5643 - if (wqptr>wq)
13.5644 - wqptr-=wqSIZE;
13.5645 -}
13.5646 -
13.5647 -static int *readwhile(void)
13.5648 -{
13.5649 - if (wqptr<=wq){
13.5650 - error(24); /* out of context */
13.5651 - return NULL;
13.5652 - } else {
13.5653 - return (wqptr-wqSIZE);
13.5654 - } /* if */
13.5655 -}
13.5656 -
14.1 --- a/compiler-init/sc2.c Sat Jul 15 05:02:38 2006 +0000
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,2817 +0,0 @@
14.4 -/* Pawn compiler - File input, preprocessing and lexical analysis functions
14.5 - *
14.6 - * Copyright (c) ITB CompuPhase, 1997-2006
14.7 - *
14.8 - * This software is provided "as-is", without any express or implied warranty.
14.9 - * In no event will the authors be held liable for any damages arising from
14.10 - * the use of this software.
14.11 - *
14.12 - * Permission is granted to anyone to use this software for any purpose,
14.13 - * including commercial applications, and to alter it and redistribute it
14.14 - * freely, subject to the following restrictions:
14.15 - *
14.16 - * 1. The origin of this software must not be misrepresented; you must not
14.17 - * claim that you wrote the original software. If you use this software in
14.18 - * a product, an acknowledgment in the product documentation would be
14.19 - * appreciated but is not required.
14.20 - * 2. Altered source versions must be plainly marked as such, and must not be
14.21 - * misrepresented as being the original software.
14.22 - * 3. This notice may not be removed or altered from any source distribution.
14.23 - *
14.24 - * Version: $Id: sc2.c 3590 2006-06-24 14:16:39Z thiadmer $
14.25 - */
14.26 -#include <assert.h>
14.27 -#include <stdio.h>
14.28 -#include <stdlib.h>
14.29 -#include <string.h>
14.30 -#include <ctype.h>
14.31 -#include <math.h>
14.32 -#include "lstring.h"
14.33 -#include "sc.h"
14.34 -#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
14.35 - #include <sclinux.h>
14.36 -#endif
14.37 -
14.38 -#if defined FORTIFY
14.39 - #include <alloc/fortify.h>
14.40 -#endif
14.41 -
14.42 -/* flags for litchar() */
14.43 -#define RAWMODE 1
14.44 -#define UTF8MODE 2
14.45 -static cell litchar(const unsigned char **lptr,int flags);
14.46 -static symbol *find_symbol(const symbol *root,const char *name,int fnumber,int automaton,int *cmptag);
14.47 -
14.48 -static void substallpatterns(unsigned char *line,int buffersize);
14.49 -static int match(char *st,int end);
14.50 -static int alpha(char c);
14.51 -
14.52 -#define SKIPMODE 1 /* bit field in "#if" stack */
14.53 -#define PARSEMODE 2 /* bit field in "#if" stack */
14.54 -#define HANDLED_ELSE 4 /* bit field in "#if" stack */
14.55 -#define SKIPPING (skiplevel>0 && (ifstack[skiplevel-1] & SKIPMODE)==SKIPMODE)
14.56 -
14.57 -static short icomment; /* currently in multiline comment? */
14.58 -static char ifstack[sCOMP_STACK]; /* "#if" stack */
14.59 -static short iflevel; /* nesting level if #if/#else/#endif */
14.60 -static short skiplevel; /* level at which we started skipping (including nested #if .. #endif) */
14.61 -static unsigned char term_expr[] = "";
14.62 -static int listline=-1; /* "current line" for the list file */
14.63 -
14.64 -
14.65 -/* pushstk & popstk
14.66 - *
14.67 - * Uses a LIFO stack to store information. The stack is used by doinclude(),
14.68 - * doswitch() (to hold the state of "swactive") and some other routines.
14.69 - *
14.70 - * Porting note: I made the bold assumption that an integer will not be
14.71 - * larger than a pointer (it may be smaller). That is, the stack element
14.72 - * is typedef'ed as a pointer type, but I also store integers on it. See
14.73 - * SC.H for "stkitem"
14.74 - *
14.75 - * Global references: stack,stkidx,stktop (private to pushstk(), popstk()
14.76 - * and clearstk())
14.77 - */
14.78 -static stkitem *stack=NULL;
14.79 -static int stkidx=0,stktop=0;
14.80 -
14.81 -SC_FUNC void pushstk(stkitem val)
14.82 -{
14.83 - assert(stkidx<=stktop);
14.84 - if (stkidx==stktop) {
14.85 - stkitem *newstack;
14.86 - int newsize= (stktop==0) ? 16 : 2*stktop;
14.87 - /* try to resize the stack */
14.88 - assert(newsize>stktop);
14.89 - newstack=(stkitem*)malloc(newsize*sizeof(stkitem));
14.90 - if (newstack==NULL)
14.91 - error(102,"parser stack"); /* stack overflow (recursive include?) */
14.92 - /* swap the stacks */
14.93 - memcpy(newstack,stack,stkidx*sizeof(stkitem));
14.94 - if (stack!=NULL)
14.95 - free(stack);
14.96 - stack=newstack;
14.97 - stktop=newsize;
14.98 - } /* if */
14.99 - assert(stkidx<stktop);
14.100 - stack[stkidx]=val;
14.101 - stkidx+=1;
14.102 -}
14.103 -
14.104 -SC_FUNC stkitem popstk(void)
14.105 -{
14.106 - if (stkidx==0) {
14.107 - stkitem s;
14.108 - s.i=-1; /* stack is empty */
14.109 - return s;
14.110 - } /* if */
14.111 - stkidx--;
14.112 - assert(stack!=NULL);
14.113 - return stack[stkidx];
14.114 -}
14.115 -
14.116 -SC_FUNC void clearstk(void)
14.117 -{
14.118 - assert(stack!=NULL || stktop==0);
14.119 - if (stack!=NULL) {
14.120 - free(stack);
14.121 - stack=NULL;
14.122 - stktop=0;
14.123 - } /* if */
14.124 - assert(stktop==0);
14.125 -}
14.126 -
14.127 -SC_FUNC int plungequalifiedfile(char *name)
14.128 -{
14.129 -static char *extensions[] = { ".inc", ".p", ".pawn" };
14.130 - FILE *fp;
14.131 - char *ext;
14.132 - int ext_idx;
14.133 -
14.134 - ext_idx=0;
14.135 - do {
14.136 - fp=(FILE*)pc_opensrc(name);
14.137 - ext=strchr(name,'\0'); /* save position */
14.138 - if (fp==NULL) {
14.139 - /* try to append an extension */
14.140 - strcpy(ext,extensions[ext_idx]);
14.141 - fp=(FILE*)pc_opensrc(name);
14.142 - if (fp==NULL)
14.143 - *ext='\0'; /* on failure, restore filename */
14.144 - } /* if */
14.145 - ext_idx++;
14.146 - } while (fp==NULL && ext_idx<(sizeof extensions / sizeof extensions[0]));
14.147 - if (fp==NULL) {
14.148 - *ext='\0'; /* restore filename */
14.149 - return FALSE;
14.150 - } /* if */
14.151 - PUSHSTK_P(inpf);
14.152 - PUSHSTK_P(inpfname); /* pointer to current file name */
14.153 - PUSHSTK_P(curlibrary);
14.154 - PUSHSTK_I(iflevel);
14.155 - assert(!SKIPPING);
14.156 - assert(skiplevel==iflevel); /* these two are always the same when "parsing" */
14.157 - PUSHSTK_I(sc_is_utf8);
14.158 - PUSHSTK_I(icomment);
14.159 - PUSHSTK_I(fcurrent);
14.160 - PUSHSTK_I(fline);
14.161 - inpfname=duplicatestring(name);/* set name of include file */
14.162 - if (inpfname==NULL)
14.163 - error(103); /* insufficient memory */
14.164 - inpf=fp; /* set input file pointer to include file */
14.165 - fnumber++;
14.166 - fline=0; /* set current line number to 0 */
14.167 - fcurrent=fnumber;
14.168 - icomment=0; /* not in a comment */
14.169 - insert_dbgfile(inpfname);
14.170 - setfiledirect(inpfname);
14.171 - listline=-1; /* force a #line directive when changing the file */
14.172 - sc_is_utf8=(short)scan_utf8(inpf,name);
14.173 - return TRUE;
14.174 -}
14.175 -
14.176 -SC_FUNC int plungefile(char *name,int try_currentpath,int try_includepaths)
14.177 -{
14.178 - int result=FALSE;
14.179 -
14.180 - if (try_currentpath) {
14.181 - result=plungequalifiedfile(name);
14.182 - if (!result) {
14.183 - /* failed to open the file in the active directory, try to open the file
14.184 - * in the same directory as the current file --but first check whether
14.185 - * there is a (relative) path for the current file
14.186 - */
14.187 - char *ptr;
14.188 - if ((ptr=strrchr(inpfname,DIRSEP_CHAR))!=0) {
14.189 - int len=(int)(ptr-inpfname)+1;
14.190 - if (len+strlen(name)<_MAX_PATH) {
14.191 - char path[_MAX_PATH];
14.192 - strlcpy(path,inpfname,len+1);
14.193 - strlcat(path,name,sizeof path);
14.194 - result=plungequalifiedfile(path);
14.195 - } /* if */
14.196 - } /* if */
14.197 - } /* if */
14.198 - } /* if */
14.199 -
14.200 - if (try_includepaths && name[0]!=DIRSEP_CHAR) {
14.201 - int i;
14.202 - char *ptr;
14.203 - for (i=0; !result && (ptr=get_path(i))!=NULL; i++) {
14.204 - char path[_MAX_PATH];
14.205 - strlcpy(path,ptr,sizeof path);
14.206 - strlcat(path,name,sizeof path);
14.207 - result=plungequalifiedfile(path);
14.208 - } /* while */
14.209 - } /* if */
14.210 - return result;
14.211 -}
14.212 -
14.213 -static void check_empty(const unsigned char *lptr)
14.214 -{
14.215 - /* verifies that the string contains only whitespace */
14.216 - while (*lptr<=' ' && *lptr!='\0')
14.217 - lptr++;
14.218 - if (*lptr!='\0')
14.219 - error(38); /* extra characters on line */
14.220 -}
14.221 -
14.222 -/* doinclude
14.223 - *
14.224 - * Gets the name of an include file, pushes the old file on the stack and
14.225 - * sets some options. This routine doesn't use lex(), since lex() doesn't
14.226 - * recognize file names (and directories).
14.227 - *
14.228 - * Global references: inpf (altered)
14.229 - * inpfname (altered)
14.230 - * fline (altered)
14.231 - * lptr (altered)
14.232 - */
14.233 -static void doinclude(int silent)
14.234 -{
14.235 - char name[_MAX_PATH];
14.236 - char symname[sNAMEMAX];
14.237 - char *ptr;
14.238 - char c;
14.239 - int i, result;
14.240 -
14.241 - while (*lptr<=' ' && *lptr!='\0') /* skip leading whitespace */
14.242 - lptr++;
14.243 - if (*lptr=='<' || *lptr=='\"'){
14.244 - c=(char)((*lptr=='\"') ? '\"' : '>'); /* termination character */
14.245 - lptr++;
14.246 - while (*lptr<=' ' && *lptr!='\0') /* skip whitespace after quote */
14.247 - lptr++;
14.248 - } else {
14.249 - c='\0';
14.250 - } /* if */
14.251 -
14.252 - i=0;
14.253 - while (*lptr!=c && *lptr!='\0' && i<sizeof name - 1) /* find the end of the string */
14.254 - name[i++]=*lptr++;
14.255 - while (i>0 && name[i-1]<=' ')
14.256 - i--; /* strip trailing whitespace */
14.257 - assert(i>=0 && i<sizeof name);
14.258 - name[i]='\0'; /* zero-terminate the string */
14.259 -
14.260 - if (*lptr!=c) { /* verify correct string termination */
14.261 - error(37); /* invalid string */
14.262 - return;
14.263 - } /* if */
14.264 - if (c!='\0')
14.265 - check_empty(lptr+1); /* verify that the rest of the line is whitespace */
14.266 -
14.267 - /* create a symbol from the name of the include file; this allows the system
14.268 - * to test for multiple inclusions
14.269 - */
14.270 - strcpy(symname,"_inc_");
14.271 - if ((ptr=strrchr(name,DIRSEP_CHAR))!=NULL)
14.272 - strlcat(symname,ptr+1,sizeof symname);
14.273 - else
14.274 - strlcat(symname,name,sizeof symname);
14.275 - if (find_symbol(&glbtab,symname,fcurrent,-1,NULL)==NULL) {
14.276 - /* constant is not present, so this file has not been included yet */
14.277 -
14.278 - /* Include files between "..." or without quotes are read from the current
14.279 - * directory, or from a list of "include directories". Include files
14.280 - * between <...> are only read from the list of include directories.
14.281 - */
14.282 - result=plungefile(name,(c!='>'),TRUE);
14.283 - if (result)
14.284 - add_constant(symname,1,sGLOBAL,0);
14.285 - else if (!silent)
14.286 - error(100,name); /* cannot read from ... (fatal error) */
14.287 - } /* if */
14.288 -}
14.289 -
14.290 -/* readline
14.291 - *
14.292 - * Reads in a new line from the input file pointed to by "inpf". readline()
14.293 - * concatenates lines that end with a \ with the next line. If no more data
14.294 - * can be read from the file, readline() attempts to pop off the previous file
14.295 - * from the stack. If that fails too, it sets "freading" to 0.
14.296 - *
14.297 - * Global references: inpf,fline,inpfname,freading,icomment (altered)
14.298 - */
14.299 -static void readline(unsigned char *line)
14.300 -{
14.301 - int i,num,cont;
14.302 - unsigned char *ptr;
14.303 -
14.304 - if (lptr==term_expr)
14.305 - return;
14.306 - num=sLINEMAX;
14.307 - cont=FALSE;
14.308 - do {
14.309 - if (inpf==NULL || pc_eofsrc(inpf)) {
14.310 - if (cont)
14.311 - error(49); /* invalid line continuation */
14.312 - if (inpf!=NULL && inpf!=inpf_org)
14.313 - pc_closesrc(inpf);
14.314 - i=POPSTK_I();
14.315 - if (i==-1) { /* All's done; popstk() returns "stack is empty" */
14.316 - freading=FALSE;
14.317 - *line='\0';
14.318 - /* when there is nothing more to read, the #if/#else stack should
14.319 - * be empty and we should not be in a comment
14.320 - */
14.321 - assert(iflevel>=0);
14.322 - if (iflevel>0)
14.323 - error(1,"#endif","-end of file-");
14.324 - else if (icomment!=0)
14.325 - error(1,"*/","-end of file-");
14.326 - return;
14.327 - } /* if */
14.328 - fline=i;
14.329 - fcurrent=(short)POPSTK_I();
14.330 - icomment=(short)POPSTK_I();
14.331 - sc_is_utf8=(short)POPSTK_I();
14.332 - iflevel=(short)POPSTK_I();
14.333 - skiplevel=iflevel; /* this condition held before including the file */
14.334 - assert(!SKIPPING); /* idem ditto */
14.335 - curlibrary=(constvalue *)POPSTK_P();
14.336 - free(inpfname); /* return memory allocated for the include file name */
14.337 - inpfname=(char *)POPSTK_P();
14.338 - inpf=(FILE *)POPSTK_P();
14.339 - insert_dbgfile(inpfname);
14.340 - setfiledirect(inpfname);
14.341 - listline=-1; /* force a #line directive when changing the file */
14.342 - } /* if */
14.343 -
14.344 - if (pc_readsrc(inpf,line,num)==NULL) {
14.345 - *line='\0'; /* delete line */
14.346 - cont=FALSE;
14.347 - } else {
14.348 - /* check whether to erase leading spaces */
14.349 - if (cont) {
14.350 - unsigned char *ptr=line;
14.351 - while (*ptr<=' ' && *ptr!='\0')
14.352 - ptr++;
14.353 - if (ptr!=line)
14.354 - memmove(line,ptr,strlen((char*)ptr)+1);
14.355 - } /* if */
14.356 - cont=FALSE;
14.357 - /* check whether a full line was read */
14.358 - if (strchr((char*)line,'\n')==NULL && !pc_eofsrc(inpf))
14.359 - error(75); /* line too long */
14.360 - /* check if the next line must be concatenated to this line */
14.361 - if ((ptr=(unsigned char*)strchr((char*)line,'\n'))==NULL)
14.362 - ptr=(unsigned char*)strchr((char*)line,'\r');
14.363 - if (ptr!=NULL && ptr>line) {
14.364 - assert(*(ptr+1)=='\0'); /* '\n' or '\r' should be last in the string */
14.365 - while (ptr>line && *ptr<=' ')
14.366 - ptr--; /* skip trailing whitespace */
14.367 - if (*ptr=='\\') {
14.368 - cont=TRUE;
14.369 - /* set '\a' at the position of '\\' to make it possible to check
14.370 - * for a line continuation in a single line comment (error 49)
14.371 - */
14.372 - *ptr++='\a';
14.373 - *ptr='\0'; /* erase '\n' (and any trailing whitespace) */
14.374 - } /* if */
14.375 - } /* if */
14.376 - num-=strlen((char*)line);
14.377 - line+=strlen((char*)line);
14.378 - } /* if */
14.379 - fline+=1;
14.380 - } while (num>=0 && cont);
14.381 -}
14.382 -
14.383 -/* stripcom
14.384 - *
14.385 - * Replaces all comments from the line by space characters. It updates
14.386 - * a global variable ("icomment") for multiline comments.
14.387 - *
14.388 - * This routine also supports the C++ extension for single line comments.
14.389 - * These comments are started with "//" and end at the end of the line.
14.390 - *
14.391 - * The function also detects (and manages) "documentation comments". The
14.392 - * global variable "icomment" is set to 2 for documentation comments.
14.393 - *
14.394 - * Global references: icomment (private to "stripcom")
14.395 - */
14.396 -static void stripcom(unsigned char *line)
14.397 -{
14.398 - char c;
14.399 - #if !defined SC_LIGHT
14.400 - #define COMMENT_LIMIT 100
14.401 - #define COMMENT_MARGIN 40 /* length of the longest word */
14.402 - char comment[COMMENT_LIMIT+COMMENT_MARGIN];
14.403 - int commentidx=0;
14.404 - int skipstar=TRUE;
14.405 - static int prev_singleline=FALSE;
14.406 - int singleline=prev_singleline;
14.407 -
14.408 - prev_singleline=FALSE; /* preset */
14.409 - #endif
14.410 -
14.411 - while (*line){
14.412 - if (icomment!=0) {
14.413 - if (*line=='*' && *(line+1)=='/') {
14.414 - #if !defined SC_LIGHT
14.415 - if (icomment==2) {
14.416 - assert(commentidx<COMMENT_LIMIT+COMMENT_MARGIN);
14.417 - comment[commentidx]='\0';
14.418 - if (strlen(comment)>0)
14.419 - insert_docstring(comment);
14.420 - } /* if */
14.421 - #endif
14.422 - icomment=0; /* comment has ended */
14.423 - *line=' '; /* replace '*' and '/' characters by spaces */
14.424 - *(line+1)=' ';
14.425 - line+=2;
14.426 - } else {
14.427 - if (*line=='/' && *(line+1)=='*')
14.428 - error(216); /* nested comment */
14.429 - #if !defined SC_LIGHT
14.430 - /* collect the comment characters in a string */
14.431 - if (icomment==2) {
14.432 - if (skipstar && (*line!='\0' && *line<=' ' || *line=='*')) {
14.433 - /* ignore leading whitespace and '*' characters */
14.434 - } else if (commentidx<COMMENT_LIMIT+COMMENT_MARGIN-1) {
14.435 - comment[commentidx++]=(char)((*line!='\n') ? *line : ' ');
14.436 - if (commentidx>COMMENT_LIMIT && *line!='\0' && *line<=' ') {
14.437 - comment[commentidx]='\0';
14.438 - insert_docstring(comment);
14.439 - commentidx=0;
14.440 - } /* if */
14.441 - skipstar=FALSE;
14.442 - } /* if */
14.443 - } /* if */
14.444 - #endif
14.445 - *line=' '; /* replace comments by spaces */
14.446 - line+=1;
14.447 - } /* if */
14.448 - } else {
14.449 - if (*line=='/' && *(line+1)=='*'){
14.450 - icomment=1; /* start comment */
14.451 - #if !defined SC_LIGHT
14.452 - /* there must be two "*" behind the slash and then white space */
14.453 - if (*(line+2)=='*' && *(line+3)<=' ') {
14.454 - /* if we are not in a function, we must attach the previous block
14.455 - * to the global documentation
14.456 - */
14.457 - if (curfunc==NULL && get_docstring(0)!=NULL)
14.458 - sc_attachdocumentation(NULL);
14.459 - icomment=2; /* documentation comment */
14.460 - } /* if */
14.461 - commentidx=0;
14.462 - skipstar=TRUE;
14.463 - #endif
14.464 - *line=' '; /* replace '/' and '*' characters by spaces */
14.465 - *(line+1)=' ';
14.466 - line+=2;
14.467 - if (icomment==2)
14.468 - *line++=' ';
14.469 - } else if (*line=='/' && *(line+1)=='/'){ /* comment to end of line */
14.470 - if (strchr((char*)line,'\a')!=NULL)
14.471 - error(49); /* invalid line continuation */
14.472 - #if !defined SC_LIGHT
14.473 - if (*(line+2)=='/' && *(line+3)<=' ') {
14.474 - /* documentation comment */
14.475 - char *str=(char*)line+3;
14.476 - char *end;
14.477 - while (*str<=' ' && *str!='\0')
14.478 - str++; /* skip leading whitespace */
14.479 - if ((end=strrchr(str,'\n'))!=NULL)
14.480 - *end='\0';/* erase trailing '\n' */
14.481 - /* if there is a disjunct block, we may need to attach the previous
14.482 - * block to the global documentation
14.483 - */
14.484 - if (!singleline && curfunc==NULL && get_docstring(0)!=NULL)
14.485 - sc_attachdocumentation(NULL);
14.486 - insert_docstring(str);
14.487 - prev_singleline=TRUE;
14.488 - } /* if */
14.489 - #endif
14.490 - *line++='\n'; /* put "newline" at first slash */
14.491 - *line='\0'; /* put "zero-terminator" at second slash */
14.492 - } else {
14.493 - if (*line=='\"' || *line=='\''){ /* leave literals unaltered */
14.494 - c=*line; /* ending quote, single or double */
14.495 - line+=1;
14.496 - while ((*line!=c || *(line-1)==sc_ctrlchar) && *line!='\0')
14.497 - line+=1;
14.498 - line+=1; /* skip final quote */
14.499 - } else {
14.500 - line+=1;
14.501 - } /* if */
14.502 - } /* if */
14.503 - } /* if */
14.504 - } /* while */
14.505 - #if !defined SC_LIGHT
14.506 - if (icomment==2) {
14.507 - assert(commentidx<COMMENT_LIMIT+COMMENT_MARGIN);
14.508 - comment[commentidx]='\0';
14.509 - if (strlen(comment)>0)
14.510 - insert_docstring(comment);
14.511 - } /* if */
14.512 - #endif
14.513 -}
14.514 -
14.515 -/* btoi
14.516 - *
14.517 - * Attempts to interpret a numeric symbol as a boolean value. On success
14.518 - * it returns the number of characters processed (so the line pointer can be
14.519 - * adjusted) and the value is stored in "val". Otherwise it returns 0 and
14.520 - * "val" is garbage.
14.521 - *
14.522 - * A boolean value must start with "0b"
14.523 - */
14.524 -static int btoi(cell *val,const unsigned char *curptr)
14.525 -{
14.526 - const unsigned char *ptr;
14.527 -
14.528 - *val=0;
14.529 - ptr=curptr;
14.530 - if (*ptr=='0' && *(ptr+1)=='b') {
14.531 - ptr+=2;
14.532 - while (*ptr=='0' || *ptr=='1' || *ptr=='_') {
14.533 - if (*ptr!='_')
14.534 - *val=(*val<<1) | (*ptr-'0');
14.535 - ptr++;
14.536 - } /* while */
14.537 - } else {
14.538 - return 0;
14.539 - } /* if */
14.540 - if (alphanum(*ptr)) /* number must be delimited by non-alphanumeric char */
14.541 - return 0;
14.542 - else
14.543 - return (int)(ptr-curptr);
14.544 -}
14.545 -
14.546 -/* dtoi
14.547 - *
14.548 - * Attempts to interpret a numeric symbol as a decimal value. On success
14.549 - * it returns the number of characters processed and the value is stored in
14.550 - * "val". Otherwise it returns 0 and "val" is garbage.
14.551 - */
14.552 -static int dtoi(cell *val,const unsigned char *curptr)
14.553 -{
14.554 - const unsigned char *ptr;
14.555 -
14.556 - *val=0;
14.557 - ptr=curptr;
14.558 - if (!isdigit(*ptr)) /* should start with digit */
14.559 - return 0;
14.560 - while (isdigit(*ptr) || *ptr=='_') {
14.561 - if (*ptr!='_')
14.562 - *val=(*val*10)+(*ptr-'0');
14.563 - ptr++;
14.564 - } /* while */
14.565 - if (alphanum(*ptr)) /* number must be delimited by non-alphanumerical */
14.566 - return 0;
14.567 - if (*ptr=='.' && isdigit(*(ptr+1)))
14.568 - return 0; /* but a fractional part must not be present */
14.569 - return (int)(ptr-curptr);
14.570 -}
14.571 -
14.572 -/* htoi
14.573 - *
14.574 - * Attempts to interpret a numeric symbol as a hexadecimal value. On
14.575 - * success it returns the number of characters processed and the value is
14.576 - * stored in "val". Otherwise it return 0 and "val" is garbage.
14.577 - */
14.578 -static int htoi(cell *val,const unsigned char *curptr)
14.579 -{
14.580 - const unsigned char *ptr;
14.581 -
14.582 - *val=0;
14.583 - ptr=curptr;
14.584 - if (!isdigit(*ptr)) /* should start with digit */
14.585 - return 0;
14.586 - if (*ptr=='0' && *(ptr+1)=='x') { /* C style hexadecimal notation */
14.587 - ptr+=2;
14.588 - while (ishex(*ptr) || *ptr=='_') {
14.589 - if (*ptr!='_') {
14.590 - assert(ishex(*ptr));
14.591 - *val= *val<<4;
14.592 - if (isdigit(*ptr))
14.593 - *val+= (*ptr-'0');
14.594 - else
14.595 - *val+= (tolower(*ptr)-'a'+10);
14.596 - } /* if */
14.597 - ptr++;
14.598 - } /* while */
14.599 - } else {
14.600 - return 0;
14.601 - } /* if */
14.602 - if (alphanum(*ptr))
14.603 - return 0;
14.604 - else
14.605 - return (int)(ptr-curptr);
14.606 -}
14.607 -
14.608 -#if defined __GNUC__
14.609 -static double pow10(int value)
14.610 -{
14.611 - double res=1.0;
14.612 - while (value>=4) {
14.613 - res*=10000.0;
14.614 - value-=5;
14.615 - } /* while */
14.616 - while (value>=2) {
14.617 - res*=100.0;
14.618 - value-=2;
14.619 - } /* while */
14.620 - while (value>=1) {
14.621 - res*=10.0;
14.622 - value-=1;
14.623 - } /* while */
14.624 - return res;
14.625 -}
14.626 -#endif
14.627 -
14.628 -/* ftoi
14.629 - *
14.630 - * Attempts to interpret a numeric symbol as a rational number, either as
14.631 - * IEEE 754 single/double precision floating point or as a fixed point integer.
14.632 - * On success it returns the number of characters processed and the value is
14.633 - * stored in "val". Otherwise it returns 0 and "val" is unchanged.
14.634 - *
14.635 - * Pawn has stricter definition for rational numbers than most:
14.636 - * o the value must start with a digit; ".5" is not a valid number, you
14.637 - * should write "0.5"
14.638 - * o a period must appear in the value, even if an exponent is given; "2e3"
14.639 - * is not a valid number, you should write "2.0e3"
14.640 - * o at least one digit must follow the period; "6." is not a valid number,
14.641 - * you should write "6.0"
14.642 - */
14.643 -static int ftoi(cell *val,const unsigned char *curptr)
14.644 -{
14.645 - const unsigned char *ptr;
14.646 - double fnum,ffrac,fmult;
14.647 - unsigned long dnum,dbase;
14.648 - int i, ignore;
14.649 -
14.650 - assert(rational_digits>=0 && rational_digits<9);
14.651 - for (i=0,dbase=1; i<rational_digits; i++)
14.652 - dbase*=10;
14.653 - fnum=0.0;
14.654 - dnum=0L;
14.655 - ptr=curptr;
14.656 - if (!isdigit(*ptr)) /* should start with digit */
14.657 - return 0;
14.658 - while (isdigit(*ptr) || *ptr=='_') {
14.659 - if (*ptr!='_') {
14.660 - fnum=(fnum*10.0)+(*ptr-'0');
14.661 - dnum=(dnum*10L)+(*ptr-'0')*dbase;
14.662 - } /* if */
14.663 - ptr++;
14.664 - } /* while */
14.665 - if (*ptr!='.')
14.666 - return 0; /* there must be a period */
14.667 - ptr++;
14.668 - if (!isdigit(*ptr)) /* there must be at least one digit after the dot */
14.669 - return 0;
14.670 - ffrac=0.0;
14.671 - fmult=1.0;
14.672 - ignore=FALSE;
14.673 - while (isdigit(*ptr) || *ptr=='_') {
14.674 - if (*ptr!='_') {
14.675 - ffrac=(ffrac*10.0)+(*ptr-'0');
14.676 - fmult=fmult/10.0;
14.677 - dbase /= 10L;
14.678 - dnum += (*ptr-'0')*dbase;
14.679 - if (dbase==0L && sc_rationaltag && rational_digits>0 && !ignore) {
14.680 - error(222); /* number of digits exceeds rational number precision */
14.681 - ignore=TRUE;
14.682 - } /* if */
14.683 - } /* if */
14.684 - ptr++;
14.685 - } /* while */
14.686 - fnum += ffrac*fmult; /* form the number so far */
14.687 - if (*ptr=='e') { /* optional fractional part */
14.688 - int exp,sign;
14.689 - ptr++;
14.690 - if (*ptr=='-') {
14.691 - sign=-1;
14.692 - ptr++;
14.693 - } else {
14.694 - sign=1;
14.695 - } /* if */
14.696 - if (!isdigit(*ptr)) /* 'e' should be followed by a digit */
14.697 - return 0;
14.698 - exp=0;
14.699 - while (isdigit(*ptr)) {
14.700 - exp=(exp*10)+(*ptr-'0');
14.701 - ptr++;
14.702 - } /* while */
14.703 - #if defined __GNUC__
14.704 - fmult=pow10(exp*sign);
14.705 - #else
14.706 - fmult=pow(10,exp*sign);
14.707 - #endif
14.708 - fnum *= fmult;
14.709 - dnum *= (unsigned long)(fmult+0.5);
14.710 - } /* if */
14.711 -
14.712 - /* decide how to store the number */
14.713 - if (sc_rationaltag==0) {
14.714 - error(70); /* rational number support was not enabled */
14.715 - *val=0;
14.716 - } else if (rational_digits==0) {
14.717 - /* floating point */
14.718 - #if PAWN_CELL_SIZE==32
14.719 - float value=(float)fnum;
14.720 - *val=*((cell *)&value);
14.721 - #if 0 /* SourceMod - not needed */
14.722 - /* I assume that the C/C++ compiler stores "float" values in IEEE 754
14.723 - * format (as mandated in the ANSI standard). Test this assumption
14.724 - * anyway.
14.725 - * Note: problems have been reported with GCC 3.2.x, version 3.3.x works.
14.726 - */
14.727 - { float test1 = 0.0, test2 = 50.0, test3 = -50.0;
14.728 - uint32_t bit = 1;
14.729 - /* test 0.0 == all bits 0 */
14.730 - assert(*(uint32_t*)&test1==0x00000000L);
14.731 - /* test sign & magnitude format */
14.732 - assert(((*(uint32_t*)&test2) ^ (*(uint32_t*)&test3)) == (bit << (PAWN_CELL_SIZE-1)));
14.733 - /* test a known value */
14.734 - assert(*(uint32_t*)&test2==0x42480000L);
14.735 - }
14.736 - #endif
14.737 - #elif PAWN_CELL_SIZE==64
14.738 - *val=*((cell *)&fnum);
14.739 - #if 0 /* SourceMod - not needed */
14.740 - /* I assume that the C/C++ compiler stores "double" values in IEEE 754
14.741 - * format (as mandated in the ANSI standard).
14.742 - */
14.743 - { float test1 = 0.0, test2 = 50.0, test3 = -50.0;
14.744 - uint64_t bit = 1;
14.745 - /* test 0.0 == all bits 0 */
14.746 - assert(*(uint64_t*)&test1==0x00000000L);
14.747 - /* test sign & magnitude format */
14.748 - assert(((*(uint64_t*)&test2) ^ (*(uint64_t*)&test3)) == (bit << (PAWN_CELL_SIZE-1)));
14.749 - }
14.750 - #endif
14.751 - #else
14.752 - #error Unsupported cell size
14.753 - #endif
14.754 - } else {
14.755 - /* fixed point */
14.756 - *val=(cell)dnum;
14.757 - } /* if */
14.758 -
14.759 - return (int)(ptr-curptr);
14.760 -}
14.761 -
14.762 -/* number
14.763 - *
14.764 - * Reads in a number (binary, decimal or hexadecimal). It returns the number
14.765 - * of characters processed or 0 if the symbol couldn't be interpreted as a
14.766 - * number (in this case the argument "val" remains unchanged). This routine
14.767 - * relies on the 'early dropout' implementation of the logical or (||)
14.768 - * operator.
14.769 - *
14.770 - * Note: the routine doesn't check for a sign (+ or -). The - is checked
14.771 - * for at "hier2()" (in fact, it is viewed as an operator, not as a
14.772 - * sign) and the + is invalid (as in K&R C, and unlike ANSI C).
14.773 - */
14.774 -static int number(cell *val,const unsigned char *curptr)
14.775 -{
14.776 - int i;
14.777 - cell value;
14.778 -
14.779 - if ((i=btoi(&value,curptr))!=0 /* binary? */
14.780 - || (i=htoi(&value,curptr))!=0 /* hexadecimal? */
14.781 - || (i=dtoi(&value,curptr))!=0) /* decimal? */
14.782 - {
14.783 - *val=value;
14.784 - return i;
14.785 - } else {
14.786 - return 0; /* else not a number */
14.787 - } /* if */
14.788 -}
14.789 -
14.790 -static void chrcat(char *str,char chr)
14.791 -{
14.792 - str=strchr(str,'\0');
14.793 - *str++=chr;
14.794 - *str='\0';
14.795 -}
14.796 -
14.797 -static int preproc_expr(cell *val,int *tag)
14.798 -{
14.799 - int result;
14.800 - int index;
14.801 - cell code_index;
14.802 - char *term;
14.803 -
14.804 - /* Disable staging; it should be disabled already because
14.805 - * expressions may not be cut off half-way between conditional
14.806 - * compilations. Reset the staging index, but keep the code
14.807 - * index.
14.808 - */
14.809 - if (stgget(&index,&code_index)) {
14.810 - error(57); /* unfinished expression */
14.811 - stgdel(0,code_index);
14.812 - stgset(FALSE);
14.813 - } /* if */
14.814 - assert((lptr-pline)<(int)strlen((char*)pline)); /* lptr must point inside the string */
14.815 - #if !defined NO_DEFINE
14.816 - /* preprocess the string */
14.817 - substallpatterns(pline,sLINEMAX);
14.818 - assert((lptr-pline)<(int)strlen((char*)pline)); /* lptr must STILL point inside the string */
14.819 - #endif
14.820 - /* append a special symbol to the string, so the expression
14.821 - * analyzer won't try to read a next line when it encounters
14.822 - * an end-of-line
14.823 - */
14.824 - assert(strlen((char*)pline)<sLINEMAX);
14.825 - term=strchr((char*)pline,'\0');
14.826 - assert(term!=NULL);
14.827 - chrcat((char*)pline,PREPROC_TERM); /* the "DEL" code (see SC.H) */
14.828 - result=constexpr(val,tag,NULL); /* get value (or 0 on error) */
14.829 - *term='\0'; /* erase the token (if still present) */
14.830 - lexclr(FALSE); /* clear any "pushed" tokens */
14.831 - return result;
14.832 -}
14.833 -
14.834 -/* getstring
14.835 - * Returns returns a pointer behind the closing quote or to the other
14.836 - * character that caused the input to be ended.
14.837 - */
14.838 -static const unsigned char *getstring(unsigned char *dest,int max,const unsigned char *line)
14.839 -{
14.840 - assert(dest!=NULL && line!=NULL);
14.841 - *dest='\0';
14.842 - while (*line<=' ' && *line!='\0')
14.843 - line++; /* skip whitespace */
14.844 - if (*line=='"') {
14.845 - int len=0;
14.846 - line++; /* skip " */
14.847 - while (*line!='"' && *line!='\0') {
14.848 - if (len<max-1)
14.849 - dest[len++]=*line;
14.850 - line++;
14.851 - } /* if */
14.852 - dest[len]='\0';
14.853 - if (*line=='"')
14.854 - line++; /* skip closing " */
14.855 - else
14.856 - error(37); /* invalid string */
14.857 - } else {
14.858 - error(37); /* invalid string */
14.859 - } /* if */
14.860 - return line;
14.861 -}
14.862 -
14.863 -enum {
14.864 - CMD_NONE,
14.865 - CMD_TERM,
14.866 - CMD_EMPTYLINE,
14.867 - CMD_CONDFALSE,
14.868 - CMD_INCLUDE,
14.869 - CMD_DEFINE,
14.870 - CMD_IF,
14.871 - CMD_DIRECTIVE,
14.872 -};
14.873 -
14.874 -/* command
14.875 - *
14.876 - * Recognizes the compiler directives. The function returns:
14.877 - * CMD_NONE the line must be processed
14.878 - * CMD_TERM a pending expression must be completed before processing further lines
14.879 - * Other value: the line must be skipped, because:
14.880 - * CMD_CONDFALSE false "#if.." code
14.881 - * CMD_EMPTYLINE line is empty
14.882 - * CMD_INCLUDE the line contains a #include directive
14.883 - * CMD_DEFINE the line contains a #subst directive
14.884 - * CMD_IF the line contains a #if/#else/#endif directive
14.885 - * CMD_DIRECTIVE the line contains some other compiler directive
14.886 - *
14.887 - * Global variables: iflevel, ifstack (altered)
14.888 - * lptr (altered)
14.889 - */
14.890 -static int command(void)
14.891 -{
14.892 - int tok,ret;
14.893 - cell val;
14.894 - char *str;
14.895 - int index;
14.896 - cell code_index;
14.897 -
14.898 - while (*lptr<=' ' && *lptr!='\0')
14.899 - lptr+=1;
14.900 - if (*lptr=='\0')
14.901 - return CMD_EMPTYLINE; /* empty line */
14.902 - if (*lptr!='#')
14.903 - return SKIPPING ? CMD_CONDFALSE : CMD_NONE; /* it is not a compiler directive */
14.904 - /* compiler directive found */
14.905 - indent_nowarn=TRUE; /* allow loose indentation" */
14.906 - lexclr(FALSE); /* clear any "pushed" tokens */
14.907 - /* on a pending expression, force to return a silent ';' token and force to
14.908 - * re-read the line
14.909 - */
14.910 - if (!sc_needsemicolon && stgget(&index,&code_index)) {
14.911 - lptr=term_expr;
14.912 - return CMD_TERM;
14.913 - } /* if */
14.914 - tok=lex(&val,&str);
14.915 - ret=SKIPPING ? CMD_CONDFALSE : CMD_DIRECTIVE; /* preset 'ret' to CMD_DIRECTIVE (most common case) */
14.916 - switch (tok) {
14.917 - case tpIF: /* conditional compilation */
14.918 - ret=CMD_IF;
14.919 - assert(iflevel>=0);
14.920 - if (iflevel>=sCOMP_STACK)
14.921 - error(102,"Conditional compilation stack"); /* table overflow */
14.922 - iflevel++;
14.923 - if (SKIPPING)
14.924 - break; /* break out of switch */
14.925 - skiplevel=iflevel;
14.926 - preproc_expr(&val,NULL); /* get value (or 0 on error) */
14.927 - ifstack[iflevel-1]=(char)(val ? PARSEMODE : SKIPMODE);
14.928 - check_empty(lptr);
14.929 - break;
14.930 - case tpELSE:
14.931 - case tpELSEIF:
14.932 - ret=CMD_IF;
14.933 - assert(iflevel>=0);
14.934 - if (iflevel==0) {
14.935 - error(26); /* no matching #if */
14.936 - errorset(sRESET,0);
14.937 - } else {
14.938 - /* check for earlier #else */
14.939 - if ((ifstack[iflevel-1] & HANDLED_ELSE)==HANDLED_ELSE) {
14.940 - if (tok==tpELSEIF)
14.941 - error(61); /* #elseif directive may not follow an #else */
14.942 - else
14.943 - error(60); /* multiple #else directives between #if ... #endif */
14.944 - errorset(sRESET,0);
14.945 - } else {
14.946 - assert(iflevel>0);
14.947 - /* if there has been a "parse mode" on this level, set "skip mode",
14.948 - * otherwise, clear "skip mode"
14.949 - */
14.950 - if ((ifstack[iflevel-1] & PARSEMODE)==PARSEMODE) {
14.951 - /* there has been a parse mode already on this level, so skip the rest */
14.952 - ifstack[iflevel-1] |= (char)SKIPMODE;
14.953 - } else {
14.954 - /* previous conditions were all FALSE */
14.955 - if (tok==tpELSEIF) {
14.956 - /* get new expression */
14.957 - preproc_expr(&val,NULL); /* get value (or 0 on error) */
14.958 - ifstack[iflevel-1]=(char)(val ? PARSEMODE : SKIPMODE);
14.959 - } else {
14.960 - /* a simple #else, clear skip mode */
14.961 - ifstack[iflevel-1] &= (char)~SKIPMODE;
14.962 - } /* if */
14.963 - } /* if */
14.964 - } /* if */
14.965 - } /* if */
14.966 - check_empty(lptr);
14.967 - break;
14.968 - case tpENDIF:
14.969 - ret=CMD_IF;
14.970 - if (iflevel==0){
14.971 - error(26); /* no matching "#if" */
14.972 - errorset(sRESET,0);
14.973 - } else {
14.974 - iflevel--;
14.975 - if (iflevel<skiplevel)
14.976 - skiplevel=iflevel;
14.977 - } /* if */
14.978 - check_empty(lptr);
14.979 - break;
14.980 - case tINCLUDE: /* #include directive */
14.981 - case tpTRYINCLUDE:
14.982 - ret=CMD_INCLUDE;
14.983 - if (!SKIPPING)
14.984 - doinclude(tok==tpTRYINCLUDE);
14.985 - break;
14.986 - case tpFILE:
14.987 - if (!SKIPPING) {
14.988 - char pathname[_MAX_PATH];
14.989 - lptr=getstring((unsigned char*)pathname,sizeof pathname,lptr);
14.990 - if (strlen(pathname)>0) {
14.991 - free(inpfname);
14.992 - inpfname=duplicatestring(pathname);
14.993 - if (inpfname==NULL)
14.994 - error(103); /* insufficient memory */
14.995 - } /* if */
14.996 - } /* if */
14.997 - check_empty(lptr);
14.998 - break;
14.999 - case tpLINE:
14.1000 - if (!SKIPPING) {
14.1001 - if (lex(&val,&str)!=tNUMBER)
14.1002 - error(8); /* invalid/non-constant expression */
14.1003 - fline=(int)val;
14.1004 - } /* if */
14.1005 - check_empty(lptr);
14.1006 - break;
14.1007 - case tpASSERT:
14.1008 - if (!SKIPPING && (sc_debug & sCHKBOUNDS)!=0) {
14.1009 - for (str=(char*)lptr; *str<=' ' && *str!='\0'; str++)
14.1010 - /* nothing */; /* save start of expression */
14.1011 - preproc_expr(&val,NULL); /* get constant expression (or 0 on error) */
14.1012 - if (!val)
14.1013 - error(110,str); /* assertion failed */
14.1014 - check_empty(lptr);
14.1015 - } /* if */
14.1016 - break;
14.1017 - case tpPRAGMA:
14.1018 - if (!SKIPPING) {
14.1019 - if (lex(&val,&str)==tSYMBOL) {
14.1020 - if (strcmp(str,"amxlimit")==0) {
14.1021 - preproc_expr(&pc_amxlimit,NULL);
14.1022 - } else if (strcmp(str,"amxram")==0) {
14.1023 - preproc_expr(&pc_amxram,NULL);
14.1024 - } else if (strcmp(str,"codepage")==0) {
14.1025 - char name[sNAMEMAX+1];
14.1026 - while (*lptr<=' ' && *lptr!='\0')
14.1027 - lptr++;
14.1028 - if (*lptr=='"') {
14.1029 - lptr=getstring((unsigned char*)name,sizeof name,lptr);
14.1030 - } else {
14.1031 - int i;
14.1032 - for (i=0; i<sizeof name && alphanum(*lptr); i++,lptr++)
14.1033 - name[i]=*lptr;
14.1034 - name[i]='\0';
14.1035 - } /* if */
14.1036 - if (!cp_set(name))
14.1037 - error(108); /* codepage mapping file not found */
14.1038 - } else if (strcmp(str,"compress")==0) {
14.1039 - cell val;
14.1040 - preproc_expr(&val,NULL);
14.1041 - sc_compress=(int)val; /* switch code packing on/off */
14.1042 - } else if (strcmp(str,"ctrlchar")==0) {
14.1043 - while (*lptr<=' ' && *lptr!='\0')
14.1044 - lptr++;
14.1045 - if (*lptr=='\0') {
14.1046 - sc_ctrlchar=sc_ctrlchar_org;
14.1047 - } else {
14.1048 - if (lex(&val,&str)!=tNUMBER)
14.1049 - error(27); /* invalid character constant */
14.1050 - sc_ctrlchar=(char)val;
14.1051 - } /* if */
14.1052 - } else if (strcmp(str,"depricated")==0) {
14.1053 - while (*lptr<=' ' && *lptr!='\0')
14.1054 - lptr++;
14.1055 - pc_depricate=(char*)malloc(strlen((char*)lptr)+1);
14.1056 - if (pc_depricate!=NULL)
14.1057 - strcpy(pc_depricate,(char*)lptr);
14.1058 - lptr=(unsigned char*)strchr((char*)lptr,'\0'); /* skip to end (ignore "extra characters on line") */
14.1059 - } else if (strcmp(str,"dynamic")==0) {
14.1060 - preproc_expr(&pc_stksize,NULL);
14.1061 - } else if (strcmp(str,"library")==0) {
14.1062 - char name[sNAMEMAX+1];
14.1063 - while (*lptr<=' ' && *lptr!='\0')
14.1064 - lptr++;
14.1065 - if (*lptr=='"') {
14.1066 - lptr=getstring((unsigned char*)name,sizeof name,lptr);
14.1067 - } else {
14.1068 - int i;
14.1069 - for (i=0; i<sizeof name && (alphanum(*lptr) || *lptr=='-'); i++,lptr++)
14.1070 - name[i]=*lptr;
14.1071 - name[i]='\0';
14.1072 - } /* if */
14.1073 - if (strlen(name)==0) {
14.1074 - curlibrary=NULL;
14.1075 - } else if (strcmp(name,"-")==0) {
14.1076 - pc_addlibtable=FALSE;
14.1077 - } else {
14.1078 - /* add the name if it does not yet exist in the table */
14.1079 - if (find_constval(&libname_tab,name,0)==NULL)
14.1080 - curlibrary=append_constval(&libname_tab,name,0,0);
14.1081 - } /* if */
14.1082 -#if 0 /* more unused */
14.1083 - } else if (strcmp(str,"pack")==0) {
14.1084 - cell val;
14.1085 - preproc_expr(&val,NULL); /* default = packed/unpacked */
14.1086 - sc_packstr=(int)val;
14.1087 -#endif
14.1088 - } else if (strcmp(str,"rational")==0) {
14.1089 - char name[sNAMEMAX+1];
14.1090 - cell digits=0;
14.1091 - int i;
14.1092 - /* first gather all information, start with the tag name */
14.1093 - while (*lptr<=' ' && *lptr!='\0')
14.1094 - lptr++;
14.1095 - for (i=0; i<sizeof name && alphanum(*lptr); i++,lptr++)
14.1096 - name[i]=*lptr;
14.1097 - name[i]='\0';
14.1098 - /* then the precision (for fixed point arithmetic) */
14.1099 - while (*lptr<=' ' && *lptr!='\0')
14.1100 - lptr++;
14.1101 - if (*lptr=='(') {
14.1102 - preproc_expr(&digits,NULL);
14.1103 - if (digits<=0 || digits>9) {
14.1104 - error(68); /* invalid rational number precision */
14.1105 - digits=0;
14.1106 - } /* if */
14.1107 - if (*lptr==')')
14.1108 - lptr++;
14.1109 - } /* if */
14.1110 - /* add the tag (make it public) and check the values */
14.1111 - i=pc_addtag(name);
14.1112 - exporttag(i);
14.1113 - if (sc_rationaltag==0 || (sc_rationaltag==i && rational_digits==(int)digits)) {
14.1114 - sc_rationaltag=i;
14.1115 - rational_digits=(int)digits;
14.1116 - } else {
14.1117 - error(69); /* rational number format already set, can only be set once */
14.1118 - } /* if */
14.1119 - } else if (strcmp(str,"semicolon")==0) {
14.1120 - cell val;
14.1121 - preproc_expr(&val,NULL);
14.1122 - sc_needsemicolon=(int)val;
14.1123 - } else if (strcmp(str,"tabsize")==0) {
14.1124 - cell val;
14.1125 - preproc_expr(&val,NULL);
14.1126 - sc_tabsize=(int)val;
14.1127 - } else if (strcmp(str,"align")==0) {
14.1128 - sc_alignnext=TRUE;
14.1129 - } else if (strcmp(str,"unused")==0) {
14.1130 - char name[sNAMEMAX+1];
14.1131 - int i,comma;
14.1132 - symbol *sym;
14.1133 - do {
14.1134 - /* get the name */
14.1135 - while (*lptr<=' ' && *lptr!='\0')
14.1136 - lptr++;
14.1137 - for (i=0; i<sizeof name && alphanum(*lptr); i++,lptr++)
14.1138 - name[i]=*lptr;
14.1139 - name[i]='\0';
14.1140 - /* get the symbol */
14.1141 - sym=findloc(name);
14.1142 - if (sym==NULL)
14.1143 - sym=findglb(name,sSTATEVAR);
14.1144 - if (sym!=NULL) {
14.1145 - sym->usage |= uREAD;
14.1146 - if (sym->ident==iVARIABLE || sym->ident==iREFERENCE
14.1147 - || sym->ident==iARRAY || sym->ident==iREFARRAY)
14.1148 - sym->usage |= uWRITTEN;
14.1149 - } else {
14.1150 - error(17,name); /* undefined symbol */
14.1151 - } /* if */
14.1152 - /* see if a comma follows the name */
14.1153 - while (*lptr<=' ' && *lptr!='\0')
14.1154 - lptr++;
14.1155 - comma= (*lptr==',');
14.1156 - if (comma)
14.1157 - lptr++;
14.1158 - } while (comma);
14.1159 - } else {
14.1160 - error(207); /* unknown #pragma */
14.1161 - } /* if */
14.1162 - } else {
14.1163 - error(207); /* unknown #pragma */
14.1164 - } /* if */
14.1165 - check_empty(lptr);
14.1166 - } /* if */
14.1167 - break;
14.1168 - case tpENDINPUT:
14.1169 - case tpENDSCRPT:
14.1170 - if (!SKIPPING) {
14.1171 - check_empty(lptr);
14.1172 - assert(inpf!=NULL);
14.1173 - if (inpf!=inpf_org)
14.1174 - pc_closesrc(inpf);
14.1175 - inpf=NULL;
14.1176 - } /* if */
14.1177 - break;
14.1178 -#if !defined NOEMIT
14.1179 - case tpEMIT: {
14.1180 - /* write opcode to output file */
14.1181 - char name[40];
14.1182 - int i;
14.1183 - while (*lptr<=' ' && *lptr!='\0')
14.1184 - lptr++;
14.1185 - for (i=0; i<40 && (isalpha(*lptr) || *lptr=='.'); i++,lptr++)
14.1186 - name[i]=(char)tolower(*lptr);
14.1187 - name[i]='\0';
14.1188 - stgwrite("\t");
14.1189 - stgwrite(name);
14.1190 - stgwrite(" ");
14.1191 - code_idx+=opcodes(1);
14.1192 - /* write parameter (if any) */
14.1193 - while (*lptr<=' ' && *lptr!='\0')
14.1194 - lptr++;
14.1195 - if (*lptr!='\0') {
14.1196 - symbol *sym;
14.1197 - tok=lex(&val,&str);
14.1198 - switch (tok) {
14.1199 - case tNUMBER:
14.1200 - case tRATIONAL:
14.1201 - outval(val,FALSE);
14.1202 - code_idx+=opargs(1);
14.1203 - break;
14.1204 - case tSYMBOL:
14.1205 - sym=findloc(str);
14.1206 - if (sym==NULL)
14.1207 - sym=findglb(str,sSTATEVAR);
14.1208 - if (sym==NULL || sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0) {
14.1209 - error(17,str); /* undefined symbol */
14.1210 - } else {
14.1211 - outval(sym->addr,FALSE);
14.1212 - /* mark symbol as "used", unknown whether for read or write */
14.1213 - markusage(sym,uREAD | uWRITTEN);
14.1214 - code_idx+=opargs(1);
14.1215 - } /* if */
14.1216 - break;
14.1217 - default: {
14.1218 - char s2[20];
14.1219 - extern char *sc_tokens[];/* forward declaration */
14.1220 - if (tok<256)
14.1221 - sprintf(s2,"%c",(char)tok);
14.1222 - else
14.1223 - strcpy(s2,sc_tokens[tok-tFIRST]);
14.1224 - error(1,sc_tokens[tSYMBOL-tFIRST],s2);
14.1225 - break;
14.1226 - } /* case */
14.1227 - } /* switch */
14.1228 - } /* if */
14.1229 - stgwrite("\n");
14.1230 - check_empty(lptr);
14.1231 - break;
14.1232 - } /* case */
14.1233 -#endif
14.1234 -#if !defined NO_DEFINE
14.1235 - case tpDEFINE: {
14.1236 - ret=CMD_DEFINE;
14.1237 - if (!SKIPPING) {
14.1238 - char *pattern,*substitution;
14.1239 - const unsigned char *start,*end;
14.1240 - int count,prefixlen;
14.1241 - stringpair *def;
14.1242 - /* find the pattern to match */
14.1243 - while (*lptr<=' ' && *lptr!='\0')
14.1244 - lptr++;
14.1245 - start=lptr; /* save starting point of the match pattern */
14.1246 - count=0;
14.1247 - while (*lptr>' ' && *lptr!='\0') {
14.1248 - litchar(&lptr,0); /* litchar() advances "lptr" and handles escape characters */
14.1249 - count++;
14.1250 - } /* while */
14.1251 - end=lptr;
14.1252 - /* check pattern to match */
14.1253 - if (!alpha(*start)) {
14.1254 - error(74); /* pattern must start with an alphabetic character */
14.1255 - break;
14.1256 - } /* if */
14.1257 - /* store matched pattern */
14.1258 - pattern=(char*)malloc(count+1);
14.1259 - if (pattern==NULL)
14.1260 - error(103); /* insufficient memory */
14.1261 - lptr=start;
14.1262 - count=0;
14.1263 - while (lptr!=end) {
14.1264 - assert(lptr<end);
14.1265 - assert(*lptr!='\0');
14.1266 - pattern[count++]=(char)litchar(&lptr,0);
14.1267 - } /* while */
14.1268 - pattern[count]='\0';
14.1269 - /* special case, erase trailing variable, because it could match anything */
14.1270 - if (count>=2 && isdigit(pattern[count-1]) && pattern[count-2]=='%')
14.1271 - pattern[count-2]='\0';
14.1272 - /* find substitution string */
14.1273 - while (*lptr<=' ' && *lptr!='\0')
14.1274 - lptr++;
14.1275 - start=lptr; /* save starting point of the match pattern */
14.1276 - count=0;
14.1277 - end=NULL;
14.1278 - while (*lptr!='\0') {
14.1279 - /* keep position of the start of trailing whitespace */
14.1280 - if (*lptr<=' ') {
14.1281 - if (end==NULL)
14.1282 - end=lptr;
14.1283 - } else {
14.1284 - end=NULL;
14.1285 - } /* if */
14.1286 - count++;
14.1287 - lptr++;
14.1288 - } /* while */
14.1289 - if (end==NULL)
14.1290 - end=lptr;
14.1291 - /* store matched substitution */
14.1292 - substitution=(char*)malloc(count+1); /* +1 for '\0' */
14.1293 - if (substitution==NULL)
14.1294 - error(103); /* insufficient memory */
14.1295 - lptr=start;
14.1296 - count=0;
14.1297 - while (lptr!=end) {
14.1298 - assert(lptr<end);
14.1299 - assert(*lptr!='\0');
14.1300 - substitution[count++]=*lptr++;
14.1301 - } /* while */
14.1302 - substitution[count]='\0';
14.1303 - /* check whether the definition already exists */
14.1304 - for (prefixlen=0,start=(unsigned char*)pattern; alphanum(*start); prefixlen++,start++)
14.1305 - /* nothing */;
14.1306 - assert(prefixlen>0);
14.1307 - if ((def=find_subst(pattern,prefixlen))!=NULL) {
14.1308 - if (strcmp(def->first,pattern)!=0 || strcmp(def->second,substitution)!=0)
14.1309 - error(201,pattern); /* redefinition of macro (non-identical) */
14.1310 - delete_subst(pattern,prefixlen);
14.1311 - } /* if */
14.1312 - /* add the pattern/substitution pair to the list */
14.1313 - assert(strlen(pattern)>0);
14.1314 - insert_subst(pattern,substitution,prefixlen);
14.1315 - free(pattern);
14.1316 - free(substitution);
14.1317 - } /* if */
14.1318 - break;
14.1319 - } /* case */
14.1320 - case tpUNDEF:
14.1321 - if (!SKIPPING) {
14.1322 - if (lex(&val,&str)==tSYMBOL) {
14.1323 - ret=delete_subst(str,strlen(str));
14.1324 - if (!ret) {
14.1325 - /* also undefine normal constants */
14.1326 - symbol *sym=findconst(str,NULL);
14.1327 - if (sym!=NULL && (sym->usage & (uENUMROOT | uENUMFIELD))==0) {
14.1328 - delete_symbol(&glbtab,sym);
14.1329 - ret=TRUE;
14.1330 - } /* if */
14.1331 - } /* if */
14.1332 - if (!ret)
14.1333 - error(17,str); /* undefined symbol */
14.1334 - } else {
14.1335 - error(20,str); /* invalid symbol name */
14.1336 - } /* if */
14.1337 - check_empty(lptr);
14.1338 - } /* if */
14.1339 - break;
14.1340 -#endif
14.1341 - case tpERROR:
14.1342 - while (*lptr<=' ' && *lptr!='\0')
14.1343 - lptr++;
14.1344 - if (!SKIPPING)
14.1345 - error(111,lptr); /* user error */
14.1346 - break;
14.1347 - default:
14.1348 - error(31); /* unknown compiler directive */
14.1349 - ret=SKIPPING ? CMD_CONDFALSE : CMD_NONE; /* process as normal line */
14.1350 - } /* switch */
14.1351 - return ret;
14.1352 -}
14.1353 -
14.1354 -#if !defined NO_DEFINE
14.1355 -static int is_startstring(const unsigned char *string)
14.1356 -{
14.1357 - if (*string=='\"' || *string=='\'')
14.1358 - return TRUE; /* "..." */
14.1359 -
14.1360 - if (*string=='!') {
14.1361 - string++;
14.1362 - if (*string=='\"' || *string=='\'')
14.1363 - return TRUE; /* !"..." */
14.1364 - if (*string==sc_ctrlchar) {
14.1365 - string++;
14.1366 - if (*string=='\"' || *string=='\'')
14.1367 - return TRUE; /* !\"..." */
14.1368 - } /* if */
14.1369 - } else if (*string==sc_ctrlchar) {
14.1370 - string++;
14.1371 - if (*string=='\"' || *string=='\'')
14.1372 - return TRUE; /* \"..." */
14.1373 - if (*string=='!') {
14.1374 - string++;
14.1375 - if (*string=='\"' || *string=='\'')
14.1376 - return TRUE; /* \!"..." */
14.1377 - } /* if */
14.1378 - } /* if */
14.1379 -
14.1380 - return FALSE;
14.1381 -}
14.1382 -
14.1383 -static const unsigned char *skipstring(const unsigned char *string)
14.1384 -{
14.1385 - char endquote;
14.1386 - int flags=0;
14.1387 -
14.1388 - while (*string=='!' || *string==sc_ctrlchar) {
14.1389 - if (*string==sc_ctrlchar)
14.1390 - flags=RAWMODE;
14.1391 - string++;
14.1392 - } /* while */
14.1393 -
14.1394 - endquote=*string;
14.1395 - assert(endquote=='"' || endquote=='\'');
14.1396 - string++; /* skip open quote */
14.1397 - while (*string!=endquote && *string!='\0')
14.1398 - litchar(&string,flags);
14.1399 - return string;
14.1400 -}
14.1401 -
14.1402 -static const unsigned char *skippgroup(const unsigned char *string)
14.1403 -{
14.1404 - int nest=0;
14.1405 - char open=*string;
14.1406 - char close;
14.1407 -
14.1408 - switch (open) {
14.1409 - case '(':
14.1410 - close=')';
14.1411 - break;
14.1412 - case '{':
14.1413 - close='}';
14.1414 - break;
14.1415 - case '[':
14.1416 - close=']';
14.1417 - break;
14.1418 - case '<':
14.1419 - close='>';
14.1420 - break;
14.1421 - default:
14.1422 - assert(0);
14.1423 - close='\0'; /* only to avoid a compiler warning */
14.1424 - }/* switch */
14.1425 -
14.1426 - string++;
14.1427 - while (*string!=close || nest>0) {
14.1428 - if (*string==open)
14.1429 - nest++;
14.1430 - else if (*string==close)
14.1431 - nest--;
14.1432 - else if (is_startstring(string))
14.1433 - string=skipstring(string);
14.1434 - if (*string=='\0')
14.1435 - break;
14.1436 - string++;
14.1437 - } /* while */
14.1438 - return string;
14.1439 -}
14.1440 -
14.1441 -static char *strdel(char *str,size_t len)
14.1442 -{
14.1443 - size_t length=strlen(str);
14.1444 - if (len>length)
14.1445 - len=length;
14.1446 - memmove(str, str+len, length-len+1); /* include EOS byte */
14.1447 - return str;
14.1448 -}
14.1449 -
14.1450 -static char *strins(char *dest,char *src,size_t srclen)
14.1451 -{
14.1452 - size_t destlen=strlen(dest);
14.1453 - assert(srclen<=strlen(src));
14.1454 - memmove(dest+srclen, dest, destlen+1);/* include EOS byte */
14.1455 - memcpy(dest, src, srclen);
14.1456 - return dest;
14.1457 -}
14.1458 -
14.1459 -static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char *substitution)
14.1460 -{
14.1461 - int prefixlen;
14.1462 - const unsigned char *p,*s,*e;
14.1463 - unsigned char *args[10];
14.1464 - int match,arg,len,argsnum=0;
14.1465 -
14.1466 - memset(args,0,sizeof args);
14.1467 -
14.1468 - /* check the length of the prefix */
14.1469 - for (prefixlen=0,s=(unsigned char*)pattern; alphanum(*s); prefixlen++,s++)
14.1470 - /* nothing */;
14.1471 - assert(prefixlen>0);
14.1472 - assert(strncmp((char*)line,pattern,prefixlen)==0);
14.1473 -
14.1474 - /* pattern prefix matches; match the rest of the pattern, gather
14.1475 - * the parameters
14.1476 - */
14.1477 - s=line+prefixlen;
14.1478 - p=(unsigned char*)pattern+prefixlen;
14.1479 - match=TRUE; /* so far, pattern matches */
14.1480 - while (match && *s!='\0' && *p!='\0') {
14.1481 - if (*p=='%') {
14.1482 - p++; /* skip '%' */
14.1483 - if (isdigit(*p)) {
14.1484 - arg=*p-'0';
14.1485 - assert(arg>=0 && arg<=9);
14.1486 - p++; /* skip parameter id */
14.1487 - assert(*p!='\0');
14.1488 - /* match the source string up to the character after the digit
14.1489 - * (skipping strings in the process
14.1490 - */
14.1491 - e=s;
14.1492 - while (*e!=*p && *e!='\0' && *e!='\n') {
14.1493 - if (is_startstring(e)) /* skip strings */
14.1494 - e=skipstring(e);
14.1495 - else if (strchr("({[",*e)!=NULL) /* skip parenthized groups */
14.1496 - e=skippgroup(e);
14.1497 - if (*e!='\0')
14.1498 - e++; /* skip non-alphapetic character (or closing quote of
14.1499 - * a string, or the closing paranthese of a group) */
14.1500 - } /* while */
14.1501 - /* store the parameter (overrule any earlier) */
14.1502 - if (args[arg]!=NULL)
14.1503 - free(args[arg]);
14.1504 - else
14.1505 - argsnum++;
14.1506 - len=(int)(e-s);
14.1507 - args[arg]=(unsigned char*)malloc(len+1);
14.1508 - if (args[arg]==NULL)
14.1509 - error(103); /* insufficient memory */
14.1510 - strlcpy((char*)args[arg],(char*)s,len+1);
14.1511 - /* character behind the pattern was matched too */
14.1512 - if (*e==*p) {
14.1513 - s=e+1;
14.1514 - } else if (*e=='\n' && *p==';' && *(p+1)=='\0' && !sc_needsemicolon) {
14.1515 - s=e; /* allow a trailing ; in the pattern match to end of line */
14.1516 - } else {
14.1517 - assert(*e=='\0' || *e=='\n');
14.1518 - match=FALSE;
14.1519 - s=e;
14.1520 - } /* if */
14.1521 - p++;
14.1522 - } else {
14.1523 - match=FALSE;
14.1524 - } /* if */
14.1525 - } else if (*p==';' && *(p+1)=='\0' && !sc_needsemicolon) {
14.1526 - /* source may be ';' or end of the line */
14.1527 - while (*s<=' ' && *s!='\0')
14.1528 - s++; /* skip white space */
14.1529 - if (*s!=';' && *s!='\0')
14.1530 - match=FALSE;
14.1531 - p++; /* skip the semicolon in the pattern */
14.1532 - } else {
14.1533 - cell ch;
14.1534 - /* skip whitespace between two non-alphanumeric characters, except
14.1535 - * for two identical symbols
14.1536 - */
14.1537 - assert((char*)p>pattern);
14.1538 - if (!alphanum(*p) && *(p-1)!=*p)
14.1539 - while (*s<=' ' && *s!='\0')
14.1540 - s++; /* skip white space */
14.1541 - ch=litchar(&p,0); /* this increments "p" */
14.1542 - if (*s!=ch)
14.1543 - match=FALSE;
14.1544 - else
14.1545 - s++; /* this character matches */
14.1546 - } /* if */
14.1547 - } /* while */
14.1548 -
14.1549 - if (match && *p=='\0') {
14.1550 - /* if the last character to match is an alphanumeric character, the
14.1551 - * current character in the source may not be alphanumeric
14.1552 - */
14.1553 - assert(p>(unsigned char*)pattern);
14.1554 - if (alphanum(*(p-1)) && alphanum(*s))
14.1555 - match=FALSE;
14.1556 - } /* if */
14.1557 -
14.1558 - if (match) {
14.1559 - /* calculate the length of the substituted string */
14.1560 - for (e=(unsigned char*)substitution,len=0; *e!='\0'; e++) {
14.1561 - if (*e=='%' && isdigit(*(e+1)) && argsnum) {
14.1562 - arg=*(e+1)-'0';
14.1563 - assert(arg>=0 && arg<=9);
14.1564 - if (args[arg]!=NULL) {
14.1565 - len+=strlen((char*)args[arg]);
14.1566 - e++;
14.1567 - } else {
14.1568 - len++;
14.1569 - }
14.1570 - } else {
14.1571 - len++;
14.1572 - } /* if */
14.1573 - } /* for */
14.1574 - /* check length of the string after substitution */
14.1575 - if (strlen((char*)line) + len - (int)(s-line) > buffersize) {
14.1576 - error(75); /* line too long */
14.1577 - } else {
14.1578 - /* substitute pattern */
14.1579 - strdel((char*)line,(int)(s-line));
14.1580 - for (e=(unsigned char*)substitution,s=line; *e!='\0'; e++) {
14.1581 - if (*e=='%' && isdigit(*(e+1))) {
14.1582 - arg=*(e+1)-'0';
14.1583 - assert(arg>=0 && arg<=9);
14.1584 - if (args[arg]!=NULL) {
14.1585 - strins((char*)s,(char*)args[arg],strlen((char*)args[arg]));
14.1586 - s+=strlen((char*)args[arg]);
14.1587 - e++;
14.1588 - } else {
14.1589 - error(236); /* parameter does not exist, incorrect #define pattern */
14.1590 - strins((char*)s,(char*)e,2);
14.1591 - s+=2;
14.1592 - } /* if */
14.1593 - e++; /* skip %, digit is skipped later */
14.1594 - } else if (*e == '"') {
14.1595 - p=e;
14.1596 - if (is_startstring(e)) {
14.1597 - e=skipstring(e);
14.1598 - strins((char*)s,(char *)p,(e-p+1));
14.1599 - s+=(e-p+1);
14.1600 - } else {
14.1601 - strins((char*)s,(char*)e,1);
14.1602 - s++;
14.1603 - }
14.1604 - } else {
14.1605 - strins((char*)s,(char*)e,1);
14.1606 - s++;
14.1607 - } /* if */
14.1608 - } /* for */
14.1609 - } /* if */
14.1610 - } /* if */
14.1611 -
14.1612 - for (arg=0; arg<10; arg++)
14.1613 - if (args[arg]!=NULL)
14.1614 - free(args[arg]);
14.1615 -
14.1616 - return match;
14.1617 -}
14.1618 -
14.1619 -static void substallpatterns(unsigned char *line,int buffersize)
14.1620 -{
14.1621 - unsigned char *start, *end;
14.1622 - int prefixlen;
14.1623 - stringpair *subst;
14.1624 -
14.1625 - start=line;
14.1626 - while (*start!='\0') {
14.1627 - /* find the start of a prefix (skip all non-alphabetic characters),
14.1628 - * also skip strings
14.1629 - */
14.1630 - while (!alpha(*start) && *start!='\0') {
14.1631 - /* skip strings */
14.1632 - if (is_startstring(start)) {
14.1633 - start=(unsigned char *)skipstring(start);
14.1634 - if (*start=='\0')
14.1635 - break; /* abort loop on error */
14.1636 - } /* if */
14.1637 - start++; /* skip non-alphapetic character (or closing quote of a string) */
14.1638 - } /* while */
14.1639 - if (*start=='\0')
14.1640 - break; /* abort loop on error */
14.1641 - /* if matching the operator "defined", skip it plus the symbol behind it */
14.1642 - if (strncmp((char*)start,"defined",7)==0 && !isalpha((char)*(start+7))) {
14.1643 - start+=7; /* skip "defined" */
14.1644 - /* skip white space & parantheses */
14.1645 - while (*start<=' ' && *start!='\0' || *start=='(')
14.1646 - start++;
14.1647 - /* skip the symbol behind it */
14.1648 - while (alphanum(*start))
14.1649 - start++;
14.1650 - /* drop back into the main loop */
14.1651 - continue;
14.1652 - } /* if */
14.1653 - /* get the prefix (length), look for a matching definition */
14.1654 - prefixlen=0;
14.1655 - end=start;
14.1656 - while (alphanum(*end)) {
14.1657 - prefixlen++;
14.1658 - end++;
14.1659 - } /* while */
14.1660 - assert(prefixlen>0);
14.1661 - subst=find_subst((char*)start,prefixlen);
14.1662 - if (subst!=NULL) {
14.1663 - /* properly match the pattern and substitute */
14.1664 - if (!substpattern(start,buffersize-(int)(start-line),subst->first,subst->second))
14.1665 - start=end; /* match failed, skip this prefix */
14.1666 - /* match succeeded: do not update "start", because the substitution text
14.1667 - * may be matched by other macros
14.1668 - */
14.1669 - } else {
14.1670 - start=end; /* no macro with this prefix, skip this prefix */
14.1671 - } /* if */
14.1672 - } /* while */
14.1673 -}
14.1674 -#endif
14.1675 -
14.1676 -/* preprocess
14.1677 - *
14.1678 - * Reads a line by readline() into "pline" and performs basic preprocessing:
14.1679 - * deleting comments, skipping lines with false "#if.." code and recognizing
14.1680 - * other compiler directives. There is an indirect recursion: lex() calls
14.1681 - * preprocess() if a new line must be read, preprocess() calls command(),
14.1682 - * which at his turn calls lex() to identify the token.
14.1683 - *
14.1684 - * Global references: lptr (altered)
14.1685 - * pline (altered)
14.1686 - * freading (referred to only)
14.1687 - */
14.1688 -SC_FUNC void preprocess(void)
14.1689 -{
14.1690 - int iscommand;
14.1691 -
14.1692 - if (!freading)
14.1693 - return;
14.1694 - do {
14.1695 - readline(pline);
14.1696 - stripcom(pline); /* ??? no need for this when reading back from list file (in the second pass) */
14.1697 - lptr=pline; /* set "line pointer" to start of the parsing buffer */
14.1698 - iscommand=command();
14.1699 - if (iscommand!=CMD_NONE)
14.1700 - errorset(sRESET,0); /* reset error flag ("panic mode") on empty line or directive */
14.1701 - #if !defined NO_DEFINE
14.1702 - if (iscommand==CMD_NONE) {
14.1703 - assert(lptr!=term_expr);
14.1704 - substallpatterns(pline,sLINEMAX);
14.1705 - lptr=pline; /* reset "line pointer" to start of the parsing buffer */
14.1706 - } /* if */
14.1707 - #endif
14.1708 - if (sc_status==statFIRST && sc_listing && freading
14.1709 - && (iscommand==CMD_NONE || iscommand==CMD_EMPTYLINE || iscommand==CMD_DIRECTIVE))
14.1710 - {
14.1711 - listline++;
14.1712 - if (fline!=listline) {
14.1713 - listline=fline;
14.1714 - setlinedirect(fline);
14.1715 - } /* if */
14.1716 - if (iscommand==CMD_EMPTYLINE)
14.1717 - pc_writeasm(outf,"\n");
14.1718 - else
14.1719 - pc_writeasm(outf,(char*)pline);
14.1720 - } /* if */
14.1721 - } while (iscommand!=CMD_NONE && iscommand!=CMD_TERM && freading); /* enddo */
14.1722 -}
14.1723 -
14.1724 -static const unsigned char *unpackedstring(const unsigned char *lptr,int flags)
14.1725 -{
14.1726 - while (*lptr!='\"' && *lptr!='\0') {
14.1727 - if (*lptr=='\a') { /* ignore '\a' (which was inserted at a line concatenation) */
14.1728 - lptr++;
14.1729 - continue;
14.1730 - } /* if */
14.1731 - litadd(litchar(&lptr,flags | UTF8MODE)); /* litchar() alters "lptr" */
14.1732 - } /* while */
14.1733 - litadd(0); /* terminate string */
14.1734 - return lptr;
14.1735 -}
14.1736 -
14.1737 -static const unsigned char *packedstring(const unsigned char *lptr,int flags)
14.1738 -{
14.1739 - int i;
14.1740 - ucell val,c;
14.1741 -
14.1742 - i=sizeof(ucell)-(sCHARBITS/8); /* start at most significant byte */
14.1743 - val=0;
14.1744 - while (*lptr!='\"' && *lptr!='\0') {
14.1745 - if (*lptr=='\a') { /* ignore '\a' (which was inserted at a line concatenation) */
14.1746 - lptr++;
14.1747 - continue;
14.1748 - } /* if */
14.1749 - c=litchar(&lptr,flags); /* litchar() alters "lptr" */
14.1750 - if (c>=(ucell)(1 << sCHARBITS))
14.1751 - error(43); /* character constant exceeds range */
14.1752 - val |= (c << 8*i);
14.1753 - if (i==0) {
14.1754 - litadd(val);
14.1755 - val=0;
14.1756 - } /* if */
14.1757 - i=(i+sizeof(ucell)-(sCHARBITS/8)) % sizeof(ucell);
14.1758 - } /* if */
14.1759 - /* save last code; make sure there is at least one terminating zero character */
14.1760 - if (i!=(int)(sizeof(ucell)-(sCHARBITS/8)))
14.1761 - litadd(val); /* at least one zero character in "val" */
14.1762 - else
14.1763 - litadd(0); /* add full cell of zeros */
14.1764 - return lptr;
14.1765 -}
14.1766 -
14.1767 -/* lex(lexvalue,lexsym) Lexical Analysis
14.1768 - *
14.1769 - * lex() first deletes leading white space, then checks for multi-character
14.1770 - * operators, keywords (including most compiler directives), numbers,
14.1771 - * labels, symbols and literals (literal characters are converted to a number
14.1772 - * and are returned as such). If every check fails, the line must contain
14.1773 - * a single-character operator. So, lex() returns this character. In the other
14.1774 - * case (something did match), lex() returns the number of the token. All
14.1775 - * these tokens have been assigned numbers above 255.
14.1776 - *
14.1777 - * Some tokens have "attributes":
14.1778 - * tNUMBER the value of the number is return in "lexvalue".
14.1779 - * tRATIONAL the value is in IEEE 754 encoding or in fixed point
14.1780 - * encoding in "lexvalue".
14.1781 - * tSYMBOL the first sNAMEMAX characters of the symbol are
14.1782 - * stored in a buffer, a pointer to this buffer is
14.1783 - * returned in "lexsym".
14.1784 - * tLABEL the first sNAMEMAX characters of the label are
14.1785 - * stored in a buffer, a pointer to this buffer is
14.1786 - * returned in "lexsym".
14.1787 - * tSTRING the string is stored in the literal pool, the index
14.1788 - * in the literal pool to this string is stored in
14.1789 - * "lexvalue".
14.1790 - *
14.1791 - * lex() stores all information (the token found and possibly its attribute)
14.1792 - * in global variables. This allows a token to be examined twice. If "_pushed"
14.1793 - * is true, this information is returned.
14.1794 - *
14.1795 - * Global references: lptr (altered)
14.1796 - * fline (referred to only)
14.1797 - * litidx (referred to only)
14.1798 - * _lextok, _lexval, _lexstr
14.1799 - * _pushed
14.1800 - */
14.1801 -
14.1802 -static int _pushed;
14.1803 -static int _lextok;
14.1804 -static cell _lexval;
14.1805 -static char _lexstr[sLINEMAX+1];
14.1806 -static int _lexnewline;
14.1807 -
14.1808 -SC_FUNC void lexinit(void)
14.1809 -{
14.1810 - stkidx=0; /* index for pushstk() and popstk() */
14.1811 - iflevel=0; /* preprocessor: nesting of "#if" is currently 0 */
14.1812 - skiplevel=0; /* preprocessor: not currently skipping */
14.1813 - icomment=0; /* currently not in a multiline comment */
14.1814 - _pushed=FALSE; /* no token pushed back into lex */
14.1815 - _lexnewline=FALSE;
14.1816 -}
14.1817 -
14.1818 -char *sc_tokens[] = {
14.1819 - "*=", "/=", "%=", "+=", "-=", "<<=", ">>>=", ">>=", "&=", "^=", "|=",
14.1820 - "||", "&&", "==", "!=", "<=", ">=", "<<", ">>>", ">>", "++", "--",
14.1821 - "...", "..", "::",
14.1822 - "assert", "break", "case", "char", "const", "continue", "default",
14.1823 - "defined", "do", "else", "enum", "exit", "for", "forward", "goto",
14.1824 - "if", "native", "new", "decl", "operator", "public", "return", "sizeof",
14.1825 - "sleep", "state", "static", "stock", "switch", "tagof", "while",
14.1826 - "#assert", "#define", "#else", "#elseif", "#emit", "#endif", "#endinput",
14.1827 - "#endscript", "#error", "#file", "#if", "#include", "#line", "#pragma",
14.1828 - "#tryinclude", "#undef",
14.1829 - ";", ";", "-integer value-", "-rational value-", "-identifier-",
14.1830 - "-label-", "-string-"
14.1831 - };
14.1832 -
14.1833 -SC_FUNC int lex(cell *lexvalue,char **lexsym)
14.1834 -{
14.1835 - int i,toolong,newline,stringflags;
14.1836 - char **tokptr;
14.1837 - const unsigned char *starttoken;
14.1838 -
14.1839 - if (_pushed) {
14.1840 - _pushed=FALSE; /* reset "_pushed" flag */
14.1841 - *lexvalue=_lexval;
14.1842 - *lexsym=_lexstr;
14.1843 - return _lextok;
14.1844 - } /* if */
14.1845 -
14.1846 - _lextok=0; /* preset all values */
14.1847 - _lexval=0;
14.1848 - _lexstr[0]='\0';
14.1849 - *lexvalue=_lexval;
14.1850 - *lexsym=_lexstr;
14.1851 - _lexnewline=FALSE;
14.1852 - if (!freading)
14.1853 - return 0;
14.1854 -
14.1855 - newline= (lptr==pline); /* does lptr point to start of line buffer */
14.1856 - while (*lptr<=' ') { /* delete leading white space */
14.1857 - if (*lptr=='\0') {
14.1858 - preprocess(); /* preprocess resets "lptr" */
14.1859 - if (!freading)
14.1860 - return 0;
14.1861 - if (lptr==term_expr) /* special sequence to terminate a pending expression */
14.1862 - return (_lextok=tENDEXPR);
14.1863 - _lexnewline=TRUE; /* set this after preprocess(), because
14.1864 - * preprocess() calls lex() recursively */
14.1865 - newline=TRUE;
14.1866 - } else {
14.1867 - lptr+=1;
14.1868 - } /* if */
14.1869 - } /* while */
14.1870 - if (newline) {
14.1871 - stmtindent=0;
14.1872 - for (i=0; i<(int)(lptr-pline); i++)
14.1873 - if (pline[i]=='\t' && sc_tabsize>0)
14.1874 - stmtindent += (int)(sc_tabsize - (stmtindent+sc_tabsize) % sc_tabsize);
14.1875 - else
14.1876 - stmtindent++;
14.1877 - } /* if */
14.1878 -
14.1879 - i=tFIRST;
14.1880 - tokptr=sc_tokens;
14.1881 - while (i<=tMIDDLE) { /* match multi-character operators */
14.1882 - if (*lptr==**tokptr && match(*tokptr,FALSE)) {
14.1883 - _lextok=i;
14.1884 - if (pc_docexpr) /* optionally concatenate to documentation string */
14.1885 - insert_autolist(*tokptr);
14.1886 - return _lextok;
14.1887 - } /* if */
14.1888 - i+=1;
14.1889 - tokptr+=1;
14.1890 - } /* while */
14.1891 - while (i<=tLAST) { /* match reserved words and compiler directives */
14.1892 - if (*lptr==**tokptr && match(*tokptr,TRUE)) {
14.1893 - _lextok=i;
14.1894 - errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
14.1895 - if (pc_docexpr) /* optionally concatenate to documentation string */
14.1896 - insert_autolist(*tokptr);
14.1897 - return _lextok;
14.1898 - } /* if */
14.1899 - i+=1;
14.1900 - tokptr+=1;
14.1901 - } /* while */
14.1902 -
14.1903 - starttoken=lptr; /* save start pointer (for concatenating to documentation string) */
14.1904 - if ((i=number(&_lexval,lptr))!=0) { /* number */
14.1905 - _lextok=tNUMBER;
14.1906 - *lexvalue=_lexval;
14.1907 - lptr+=i;
14.1908 - } else if ((i=ftoi(&_lexval,lptr))!=0) {
14.1909 - _lextok=tRATIONAL;
14.1910 - *lexvalue=_lexval;
14.1911 - lptr+=i;
14.1912 - } else if (alpha(*lptr)) { /* symbol or label */
14.1913 - /* Note: only sNAMEMAX characters are significant. The compiler
14.1914 - * generates a warning if a symbol exceeds this length.
14.1915 - */
14.1916 - _lextok=tSYMBOL;
14.1917 - i=0;
14.1918 - toolong=0;
14.1919 - while (alphanum(*lptr)){
14.1920 - _lexstr[i]=*lptr;
14.1921 - lptr+=1;
14.1922 - if (i<sNAMEMAX)
14.1923 - i+=1;
14.1924 - else
14.1925 - toolong=1;
14.1926 - } /* while */
14.1927 - _lexstr[i]='\0';
14.1928 - if (toolong)
14.1929 - error(200,_lexstr,sNAMEMAX); /* symbol too long, truncated to sNAMEMAX chars */
14.1930 - if (_lexstr[0]==PUBLIC_CHAR && _lexstr[1]=='\0') {
14.1931 - _lextok=PUBLIC_CHAR; /* '@' all alone is not a symbol, it is an operator */
14.1932 - } else if (_lexstr[0]=='_' && _lexstr[1]=='\0') {
14.1933 - _lextok='_'; /* '_' by itself is not a symbol, it is a placeholder */
14.1934 - } /* if */
14.1935 - if (*lptr==':' && *(lptr+1)!=':' && _lextok!=PUBLIC_CHAR) {
14.1936 - if (sc_allowtags) {
14.1937 - _lextok=tLABEL; /* it wasn't a normal symbol, it was a label/tagname */
14.1938 - lptr+=1; /* skip colon */
14.1939 - } else if (find_constval(&tagname_tab,_lexstr,0)!=NULL) {
14.1940 - /* this looks like a tag override (because a tag with this name
14.1941 - * exists), but tags are not allowed right now, so it is probably an
14.1942 - * error
14.1943 - */
14.1944 - error(220);
14.1945 - } /* if */
14.1946 - } /* if */
14.1947 - } else if (*lptr=='\"' || *lptr==sc_ctrlchar && *(lptr+1)=='\"')
14.1948 - { /* unpacked string literal */
14.1949 - _lextok=tSTRING;
14.1950 - stringflags= (*lptr==sc_ctrlchar) ? RAWMODE : 0;
14.1951 - *lexvalue=_lexval=litidx;
14.1952 - lptr+=1; /* skip double quote */
14.1953 - if ((stringflags & RAWMODE)!=0)
14.1954 - lptr+=1; /* skip "escape" character too */
14.1955 - lptr=sc_packstr ? packedstring(lptr,stringflags) : unpackedstring(lptr,stringflags);
14.1956 - if (*lptr=='\"')
14.1957 - lptr+=1; /* skip final quote */
14.1958 - else
14.1959 - error(37); /* invalid (non-terminated) string */
14.1960 - } else if (*lptr=='!' && *(lptr+1)=='\"'
14.1961 - || *lptr=='!' && *(lptr+1)==sc_ctrlchar && *(lptr+2)=='\"'
14.1962 - || *lptr==sc_ctrlchar && *(lptr+1)=='!' && *(lptr+2)=='\"')
14.1963 - { /* packed string literal */
14.1964 - _lextok=tSTRING;
14.1965 - stringflags= (*lptr==sc_ctrlchar || *(lptr+1)==sc_ctrlchar) ? RAWMODE : 0;
14.1966 - *lexvalue=_lexval=litidx;
14.1967 - lptr+=2; /* skip exclamation point and double quote */
14.1968 - if ((stringflags & RAWMODE)!=0)
14.1969 - lptr+=1; /* skip "escape" character too */
14.1970 - lptr=sc_packstr ? unpackedstring(lptr,stringflags) : packedstring(lptr,stringflags);
14.1971 - if (*lptr=='\"')
14.1972 - lptr+=1; /* skip final quote */
14.1973 - else
14.1974 - error(37); /* invalid (non-terminated) string */
14.1975 - } else if (*lptr=='\'') { /* character literal */
14.1976 - lptr+=1; /* skip quote */
14.1977 - _lextok=tNUMBER;
14.1978 - *lexvalue=_lexval=litchar(&lptr,UTF8MODE);
14.1979 - if (*lptr=='\'')
14.1980 - lptr+=1; /* skip final quote */
14.1981 - else
14.1982 - error(27); /* invalid character constant (must be one character) */
14.1983 - } else if (*lptr==';') { /* semicolumn resets "error" flag */
14.1984 - _lextok=';';
14.1985 - lptr+=1;
14.1986 - errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
14.1987 - } else {
14.1988 - _lextok=*lptr; /* if every match fails, return the character */
14.1989 - lptr+=1; /* increase the "lptr" pointer */
14.1990 - } /* if */
14.1991 -
14.1992 - if (pc_docexpr) { /* optionally concatenate to documentation string */
14.1993 - char *docstr=(char*)malloc(((int)(lptr-starttoken)+1)*sizeof(char));
14.1994 - if (docstr!=NULL) {
14.1995 - strlcpy(docstr,(char*)starttoken,(int)(lptr-starttoken)+1);
14.1996 - insert_autolist(docstr);
14.1997 - free(docstr);
14.1998 - } /* if */
14.1999 - } /* if */
14.2000 - return _lextok;
14.2001 -}
14.2002 -
14.2003 -/* lexpush
14.2004 - *
14.2005 - * Pushes a token back, so the next call to lex() will return the token
14.2006 - * last examined, instead of a new token.
14.2007 - *
14.2008 - * Only one token can be pushed back.
14.2009 - *
14.2010 - * In fact, lex() already stores the information it finds into global
14.2011 - * variables, so all that is to be done is set a flag that informs lex()
14.2012 - * to read and return the information from these variables, rather than
14.2013 - * to read in a new token from the input file.
14.2014 - */
14.2015 -SC_FUNC void lexpush(void)
14.2016 -{
14.2017 - assert(_pushed==FALSE);
14.2018 - _pushed=TRUE;
14.2019 -}
14.2020 -
14.2021 -/* lexclr
14.2022 - *
14.2023 - * Sets the variable "_pushed" to 0 to make sure lex() will read in a new
14.2024 - * symbol (a not continue with some old one). This is required upon return
14.2025 - * from Assembler mode, and in a few cases after detecting an syntax error.
14.2026 - */
14.2027 -SC_FUNC void lexclr(int clreol)
14.2028 -{
14.2029 - _pushed=FALSE;
14.2030 - if (clreol) {
14.2031 - lptr=(unsigned char*)strchr((char*)pline,'\0');
14.2032 - assert(lptr!=NULL);
14.2033 - } /* if */
14.2034 -}
14.2035 -
14.2036 -/* matchtoken
14.2037 - *
14.2038 - * This routine is useful if only a simple check is needed. If the token
14.2039 - * differs from the one expected, it is pushed back.
14.2040 - * This function returns 1 for "token found" and 2 for "implied statement
14.2041 - * termination token" found --the statement termination is an end of line in
14.2042 - * an expression where there is no pending operation. Such an implied token
14.2043 - * (i.e. not present in the source code) should not be pushed back, which is
14.2044 - * why it is sometimes important to distinguish the two.
14.2045 - */
14.2046 -SC_FUNC int matchtoken(int token)
14.2047 -{
14.2048 - cell val;
14.2049 - char *str;
14.2050 - int tok;
14.2051 -
14.2052 - tok=lex(&val,&str);
14.2053 - if (tok==token || token==tTERM && (tok==';' || tok==tENDEXPR)) {
14.2054 - return 1;
14.2055 - } else if (!sc_needsemicolon && token==tTERM && (_lexnewline || !freading)) {
14.2056 - /* Push "tok" back, because it is the token following the implicit statement
14.2057 - * termination (newline) token.
14.2058 - */
14.2059 - lexpush();
14.2060 - return 2;
14.2061 - } else {
14.2062 - lexpush();
14.2063 - return 0;
14.2064 - } /* if */
14.2065 -}
14.2066 -
14.2067 -/* tokeninfo
14.2068 - *
14.2069 - * Returns additional information of a token after using "matchtoken()"
14.2070 - * or needtoken(). It does no harm using this routine after a call to
14.2071 - * "lex()", but lex() already returns the same information.
14.2072 - *
14.2073 - * The token itself is the return value. Normally, this one is already known.
14.2074 - */
14.2075 -SC_FUNC int tokeninfo(cell *val,char **str)
14.2076 -{
14.2077 - /* if the token was pushed back, tokeninfo() returns the token and
14.2078 - * parameters of the *next* token, not of the *current* token.
14.2079 - */
14.2080 - assert(!_pushed);
14.2081 - *val=_lexval;
14.2082 - *str=_lexstr;
14.2083 - return _lextok;
14.2084 -}
14.2085 -
14.2086 -/* needtoken
14.2087 - *
14.2088 - * This routine checks for a required token and gives an error message if
14.2089 - * it isn't there (and returns 0/FALSE in that case). Like function matchtoken(),
14.2090 - * this function returns 1 for "token found" and 2 for "statement termination
14.2091 - * token" found; see function matchtoken() for details.
14.2092 - *
14.2093 - * Global references: _lextok;
14.2094 - */
14.2095 -SC_FUNC int needtoken(int token)
14.2096 -{
14.2097 - char s1[20],s2[20];
14.2098 - int t;
14.2099 -
14.2100 - if ((t=matchtoken(token))!=0) {
14.2101 - return t;
14.2102 - } else {
14.2103 - /* token already pushed back */
14.2104 - assert(_pushed);
14.2105 - if (token<256)
14.2106 - sprintf(s1,"%c",(char)token); /* single character token */
14.2107 - else
14.2108 - strcpy(s1,sc_tokens[token-tFIRST]); /* multi-character symbol */
14.2109 - if (!freading)
14.2110 - strcpy(s2,"-end of file-");
14.2111 - else if (_lextok<256)
14.2112 - sprintf(s2,"%c",(char)_lextok);
14.2113 - else
14.2114 - strcpy(s2,sc_tokens[_lextok-tFIRST]);
14.2115 - error(1,s1,s2); /* expected ..., but found ... */
14.2116 - return FALSE;
14.2117 - } /* if */
14.2118 -}
14.2119 -
14.2120 -/* match
14.2121 - *
14.2122 - * Compares a series of characters from the input file with the characters
14.2123 - * in "st" (that contains a token). If the token on the input file matches
14.2124 - * "st", the input file pointer "lptr" is adjusted to point to the next
14.2125 - * token, otherwise "lptr" remains unaltered.
14.2126 - *
14.2127 - * If the parameter "end: is true, match() requires that the first character
14.2128 - * behind the recognized token is non-alphanumeric.
14.2129 - *
14.2130 - * Global references: lptr (altered)
14.2131 - */
14.2132 -static int match(char *st,int end)
14.2133 -{
14.2134 - int k;
14.2135 - const unsigned char *ptr;
14.2136 -
14.2137 - k=0;
14.2138 - ptr=lptr;
14.2139 - while (st[k]) {
14.2140 - if ((unsigned char)st[k]!=*ptr)
14.2141 - return 0;
14.2142 - k+=1;
14.2143 - ptr+=1;
14.2144 - } /* while */
14.2145 - if (end) { /* symbol must terminate with non-alphanumeric char */
14.2146 - if (alphanum(*ptr))
14.2147 - return 0;
14.2148 - } /* if */
14.2149 - lptr=ptr; /* match found, skip symbol */
14.2150 - return 1;
14.2151 -}
14.2152 -
14.2153 -static void chk_grow_litq(void)
14.2154 -{
14.2155 - if (litidx>=litmax) {
14.2156 - cell *p;
14.2157 -
14.2158 - litmax+=sDEF_LITMAX;
14.2159 - p=(cell *)realloc(litq,litmax*sizeof(cell));
14.2160 - if (p==NULL)
14.2161 - error(102,"literal table"); /* literal table overflow (fatal error) */
14.2162 - litq=p;
14.2163 - } /* if */
14.2164 -}
14.2165 -
14.2166 -/* litadd
14.2167 - *
14.2168 - * Adds a value at the end of the literal queue. The literal queue is used
14.2169 - * for literal strings used in functions and for initializing array variables.
14.2170 - *
14.2171 - * Global references: litidx (altered)
14.2172 - * litq (altered)
14.2173 - */
14.2174 -SC_FUNC void litadd(cell value)
14.2175 -{
14.2176 - chk_grow_litq();
14.2177 - assert(litidx<litmax);
14.2178 - litq[litidx++]=value;
14.2179 -}
14.2180 -
14.2181 -/* litinsert
14.2182 - *
14.2183 - * Inserts a value into the literal queue. This is sometimes necessary for
14.2184 - * initializing multi-dimensional arrays.
14.2185 - *
14.2186 - * Global references: litidx (altered)
14.2187 - * litq (altered)
14.2188 - */
14.2189 -SC_FUNC void litinsert(cell value,int pos)
14.2190 -{
14.2191 - chk_grow_litq();
14.2192 - assert(litidx<litmax);
14.2193 - assert(pos>=0 && pos<=litidx);
14.2194 - memmove(litq+(pos+1),litq+pos,(litidx-pos)*sizeof(cell));
14.2195 - litidx++;
14.2196 - litq[pos]=value;
14.2197 -}
14.2198 -
14.2199 -/* litchar
14.2200 - *
14.2201 - * Return current literal character and increase the pointer to point
14.2202 - * just behind this literal character.
14.2203 - *
14.2204 - * Note: standard "escape sequences" are suported, but the backslash may be
14.2205 - * replaced by another character; the syntax '\ddd' is supported,
14.2206 - * but ddd must be decimal!
14.2207 - */
14.2208 -static cell litchar(const unsigned char **lptr,int flags)
14.2209 -{
14.2210 - cell c=0;
14.2211 - const unsigned char *cptr;
14.2212 -
14.2213 - cptr=*lptr;
14.2214 - if ((flags & RAWMODE)!=0 || *cptr!=sc_ctrlchar) { /* no escape character */
14.2215 - #if !defined NO_UTF8
14.2216 - if (sc_is_utf8 && (flags & UTF8MODE)!=0) {
14.2217 - c=get_utf8_char(cptr,&cptr);
14.2218 - assert(c>=0); /* file was already scanned for conformance to UTF-8 */
14.2219 - } else {
14.2220 - #endif
14.2221 - #if !defined NO_CODEPAGE
14.2222 - c=cp_translate(cptr,&cptr);
14.2223 - #else
14.2224 - c=*cptr;
14.2225 - cptr+=1;
14.2226 - #endif
14.2227 - #if !defined NO_UTF8
14.2228 - } /* if */
14.2229 - #endif
14.2230 - } else {
14.2231 - cptr+=1;
14.2232 - if (*cptr==sc_ctrlchar) {
14.2233 - c=*cptr; /* \\ == \ (the escape character itself) */
14.2234 - cptr+=1;
14.2235 - } else {
14.2236 - switch (*cptr) {
14.2237 - case 'a': /* \a == audible alarm */
14.2238 - c=7;
14.2239 - cptr+=1;
14.2240 - break;
14.2241 - case 'b': /* \b == backspace */
14.2242 - c=8;
14.2243 - cptr+=1;
14.2244 - break;
14.2245 - case 'e': /* \e == escape */
14.2246 - c=27;
14.2247 - cptr+=1;
14.2248 - break;
14.2249 - case 'f': /* \f == form feed */
14.2250 - c=12;
14.2251 - cptr+=1;
14.2252 - break;
14.2253 - case 'n': /* \n == NewLine character */
14.2254 - c=10;
14.2255 - cptr+=1;
14.2256 - break;
14.2257 - case 'r': /* \r == carriage return */
14.2258 - c=13;
14.2259 - cptr+=1;
14.2260 - break;
14.2261 - case 't': /* \t == horizontal TAB */
14.2262 - c=9;
14.2263 - cptr+=1;
14.2264 - break;
14.2265 - case 'v': /* \v == vertical TAB */
14.2266 - c=11;
14.2267 - cptr+=1;
14.2268 - break;
14.2269 - case 'x':
14.2270 - cptr+=1;
14.2271 - c=0;
14.2272 - while (ishex(*cptr)) {
14.2273 - if (isdigit(*cptr))
14.2274 - c=(c<<4)+(*cptr-'0');
14.2275 - else
14.2276 - c=(c<<4)+(tolower(*cptr)-'a'+10);
14.2277 - cptr++;
14.2278 - } /* while */
14.2279 - if (*cptr==';')
14.2280 - cptr++; /* swallow a trailing ';' */
14.2281 - break;
14.2282 - case '\'': /* \' == ' (single quote) */
14.2283 - case '"': /* \" == " (single quote) */
14.2284 - case '%': /* \% == % (percent) */
14.2285 - c=*cptr;
14.2286 - cptr+=1;
14.2287 - break;
14.2288 - default:
14.2289 - if (isdigit(*cptr)) { /* \ddd */
14.2290 - c=0;
14.2291 - while (*cptr>='0' && *cptr<='9') /* decimal! */
14.2292 - c=c*10 + *cptr++ - '0';
14.2293 - if (*cptr==';')
14.2294 - cptr++; /* swallow a trailing ';' */
14.2295 - } else {
14.2296 - error(27); /* invalid character constant */
14.2297 - } /* if */
14.2298 - } /* switch */
14.2299 - } /* if */
14.2300 - } /* if */
14.2301 - *lptr=cptr;
14.2302 - assert(c>=0);
14.2303 - return c;
14.2304 -}
14.2305 -
14.2306 -/* alpha
14.2307 - *
14.2308 - * Test if character "c" is alphabetic ("a".."z"), an underscore ("_")
14.2309 - * or an "at" sign ("@"). The "@" is an extension to standard C.
14.2310 - */
14.2311 -static int alpha(char c)
14.2312 -{
14.2313 - return (isalpha(c) || c=='_' || c==PUBLIC_CHAR);
14.2314 -}
14.2315 -
14.2316 -/* alphanum
14.2317 - *
14.2318 - * Test if character "c" is alphanumeric ("a".."z", "0".."9", "_" or "@")
14.2319 - */
14.2320 -SC_FUNC int alphanum(char c)
14.2321 -{
14.2322 - return (alpha(c) || isdigit(c));
14.2323 -}
14.2324 -
14.2325 -/* ishex
14.2326 - *
14.2327 - * Test if character "c" is a hexadecimal digit ("0".."9" or "a".."f").
14.2328 - */
14.2329 -SC_FUNC int ishex(char c)
14.2330 -{
14.2331 - return (c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F');
14.2332 -}
14.2333 -
14.2334 -/* The local variable table must be searched backwards, so that the deepest
14.2335 - * nesting of local variables is searched first. The simplest way to do
14.2336 - * this is to insert all new items at the head of the list.
14.2337 - * In the global list, the symbols are kept in sorted order, so that the
14.2338 - * public functions are written in sorted order.
14.2339 - */
14.2340 -static symbol *add_symbol(symbol *root,symbol *entry,int sort)
14.2341 -{
14.2342 - symbol *newsym;
14.2343 -
14.2344 - if (sort)
14.2345 - while (root->next!=NULL && strcmp(entry->name,root->next->name)>0)
14.2346 - root=root->next;
14.2347 -
14.2348 - if ((newsym=(symbol *)malloc(sizeof(symbol)))==NULL) {
14.2349 - error(103);
14.2350 - return NULL;
14.2351 - } /* if */
14.2352 - memcpy(newsym,entry,sizeof(symbol));
14.2353 - newsym->next=root->next;
14.2354 - root->next=newsym;
14.2355 - return newsym;
14.2356 -}
14.2357 -
14.2358 -static void free_symbol(symbol *sym)
14.2359 -{
14.2360 - arginfo *arg;
14.2361 -
14.2362 - /* free all sub-symbol allocated memory blocks, depending on the
14.2363 - * kind of the symbol
14.2364 - */
14.2365 - assert(sym!=NULL);
14.2366 - if (sym->ident==iFUNCTN) {
14.2367 - /* run through the argument list; "default array" arguments
14.2368 - * must be freed explicitly; the tag list must also be freed */
14.2369 - assert(sym->dim.arglist!=NULL);
14.2370 - for (arg=sym->dim.arglist; arg->ident!=0; arg++) {
14.2371 - if (arg->ident==iREFARRAY && arg->hasdefault)
14.2372 - free(arg->defvalue.array.data);
14.2373 - else if (arg->ident==iVARIABLE
14.2374 - && ((arg->hasdefault & uSIZEOF)!=0 || (arg->hasdefault & uTAGOF)!=0))
14.2375 - free(arg->defvalue.size.symname);
14.2376 - assert(arg->tags!=NULL);
14.2377 - free(arg->tags);
14.2378 - } /* for */
14.2379 - free(sym->dim.arglist);
14.2380 - if (sym->states!=NULL) {
14.2381 - delete_consttable(sym->states);
14.2382 - free(sym->states);
14.2383 - } /* if */
14.2384 - } else if (sym->ident==iVARIABLE || sym->ident==iARRAY) {
14.2385 - if (sym->states!=NULL) {
14.2386 - delete_consttable(sym->states);
14.2387 - free(sym->states);
14.2388 - } /* if */
14.2389 - } else if (sym->ident==iCONSTEXPR && (sym->usage & uENUMROOT)==uENUMROOT) {
14.2390 - /* free the constant list of an enum root */
14.2391 - assert(sym->dim.enumlist!=NULL);
14.2392 - delete_consttable(sym->dim.enumlist);
14.2393 - free(sym->dim.enumlist);
14.2394 - } /* if */
14.2395 - assert(sym->refer!=NULL);
14.2396 - free(sym->refer);
14.2397 - if (sym->documentation!=NULL)
14.2398 - free(sym->documentation);
14.2399 - free(sym);
14.2400 -}
14.2401 -
14.2402 -SC_FUNC void delete_symbol(symbol *root,symbol *sym)
14.2403 -{
14.2404 - /* find the symbol and its predecessor
14.2405 - * (this function assumes that you will never delete a symbol that is not
14.2406 - * in the table pointed at by "root")
14.2407 - */
14.2408 - assert(root!=sym);
14.2409 - while (root->next!=sym) {
14.2410 - root=root->next;
14.2411 - assert(root!=NULL);
14.2412 - } /* while */
14.2413 -
14.2414 - /* unlink it, then free it */
14.2415 - root->next=sym->next;
14.2416 - free_symbol(sym);
14.2417 -}
14.2418 -
14.2419 -SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_functions)
14.2420 -{
14.2421 - symbol *sym,*parent_sym;
14.2422 - constvalue *stateptr;
14.2423 - int mustdelete;
14.2424 -
14.2425 - /* erase only the symbols with a deeper nesting level than the
14.2426 - * specified nesting level */
14.2427 - while (root->next!=NULL) {
14.2428 - sym=root->next;
14.2429 - if (sym->compound<level)
14.2430 - break;
14.2431 - switch (sym->ident) {
14.2432 - case iLABEL:
14.2433 - mustdelete=delete_labels;
14.2434 - break;
14.2435 - case iVARIABLE:
14.2436 - case iARRAY:
14.2437 - /* do not delete global variables if functions are preserved */
14.2438 - mustdelete=delete_functions;
14.2439 - break;
14.2440 - case iREFERENCE:
14.2441 - /* always delete references (only exist as function parameters) */
14.2442 - mustdelete=TRUE;
14.2443 - break;
14.2444 - case iREFARRAY:
14.2445 - /* a global iREFARRAY symbol is the return value of a function: delete
14.2446 - * this only if "globals" must be deleted; other iREFARRAY instances
14.2447 - * (locals) are also deleted
14.2448 - */
14.2449 - mustdelete=delete_functions;
14.2450 - for (parent_sym=sym->parent; parent_sym!=NULL && parent_sym->ident!=iFUNCTN; parent_sym=parent_sym->parent)
14.2451 - assert(parent_sym->ident==iREFARRAY);
14.2452 - assert(parent_sym==NULL || (parent_sym->ident==iFUNCTN && parent_sym->parent==NULL));
14.2453 - if (parent_sym==NULL || parent_sym->ident!=iFUNCTN)
14.2454 - mustdelete=TRUE;
14.2455 - break;
14.2456 - case iCONSTEXPR:
14.2457 - /* delete constants, except predefined constants */
14.2458 - mustdelete=delete_functions || (sym->usage & uPREDEF)==0;
14.2459 - break;
14.2460 - case iFUNCTN:
14.2461 - /* optionally preserve globals (variables & functions), but
14.2462 - * NOT native functions
14.2463 - */
14.2464 - mustdelete=delete_functions || (sym->usage & uNATIVE)!=0;
14.2465 - assert(sym->parent==NULL);
14.2466 - break;
14.2467 - case iARRAYCELL:
14.2468 - case iARRAYCHAR:
14.2469 - case iEXPRESSION:
14.2470 - case iVARARGS:
14.2471 - default:
14.2472 - assert(0);
14.2473 - break;
14.2474 - } /* switch */
14.2475 - if (mustdelete) {
14.2476 - root->next=sym->next;
14.2477 - free_symbol(sym);
14.2478 - } else {
14.2479 - /* if the function was prototyped, but not implemented in this source,
14.2480 - * mark it as such, so that its use can be flagged
14.2481 - */
14.2482 - if (sym->ident==iFUNCTN && (sym->usage & uDEFINE)==0)
14.2483 - sym->usage |= uMISSING;
14.2484 - if (sym->ident==iFUNCTN || sym->ident==iVARIABLE || sym->ident==iARRAY)
14.2485 - sym->usage &= ~uDEFINE; /* clear "defined" flag */
14.2486 - /* set all states as "undefined" too */
14.2487 - if (sym->states!=NULL)
14.2488 - for (stateptr=sym->states->next; stateptr!=NULL; stateptr=stateptr->next)
14.2489 - stateptr->value=0;
14.2490 - /* for user defined operators, also remove the "prototyped" flag, as
14.2491 - * user-defined operators *must* be declared before use
14.2492 - */
14.2493 - if (sym->ident==iFUNCTN && !alpha(*sym->name))
14.2494 - sym->usage &= ~uPROTOTYPED;
14.2495 - root=sym; /* skip the symbol */
14.2496 - } /* if */
14.2497 - } /* if */
14.2498 -}
14.2499 -
14.2500 -/* The purpose of the hash is to reduce the frequency of a "name"
14.2501 - * comparison (which is costly). There is little interest in avoiding
14.2502 - * clusters in similar names, which is why this function is plain simple.
14.2503 - */
14.2504 -SC_FUNC uint32_t namehash(const char *name)
14.2505 -{
14.2506 - const unsigned char *ptr=(const unsigned char *)name;
14.2507 - int len=strlen(name);
14.2508 - if (len==0)
14.2509 - return 0L;
14.2510 - assert(len<256);
14.2511 - return (len<<24Lu) + (ptr[0]<<16Lu) + (ptr[len-1]<<8Lu) + (ptr[len>>1Lu]);
14.2512 -}
14.2513 -
14.2514 -static symbol *find_symbol(const symbol *root,const char *name,int fnumber,int automaton,int *cmptag)
14.2515 -{
14.2516 - symbol *firstmatch=NULL;
14.2517 - symbol *sym=root->next;
14.2518 - int count=0;
14.2519 - unsigned long hash=namehash(name);
14.2520 - while (sym!=NULL) {
14.2521 - if (hash==sym->hash && strcmp(name,sym->name)==0 /* check name */
14.2522 - && (sym->parent==NULL || sym->ident==iCONSTEXPR) /* sub-types (hierarchical types) are skipped, except for enum fields */
14.2523 - && (sym->fnumber<0 || sym->fnumber==fnumber)) /* check file number for scope */
14.2524 - {
14.2525 - assert(sym->states==NULL || sym->states->next!=NULL); /* first element of the state list is the "root" */
14.2526 - if (sym->ident==iFUNCTN
14.2527 - || automaton<0 && sym->states==NULL
14.2528 - || automaton>=0 && sym->states!=NULL && state_getfsa(sym->states->next->index)==automaton)
14.2529 - {
14.2530 - if (cmptag==NULL)
14.2531 - return sym; /* return first match */
14.2532 - /* return closest match or first match; count number of matches */
14.2533 - if (firstmatch==NULL)
14.2534 - firstmatch=sym;
14.2535 - assert(cmptag!=NULL);
14.2536 - if (*cmptag==0)
14.2537 - count++;
14.2538 - if (*cmptag==sym->tag) {
14.2539 - *cmptag=1; /* good match found, set number of matches to 1 */
14.2540 - return sym;
14.2541 - } /* if */
14.2542 - } /* if */
14.2543 - } /* */
14.2544 - sym=sym->next;
14.2545 - } /* while */
14.2546 - if (cmptag!=NULL && firstmatch!=NULL)
14.2547 - *cmptag=count;
14.2548 - return firstmatch;
14.2549 -}
14.2550 -
14.2551 -static symbol *find_symbol_child(const symbol *root,const symbol *sym)
14.2552 -{
14.2553 - symbol *ptr=root->next;
14.2554 - while (ptr!=NULL) {
14.2555 - if (ptr->parent==sym)
14.2556 - return ptr;
14.2557 - ptr=ptr->next;
14.2558 - } /* while */
14.2559 - return NULL;
14.2560 -}
14.2561 -
14.2562 -/* Adds "bywhom" to the list of referrers of "entry". Typically,
14.2563 - * bywhom will be the function that uses a variable or that calls
14.2564 - * the function.
14.2565 - */
14.2566 -SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom)
14.2567 -{
14.2568 - int count;
14.2569 -
14.2570 - assert(bywhom!=NULL); /* it makes no sense to add a "void" referrer */
14.2571 - assert(entry!=NULL);
14.2572 - assert(entry->refer!=NULL);
14.2573 -
14.2574 - /* see if it is already there */
14.2575 - for (count=0; count<entry->numrefers && entry->refer[count]!=bywhom; count++)
14.2576 - /* nothing */;
14.2577 - if (count<entry->numrefers) {
14.2578 - assert(entry->refer[count]==bywhom);
14.2579 - return TRUE;
14.2580 - } /* if */
14.2581 -
14.2582 - /* see if there is an empty spot in the referrer list */
14.2583 - for (count=0; count<entry->numrefers && entry->refer[count]!=NULL; count++)
14.2584 - /* nothing */;
14.2585 - assert(count <= entry->numrefers);
14.2586 - if (count==entry->numrefers) {
14.2587 - symbol **refer;
14.2588 - int newsize=2*entry->numrefers;
14.2589 - assert(newsize>0);
14.2590 - /* grow the referrer list */
14.2591 - refer=(symbol**)realloc(entry->refer,newsize*sizeof(symbol*));
14.2592 - if (refer==NULL)
14.2593 - return FALSE; /* insufficient memory */
14.2594 - /* initialize the new entries */
14.2595 - entry->refer=refer;
14.2596 - for (count=entry->numrefers; count<newsize; count++)
14.2597 - entry->refer[count]=NULL;
14.2598 - count=entry->numrefers; /* first empty spot */
14.2599 - entry->numrefers=newsize;
14.2600 - } /* if */
14.2601 -
14.2602 - /* add the referrer */
14.2603 - assert(entry->refer[count]==NULL);
14.2604 - entry->refer[count]=bywhom;
14.2605 - return TRUE;
14.2606 -}
14.2607 -
14.2608 -SC_FUNC void markusage(symbol *sym,int usage)
14.2609 -{
14.2610 - assert(sym!=NULL);
14.2611 - sym->usage |= (char)usage;
14.2612 - if ((usage & uWRITTEN)!=0)
14.2613 - sym->lnumber=fline;
14.2614 - /* check if (global) reference must be added to the symbol */
14.2615 - if ((usage & (uREAD | uWRITTEN))!=0) {
14.2616 - /* only do this for global symbols */
14.2617 - if (sym->vclass==sGLOBAL) {
14.2618 - /* "curfunc" should always be valid, since statements may not occurs
14.2619 - * outside functions; in the case of syntax errors, however, the
14.2620 - * compiler may arrive through this function
14.2621 - */
14.2622 - if (curfunc!=NULL)
14.2623 - refer_symbol(sym,curfunc);
14.2624 - } /* if */
14.2625 - } /* if */
14.2626 -}
14.2627 -
14.2628 -
14.2629 -/* findglb
14.2630 - *
14.2631 - * Returns a pointer to the global symbol (if found) or NULL (if not found)
14.2632 - */
14.2633 -SC_FUNC symbol *findglb(const char *name,int filter)
14.2634 -{
14.2635 - /* find a symbol with a matching automaton first */
14.2636 - symbol *sym=NULL;
14.2637 -
14.2638 - if (filter>sGLOBAL && sc_curstates>0) {
14.2639 - /* find a symbol whose state list matches the current fsa */
14.2640 - sym=find_symbol(&glbtab,name,fcurrent,state_getfsa(sc_curstates),NULL);
14.2641 - if (sym!=NULL && sym->ident!=iFUNCTN) {
14.2642 - /* if sym!=NULL, we found a variable in the automaton; now we should
14.2643 - * also verify whether there is an intersection between the symbol's
14.2644 - * state list and the current state list
14.2645 - */
14.2646 - assert(sym->states!=NULL && sym->states->next!=NULL);
14.2647 - if (!state_conflict_id(sc_curstates,sym->states->next->index))
14.2648 - sym=NULL;
14.2649 - } /* if */
14.2650 - } /* if */
14.2651 -
14.2652 - /* if no symbol with a matching automaton exists, find a variable/function
14.2653 - * that has no state(s) attached to it
14.2654 - */
14.2655 - if (sym==NULL)
14.2656 - sym=find_symbol(&glbtab,name,fcurrent,-1,NULL);
14.2657 - return sym;
14.2658 -}
14.2659 -
14.2660 -/* findloc
14.2661 - *
14.2662 - * Returns a pointer to the local symbol (if found) or NULL (if not found).
14.2663 - * See add_symbol() how the deepest nesting level is searched first.
14.2664 - */
14.2665 -SC_FUNC symbol *findloc(const char *name)
14.2666 -{
14.2667 - return find_symbol(&loctab,name,-1,-1,NULL);
14.2668 -}
14.2669 -
14.2670 -SC_FUNC symbol *findconst(const char *name,int *cmptag)
14.2671 -{
14.2672 - symbol *sym;
14.2673 -
14.2674 - sym=find_symbol(&loctab,name,-1,-1,cmptag); /* try local symbols first */
14.2675 - if (sym==NULL || sym->ident!=iCONSTEXPR) /* not found, or not a constant */
14.2676 - sym=find_symbol(&glbtab,name,fcurrent,-1,cmptag);
14.2677 - if (sym==NULL || sym->ident!=iCONSTEXPR)
14.2678 - return NULL;
14.2679 - assert(sym->parent==NULL || (sym->usage & uENUMFIELD)!=0);
14.2680 - /* ^^^ constants have no hierarchy, but enumeration fields may have a parent */
14.2681 - return sym;
14.2682 -}
14.2683 -
14.2684 -SC_FUNC symbol *finddepend(const symbol *parent)
14.2685 -{
14.2686 - symbol *sym;
14.2687 -
14.2688 - sym=find_symbol_child(&loctab,parent); /* try local symbols first */
14.2689 - if (sym==NULL) /* not found */
14.2690 - sym=find_symbol_child(&glbtab,parent);
14.2691 - return sym;
14.2692 -}
14.2693 -
14.2694 -/* addsym
14.2695 - *
14.2696 - * Adds a symbol to the symbol table (either global or local variables,
14.2697 - * or global and local constants).
14.2698 - */
14.2699 -SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,int usage)
14.2700 -{
14.2701 - symbol entry, **refer;
14.2702 -
14.2703 - /* labels may only be defined once */
14.2704 - assert(ident!=iLABEL || findloc(name)==NULL);
14.2705 -
14.2706 - /* create an empty referrer list */
14.2707 - if ((refer=(symbol**)malloc(sizeof(symbol*)))==NULL) {
14.2708 - error(103); /* insufficient memory */
14.2709 - return NULL;
14.2710 - } /* if */
14.2711 - *refer=NULL;
14.2712 -
14.2713 - /* first fill in the entry */
14.2714 - memset(&entry,0,sizeof entry);
14.2715 - strcpy(entry.name,name);
14.2716 - entry.hash=namehash(name);
14.2717 - entry.addr=addr;
14.2718 - entry.codeaddr=code_idx;
14.2719 - entry.vclass=(char)vclass;
14.2720 - entry.ident=(char)ident;
14.2721 - entry.tag=tag;
14.2722 - entry.usage=(char)usage;
14.2723 - entry.fnumber=-1; /* assume global visibility (ignored for local symbols) */
14.2724 - entry.lnumber=fline;
14.2725 - entry.numrefers=1;
14.2726 - entry.refer=refer;
14.2727 -
14.2728 - /* then insert it in the list */
14.2729 - if (vclass==sGLOBAL)
14.2730 - return add_symbol(&glbtab,&entry,TRUE);
14.2731 - else
14.2732 - return add_symbol(&loctab,&entry,FALSE);
14.2733 -}
14.2734 -
14.2735 -SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
14.2736 - int dim[],int numdim,int idxtag[])
14.2737 -{
14.2738 - symbol *sym;
14.2739 -
14.2740 - /* global variables may only be defined once
14.2741 - * One complication is that functions returning arrays declare an array
14.2742 - * with the same name as the function, so the assertion must allow for
14.2743 - * this special case. Another complication is that variables may be
14.2744 - * "redeclared" if they are local to an automaton (and findglb() will find
14.2745 - * the symbol without states if no symbol with states exists).
14.2746 - */
14.2747 - assert(vclass!=sGLOBAL || (sym=findglb(name,sGLOBAL))==NULL || (sym->usage & uDEFINE)==0
14.2748 - || sym->ident==iFUNCTN && sym==curfunc
14.2749 - || sym->states==NULL && sc_curstates>0);
14.2750 -
14.2751 - if (ident==iARRAY || ident==iREFARRAY) {
14.2752 - symbol *parent=NULL,*top;
14.2753 - int level;
14.2754 - sym=NULL; /* to avoid a compiler warning */
14.2755 - for (level=0; level<numdim; level++) {
14.2756 - top=addsym(name,addr,ident,vclass,tag,uDEFINE);
14.2757 - top->dim.array.length=dim[level];
14.2758 - top->dim.array.level=(short)(numdim-level-1);
14.2759 - top->x.tags.index=idxtag[level];
14.2760 - top->parent=parent;
14.2761 - parent=top;
14.2762 - if (level==0)
14.2763 - sym=top;
14.2764 - } /* for */
14.2765 - } else {
14.2766 - sym=addsym(name,addr,ident,vclass,tag,uDEFINE);
14.2767 - } /* if */
14.2768 - return sym;
14.2769 -}
14.2770 -
14.2771 -/* getlabel
14.2772 - *
14.2773 - * Returns te next internal label number. The global variable sc_labnum is
14.2774 - * initialized to zero.
14.2775 - */
14.2776 -SC_FUNC int getlabel(void)
14.2777 -{
14.2778 - return sc_labnum++;
14.2779 -}
14.2780 -
14.2781 -/* itoh
14.2782 - *
14.2783 - * Converts a number to a hexadecimal string and returns a pointer to that
14.2784 - * string. This function is NOT re-entrant.
14.2785 - */
14.2786 -SC_FUNC char *itoh(ucell val)
14.2787 -{
14.2788 -static char itohstr[30];
14.2789 - char *ptr;
14.2790 - int i,nibble[16]; /* a 64-bit hexadecimal cell has 16 nibbles */
14.2791 - int max;
14.2792 -
14.2793 - #if PAWN_CELL_SIZE==16
14.2794 - max=4;
14.2795 - #elif PAWN_CELL_SIZE==32
14.2796 - max=8;
14.2797 - #elif PAWN_CELL_SIZE==64
14.2798 - max=16;
14.2799 - #else
14.2800 - #error Unsupported cell size
14.2801 - #endif
14.2802 - ptr=itohstr;
14.2803 - for (i=0; i<max; i+=1){
14.2804 - nibble[i]=(int)(val & 0x0f); /* nibble 0 is lowest nibble */
14.2805 - val>>=4;
14.2806 - } /* endfor */
14.2807 - i=max-1;
14.2808 - while (nibble[i]==0 && i>0) /* search for highest non-zero nibble */
14.2809 - i-=1;
14.2810 - while (i>=0){
14.2811 - if (nibble[i]>=10)
14.2812 - *ptr++=(char)('a'+(nibble[i]-10));
14.2813 - else
14.2814 - *ptr++=(char)('0'+nibble[i]);
14.2815 - i-=1;
14.2816 - } /* while */
14.2817 - *ptr='\0'; /* and a zero-terminator */
14.2818 - return itohstr;
14.2819 -}
14.2820 -
15.1 --- a/compiler-init/sc3.c Sat Jul 15 05:02:38 2006 +0000
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,2469 +0,0 @@
15.4 -/* Pawn compiler - Recursive descend expresion parser
15.5 - *
15.6 - * Copyright (c) ITB CompuPhase, 1997-2005
15.7 - *
15.8 - * This software is provided "as-is", without any express or implied warranty.
15.9 - * In no event will the authors be held liable for any damages arising from
15.10 - * the use of this software.
15.11 - *
15.12 - * Permission is granted to anyone to use this software for any purpose,
15.13 - * including commercial applications, and to alter it and redistribute it
15.14 - * freely, subject to the following restrictions:
15.15 - *
15.16 - * 1. The origin of this software must not be misrepresented; you must not
15.17 - * claim that you wrote the original software. If you use this software in
15.18 - * a product, an acknowledgment in the product documentation would be
15.19 - * appreciated but is not required.
15.20 - * 2. Altered source versions must be plainly marked as such, and must not be
15.21 - * misrepresented as being the original software.
15.22 - * 3. This notice may not be removed or altered from any source distribution.
15.23 - *
15.24 - * Version: $Id: sc3.c 3598 2006-07-04 13:44:04Z thiadmer $
15.25 - */
15.26 -#include <assert.h>
15.27 -#include <stdio.h>
15.28 -#include <stdlib.h> /* for _MAX_PATH */
15.29 -#include <string.h>
15.30 -#if defined FORTIFY
15.31 - #include <alloc/fortify.h>
15.32 -#endif
15.33 -#include "sc.h"
15.34 -
15.35 -static int skim(int *opstr,void (*testfunc)(int),int dropval,int endval,
15.36 - int (*hier)(value*),value *lval);
15.37 -static void dropout(int lvalue,void (*testfunc)(int val),int exit1,value *lval);
15.38 -static int plnge(int *opstr,int opoff,int (*hier)(value *lval),value *lval,
15.39 - char *forcetag,int chkbitwise);
15.40 -static int plnge1(int (*hier)(value *lval),value *lval);
15.41 -static void plnge2(void (*oper)(void),
15.42 - int (*hier)(value *lval),
15.43 - value *lval1,value *lval2);
15.44 -static cell calc(cell left,void (*oper)(),cell right,char *boolresult);
15.45 -static int hier14(value *lval);
15.46 -static int hier13(value *lval);
15.47 -static int hier12(value *lval);
15.48 -static int hier11(value *lval);
15.49 -static int hier10(value *lval);
15.50 -static int hier9(value *lval);
15.51 -static int hier8(value *lval);
15.52 -static int hier7(value *lval);
15.53 -static int hier6(value *lval);
15.54 -static int hier5(value *lval);
15.55 -static int hier4(value *lval);
15.56 -static int hier3(value *lval);
15.57 -static int hier2(value *lval);
15.58 -static int hier1(value *lval1);
15.59 -static int primary(value *lval);
15.60 -static void clear_value(value *lval);
15.61 -static void callfunction(symbol *sym,value *lval_result,int matchparanthesis);
15.62 -static int dbltest(void (*oper)(),value *lval1,value *lval2);
15.63 -static int commutative(void (*oper)());
15.64 -static int constant(value *lval);
15.65 -
15.66 -static char lastsymbol[sNAMEMAX+1]; /* name of last function/variable */
15.67 -static int bitwise_opercount; /* count of bitwise operators in an expression */
15.68 -static int decl_heap=0;
15.69 -
15.70 -/* Function addresses of binary operators for signed operations */
15.71 -static void (*op1[17])(void) = {
15.72 - os_mult,os_div,os_mod, /* hier3, index 0 */
15.73 - ob_add,ob_sub, /* hier4, index 3 */
15.74 - ob_sal,os_sar,ou_sar, /* hier5, index 5 */
15.75 - ob_and, /* hier6, index 8 */
15.76 - ob_xor, /* hier7, index 9 */
15.77 - ob_or, /* hier8, index 10 */
15.78 - os_le,os_ge,os_lt,os_gt, /* hier9, index 11 */
15.79 - ob_eq,ob_ne, /* hier10, index 15 */
15.80 -};
15.81 -/* These two functions are defined because the functions inc() and dec() in
15.82 - * SC4.C have a different prototype than the other code generation functions.
15.83 - * The arrays for user-defined functions use the function pointers for
15.84 - * identifying what kind of operation is requested; these functions must all
15.85 - * have the same prototype. As inc() and dec() are special cases already, it
15.86 - * is simplest to add two "do-nothing" functions.
15.87 - */
15.88 -static void user_inc(void) {}
15.89 -static void user_dec(void) {}
15.90 -
15.91 -/*
15.92 - * Searches for a binary operator a list of operators. The list is stored in
15.93 - * the array "list". The last entry in the list should be set to 0.
15.94 - *
15.95 - * The index of an operator in "list" (if found) is returned in "opidx". If
15.96 - * no operator is found, nextop() returns 0.
15.97 - *
15.98 - * If an operator is found in the expression, it cannot be used in a function
15.99 - * call with omitted parantheses. Mark this...
15.100 - *
15.101 - * Global references: sc_allowproccall (modified)
15.102 - */
15.103 -static int nextop(int *opidx,int *list)
15.104 -{
15.105 - *opidx=0;
15.106 - while (*list){
15.107 - if (matchtoken(*list)){
15.108 - sc_allowproccall=FALSE;
15.109 - return TRUE; /* found! */
15.110 - } else {
15.111 - list+=1;
15.112 - *opidx+=1;
15.113 - } /* if */
15.114 - } /* while */
15.115 - return FALSE; /* entire list scanned, nothing found */
15.116 -}
15.117 -
15.118 -SC_FUNC int check_userop(void (*oper)(void),int tag1,int tag2,int numparam,
15.119 - value *lval,int *resulttag)
15.120 -{
15.121 -static char *binoperstr[] = { "*", "/", "%", "+", "-", "", "", "",
15.122 - "", "", "", "<=", ">=", "<", ">", "==", "!=" };
15.123 -static int binoper_savepri[] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
15.124 - FALSE, FALSE, FALSE, FALSE, FALSE,
15.125 - TRUE, TRUE, TRUE, TRUE, FALSE, FALSE };
15.126 -static char *unoperstr[] = { "!", "-", "++", "--" };
15.127 -static void (*unopers[])(void) = { lneg, neg, user_inc, user_dec };
15.128 - char opername[4] = "", symbolname[sNAMEMAX+1];
15.129 - int i,swapparams,savepri,savealt;
15.130 - int paramspassed;
15.131 - symbol *sym;
15.132 -
15.133 - /* since user-defined operators on untagged operands are forbidden, we have
15.134 - * a quick exit.
15.135 - */
15.136 - assert(numparam==1 || numparam==2);
15.137 - if (tag1==0 && (numparam==1 || tag2==0))
15.138 - return FALSE;
15.139 -
15.140 - savepri=savealt=FALSE;
15.141 - /* find the name with the operator */
15.142 - if (numparam==2) {
15.143 - if (oper==NULL) {
15.144 - /* assignment operator: a special case */
15.145 - strcpy(opername,"=");
15.146 - if (lval!=NULL && (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR))
15.147 - savealt=TRUE;
15.148 - } else {
15.149 - assert( (sizeof binoperstr / sizeof binoperstr[0]) == (sizeof op1 / sizeof op1[0]) );
15.150 - for (i=0; i<sizeof op1 / sizeof op1[0]; i++) {
15.151 - if (oper==op1[i]) {
15.152 - strcpy(opername,binoperstr[i]);
15.153 - savepri=binoper_savepri[i];
15.154 - break;
15.155 - } /* if */
15.156 - } /* for */
15.157 - } /* if */
15.158 - } else {
15.159 - assert(oper!=NULL);
15.160 - assert(numparam==1);
15.161 - /* try a select group of unary operators */
15.162 - assert( (sizeof unoperstr / sizeof unoperstr[0]) == (sizeof unopers / sizeof unopers[0]) );
15.163 - if (opername[0]=='\0') {
15.164 - for (i=0; i<sizeof unopers / sizeof unopers[0]; i++) {
15.165 - if (oper==unopers[i]) {
15.166 - strcpy(opername,unoperstr[i]);
15.167 - break;
15.168 - } /* if */
15.169 - } /* for */
15.170 - } /* if */
15.171 - } /* if */
15.172 - /* if not found, quit */
15.173 - if (opername[0]=='\0')
15.174 - return FALSE;
15.175 -
15.176 - /* create a symbol name from the tags and the operator name */
15.177 - assert(numparam==1 || numparam==2);
15.178 - operator_symname(symbolname,opername,tag1,tag2,numparam,tag2);
15.179 - swapparams=FALSE;
15.180 - sym=findglb(symbolname,sGLOBAL);
15.181 - if (sym==NULL /*|| (sym->usage & uDEFINE)==0*/) { /* ??? should not check uDEFINE; first pass clears these bits */
15.182 - /* check for commutative operators */
15.183 - if (tag1==tag2 || oper==NULL || !commutative(oper))
15.184 - return FALSE; /* not commutative, cannot swap operands */
15.185 - /* if arrived here, the operator is commutative and the tags are different,
15.186 - * swap tags and try again
15.187 - */
15.188 - assert(numparam==2); /* commutative operator must be a binary operator */
15.189 - operator_symname(symbolname,opername,tag2,tag1,numparam,tag1);
15.190 - swapparams=TRUE;
15.191 - sym=findglb(symbolname,sGLOBAL);
15.192 - if (sym==NULL /*|| (sym->usage & uDEFINE)==0*/)
15.193 - return FALSE;
15.194 - } /* if */
15.195 -
15.196 - /* check existance and the proper declaration of this function */
15.197 - if ((sym->usage & uMISSING)!=0 || (sym->usage & uPROTOTYPED)==0) {
15.198 - char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
15.199 - funcdisplayname(symname,sym->name);
15.200 - if ((sym->usage & uMISSING)!=0)
15.201 - error(4,symname); /* function not defined */
15.202 - if ((sym->usage & uPROTOTYPED)==0)
15.203 - error(71,symname); /* operator must be declared before use */
15.204 - } /* if */
15.205 -
15.206 - /* we don't want to use the redefined operator in the function that
15.207 - * redefines the operator itself, otherwise the snippet below gives
15.208 - * an unexpected recursion:
15.209 - * fixed:operator+(fixed:a, fixed:b)
15.210 - * return a + b
15.211 - */
15.212 - if (sym==curfunc)
15.213 - return FALSE;
15.214 -
15.215 - /* for increment and decrement operators, the symbol must first be loaded
15.216 - * (and stored back afterwards)
15.217 - */
15.218 - if (oper==user_inc || oper==user_dec) {
15.219 - assert(!savepri);
15.220 - assert(lval!=NULL);
15.221 - if (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR)
15.222 - pushreg(sPRI); /* save current address in PRI */
15.223 - rvalue(lval); /* get the symbol's value in PRI */
15.224 - } /* if */
15.225 -
15.226 - assert(!savepri || !savealt); /* either one MAY be set, but not both */
15.227 - if (savepri) {
15.228 - /* the chained comparison operators require that the ALT register is
15.229 - * unmodified, so we save it here; actually, we save PRI because the normal
15.230 - * instruction sequence (without user operator) swaps PRI and ALT
15.231 - */
15.232 - pushreg(sPRI); /* right-hand operand is in PRI */
15.233 - } else if (savealt) {
15.234 - /* for the assignment operator, ALT may contain an address at which the
15.235 - * result must be stored; this address must be preserved accross the
15.236 - * call
15.237 - */
15.238 - assert(lval!=NULL); /* this was checked earlier */
15.239 - assert(lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR); /* checked earlier */
15.240 - pushreg(sALT);
15.241 - } /* if */
15.242 -
15.243 - /* push parameters, call the function */
15.244 - paramspassed= (oper==NULL) ? 1 : numparam;
15.245 - switch (paramspassed) {
15.246 - case 1:
15.247 - pushreg(sPRI);
15.248 - break;
15.249 - case 2:
15.250 - /* note that 1) a function expects that the parameters are pushed
15.251 - * in reversed order, and 2) the left operand is in the secondary register
15.252 - * and the right operand is in the primary register */
15.253 - if (swapparams) {
15.254 - pushreg(sALT);
15.255 - pushreg(sPRI);
15.256 - } else {
15.257 - pushreg(sPRI);
15.258 - pushreg(sALT);
15.259 - } /* if */
15.260 - break;
15.261 - default:
15.262 - assert(0);
15.263 - } /* switch */
15.264 - markexpr(sPARM,NULL,0); /* mark the end of a sub-expression */
15.265 - pushval((cell)paramspassed*sizeof(cell));
15.266 - assert(sym->ident==iFUNCTN);
15.267 - ffcall(sym,NULL,paramspassed);
15.268 - if (sc_status!=statSKIP)
15.269 - markusage(sym,uREAD); /* do not mark as "used" when this call itself is skipped */
15.270 - if ((sym->usage & uNATIVE)!=0 && sym->x.lib!=NULL)
15.271 - sym->x.lib->value += 1; /* increment "usage count" of the library */
15.272 - sideeffect=TRUE; /* assume functions carry out a side-effect */
15.273 - assert(resulttag!=NULL);
15.274 - *resulttag=sym->tag; /* save tag of the called function */
15.275 -
15.276 - if (savepri || savealt)
15.277 - popreg(sALT); /* restore the saved PRI/ALT that into ALT */
15.278 - if (oper==user_inc || oper==user_dec) {
15.279 - assert(lval!=NULL);
15.280 - if (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR)
15.281 - popreg(sALT); /* restore address (in ALT) */
15.282 - store(lval); /* store PRI in the symbol */
15.283 - moveto1(); /* make sure PRI is restored on exit */
15.284 - } /* if */
15.285 - return TRUE;
15.286 -}
15.287 -
15.288 -SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce)
15.289 -{
15.290 - if (formaltag!=actualtag) {
15.291 - /* if the formal tag is zero and the actual tag is not "fixed", the actual
15.292 - * tag is "coerced" to zero
15.293 - */
15.294 - if (!allowcoerce || formaltag!=0 || (actualtag & FIXEDTAG)!=0)
15.295 - return FALSE;
15.296 - } /* if */
15.297 - return TRUE;
15.298 -}
15.299 -
15.300 -/*
15.301 - * The AMX pseudo-processor has no direct support for logical (boolean)
15.302 - * operations. These have to be done via comparing and jumping. Since we are
15.303 - * already jumping through the code, we might as well implement an "early
15.304 - * drop-out" evaluation (also called "short-circuit"). This conforms to
15.305 - * standard C:
15.306 - *
15.307 - * expr1 || expr2 expr2 will only be evaluated if expr1 is false.
15.308 - * expr1 && expr2 expr2 will only be evaluated if expr1 is true.
15.309 - *
15.310 - * expr1 || expr2 && expr3 expr2 will only be evaluated if expr1 is false
15.311 - * and expr3 will only be evaluated if expr1 is
15.312 - * false and expr2 is true.
15.313 - *
15.314 - * Code generation for the last example proceeds thus:
15.315 - *
15.316 - * evaluate expr1
15.317 - * operator || found
15.318 - * jump to "l1" if result of expr1 not equal to 0
15.319 - * evaluate expr2
15.320 - * -> operator && found; skip to higher level in hierarchy diagram
15.321 - * jump to "l2" if result of expr2 equal to 0
15.322 - * evaluate expr3
15.323 - * jump to "l2" if result of expr3 equal to 0
15.324 - * set expression result to 1 (true)
15.325 - * jump to "l3"
15.326 - * l2: set expression result to 0 (false)
15.327 - * l3:
15.328 - * <- drop back to previous hierarchy level
15.329 - * jump to "l1" if result of expr2 && expr3 not equal to 0
15.330 - * set expression result to 0 (false)
15.331 - * jump to "l4"
15.332 - * l1: set expression result to 1 (true)
15.333 - * l4:
15.334 - *
15.335 - */
15.336 -
15.337 -/* Skim over terms adjoining || and && operators
15.338 - * dropval The value of the expression after "dropping out". An "or" drops
15.339 - * out when the left hand is TRUE, so dropval must be 1 on "or"
15.340 - * expressions.
15.341 - * endval The value of the expression when no expression drops out. In an
15.342 - * "or" expression, this happens when both the left hand and the
15.343 - * right hand are FALSE, so endval must be 0 for "or" expressions.
15.344 - */
15.345 -static int skim(int *opstr,void (*testfunc)(int),int dropval,int endval,
15.346 - int (*hier)(value*),value *lval)
15.347 -{
15.348 - int lvalue,hits,droplab,endlab,opidx;
15.349 - int allconst,foundop;
15.350 - cell constval;
15.351 - int index;
15.352 - cell cidx;
15.353 -
15.354 - stgget(&index,&cidx); /* mark position in code generator */
15.355 - hits=FALSE; /* no logical operators "hit" yet */
15.356 - allconst=TRUE; /* assume all values "const" */
15.357 - constval=0;
15.358 - droplab=0; /* to avoid a compiler warning */
15.359 - for ( ;; ) {
15.360 - lvalue=plnge1(hier,lval); /* evaluate left expression */
15.361 -
15.362 - allconst= allconst && (lval->ident==iCONSTEXPR);
15.363 - if (allconst) {
15.364 - if (hits) {
15.365 - /* one operator was already found */
15.366 - if (testfunc==jmp_ne0)
15.367 - lval->constval= lval->constval || constval;
15.368 - else
15.369 - lval->constval= lval->constval && constval;
15.370 - } /* if */
15.371 - constval=lval->constval; /* save result accumulated so far */
15.372 - } /* if */
15.373 -
15.374 - foundop=nextop(&opidx,opstr);
15.375 - if ((foundop || hits) && (lval->ident==iARRAY || lval->ident==iREFARRAY))
15.376 - error(33, lval->sym ? (lval->sym->name ? lval->sym->name : "-unknown") : "-unknown-"); /* array was not indexed in an expression */
15.377 - if (foundop) {
15.378 - if (!hits) {
15.379 - /* this is the first operator in the list */
15.380 - hits=TRUE;
15.381 - droplab=getlabel();
15.382 - } /* if */
15.383 - dropout(lvalue,testfunc,droplab,lval);
15.384 - } else if (hits) { /* no (more) identical operators */
15.385 - dropout(lvalue,testfunc,droplab,lval); /* found at least one operator! */
15.386 - ldconst(endval,sPRI);
15.387 - jumplabel(endlab=getlabel());
15.388 - setlabel(droplab);
15.389 - ldconst(dropval,sPRI);
15.390 - setlabel(endlab);
15.391 - lval->sym=NULL;
15.392 - lval->tag=pc_addtag("bool"); /* force tag to be "bool" */
15.393 - if (allconst) {
15.394 - lval->ident=iCONSTEXPR;
15.395 - lval->constval=constval;
15.396 - stgdel(index,cidx); /* scratch generated code and calculate */
15.397 - } else {
15.398 - lval->ident=iEXPRESSION;
15.399 - lval->constval=0;
15.400 - } /* if */
15.401 - return FALSE;
15.402 - } else {
15.403 - return lvalue; /* none of the operators in "opstr" were found */
15.404 - } /* if */
15.405 -
15.406 - } /* while */
15.407 -}
15.408 -
15.409 -/*
15.410 - * Reads into the primary register the variable pointed to by lval if
15.411 - * plunging through the hierarchy levels detected an lvalue. Otherwise
15.412 - * if a constant was detected, it is loaded. If there is no constant and
15.413 - * no lvalue, the primary register must already contain the expression
15.414 - * result.
15.415 - *
15.416 - * After that, the compare routines "jmp_ne0" or "jmp_eq0" are called, which
15.417 - * compare the primary register against 0, and jump to the "early drop-out"
15.418 - * label "exit1" if the condition is true.
15.419 - */
15.420 -static void dropout(int lvalue,void (*testfunc)(int val),int exit1,value *lval)
15.421 -{
15.422 - if (lvalue)
15.423 - rvalue(lval);
15.424 - else if (lval->ident==iCONSTEXPR)
15.425 - ldconst(lval->constval,sPRI);
15.426 - (*testfunc)(exit1);
15.427 -}
15.428 -
15.429 -static void checkfunction(value *lval)
15.430 -{
15.431 - symbol *sym=lval->sym;
15.432 -
15.433 - if (sym==NULL || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC))
15.434 - return; /* no known symbol, or not a function result */
15.435 -
15.436 - if ((sym->usage & uDEFINE)!=0) {
15.437 - /* function is defined, can now check the return value (but make an
15.438 - * exception for directly recursive functions)
15.439 - */
15.440 - if (sym!=curfunc && (sym->usage & uRETVALUE)==0) {
15.441 - char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
15.442 - funcdisplayname(symname,sym->name);
15.443 - error(209,symname); /* function should return a value */
15.444 - } /* if */
15.445 - } else {
15.446 - /* function not yet defined, set */
15.447 - sym->usage|=uRETVALUE; /* make sure that a future implementation of
15.448 - * the function uses "return <value>" */
15.449 - } /* if */
15.450 -}
15.451 -
15.452 -/*
15.453 - * Plunge to a lower level
15.454 - */
15.455 -static int plnge(int *opstr,int opoff,int (*hier)(value *lval),value *lval,
15.456 - char *forcetag,int chkbitwise)
15.457 -{
15.458 - int lvalue,opidx;
15.459 - int count;
15.460 - value lval2 = {0};
15.461 -
15.462 - lvalue=plnge1(hier,lval);
15.463 - if (nextop(&opidx,opstr)==0)
15.464 - return lvalue; /* no operator in "opstr" found */
15.465 - if (lvalue)
15.466 - rvalue(lval);
15.467 - count=0;
15.468 - do {
15.469 - if (chkbitwise && count++>0 && bitwise_opercount!=0)
15.470 - error(212);
15.471 - opidx+=opoff; /* add offset to index returned by nextop() */
15.472 - plnge2(op1[opidx],hier,lval,&lval2);
15.473 - if (op1[opidx]==ob_and || op1[opidx]==ob_or)
15.474 - bitwise_opercount++;
15.475 - if (forcetag!=NULL)
15.476 - lval->tag=pc_addtag(forcetag);
15.477 - } while (nextop(&opidx,opstr)); /* do */
15.478 - return FALSE; /* result of expression is not an lvalue */
15.479 -}
15.480 -
15.481 -/* plnge_rel
15.482 - *
15.483 - * Binary plunge to lower level; this is very simular to plnge, but
15.484 - * it has special code generation sequences for chained operations.
15.485 - */
15.486 -static int plnge_rel(int *opstr,int opoff,int (*hier)(value *lval),value *lval)
15.487 -{
15.488 - int lvalue,opidx;
15.489 - value lval2={0};
15.490 - int count;
15.491 -
15.492 - /* this function should only be called for relational operators */
15.493 - assert(op1[opoff]==os_le);
15.494 - lvalue=plnge1(hier,lval);
15.495 - if (nextop(&opidx,opstr)==0)
15.496 - return lvalue; /* no operator in "opstr" found */
15.497 - if (lvalue)
15.498 - rvalue(lval);
15.499 - count=0;
15.500 - lval->boolresult=TRUE;
15.501 - do {
15.502 - /* same check as in plnge(), but "chkbitwise" is always TRUE */
15.503 - if (count>0 && bitwise_opercount!=0)
15.504 - error(212);
15.505 - if (count>0) {
15.506 - relop_prefix();
15.507 - *lval=lval2; /* copy right hand expression of the previous iteration */
15.508 - } /* if */
15.509 - opidx+=opoff;
15.510 - plnge2(op1[opidx],hier,lval,&lval2);
15.511 - if (count++>0)
15.512 - relop_suffix();
15.513 - } while (nextop(&opidx,opstr)); /* enddo */
15.514 - lval->constval=lval->boolresult;
15.515 - lval->tag=pc_addtag("bool"); /* force tag to be "bool" */
15.516 - return FALSE; /* result of expression is not an lvalue */
15.517 -}
15.518 -
15.519 -/* plnge1
15.520 - *
15.521 - * Unary plunge to lower level
15.522 - * Called by: skim(), plnge(), plnge2(), plnge_rel(), hier14() and hier13()
15.523 - */
15.524 -static int plnge1(int (*hier)(value *lval),value *lval)
15.525 -{
15.526 - int lvalue,index;
15.527 - cell cidx;
15.528 -
15.529 - stgget(&index,&cidx); /* mark position in code generator */
15.530 - lvalue=(*hier)(lval);
15.531 - if (lval->ident==iCONSTEXPR)
15.532 - stgdel(index,cidx); /* load constant later */
15.533 - return lvalue;
15.534 -}
15.535 -
15.536 -/* plnge2
15.537 - *
15.538 - * Binary plunge to lower level
15.539 - * Called by: plnge(), plnge_rel(), hier14() and hier1()
15.540 - */
15.541 -static void plnge2(void (*oper)(void),
15.542 - int (*hier)(value *lval),
15.543 - value *lval1,value *lval2)
15.544 -{
15.545 - int index;
15.546 - cell cidx;
15.547 -
15.548 - stgget(&index,&cidx); /* mark position in code generator */
15.549 - if (lval1->ident==iCONSTEXPR) { /* constant on left side; it is not yet loaded */
15.550 - if (plnge1(hier,lval2))
15.551 - rvalue(lval2); /* load lvalue now */
15.552 - else if (lval2->ident==iCONSTEXPR)
15.553 - ldconst(lval2->constval<<dbltest(oper,lval2,lval1),sPRI);
15.554 - ldconst(lval1->constval<<dbltest(oper,lval2,lval1),sALT);
15.555 - /* ^ doubling of constants operating on integer addresses */
15.556 - /* is restricted to "add" and "subtract" operators */
15.557 - } else { /* non-constant on left side */
15.558 - pushreg(sPRI);
15.559 - if (plnge1(hier,lval2))
15.560 - rvalue(lval2);
15.561 - if (lval2->ident==iCONSTEXPR) { /* constant on right side */
15.562 - if (commutative(oper)) { /* test for commutative operators */
15.563 - value lvaltmp = {0};
15.564 - stgdel(index,cidx); /* scratch pushreg() and constant fetch (then
15.565 - * fetch the constant again */
15.566 - ldconst(lval2->constval<<dbltest(oper,lval1,lval2),sALT);
15.567 - /* now, the primary register has the left operand and the secondary
15.568 - * register the right operand; swap the "lval" variables so that lval1
15.569 - * is associated with the secondary register and lval2 with the
15.570 - * primary register, as is the "normal" case.
15.571 - */
15.572 - lvaltmp=*lval1;
15.573 - *lval1=*lval2;
15.574 - *lval2=lvaltmp;
15.575 - } else {
15.576 - ldconst(lval2->constval<<dbltest(oper,lval1,lval2),sPRI);
15.577 - popreg(sALT); /* pop result of left operand into secondary register */
15.578 - } /* if */
15.579 - } else { /* non-constants on both sides */
15.580 - popreg(sALT);
15.581 - if (dbltest(oper,lval1,lval2))
15.582 - cell2addr(); /* double primary register */
15.583 - if (dbltest(oper,lval2,lval1))
15.584 - cell2addr_alt(); /* double secondary register */
15.585 - } /* if */
15.586 - } /* if */
15.587 - if (oper) {
15.588 - /* If used in an expression, a function should return a value.
15.589 - * If the function has been defined, we can check this. If the
15.590 - * function was not defined, we can set this requirement (so that
15.591 - * a future function definition can check this bit.
15.592 - */
15.593 - checkfunction(lval1);
15.594 - checkfunction(lval2);
15.595 - if (lval1->ident==iARRAY || lval1->ident==iREFARRAY) {
15.596 - char *ptr=(lval1->sym!=NULL) ? lval1->sym->name : "-unknown-";
15.597 - error(33,ptr); /* array must be indexed */
15.598 - } else if (lval2->ident==iARRAY || lval2->ident==iREFARRAY) {
15.599 - char *ptr=(lval2->sym!=NULL) ? lval2->sym->name : "-unknown-";
15.600 - error(33,ptr); /* array must be indexed */
15.601 - } /* if */
15.602 - /* ??? ^^^ should do same kind of error checking with functions */
15.603 -
15.604 - /* check whether an "operator" function is defined for the tag names
15.605 - * (a constant expression cannot be optimized in that case)
15.606 - */
15.607 - if (check_userop(oper,lval1->tag,lval2->tag,2,NULL,&lval1->tag)) {
15.608 - lval1->ident=iEXPRESSION;
15.609 - lval1->constval=0;
15.610 - } else if (lval1->ident==iCONSTEXPR && lval2->ident==iCONSTEXPR) {
15.611 - /* only constant expression if both constant */
15.612 - stgdel(index,cidx); /* scratch generated code and calculate */
15.613 - if (!matchtag(lval1->tag,lval2->tag,FALSE))
15.614 - error(213); /* tagname mismatch */
15.615 - lval1->constval=calc(lval1->constval,oper,lval2->constval,&lval1->boolresult);
15.616 - } else {
15.617 - if (!matchtag(lval1->tag,lval2->tag,FALSE))
15.618 - error(213); /* tagname mismatch */
15.619 - (*oper)(); /* do the (signed) operation */
15.620 - lval1->ident=iEXPRESSION;
15.621 - } /* if */
15.622 - } /* if */
15.623 -}
15.624 -
15.625 -static cell truemodulus(cell a,cell b)
15.626 -{
15.627 - return (a % b + b) % b;
15.628 -}
15.629 -
15.630 -static cell calc(cell left,void (*oper)(),cell right,char *boolresult)
15.631 -{
15.632 - if (oper==ob_or)
15.633 - return (left | right);
15.634 - else if (oper==ob_xor)
15.635 - return (left ^ right);
15.636 - else if (oper==ob_and)
15.637 - return (left & right);
15.638 - else if (oper==ob_eq)
15.639 - return (left == right);
15.640 - else if (oper==ob_ne)
15.641 - return (left != right);
15.642 - else if (oper==os_le)
15.643 - return *boolresult &= (char)(left <= right), right;
15.644 - else if (oper==os_ge)
15.645 - return *boolresult &= (char)(left >= right), right;
15.646 - else if (oper==os_lt)
15.647 - return *boolresult &= (char)(left < right), right;
15.648 - else if (oper==os_gt)
15.649 - return *boolresult &= (char)(left > right), right;
15.650 - else if (oper==os_sar)
15.651 - return (left >> (int)right);
15.652 - else if (oper==ou_sar)
15.653 - return ((ucell)left >> (ucell)right);
15.654 - else if (oper==ob_sal)
15.655 - return ((ucell)left << (int)right);
15.656 - else if (oper==ob_add)
15.657 - return (left + right);
15.658 - else if (oper==ob_sub)
15.659 - return (left - right);
15.660 - else if (oper==os_mult)
15.661 - return (left * right);
15.662 - else if (oper==os_div)
15.663 - return (left - truemodulus(left,right)) / right;
15.664 - else if (oper==os_mod)
15.665 - return truemodulus(left,right);
15.666 - else
15.667 - error(29); /* invalid expression, assumed 0 (this should never occur) */
15.668 - return 0;
15.669 -}
15.670 -
15.671 -SC_FUNC int expression(cell *val,int *tag,symbol **symptr,int chkfuncresult)
15.672 -{
15.673 - int locheap=decl_heap;
15.674 - value lval={0};
15.675 -
15.676 - if (hier14(&lval))
15.677 - rvalue(&lval);
15.678 - /* scrap any arrays left on the heap */
15.679 - assert(decl_heap>=locheap);
15.680 - modheap((locheap-decl_heap)*sizeof(cell)); /* remove heap space, so negative delta */
15.681 - decl_heap=locheap;
15.682 -
15.683 - if (lval.ident==iCONSTEXPR && val!=NULL) /* constant expression */
15.684 - *val=lval.constval;
15.685 - if (tag!=NULL)
15.686 - *tag=lval.tag;
15.687 - if (symptr!=NULL)
15.688 - *symptr=lval.sym;
15.689 - if (chkfuncresult)
15.690 - checkfunction(&lval);
15.691 - return lval.ident;
15.692 -}
15.693 -
15.694 -SC_FUNC int sc_getstateid(constvalue **automaton,constvalue **state)
15.695 -{
15.696 - char name[sNAMEMAX+1];
15.697 - cell val;
15.698 - char *str;
15.699 - int fsa,islabel;
15.700 -
15.701 - assert(automaton!=NULL);
15.702 - assert(state!=NULL);
15.703 - if (!(islabel=matchtoken(tLABEL)) && !needtoken(tSYMBOL))
15.704 - return 0;
15.705 -
15.706 - tokeninfo(&val,&str);
15.707 - assert(strlen(str)<sizeof name);
15.708 - strcpy(name,str);
15.709 - if (islabel || matchtoken(':')) {
15.710 - /* token is an automaton name, add the name and get a new token */
15.711 - *automaton=automaton_find(name);
15.712 - /* read in the state name before checking the automaton, to keep the parser
15.713 - * going (an "unknown automaton" error may occur when the "state" instruction
15.714 - * precedes any state definition)
15.715 - */
15.716 - if (!needtoken(tSYMBOL))
15.717 - return 0;
15.718 - tokeninfo(&val,&str); /* do not copy the name yet, must check automaton first */
15.719 - if (*automaton==NULL) {
15.720 - error(86,name); /* unknown automaton */
15.721 - return 0;
15.722 - } /* if */
15.723 - assert((*automaton)->index>0);
15.724 - assert(strlen(str)<sizeof name);
15.725 - strcpy(name,str);
15.726 - } else {
15.727 - *automaton=automaton_find("");
15.728 - assert(*automaton!=NULL);
15.729 - assert((*automaton)->index==0);
15.730 - } /* if */
15.731 - assert(*automaton!=NULL);
15.732 - fsa=(*automaton)->index;
15.733 -
15.734 - assert(*automaton!=NULL);
15.735 - *state=state_find(name,fsa);
15.736 - if (*state==NULL) {
15.737 - char *fsaname=(*automaton)->name;
15.738 - if (*fsaname=='\0')
15.739 - fsaname="<main>";
15.740 - error(87,name,fsaname); /* unknown state for automaton */
15.741 - return 0;
15.742 - } /* if */
15.743 -
15.744 - return 1;
15.745 -}
15.746 -
15.747 -SC_FUNC cell array_totalsize(symbol *sym)
15.748 -{
15.749 - cell length;
15.750 -
15.751 - assert(sym!=NULL);
15.752 - assert(sym->ident==iARRAY || sym->ident==iREFARRAY);
15.753 - length=sym->dim.array.length;
15.754 - if (sym->dim.array.level > 0) {
15.755 - cell sublength=array_totalsize(finddepend(sym));
15.756 - if (sublength>0)
15.757 - length=length+length*sublength;
15.758 - else
15.759 - length=0;
15.760 - } /* if */
15.761 - return length;
15.762 -}
15.763 -
15.764 -static cell array_levelsize(symbol *sym,int level)
15.765 -{
15.766 - assert(sym!=NULL);
15.767 - assert(sym->ident==iARRAY || sym->ident==iREFARRAY);
15.768 - assert(level <= sym->dim.array.level);
15.769 - while (level-- > 0) {
15.770 - sym=finddepend(sym);
15.771 - assert(sym!=NULL);
15.772 - } /* if */
15.773 - return sym->dim.array.length;
15.774 -}
15.775 -
15.776 -/* hier14
15.777 - *
15.778 - * Lowest hierarchy level (except for the , operator).
15.779 - *
15.780 - * Global references: sc_intest (reffered to only)
15.781 - * sc_allowproccall (modified)
15.782 - */
15.783 -static int hier14(value *lval1)
15.784 -{
15.785 - int lvalue;
15.786 - value lval2={0},lval3={0};
15.787 - void (*oper)(void);
15.788 - int tok,level,i;
15.789 - cell val;
15.790 - char *st;
15.791 - int bwcount,leftarray;
15.792 - cell arrayidx1[sDIMEN_MAX],arrayidx2[sDIMEN_MAX]; /* last used array indices */
15.793 - cell *org_arrayidx;
15.794 -
15.795 - bwcount=bitwise_opercount;
15.796 - bitwise_opercount=0;
15.797 - /* initialize the index arrays with unlikely constant indices; note that
15.798 - * these indices will only be changed when the array is indexed with a
15.799 - * constant, and that negative array indices are invalid (so actually, any
15.800 - * negative value would do).
15.801 - */
15.802 - for (i=0; i<sDIMEN_MAX; i++)
15.803 - arrayidx1[i]=arrayidx2[i]=(cell)(-1L << (sizeof(cell)*8-1));
15.804 - org_arrayidx=lval1->arrayidx; /* save current pointer, to reset later */
15.805 - if (lval1->arrayidx==NULL)
15.806 - lval1->arrayidx=arrayidx1;
15.807 - lvalue=plnge1(hier13,lval1);
15.808 - if (lval1->ident!=iARRAYCELL && lval1->ident!=iARRAYCHAR)
15.809 - lval1->arrayidx=NULL;
15.810 - if (lval1->ident==iCONSTEXPR) /* load constant here */
15.811 - ldconst(lval1->constval,sPRI);
15.812 - tok=lex(&val,&st);
15.813 - switch (tok) {
15.814 - case taOR:
15.815 - oper=ob_or;
15.816 - break;
15.817 - case taXOR:
15.818 - oper=ob_xor;
15.819 - break;
15.820 - case taAND:
15.821 - oper=ob_and;
15.822 - break;
15.823 - case taADD:
15.824 - oper=ob_add;
15.825 - break;
15.826 - case taSUB:
15.827 - oper=ob_sub;
15.828 - break;
15.829 - case taMULT:
15.830 - oper=os_mult;
15.831 - break;
15.832 - case taDIV:
15.833 - oper=os_div;
15.834 - break;
15.835 - case taMOD:
15.836 - oper=os_mod;
15.837 - break;
15.838 - case taSHRU:
15.839 - oper=ou_sar;
15.840 - break;
15.841 - case taSHR:
15.842 - oper=os_sar;
15.843 - break;
15.844 - case taSHL:
15.845 - oper=ob_sal;
15.846 - break;
15.847 - case '=': /* simple assignment */
15.848 - oper=NULL;
15.849 - if (sc_intest)
15.850 - error(211); /* possibly unintended assignment */
15.851 - break;
15.852 - default:
15.853 - lexpush();
15.854 - bitwise_opercount=bwcount;
15.855 - lval1->arrayidx=org_arrayidx; /* restore array index pointer */
15.856 - return lvalue;
15.857 - } /* switch */
15.858 -
15.859 - /* if we get here, it was an assignment; first check a few special cases
15.860 - * and then the general */
15.861 - if (lval1->ident==iARRAYCHAR) {
15.862 - /* special case, assignment to packed character in a cell is permitted */
15.863 - lvalue=TRUE;
15.864 - } else if (lval1->ident==iARRAY || lval1->ident==iREFARRAY) {
15.865 - /* array assignment is permitted too (with restrictions) */
15.866 - if (oper)
15.867 - return error(23); /* array assignment must be simple assigment */
15.868 - assert(lval1->sym!=NULL);
15.869 - if (array_totalsize(lval1->sym)==0)
15.870 - return error(46,lval1->sym->name); /* unknown array size */
15.871 - lvalue=TRUE;
15.872 - } /* if */
15.873 -
15.874 - /* operand on left side of assignment must be lvalue */
15.875 - if (!lvalue)
15.876 - return error(22); /* must be lvalue */
15.877 - /* may not change "constant" parameters */
15.878 - assert(lval1->sym!=NULL);
15.879 - if ((lval1->sym->usage & uCONST)!=0)
15.880 - return error(22); /* assignment to const argument */
15.881 - sc_allowproccall=FALSE; /* may no longer use "procedure call" syntax */
15.882 -
15.883 - lval3=*lval1; /* save symbol to enable storage of expresion result */
15.884 - lval1->arrayidx=org_arrayidx; /* restore array index pointer */
15.885 - if (lval1->ident==iARRAYCELL || lval1->ident==iARRAYCHAR
15.886 - || lval1->ident==iARRAY || lval1->ident==iREFARRAY)
15.887 - {
15.888 - /* if indirect fetch: save PRI (cell address) */
15.889 - if (oper) {
15.890 - pushreg(sPRI);
15.891 - rvalue(lval1);
15.892 - } /* if */
15.893 - lval2.arrayidx=arrayidx2;
15.894 - plnge2(oper,hier14,lval1,&lval2);
15.895 - if (lval2.ident!=iARRAYCELL && lval2.ident!=iARRAYCHAR)
15.896 - lval2.arrayidx=NULL;
15.897 - if (oper)
15.898 - popreg(sALT);
15.899 - if (!oper && lval3.arrayidx!=NULL && lval2.arrayidx!=NULL
15.900 - && lval3.ident==lval2.ident && lval3.sym==lval2.sym)
15.901 - {
15.902 - int same=TRUE;
15.903 - assert(lval2.arrayidx==arrayidx2);
15.904 - for (i=0; i<sDIMEN_MAX; i++)
15.905 - same=same && (lval3.arrayidx[i]==lval2.arrayidx[i]);
15.906 - if (same)
15.907 - error(226,lval3.sym->name); /* self-assignment */
15.908 - } /* if */
15.909 - } else {
15.910 - if (oper){
15.911 - rvalue(lval1);
15.912 - plnge2(oper,hier14,lval1,&lval2);
15.913 - } else {
15.914 - /* if direct fetch and simple assignment: no "push"
15.915 - * and "pop" needed -> call hier14() directly, */
15.916 - if (hier14(&lval2))
15.917 - rvalue(&lval2); /* instead of plnge2(). */
15.918 - else if (lval2.ident==iVARIABLE)
15.919 - lval2.ident=iEXPRESSION;/* mark as "rvalue" if it is not an "lvalue" */
15.920 - checkfunction(&lval2);
15.921 - /* check whether lval2 and lval3 (old lval1) refer to the same variable */
15.922 - if (lval2.ident==iVARIABLE && lval3.ident==lval2.ident && lval3.sym==lval2.sym) {
15.923 - assert(lval3.sym!=NULL);
15.924 - error(226,lval3.sym->name); /* self-assignment */
15.925 - } /* if */
15.926 - } /* if */
15.927 - } /* if */
15.928 - /* Array elements are sometimes considered as sub-arrays --when the
15.929 - * array index is an enumeration field and the enumeration size is greater
15.930 - * than 1. If the expression on the right side of the assignment is a cell,
15.931 - * or if an operation is in effect, this does not apply.
15.932 - */
15.933 - leftarray= lval3.ident==iARRAY || lval3.ident==iREFARRAY
15.934 - || ((lval3.ident==iARRAYCELL || lval3.ident==iARRAYCHAR)
15.935 - && lval3.constval>1 && lval3.sym->dim.array.level==0
15.936 - && !oper && (lval2.ident==iARRAY || lval2.ident==iREFARRAY));
15.937 - if (leftarray) {
15.938 - /* Left operand is an array, right operand should be an array variable
15.939 - * of the same size and the same dimension, an array literal (of the
15.940 - * same size) or a literal string. For single-dimensional arrays without
15.941 - * tag for the index, it is permitted to assign a smaller array into a
15.942 - * larger one (without warning). This is to make it easier to work with
15.943 - * strings.
15.944 - */
15.945 - int exactmatch=TRUE;
15.946 - int idxtag=0;
15.947 - int ltlength=(int)lval3.sym->dim.array.length;
15.948 - if ((lval3.ident==iARRAYCELL || lval3.ident==iARRAYCHAR)
15.949 - && lval3.constval>0 && lval3.sym->dim.array.level==0)
15.950 - {
15.951 - ltlength=(int)lval3.constval;
15.952 - } /* if */
15.953 - if (lval2.ident!=iARRAY && lval2.ident!=iREFARRAY
15.954 - && (lval2.sym==NULL || lval2.constval<=0))
15.955 - error(33,lval3.sym->name); /* array must be indexed */
15.956 - if (lval2.sym!=NULL) {
15.957 - if (lval2.constval==0) {
15.958 - val=lval2.sym->dim.array.length;/* array variable */
15.959 - } else {
15.960 - val=lval2.constval;
15.961 - if (lval2.sym->dim.array.level!=0)
15.962 - error(28,lval2.sym->name);
15.963 - } /* if */
15.964 - level=lval2.sym->dim.array.level;
15.965 - idxtag=lval2.sym->x.tags.index;
15.966 - if (level==0 && idxtag==0 && lval3.sym->x.tags.index==0)
15.967 - exactmatch=FALSE;
15.968 - } else {
15.969 - val=lval2.constval; /* literal array */
15.970 - level=0;
15.971 - /* If val is negative, it means that lval2 is a literal string.
15.972 - * The string array size may be smaller than the destination
15.973 - * array, provided that the destination array does not have an
15.974 - * index tag.
15.975 - */
15.976 - if (val<0) {
15.977 - val=-val;
15.978 - if (lval3.sym->x.tags.index==0)
15.979 - exactmatch=FALSE;
15.980 - } /* if */
15.981 - } /* if */
15.982 - if (lval3.sym->dim.array.level!=level)
15.983 - return error(48); /* array dimensions must match */
15.984 - else if (ltlength<val || exactmatch && ltlength>val || val==0)
15.985 - return error(47); /* array sizes must match */
15.986 - else if (lval3.ident!=iARRAYCELL && !matchtag(lval3.sym->x.tags.index,idxtag,TRUE))
15.987 - error(229,(lval2.sym!=NULL) ? lval2.sym->name : lval3.sym->name); /* index tag mismatch */
15.988 - if (level>0) {
15.989 - /* check the sizes of all sublevels too */
15.990 - symbol *sym1 = lval3.sym;
15.991 - symbol *sym2 = lval2.sym;
15.992 - int i;
15.993 - assert(sym1!=NULL && sym2!=NULL);
15.994 - /* ^^^ sym2 must be valid, because only variables can be
15.995 - * multi-dimensional (there are no multi-dimensional literals),
15.996 - * sym1 must be valid because it must be an lvalue
15.997 - */
15.998 - assert(exactmatch);
15.999 - for (i=0; i<level; i++) {
15.1000 - sym1=finddepend(sym1);
15.1001 - sym2=finddepend(sym2);
15.1002 - assert(sym1!=NULL && sym2!=NULL);
15.1003 - /* ^^^ both arrays have the same dimensions (this was checked
15.1004 - * earlier) so the dependend should always be found
15.1005 - */
15.1006 - if (sym1->dim.array.length!=sym2->dim.array.length)
15.1007 - error(47); /* array sizes must match */
15.1008 - else if (!matchtag(sym1->x.tags.index,sym2->x.tags.index,TRUE))
15.1009 - error(229,sym2->name); /* index tag mismatch */
15.1010 - } /* for */
15.1011 - /* get the total size in cells of the multi-dimensional array */
15.1012 - val=array_totalsize(lval3.sym);
15.1013 - assert(val>0); /* already checked */
15.1014 - } /* if */
15.1015 - } else {
15.1016 - /* left operand is not an array, right operand should then not be either */
15.1017 - if (lval2.ident==iARRAY || lval2.ident==iREFARRAY)
15.1018 - error(6); /* must be assigned to an array */
15.1019 - } /* if */
15.1020 - if (leftarray) {
15.1021 - memcopy(val*sizeof(cell));
15.1022 - } else {
15.1023 - check_userop(NULL,lval2.tag,lval3.tag,2,&lval3,&lval2.tag);
15.1024 - store(&lval3); /* now, store the expression result */
15.1025 - } /* if */
15.1026 - if (!oper && !matchtag(lval3.tag,lval2.tag,TRUE))
15.1027 - error(213); /* tagname mismatch (if "oper", warning already given in plunge2()) */
15.1028 - if (lval3.sym)
15.1029 - markusage(lval3.sym,uWRITTEN);
15.1030 - sideeffect=TRUE;
15.1031 - bitwise_opercount=bwcount;
15.1032 - lval1->ident=iEXPRESSION;
15.1033 - return FALSE; /* expression result is never an lvalue */
15.1034 -}
15.1035 -
15.1036 -static int hier13(value *lval)
15.1037 -{
15.1038 - int lvalue=plnge1(hier12,lval);
15.1039 - if (matchtoken('?')) {
15.1040 - int flab1=getlabel();
15.1041 - int flab2=getlabel();
15.1042 - value lval2={0};
15.1043 - int array1,array2;
15.1044 -
15.1045 - if (lvalue) {
15.1046 - rvalue(lval);
15.1047 - } else if (lval->ident==iCONSTEXPR) {
15.1048 - ldconst(lval->constval,sPRI);
15.1049 - error(lval->constval ? 206 : 205); /* redundant test */
15.1050 - } /* if */
15.1051 - jmp_eq0(flab1); /* go to second expression if primary register==0 */
15.1052 - PUSHSTK_I(sc_allowtags);
15.1053 - sc_allowtags=FALSE; /* do not allow tagnames here (colon is a special token) */
15.1054 - if (hier13(lval))
15.1055 - rvalue(lval);
15.1056 - if (lval->ident==iCONSTEXPR) /* load constant here */
15.1057 - ldconst(lval->constval,sPRI);
15.1058 - sc_allowtags=(short)POPSTK_I(); /* restore */
15.1059 - jumplabel(flab2);
15.1060 - setlabel(flab1);
15.1061 - needtoken(':');
15.1062 - if (hier13(&lval2))
15.1063 - rvalue(&lval2);
15.1064 - if (lval2.ident==iCONSTEXPR) /* load constant here */
15.1065 - ldconst(lval2.constval,sPRI);
15.1066 - array1= (lval->ident==iARRAY || lval->ident==iREFARRAY);
15.1067 - array2= (lval2.ident==iARRAY || lval2.ident==iREFARRAY);
15.1068 - if (array1 && !array2) {
15.1069 - char *ptr=(lval->sym->name!=NULL) ? lval->sym->name : "-unknown-";
15.1070 - error(33,ptr); /* array must be indexed */
15.1071 - } else if (!array1 && array2) {
15.1072 - char *ptr=(lval2.sym->name!=NULL) ? lval2.sym->name : "-unknown-";
15.1073 - error(33,ptr); /* array must be indexed */
15.1074 - } /* if */
15.1075 - /* ??? if both are arrays, should check dimensions */
15.1076 - if (!matchtag(lval->tag,lval2.tag,FALSE))
15.1077 - error(213); /* tagname mismatch ('true' and 'false' expressions) */
15.1078 - setlabel(flab2);
15.1079 - if (lval->ident==iARRAY)
15.1080 - lval->ident=iREFARRAY; /* iARRAY becomes iREFARRAY */
15.1081 - else if (lval->ident!=iREFARRAY)
15.1082 - lval->ident=iEXPRESSION; /* iREFARRAY stays iREFARRAY, rest becomes iEXPRESSION */
15.1083 - return FALSE; /* conditional expression is no lvalue */
15.1084 - } else {
15.1085 - return lvalue;
15.1086 - } /* if */
15.1087 -}
15.1088 -
15.1089 -/* the order of the operators in these lists is important and must be
15.1090 - * the same as the order of the operators in the array "op1"
15.1091 - */
15.1092 -static int list3[] = {'*','/','%',0};
15.1093 -static int list4[] = {'+','-',0};
15.1094 -static int list5[] = {tSHL,tSHR,tSHRU,0};
15.1095 -static int list6[] = {'&',0};
15.1096 -static int list7[] = {'^',0};
15.1097 -static int list8[] = {'|',0};
15.1098 -static int list9[] = {tlLE,tlGE,'<','>',0};
15.1099 -static int list10[] = {tlEQ,tlNE,0};
15.1100 -static int list11[] = {tlAND,0};
15.1101 -static int list12[] = {tlOR,0};
15.1102 -
15.1103 -static int hier12(value *lval)
15.1104 -{
15.1105 - return skim(list12,jmp_ne0,1,0,hier11,lval);
15.1106 -}
15.1107 -
15.1108 -static int hier11(value *lval)
15.1109 -{
15.1110 - return skim(list11,jmp_eq0,0,1,hier10,lval);
15.1111 -}
15.1112 -
15.1113 -static int hier10(value *lval)
15.1114 -{ /* ==, != */
15.1115 - return plnge(list10,15,hier9,lval,"bool",TRUE);
15.1116 -} /* ^ this variable is the starting index in the op1[]
15.1117 - * array of the operators of this hierarchy level */
15.1118 -
15.1119 -static int hier9(value *lval)
15.1120 -{ /* <=, >=, <, > */
15.1121 - return plnge_rel(list9,11,hier8,lval);
15.1122 -}
15.1123 -
15.1124 -static int hier8(value *lval)
15.1125 -{ /* | */
15.1126 - return plnge(list8,10,hier7,lval,NULL,FALSE);
15.1127 -}
15.1128 -
15.1129 -static int hier7(value *lval)
15.1130 -{ /* ^ */
15.1131 - return plnge(list7,9,hier6,lval,NULL,FALSE);
15.1132 -}
15.1133 -
15.1134 -static int hier6(value *lval)
15.1135 -{ /* & */
15.1136 - return plnge(list6,8,hier5,lval,NULL,FALSE);
15.1137 -}
15.1138 -
15.1139 -static int hier5(value *lval)
15.1140 -{ /* <<, >>, >>> */
15.1141 - return plnge(list5,5,hier4,lval,NULL,FALSE);
15.1142 -}
15.1143 -
15.1144 -static int hier4(value *lval)
15.1145 -{ /* +, - */
15.1146 - return plnge(list4,3,hier3,lval,NULL,FALSE);
15.1147 -}
15.1148 -
15.1149 -static int hier3(value *lval)
15.1150 -{ /* *, /, % */
15.1151 - return plnge(list3,0,hier2,lval,NULL,FALSE);
15.1152 -}
15.1153 -
15.1154 -static int hier2(value *lval)
15.1155 -{
15.1156 - int lvalue,tok;
15.1157 - int tag,paranthese;
15.1158 - cell val;
15.1159 - char *st;
15.1160 - symbol *sym;
15.1161 - int saveresult;
15.1162 -
15.1163 - tok=lex(&val,&st);
15.1164 - switch (tok) {
15.1165 - case tINC: /* ++lval */
15.1166 - if (!hier2(lval))
15.1167 - return error(22); /* must be lvalue */
15.1168 - assert(lval->sym!=NULL);
15.1169 - if ((lval->sym->usage & uCONST)!=0)
15.1170 - return error(22); /* assignment to const argument */
15.1171 - if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag))
15.1172 - inc(lval); /* increase variable first */
15.1173 - rvalue(lval); /* and read the result into PRI */
15.1174 - sideeffect=TRUE;
15.1175 - return FALSE; /* result is no longer lvalue */
15.1176 - case tDEC: /* --lval */
15.1177 - if (!hier2(lval))
15.1178 - return error(22); /* must be lvalue */
15.1179 - assert(lval->sym!=NULL);
15.1180 - if ((lval->sym->usage & uCONST)!=0)
15.1181 - return error(22); /* assignment to const argument */
15.1182 - if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag))
15.1183 - dec(lval); /* decrease variable first */
15.1184 - rvalue(lval); /* and read the result into PRI */
15.1185 - sideeffect=TRUE;
15.1186 - return FALSE; /* result is no longer lvalue */
15.1187 - case '~': /* ~ (one's complement) */
15.1188 - if (hier2(lval))
15.1189 - rvalue(lval);
15.1190 - invert(); /* bitwise NOT */
15.1191 - lval->constval=~lval->constval;
15.1192 - return FALSE;
15.1193 - case '!': /* ! (logical negate) */
15.1194 - if (hier2(lval))
15.1195 - rvalue(lval);
15.1196 - if (check_userop(lneg,lval->tag,0,1,NULL,&lval->tag)) {
15.1197 - lval->ident=iEXPRESSION;
15.1198 - lval->constval=0;
15.1199 - } else {
15.1200 - lneg(); /* 0 -> 1, !0 -> 0 */
15.1201 - lval->constval=!lval->constval;
15.1202 - lval->tag=pc_addtag("bool");
15.1203 - } /* if */
15.1204 - return FALSE;
15.1205 - case '-': /* unary - (two's complement) */
15.1206 - if (hier2(lval))
15.1207 - rvalue(lval);
15.1208 - /* make a special check for a constant expression with the tag of a
15.1209 - * rational number, so that we can simple swap the sign of that constant.
15.1210 - */
15.1211 - if (lval->ident==iCONSTEXPR && lval->tag==sc_rationaltag && sc_rationaltag!=0) {
15.1212 - if (rational_digits==0) {
15.1213 - #if PAWN_CELL_SIZE==32
15.1214 - float *f = (float *)&lval->constval;
15.1215 - #elif PAWN_CELL_SIZE==64
15.1216 - double *f = (double *)&lval->constval;
15.1217 - #else
15.1218 - #error Unsupported cell size
15.1219 - #endif
15.1220 - *f= - *f; /* this modifies lval->constval */
15.1221 - } else {
15.1222 - /* the negation of a fixed point number is just an integer negation */
15.1223 - lval->constval=-lval->constval;
15.1224 - } /* if */
15.1225 - } else if (check_userop(neg,lval->tag,0,1,NULL,&lval->tag)) {
15.1226 - lval->ident=iEXPRESSION;
15.1227 - lval->constval=0;
15.1228 - } else {
15.1229 - neg(); /* arithmic negation */
15.1230 - lval->constval=-lval->constval;
15.1231 - } /* if */
15.1232 - return FALSE;
15.1233 - case tLABEL: /* tagname override */
15.1234 - tag=pc_addtag(st);
15.1235 - lval->cmptag=tag;
15.1236 - lvalue=hier2(lval);
15.1237 - lval->tag=tag;
15.1238 - return lvalue;
15.1239 - case tDEFINED:
15.1240 - paranthese=0;
15.1241 - while (matchtoken('('))
15.1242 - paranthese++;
15.1243 - tok=lex(&val,&st);
15.1244 - if (tok!=tSYMBOL)
15.1245 - return error(20,st); /* illegal symbol name */
15.1246 - sym=findloc(st);
15.1247 - if (sym==NULL)
15.1248 - sym=findglb(st,sSTATEVAR);
15.1249 - if (sym!=NULL && sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0)
15.1250 - sym=NULL; /* symbol is not a function, it is in the table, but not "defined" */
15.1251 - val= (sym!=NULL);
15.1252 - if (!val && find_subst(st,strlen(st))!=NULL)
15.1253 - val=1;
15.1254 - clear_value(lval);
15.1255 - lval->ident=iCONSTEXPR;
15.1256 - lval->constval= val;
15.1257 - lval->tag=pc_addtag("bool");
15.1258 - ldconst(lval->constval,sPRI);
15.1259 - while (paranthese--)
15.1260 - needtoken(')');
15.1261 - return FALSE;
15.1262 - case tSIZEOF:
15.1263 - paranthese=0;
15.1264 - while (matchtoken('('))
15.1265 - paranthese++;
15.1266 - tok=lex(&val,&st);
15.1267 - if (tok!=tSYMBOL)
15.1268 - return error(20,st); /* illegal symbol name */
15.1269 - sym=findloc(st);
15.1270 - if (sym==NULL)
15.1271 - sym=findglb(st,sSTATEVAR);
15.1272 - if (sym==NULL)
15.1273 - return error(17,st); /* undefined symbol */
15.1274 - if (sym->ident==iCONSTEXPR)
15.1275 - error(39); /* constant symbol has no size */
15.1276 - else if (sym->ident==iFUNCTN || sym->ident==iREFFUNC)
15.1277 - error(72); /* "function" symbol has no size */
15.1278 - else if ((sym->usage & uDEFINE)==0)
15.1279 - return error(17,st); /* undefined symbol (symbol is in the table, but it is "used" only) */
15.1280 - clear_value(lval);
15.1281 - lval->ident=iCONSTEXPR;
15.1282 - lval->constval=1; /* preset */
15.1283 - if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
15.1284 - int level;
15.1285 - symbol *idxsym=NULL;
15.1286 - symbol *subsym=sym;
15.1287 - for (level=0; matchtoken('['); level++) {
15.1288 - idxsym=NULL;
15.1289 - if (subsym!=NULL && level==subsym->dim.array.level && matchtoken(tSYMBOL)) {
15.1290 - char *idxname;
15.1291 - int cmptag=subsym->x.tags.index;
15.1292 - tokeninfo(&val,&idxname);
15.1293 - if ((idxsym=findconst(idxname,&cmptag))==NULL)
15.1294 - error(80,idxname); /* unknown symbol, or non-constant */
15.1295 - else if (cmptag>1)
15.1296 - error(91,idxname); /* ambiguous constant */
15.1297 - } /* if */
15.1298 - needtoken(']');
15.1299 - if (subsym!=NULL)
15.1300 - subsym=finddepend(subsym);
15.1301 - } /* for */
15.1302 - if (level>sym->dim.array.level+1)
15.1303 - error(28,sym->name); /* invalid subscript */
15.1304 - else if (level==sym->dim.array.level+1)
15.1305 - lval->constval= (idxsym!=NULL && idxsym->dim.array.length>0) ? idxsym->dim.array.length : 1;
15.1306 - else
15.1307 - lval->constval=array_levelsize(sym,level);
15.1308 - if (lval->constval==0 && strchr((char *)lptr,PREPROC_TERM)==NULL)
15.1309 - error(224,st); /* indeterminate array size in "sizeof" expression */
15.1310 - } /* if */
15.1311 - ldconst(lval->constval,sPRI);
15.1312 - while (paranthese--)
15.1313 - needtoken(')');
15.1314 - return FALSE;
15.1315 - case tTAGOF:
15.1316 - paranthese=0;
15.1317 - while (matchtoken('('))
15.1318 - paranthese++;
15.1319 - tok=lex(&val,&st);
15.1320 - if (tok!=tSYMBOL && tok!=tLABEL)
15.1321 - return error(20,st); /* illegal symbol name */
15.1322 - if (tok==tLABEL) {
15.1323 - constvalue *tagsym=find_constval(&tagname_tab,st,0);
15.1324 - tag=(int)((tagsym!=NULL) ? tagsym->value : 0);
15.1325 - } else {
15.1326 - sym=findloc(st);
15.1327 - if (sym==NULL)
15.1328 - sym=findglb(st,sSTATEVAR);
15.1329 - if (sym==NULL)
15.1330 - return error(17,st); /* undefined symbol */
15.1331 - if ((sym->usage & uDEFINE)==0)
15.1332 - return error(17,st); /* undefined symbol (symbol is in the table, but it is "used" only) */
15.1333 - tag=sym->tag;
15.1334 - } /* if */
15.1335 - if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
15.1336 - int level;
15.1337 - symbol *idxsym=NULL;
15.1338 - symbol *subsym=sym;
15.1339 - for (level=0; matchtoken('['); level++) {
15.1340 - idxsym=NULL;
15.1341 - if (subsym!=NULL && level==subsym->dim.array.level && matchtoken(tSYMBOL)) {
15.1342 - char *idxname;
15.1343 - int cmptag=subsym->x.tags.index;
15.1344 - tokeninfo(&val,&idxname);
15.1345 - if ((idxsym=findconst(idxname,&cmptag))==NULL)
15.1346 - error(80,idxname); /* unknown symbol, or non-constant */
15.1347 - else if (cmptag>1)
15.1348 - error(91,idxname); /* ambiguous constant */
15.1349 - } /* if */
15.1350 - needtoken(']');
15.1351 - if (subsym!=NULL)
15.1352 - subsym=finddepend(subsym);
15.1353 - } /* for */
15.1354 - if (level>sym->dim.array.level+1)
15.1355 - error(28,sym->name); /* invalid subscript */
15.1356 - else if (level==sym->dim.array.level+1 && idxsym!=NULL)
15.1357 - tag= idxsym->x.tags.index;
15.1358 - } /* if */
15.1359 - exporttag(tag);
15.1360 - clear_value(lval);
15.1361 - lval->ident=iCONSTEXPR;
15.1362 - lval->constval=tag | PUBLICTAG;
15.1363 - ldconst(lval->constval,sPRI);
15.1364 - while (paranthese--)
15.1365 - needtoken(')');
15.1366 - return FALSE;
15.1367 - case tSTATE: {
15.1368 - constvalue *automaton;
15.1369 - constvalue *state;
15.1370 - if (sc_getstateid(&automaton,&state)) {
15.1371 - assert(automaton!=NULL);
15.1372 - assert(automaton->index==0 && automaton->name[0]=='\0' || automaton->index>0);
15.1373 - loadreg(automaton->value,sALT);
15.1374 - assert(state!=NULL);
15.1375 - ldconst(state->value,sPRI);
15.1376 - ob_eq();
15.1377 - clear_value(lval);
15.1378 - lval->ident=iEXPRESSION;
15.1379 - lval->tag=pc_addtag("bool");
15.1380 - } /* if */
15.1381 - return FALSE;
15.1382 - } /* case */
15.1383 - default:
15.1384 - lexpush();
15.1385 - lvalue=hier1(lval);
15.1386 - /* check for postfix operators */
15.1387 - if (matchtoken(';')) {
15.1388 - /* Found a ';', do not look further for postfix operators */
15.1389 - lexpush(); /* push ';' back after successful match */
15.1390 - return lvalue;
15.1391 - } else if (matchtoken(tTERM)) {
15.1392 - /* Found a newline that ends a statement (this is the case when
15.1393 - * semicolons are optional). Note that an explicit semicolon was
15.1394 - * handled above. This case is similar, except that the token must
15.1395 - * not be pushed back.
15.1396 - */
15.1397 - return lvalue;
15.1398 - } else {
15.1399 - tok=lex(&val,&st);
15.1400 - switch (tok) {
15.1401 - case tINC: /* lval++ */
15.1402 - if (!lvalue)
15.1403 - return error(22); /* must be lvalue */
15.1404 - assert(lval->sym!=NULL);
15.1405 - if ((lval->sym->usage & uCONST)!=0)
15.1406 - return error(22); /* assignment to const argument */
15.1407 - /* on incrementing array cells, the address in PRI must be saved for
15.1408 - * incremening the value, whereas the current value must be in PRI
15.1409 - * on exit.
15.1410 - */
15.1411 - saveresult= (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR);
15.1412 - if (saveresult)
15.1413 - pushreg(sPRI); /* save address in PRI */
15.1414 - rvalue(lval); /* read current value into PRI */
15.1415 - if (saveresult)
15.1416 - swap1(); /* save PRI on the stack, restore address in PRI */
15.1417 - if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag))
15.1418 - inc(lval); /* increase variable afterwards */
15.1419 - if (saveresult)
15.1420 - popreg(sPRI); /* restore PRI (result of rvalue()) */
15.1421 - sideeffect=TRUE;
15.1422 - return FALSE; /* result is no longer lvalue */
15.1423 - case tDEC: /* lval-- */
15.1424 - if (!lvalue)
15.1425 - return error(22); /* must be lvalue */
15.1426 - assert(lval->sym!=NULL);
15.1427 - if ((lval->sym->usage & uCONST)!=0)
15.1428 - return error(22); /* assignment to const argument */
15.1429 - saveresult= (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR);
15.1430 - if (saveresult)
15.1431 - pushreg(sPRI); /* save address in PRI */
15.1432 - rvalue(lval); /* read current value into PRI */
15.1433 - if (saveresult)
15.1434 - swap1(); /* save PRI on the stack, restore address in PRI */
15.1435 - if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag))
15.1436 - dec(lval); /* decrease variable afterwards */
15.1437 - if (saveresult)
15.1438 - popreg(sPRI); /* restore PRI (result of rvalue()) */
15.1439 - sideeffect=TRUE;
15.1440 - return FALSE;
15.1441 - case tCHAR: /* char (compute required # of cells */
15.1442 - if (lval->ident==iCONSTEXPR) {
15.1443 - lval->constval *= sCHARBITS/8; /* from char to bytes */
15.1444 - lval->constval = (lval->constval + sizeof(cell)-1) / sizeof(cell);
15.1445 - } else {
15.1446 - if (lvalue)
15.1447 - rvalue(lval); /* fetch value if not already in PRI */
15.1448 - char2addr(); /* from characters to bytes */
15.1449 - addconst(sizeof(cell)-1); /* make sure the value is rounded up */
15.1450 - addr2cell(); /* truncate to number of cells */
15.1451 - } /* if */
15.1452 - return FALSE;
15.1453 - default:
15.1454 - lexpush();
15.1455 - return lvalue;
15.1456 - } /* switch */
15.1457 - } /* if */
15.1458 - } /* switch */
15.1459 -}
15.1460 -
15.1461 -/* hier1
15.1462 - *
15.1463 - * The highest hierarchy level: it looks for pointer and array indices
15.1464 - * and function calls.
15.1465 - * Generates code to fetch a pointer value if it is indexed and code to
15.1466 - * add to the pointer value or the array address (the address is already
15.1467 - * read at primary()). It also generates code to fetch a function address
15.1468 - * if that hasn't already been done at primary() (check lval[4]) and calls
15.1469 - * callfunction() to call the function.
15.1470 - */
15.1471 -static int hier1(value *lval1)
15.1472 -{
15.1473 - int lvalue,index,tok,symtok;
15.1474 - cell val,cidx;
15.1475 - value lval2={0};
15.1476 - char *st;
15.1477 - char close;
15.1478 - symbol *sym;
15.1479 - symbol dummysymbol,*cursym; /* for changing the index tags in case of enumerated pseudo-arrays */
15.1480 -
15.1481 - lvalue=primary(lval1);
15.1482 - symtok=tokeninfo(&val,&st); /* get token read by primary() */
15.1483 - cursym=lval1->sym;
15.1484 -restart:
15.1485 - sym=cursym;
15.1486 - if (matchtoken('[') || matchtoken('{') || matchtoken('(')) {
15.1487 - tok=tokeninfo(&val,&st); /* get token read by matchtoken() */
15.1488 - if (sym==NULL && symtok!=tSYMBOL) {
15.1489 - /* we do not have a valid symbol and we appear not to have read a valid
15.1490 - * symbol name (so it is unlikely that we would have read a name of an
15.1491 - * undefined symbol) */
15.1492 - error(29); /* expression error, assumed 0 */
15.1493 - lexpush(); /* analyse '(', '{' or '[' again later */
15.1494 - return FALSE;
15.1495 - } /* if */
15.1496 - if (tok=='[' || tok=='{') { /* subscript */
15.1497 - close = (char)((tok=='[') ? ']' : '}');
15.1498 - if (sym==NULL) { /* sym==NULL if lval is a constant or a literal */
15.1499 - error(28,"<no variable>"); /* cannot subscript */
15.1500 - needtoken(close);
15.1501 - return FALSE;
15.1502 - } else if (sym->ident!=iARRAY && sym->ident!=iREFARRAY){
15.1503 - error(28,sym->name); /* cannot subscript, variable is not an array */
15.1504 - needtoken(close);
15.1505 - return FALSE;
15.1506 - } else if (sym->dim.array.level>0 && close!=']') {
15.1507 - error(51); /* invalid subscript, must use [ ] */
15.1508 - needtoken(close);
15.1509 - return FALSE;
15.1510 - } /* if */
15.1511 - /* set the tag to match (enumeration fields as indices) */
15.1512 - lval2.cmptag=sym->x.tags.index;
15.1513 - stgget(&index,&cidx); /* mark position in code generator */
15.1514 - pushreg(sPRI); /* save base address of the array */
15.1515 - if (hier14(&lval2)) /* create expression for the array index */
15.1516 - rvalue(&lval2);
15.1517 - if (lval2.ident==iARRAY || lval2.ident==iREFARRAY)
15.1518 - error(33,lval2.sym->name); /* array must be indexed */
15.1519 - needtoken(close);
15.1520 - if (!matchtag(sym->x.tags.index,lval2.tag,TRUE))
15.1521 - error(213);
15.1522 - if (lval2.ident==iCONSTEXPR) { /* constant expression */
15.1523 - stgdel(index,cidx); /* scratch generated code */
15.1524 - if (lval1->arrayidx!=NULL) { /* keep constant index, for checking */
15.1525 - assert(sym->dim.array.level>=0 && sym->dim.array.level<sDIMEN_MAX);
15.1526 - lval1->arrayidx[sym->dim.array.level]=lval2.constval;
15.1527 - } /* if */
15.1528 - if (close==']') {
15.1529 - /* normal array index */
15.1530 - if (lval2.constval<0 || sym->dim.array.length!=0 && sym->dim.array.length<=lval2.constval)
15.1531 - error(32,sym->name); /* array index out of bounds */
15.1532 - if (lval2.constval!=0) {
15.1533 - /* don't add offsets for zero subscripts */
15.1534 - #if PAWN_CELL_SIZE==16
15.1535 - ldconst(lval2.constval<<1,sALT);
15.1536 - #elif PAWN_CELL_SIZE==32
15.1537 - ldconst(lval2.constval<<2,sALT);
15.1538 - #elif PAWN_CELL_SIZE==64
15.1539 - ldconst(lval2.constval<<3,sALT);
15.1540 - #else
15.1541 - #error Unsupported cell size
15.1542 - #endif
15.1543 - ob_add();
15.1544 - } /* if */
15.1545 - } else {
15.1546 - /* character index */
15.1547 - if (lval2.constval<0 || sym->dim.array.length!=0
15.1548 - && sym->dim.array.length*((8*sizeof(cell))/sCHARBITS)<=(ucell)lval2.constval)
15.1549 - error(32,sym->name); /* array index out of bounds */
15.1550 - if (lval2.constval!=0) {
15.1551 - /* don't add offsets for zero subscripts */
15.1552 - #if sCHARBITS==16
15.1553 - ldconst(lval2.constval<<1,sALT);/* 16-bit character */
15.1554 - #else
15.1555 - ldconst(lval2.constval,sALT); /* 8-bit character */
15.1556 - #endif
15.1557 - ob_add();
15.1558 - } /* if */
15.1559 - charalign(); /* align character index into array */
15.1560 - } /* if */
15.1561 - /* if the array index is a field from an enumeration, get the tag name
15.1562 - * from the field and save the size of the field too.
15.1563 - */
15.1564 - assert(lval2.sym==NULL || lval2.sym->dim.array.level==0);
15.1565 - if (lval2.sym!=NULL && lval2.sym->dim.array.length>0 && sym->dim.array.level==0) {
15.1566 - lval1->tag=lval2.sym->x.tags.index;
15.1567 - lval1->constval=lval2.sym->dim.array.length;
15.1568 - } /* if */
15.1569 - } else {
15.1570 - /* array index is not constant */
15.1571 - lval1->arrayidx=NULL; /* reset, so won't be checked */
15.1572 - if (close==']') {
15.1573 - if (sym->dim.array.length!=0)
15.1574 - ffbounds(sym->dim.array.length-1); /* run time check for array bounds */
15.1575 - cell2addr(); /* normal array index */
15.1576 - } else {
15.1577 - if (sym->dim.array.length!=0)
15.1578 - ffbounds(sym->dim.array.length*(32/sCHARBITS)-1);
15.1579 - char2addr(); /* character array index */
15.1580 - } /* if */
15.1581 - popreg(sALT);
15.1582 - ob_add(); /* base address was popped into secondary register */
15.1583 - if (close!=']')
15.1584 - charalign(); /* align character index into array */
15.1585 - } /* if */
15.1586 - /* the indexed item may be another array (multi-dimensional arrays) */
15.1587 - assert(cursym==sym && sym!=NULL); /* should still be set */
15.1588 - if (sym->dim.array.level>0) {
15.1589 - assert(close==']'); /* checked earlier */
15.1590 - assert(cursym==lval1->sym);
15.1591 - /* read the offset to the subarray and add it to the current address */
15.1592 - lval1->ident=iARRAYCELL;
15.1593 - pushreg(sPRI); /* the optimizer makes this to a MOVE.alt */
15.1594 - rvalue(lval1);
15.1595 - popreg(sALT);
15.1596 - ob_add();
15.1597 - /* adjust the "value" structure and find the referenced array */
15.1598 - lval1->ident=iREFARRAY;
15.1599 - lval1->sym=finddepend(sym);
15.1600 - assert(lval1->sym!=NULL);
15.1601 - assert(lval1->sym->dim.array.level==sym->dim.array.level-1);
15.1602 - cursym=lval1->sym;
15.1603 - /* try to parse subsequent array indices */
15.1604 - lvalue=FALSE; /* for now, a iREFARRAY is no lvalue */
15.1605 - goto restart;
15.1606 - } /* if */
15.1607 - assert(sym->dim.array.level==0);
15.1608 - /* set type to fetch... INDIRECTLY */
15.1609 - lval1->ident= (char)((close==']') ? iARRAYCELL : iARRAYCHAR);
15.1610 - /* if the array index is a field from an enumeration, get the tag name
15.1611 - * from the field and save the size of the field too. Otherwise, the
15.1612 - * tag is the one from the array symbol.
15.1613 - */
15.1614 - if (lval2.ident==iCONSTEXPR && lval2.sym!=NULL
15.1615 - && lval2.sym->dim.array.length>0 && sym->dim.array.level==0)
15.1616 - {
15.1617 - lval1->tag=lval2.sym->x.tags.index;
15.1618 - lval1->constval=lval2.sym->dim.array.length;
15.1619 - if (lval2.tag==sym->x.tags.index && lval1->constval>1 && matchtoken('[')) {
15.1620 - /* an array indexed with an enumeration field may be considered a sub-array */
15.1621 - lexpush();
15.1622 - lvalue=FALSE; /* for now, a iREFARRAY is no lvalue */
15.1623 - lval1->ident=iREFARRAY;
15.1624 - /* initialize a dummy symbol, which is a copy of the current symbol,
15.1625 - * but with an adjusted index tag
15.1626 - */
15.1627 - assert(sym!=NULL);
15.1628 - dummysymbol=*sym;
15.1629 - /* get the tag of the root of the enumeration */
15.1630 - assert(lval2.sym!=NULL);
15.1631 - dummysymbol.x.tags.index=lval2.sym->x.tags.field;
15.1632 - dummysymbol.dim.array.length=lval2.sym->dim.array.length;
15.1633 - cursym=&dummysymbol;
15.1634 - /* recurse */
15.1635 - goto restart;
15.1636 - } /* if */
15.1637 - } else {
15.1638 - assert(sym!=NULL);
15.1639 - if (cursym!=&dummysymbol)
15.1640 - lval1->tag=sym->tag;
15.1641 - lval1->constval=0;
15.1642 - } /* if */
15.1643 - /* a cell in an array is an lvalue, a character in an array is not
15.1644 - * always a *valid* lvalue */
15.1645 - return TRUE;
15.1646 - } else { /* tok=='(' -> function(...) */
15.1647 - assert(tok=='(');
15.1648 - if (sym==NULL
15.1649 - || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC))
15.1650 - {
15.1651 - if (sym==NULL && sc_status==statFIRST) {
15.1652 - /* could be a "use before declaration"; in that case, create a stub
15.1653 - * function so that the usage can be marked.
15.1654 - */
15.1655 - sym=fetchfunc(lastsymbol,0);
15.1656 - if (sym==NULL)
15.1657 - error(103); /* insufficient memory */
15.1658 - markusage(sym,uREAD);
15.1659 - } else {
15.1660 - return error(12); /* invalid function call */
15.1661 - } /* if */
15.1662 - } else if ((sym->usage & uMISSING)!=0) {
15.1663 - char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
15.1664 - funcdisplayname(symname,sym->name);
15.1665 - error(4,symname); /* function not defined */
15.1666 - } /* if */
15.1667 - callfunction(sym,lval1,TRUE);
15.1668 - return FALSE; /* result of function call is no lvalue */
15.1669 - } /* if */
15.1670 - } /* if */
15.1671 - if (sym!=NULL && lval1->ident==iFUNCTN) {
15.1672 - assert(sym->ident==iFUNCTN);
15.1673 - if (sc_allowproccall) {
15.1674 - callfunction(sym,lval1,FALSE);
15.1675 - } else {
15.1676 - int n=-1,iter=0;
15.1677 - for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
15.1678 - if (sym->ident==iFUNCTN
15.1679 - && (sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0)
15.1680 - {
15.1681 - assert(sym->vclass==sGLOBAL);
15.1682 - if (strcmp(sym->name, lval1->sym->name)==0) {
15.1683 - n = iter;
15.1684 - break;
15.1685 - }
15.1686 - iter++;
15.1687 - }
15.1688 - }
15.1689 - if (n!=-1) {
15.1690 - lval1->sym=NULL;
15.1691 - lval1->ident=iCONSTEXPR;
15.1692 - lval1->constval=n;
15.1693 - lval1->tag=pc_addtag("Function");
15.1694 - } else {
15.1695 - error(76); /* invalid function call, or syntax error */
15.1696 - } /* if */
15.1697 - return FALSE;
15.1698 - }
15.1699 - } /* if */
15.1700 - return lvalue;
15.1701 -}
15.1702 -
15.1703 -/* primary
15.1704 - *
15.1705 - * Returns 1 if the operand is an lvalue (everything except arrays, functions
15.1706 - * constants and -of course- errors).
15.1707 - * Generates code to fetch the address of arrays. Code for constants is
15.1708 - * already generated by constant().
15.1709 - * This routine first clears the entire lval array (all fields are set to 0).
15.1710 - *
15.1711 - * Global references: sc_intest (may be altered, but restored upon termination)
15.1712 - */
15.1713 -static int primary(value *lval)
15.1714 -{
15.1715 - char *st;
15.1716 - int lvalue,tok;
15.1717 - cell val;
15.1718 - symbol *sym;
15.1719 -
15.1720 - if (matchtoken('(')){ /* sub-expression - (expression,...) */
15.1721 - PUSHSTK_I(sc_intest);
15.1722 - PUSHSTK_I(sc_allowtags);
15.1723 -
15.1724 - sc_intest=FALSE; /* no longer in "test" expression */
15.1725 - sc_allowtags=TRUE; /* allow tagnames to be used in parenthesized expressions */
15.1726 - sc_allowproccall=FALSE;
15.1727 - do
15.1728 - lvalue=hier14(lval);
15.1729 - while (matchtoken(','));
15.1730 - needtoken(')');
15.1731 - lexclr(FALSE); /* clear lex() push-back, it should have been
15.1732 - * cleared already by needtoken() */
15.1733 - sc_allowtags=(short)POPSTK_I();
15.1734 - sc_intest=(short)POPSTK_I();
15.1735 - return lvalue;
15.1736 - } /* if */
15.1737 -
15.1738 - clear_value(lval); /* clear lval */
15.1739 - tok=lex(&val,&st);
15.1740 - if (tok==tSYMBOL) {
15.1741 - /* lastsymbol is char[sNAMEMAX+1], lex() should have truncated any symbol
15.1742 - * to sNAMEMAX significant characters */
15.1743 - assert(strlen(st)<sizeof lastsymbol);
15.1744 - strcpy(lastsymbol,st);
15.1745 - } /* if */
15.1746 - if (tok==tSYMBOL && !findconst(st,NULL)) {
15.1747 - /* first look for a local variable */
15.1748 - if ((sym=findloc(st))!=0) {
15.1749 - if (sym->ident==iLABEL) {
15.1750 - error(29); /* expression error, assumed 0 */
15.1751 - ldconst(0,sPRI); /* load 0 */
15.1752 - return FALSE; /* return 0 for labels (expression error) */
15.1753 - } /* if */
15.1754 - lval->sym=sym;
15.1755 - lval->ident=sym->ident;
15.1756 - lval->tag=sym->tag;
15.1757 - if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
15.1758 - address(sym,sPRI); /* get starting address in primary register */
15.1759 - return FALSE; /* return 0 for array (not lvalue) */
15.1760 - } else {
15.1761 - return TRUE; /* return 1 if lvalue (not label or array) */
15.1762 - } /* if */
15.1763 - } /* if */
15.1764 - /* now try a global variable */
15.1765 - if ((sym=findglb(st,sSTATEVAR))!=0) {
15.1766 - if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
15.1767 - /* if the function is only in the table because it was inserted as a
15.1768 - * stub in the first pass (i.e. it was "used" but never declared or
15.1769 - * implemented, issue an error
15.1770 - */
15.1771 - if ((sym->usage & uPROTOTYPED)==0)
15.1772 - error(17,st);
15.1773 - } else {
15.1774 - if ((sym->usage & uDEFINE)==0)
15.1775 - error(17,st);
15.1776 - lval->sym=sym;
15.1777 - lval->ident=sym->ident;
15.1778 - lval->tag=sym->tag;
15.1779 - if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
15.1780 - address(sym,sPRI); /* get starting address in primary register */
15.1781 - return FALSE; /* return 0 for array (not lvalue) */
15.1782 - } else {
15.1783 - return TRUE; /* return 1 if lvalue (not function or array) */
15.1784 - } /* if */
15.1785 - } /* if */
15.1786 - } else {
15.1787 - if (!sc_allowproccall)
15.1788 - return error(17,st); /* undefined symbol */
15.1789 - /* an unknown symbol, but used in a way compatible with the "procedure
15.1790 - * call" syntax. So assume that the symbol refers to a function.
15.1791 - */
15.1792 - assert(sc_status==statFIRST);
15.1793 - sym=fetchfunc(st,0);
15.1794 - if (sym==NULL)
15.1795 - error(103); /* insufficient memory */
15.1796 - } /* if */
15.1797 - assert(sym!=NULL);
15.1798 - assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC);
15.1799 - lval->sym=sym;
15.1800 - lval->ident=sym->ident;
15.1801 - lval->tag=sym->tag;
15.1802 - return FALSE; /* return 0 for function (not an lvalue) */
15.1803 - } /* if */
15.1804 - lexpush(); /* push the token, it is analyzed by constant() */
15.1805 - if (constant(lval)==0) {
15.1806 - error(29); /* expression error, assumed 0 */
15.1807 - ldconst(0,sPRI); /* load 0 */
15.1808 - } /* if */
15.1809 - return FALSE; /* return 0 for constants (or errors) */
15.1810 -}
15.1811 -
15.1812 -static void clear_value(value *lval)
15.1813 -{
15.1814 - lval->sym=NULL;
15.1815 - lval->constval=0L;
15.1816 - lval->tag=0;
15.1817 - lval->ident=0;
15.1818 - lval->boolresult=FALSE;
15.1819 - /* do not clear lval->arrayidx, it is preset in hier14() */
15.1820 - /* do not clear lval->cmptag */
15.1821 -}
15.1822 -
15.1823 -static void setdefarray(cell *string,cell size,cell array_sz,cell *dataaddr,int fconst)
15.1824 -{
15.1825 - /* The routine must copy the default array data onto the heap, as to avoid
15.1826 - * that a function can change the default value. An optimization is that
15.1827 - * the default array data is "dumped" into the data segment only once (on the
15.1828 - * first use).
15.1829 - */
15.1830 - assert(string!=NULL);
15.1831 - assert(size>0);
15.1832 - /* check whether to dump the default array */
15.1833 - assert(dataaddr!=NULL);
15.1834 - if (sc_status==statWRITE && *dataaddr<0) {
15.1835 - int i;
15.1836 - *dataaddr=(litidx+glb_declared)*sizeof(cell);
15.1837 - for (i=0; i<size; i++)
15.1838 - litadd(*string++);
15.1839 - } /* if */
15.1840 -
15.1841 - /* if the function is known not to modify the array (meaning that it also
15.1842 - * does not modify the default value), directly pass the address of the
15.1843 - * array in the data segment.
15.1844 - */
15.1845 - if (fconst) {
15.1846 - ldconst(*dataaddr,sPRI);
15.1847 - } else {
15.1848 - /* Generate the code:
15.1849 - * CONST.pri dataaddr ;address of the default array data
15.1850 - * HEAP array_sz*sizeof(cell) ;heap address in ALT
15.1851 - * MOVS size*sizeof(cell) ;copy data from PRI to ALT
15.1852 - * MOVE.PRI ;PRI = address on the heap
15.1853 - */
15.1854 - ldconst(*dataaddr,sPRI);
15.1855 - /* "array_sz" is the size of the argument (the value between the brackets
15.1856 - * in the declaration), "size" is the size of the default array data.
15.1857 - */
15.1858 - assert(array_sz>=size);
15.1859 - modheap((int)array_sz*sizeof(cell));
15.1860 - /* ??? should perhaps fill with zeros first */
15.1861 - memcopy(size*sizeof(cell));
15.1862 - moveto1();
15.1863 - } /* if */
15.1864 -}
15.1865 -
15.1866 -static int findnamedarg(arginfo *arg,char *name)
15.1867 -{
15.1868 - int i;
15.1869 -
15.1870 - for (i=0; arg[i].ident!=0 && arg[i].ident!=iVARARGS; i++)
15.1871 - if (strcmp(arg[i].name,name)==0)
15.1872 - return i;
15.1873 - return -1;
15.1874 -}
15.1875 -
15.1876 -static int checktag(int tags[],int numtags,int exprtag)
15.1877 -{
15.1878 - int i;
15.1879 -
15.1880 - assert(tags!=0);
15.1881 - assert(numtags>0);
15.1882 - for (i=0; i<numtags; i++)
15.1883 - if (matchtag(tags[i],exprtag,TRUE))
15.1884 - return TRUE; /* matching tag */
15.1885 - return FALSE; /* no tag matched */
15.1886 -}
15.1887 -
15.1888 -enum {
15.1889 - ARG_UNHANDLED,
15.1890 - ARG_IGNORED,
15.1891 - ARG_DONE,
15.1892 -};
15.1893 -
15.1894 -/* callfunction
15.1895 - *
15.1896 - * Generates code to call a function. This routine handles default arguments
15.1897 - * and positional as well as named parameters.
15.1898 - */
15.1899 -static void callfunction(symbol *sym,value *lval_result,int matchparanthesis)
15.1900 -{
15.1901 -static long nest_stkusage=0L;
15.1902 -static int nesting=0;
15.1903 - int locheap;
15.1904 - int close,lvalue;
15.1905 - int argpos; /* index in the output stream (argpos==nargs if positional parameters) */
15.1906 - int argidx=0; /* index in "arginfo" list */
15.1907 - int nargs=0; /* number of arguments */
15.1908 - int heapalloc=0;
15.1909 - int namedparams=FALSE;
15.1910 - value lval = {0};
15.1911 - arginfo *arg;
15.1912 - char arglist[sMAXARGS];
15.1913 - constvalue arrayszlst = { NULL, "", 0, 0};/* array size list starts empty */
15.1914 - constvalue taglst = { NULL, "", 0, 0}; /* tag list starts empty */
15.1915 - symbol *symret;
15.1916 - cell lexval;
15.1917 - char *lexstr;
15.1918 -
15.1919 - assert(sym!=NULL);
15.1920 - lval_result->ident=iEXPRESSION; /* preset, may be changed later */
15.1921 - lval_result->constval=0;
15.1922 - lval_result->tag=sym->tag;
15.1923 - /* check whether this is a function that returns an array */
15.1924 - symret=finddepend(sym);
15.1925 - assert(symret==NULL || symret->ident==iREFARRAY);
15.1926 - if (symret!=NULL) {
15.1927 - int retsize;
15.1928 - /* allocate space on the heap for the array, and pass the pointer to the
15.1929 - * reserved memory block as a hidden parameter
15.1930 - */
15.1931 - retsize=(int)array_totalsize(symret);
15.1932 - assert(retsize>0);
15.1933 - modheap(retsize*sizeof(cell));/* address is in ALT */
15.1934 - pushreg(sALT); /* pass ALT as the last (hidden) parameter */
15.1935 - decl_heap+=retsize;
15.1936 - /* also mark the ident of the result as "array" */
15.1937 - lval_result->ident=iREFARRAY;
15.1938 - lval_result->sym=symret;
15.1939 - } /* if */
15.1940 - locheap=decl_heap;
15.1941 -
15.1942 - nesting++;
15.1943 - assert(nest_stkusage>=0);
15.1944 - #if !defined NDEBUG
15.1945 - if (nesting==1)
15.1946 - assert(nest_stkusage==0);
15.1947 - #endif
15.1948 - sc_allowproccall=FALSE; /* parameters may not use procedure call syntax */
15.1949 -
15.1950 - if ((sym->flags & flgDEPRICATED)!=0) {
15.1951 - char *ptr= (sym->documentation!=NULL) ? sym->documentation : "";
15.1952 - error(234,sym->name,ptr); /* depricated (probably a native function) */
15.1953 - } /* if */
15.1954 -
15.1955 - /* run through the arguments */
15.1956 - arg=sym->dim.arglist;
15.1957 - assert(arg!=NULL);
15.1958 - stgmark(sSTARTREORDER);
15.1959 - memset(arglist,ARG_UNHANDLED,sizeof arglist);
15.1960 - if (matchparanthesis) {
15.1961 - /* Opening brace was already parsed, if closing brace follows, this
15.1962 - * call passes no parameters.
15.1963 - */
15.1964 - close=matchtoken(')');
15.1965 - } else {
15.1966 - /* When we find an end of line here, it may be a function call passing
15.1967 - * no parameters, or it may be that the first parameter is on a line
15.1968 - * below. But as a parameter can be anything, this is difficult to check.
15.1969 - * The only simple check that we have is the use of "named parameters".
15.1970 - */
15.1971 - close=matchtoken(tTERM);
15.1972 - if (close) {
15.1973 - close=!matchtoken('.');
15.1974 - if (!close)
15.1975 - lexpush(); /* reset the '.' */
15.1976 - } /* if */
15.1977 - } /* if */
15.1978 - if (!close) {
15.1979 - do {
15.1980 - if (matchtoken('.')) {
15.1981 - namedparams=TRUE;
15.1982 - if (needtoken(tSYMBOL))
15.1983 - tokeninfo(&lexval,&lexstr);
15.1984 - else
15.1985 - lexstr="";
15.1986 - argpos=findnamedarg(arg,lexstr);
15.1987 - if (argpos<0) {
15.1988 - error(17,lexstr); /* undefined symbol */
15.1989 - break; /* exit loop, argpos is invalid */
15.1990 - } /* if */
15.1991 - needtoken('=');
15.1992 - argidx=argpos;
15.1993 - } else {
15.1994 - if (namedparams)
15.1995 - error(44); /* positional parameters must precede named parameters */
15.1996 - argpos=nargs;
15.1997 - } /* if */
15.1998 - /* the number of arguments this was already checked at the declaration
15.1999 - * of the function; check it again for functions with a variable
15.2000 - * argument list
15.2001 - */
15.2002 - if (argpos>=sMAXARGS)
15.2003 - error(45); /* too many function arguments */
15.2004 - stgmark((char)(sEXPRSTART+argpos));/* mark beginning of new expression in stage */
15.2005 - if (arglist[argpos]!=ARG_UNHANDLED)
15.2006 - error(58); /* argument already set */
15.2007 - if (matchtoken('_')) {
15.2008 - arglist[argpos]=ARG_IGNORED; /* flag argument as "present, but ignored" */
15.2009 - if (arg[argidx].ident==0 || arg[argidx].ident==iVARARGS) {
15.2010 - error(92); /* argument count mismatch */
15.2011 - } else if (!arg[argidx].hasdefault) {
15.2012 - error(34,nargs+1); /* argument has no default value */
15.2013 - } /* if */
15.2014 - if (arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS)
15.2015 - argidx++;
15.2016 - /* The rest of the code to handle default values is at the bottom
15.2017 - * of this routine where default values for unspecified parameters
15.2018 - * are (also) handled. Note that above, the argument is flagged as
15.2019 - * ARG_IGNORED.
15.2020 - */
15.2021 - } else {
15.2022 - arglist[argpos]=ARG_DONE; /* flag argument as "present" */
15.2023 - if (arg[argidx].numtags==1) /* set the expected tag, if any */
15.2024 - lval.cmptag=arg[argidx].tags[0];
15.2025 - lvalue=hier14(&lval);
15.2026 - assert(sc_status==statFIRST || arg[argidx].tags!=NULL);
15.2027 - switch (arg[argidx].ident) {
15.2028 - case 0:
15.2029 - error(92); /* argument count mismatch */
15.2030 - break;
15.2031 - case iVARARGS:
15.2032 - /* always pass by reference */
15.2033 - if (lval.ident==iVARIABLE || lval.ident==iREFERENCE) {
15.2034 - assert(lval.sym!=NULL);
15.2035 - if ((lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0) {
15.2036 - /* treat a "const" variable passed to a function with a non-const
15.2037 - * "variable argument list" as a constant here */
15.2038 - if (!lvalue) {
15.2039 - error(22); /* need lvalue */
15.2040 - } else {
15.2041 - rvalue(&lval); /* get value in PRI */
15.2042 - setheap_pri(); /* address of the value on the heap in PRI */
15.2043 - heapalloc++;
15.2044 - nest_stkusage++;
15.2045 - } /* if */
15.2046 - } else if (lvalue) {
15.2047 - address(lval.sym,sPRI);
15.2048 - } else {
15.2049 - setheap_pri(); /* address of the value on the heap in PRI */
15.2050 - heapalloc++;
15.2051 - nest_stkusage++;
15.2052 - } /* if */
15.2053 - } else if (lval.ident==iCONSTEXPR || lval.ident==iEXPRESSION
15.2054 - || lval.ident==iARRAYCHAR)
15.2055 - {
15.2056 - /* fetch value if needed */
15.2057 - if (lval.ident==iARRAYCHAR)
15.2058 - rvalue(&lval);
15.2059 - /* allocate a cell on the heap and store the
15.2060 - * value (already in PRI) there */
15.2061 - setheap_pri(); /* address of the value on the heap in PRI */
15.2062 - heapalloc++;
15.2063 - nest_stkusage++;
15.2064 - } /* if */
15.2065 - /* ??? handle const array passed by reference */
15.2066 - /* otherwise, the address is already in PRI */
15.2067 - if (lval.sym!=NULL)
15.2068 - markusage(lval.sym,uWRITTEN);
15.2069 - if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
15.2070 - error(213);
15.2071 - if (lval.tag!=0)
15.2072 - append_constval(&taglst,arg[argidx].name,lval.tag,0);
15.2073 - break;
15.2074 - case iVARIABLE:
15.2075 - if (lval.ident==iLABEL || lval.ident==iFUNCTN || lval.ident==iREFFUNC
15.2076 - || lval.ident==iARRAY || lval.ident==iREFARRAY)
15.2077 - error(35,argidx+1); /* argument type mismatch */
15.2078 - if (lvalue)
15.2079 - rvalue(&lval); /* get value (direct or indirect) */
15.2080 - /* otherwise, the expression result is already in PRI */
15.2081 - assert(arg[argidx].numtags>0);
15.2082 - check_userop(NULL,lval.tag,arg[argidx].tags[0],2,NULL,&lval.tag);
15.2083 - if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
15.2084 - error(213);
15.2085 - if (lval.tag!=0)
15.2086 - append_constval(&taglst,arg[argidx].name,lval.tag,0);
15.2087 - argidx++; /* argument done */
15.2088 - break;
15.2089 - case iREFERENCE:
15.2090 - if (!lvalue || lval.ident==iARRAYCHAR)
15.2091 - error(35,argidx+1); /* argument type mismatch */
15.2092 - if (lval.sym!=NULL && (lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0)
15.2093 - error(35,argidx+1); /* argument type mismatch */
15.2094 - if (lval.ident==iVARIABLE || lval.ident==iREFERENCE) {
15.2095 - if (lvalue) {
15.2096 - assert(lval.sym!=NULL);
15.2097 - address(lval.sym,sPRI);
15.2098 - } else {
15.2099 - setheap_pri(); /* address of the value on the heap in PRI */
15.2100 - heapalloc++;
15.2101 - nest_stkusage++;
15.2102 - } /* if */
15.2103 - } /* if */
15.2104 - /* otherwise, the address is already in PRI */
15.2105 - if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
15.2106 - error(213);
15.2107 - if (lval.tag!=0)
15.2108 - append_constval(&taglst,arg[argidx].name,lval.tag,0);
15.2109 - argidx++; /* argument done */
15.2110 - if (lval.sym!=NULL)
15.2111 - markusage(lval.sym,uWRITTEN);
15.2112 - break;
15.2113 - case iREFARRAY:
15.2114 - if (lval.ident!=iARRAY && lval.ident!=iREFARRAY
15.2115 - && lval.ident!=iARRAYCELL)
15.2116 - {
15.2117 - error(35,argidx+1); /* argument type mismatch */
15.2118 - break;
15.2119 - } /* if */
15.2120 - if (lval.sym!=NULL && (lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0)
15.2121 - error(35,argidx+1); /* argument type mismatch */
15.2122 - /* Verify that the dimensions match with those in arg[argidx].
15.2123 - * A literal array always has a single dimension.
15.2124 - * An iARRAYCELL parameter is also assumed to have a single dimension.
15.2125 - */
15.2126 - if (lval.sym==NULL || lval.ident==iARRAYCELL) {
15.2127 - if (arg[argidx].numdim!=1) {
15.2128 - error(48); /* array dimensions must match */
15.2129 - } else if (arg[argidx].dim[0]!=0) {
15.2130 - assert(arg[argidx].dim[0]>0);
15.2131 - if (lval.ident==iARRAYCELL) {
15.2132 - error(47); /* array sizes must match */
15.2133 - } else {
15.2134 - assert(lval.constval!=0); /* literal array must have a size */
15.2135 - /* A literal array must have exactly the same size as the
15.2136 - * function argument; a literal string may be smaller than
15.2137 - * the function argument.
15.2138 - */
15.2139 - if (lval.constval>0 && arg[argidx].dim[0]!=lval.constval
15.2140 - || lval.constval<0 && arg[argidx].dim[0] < -lval.constval)
15.2141 - error(47); /* array sizes must match */
15.2142 - } /* if */
15.2143 - } /* if */
15.2144 - if (lval.ident!=iARRAYCELL) {
15.2145 - /* save array size, for default values with uSIZEOF flag */
15.2146 - cell array_sz=lval.constval;
15.2147 - assert(array_sz!=0);/* literal array must have a size */
15.2148 - if (array_sz<0)
15.2149 - array_sz= -array_sz;
15.2150 - append_constval(&arrayszlst,arg[argidx].name,array_sz,0);
15.2151 - } /* if */
15.2152 - } else {
15.2153 - symbol *sym=lval.sym;
15.2154 - short level=0;
15.2155 - assert(sym!=NULL);
15.2156 - if (sym->dim.array.level+1!=arg[argidx].numdim)
15.2157 - error(48); /* array dimensions must match */
15.2158 - /* the lengths for all dimensions must match, unless the dimension
15.2159 - * length was defined at zero (which means "undefined")
15.2160 - */
15.2161 - while (sym->dim.array.level>0) {
15.2162 - assert(level<sDIMEN_MAX);
15.2163 - if (arg[argidx].dim[level]!=0 && sym->dim.array.length!=arg[argidx].dim[level])
15.2164 - error(47); /* array sizes must match */
15.2165 - else if (!matchtag(arg[argidx].idxtag[level],sym->x.tags.index,TRUE))
15.2166 - error(229,sym->name); /* index tag mismatch */
15.2167 - append_constval(&arrayszlst,arg[argidx].name,sym->dim.array.length,level);
15.2168 - sym=finddepend(sym);
15.2169 - assert(sym!=NULL);
15.2170 - level++;
15.2171 - } /* if */
15.2172 - /* the last dimension is checked too, again, unless it is zero */
15.2173 - assert(level<sDIMEN_MAX);
15.2174 - assert(sym!=NULL);
15.2175 - if (arg[argidx].dim[level]!=0 && sym->dim.array.length!=arg[argidx].dim[level])
15.2176 - error(47); /* array sizes must match */
15.2177 - else if (!matchtag(arg[argidx].idxtag[level],sym->x.tags.index,TRUE))
15.2178 - error(229,sym->name); /* index tag mismatch */
15.2179 - append_constval(&arrayszlst,arg[argidx].name,sym->dim.array.length,level);
15.2180 - } /* if */
15.2181 - /* address already in PRI */
15.2182 - if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
15.2183 - error(213);
15.2184 - if (lval.tag!=0)
15.2185 - append_constval(&taglst,arg[argidx].name,lval.tag,0);
15.2186 - // ??? set uWRITTEN?
15.2187 - argidx++; /* argument done */
15.2188 - break;
15.2189 - } /* switch */
15.2190 - pushreg(sPRI); /* store the function argument on the stack */
15.2191 - markexpr(sPARM,NULL,0); /* mark the end of a sub-expression */
15.2192 - nest_stkusage++;
15.2193 - } /* if */
15.2194 - assert(arglist[argpos]!=ARG_UNHANDLED);
15.2195 - nargs++;
15.2196 - if (matchparanthesis) {
15.2197 - close=matchtoken(')');
15.2198 - if (!close) /* if not paranthese... */
15.2199 - if (!needtoken(',')) /* ...should be comma... */
15.2200 - break; /* ...but abort loop if neither */
15.2201 - } else {
15.2202 - close=!matchtoken(',');
15.2203 - if (close) { /* if not comma... */
15.2204 - if (needtoken(tTERM)==1)/* ...must be end of statement */
15.2205 - lexpush(); /* push again, because end of statement is analised later */
15.2206 - } /* if */
15.2207 - } /* if */
15.2208 - } while (!close && freading && !matchtoken(tENDEXPR)); /* do */
15.2209 - } /* if */
15.2210 - /* check remaining function arguments (they may have default values) */
15.2211 - for (argidx=0; arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS; argidx++) {
15.2212 - if (arglist[argidx]==ARG_DONE)
15.2213 - continue; /* already seen and handled this argument */
15.2214 - /* in this first stage, we also skip the arguments with uSIZEOF and uTAGOF;
15.2215 - * these are handled last
15.2216 - */
15.2217 - if ((arg[argidx].hasdefault & uSIZEOF)!=0 || (arg[argidx].hasdefault & uTAGOF)!=0) {
15.2218 - assert(arg[argidx].ident==iVARIABLE);
15.2219 - continue;
15.2220 - } /* if */
15.2221 - stgmark((char)(sEXPRSTART+argidx));/* mark beginning of new expression in stage */
15.2222 - if (arg[argidx].hasdefault) {
15.2223 - if (arg[argidx].ident==iREFARRAY) {
15.2224 - short level;
15.2225 - setdefarray(arg[argidx].defvalue.array.data,
15.2226 - arg[argidx].defvalue.array.size,
15.2227 - arg[argidx].defvalue.array.arraysize,
15.2228 - &arg[argidx].defvalue.array.addr,
15.2229 - (arg[argidx].usage & uCONST)!=0);
15.2230 - if ((arg[argidx].usage & uCONST)==0) {
15.2231 - heapalloc+=arg[argidx].defvalue.array.arraysize;
15.2232 - nest_stkusage+=arg[argidx].defvalue.array.arraysize;
15.2233 - } /* if */
15.2234 - /* keep the lengths of all dimensions of a multi-dimensional default array */
15.2235 - assert(arg[argidx].numdim>0);
15.2236 - if (arg[argidx].numdim==1) {
15.2237 - append_constval(&arrayszlst,arg[argidx].name,arg[argidx].defvalue.array.arraysize,0);
15.2238 - } else {
15.2239 - for (level=0; level<arg[argidx].numdim; level++) {
15.2240 - assert(level<sDIMEN_MAX);
15.2241 - append_constval(&arrayszlst,arg[argidx].name,arg[argidx].dim[level],level);
15.2242 - } /* for */
15.2243 - } /* if */
15.2244 - } else if (arg[argidx].ident==iREFERENCE) {
15.2245 - setheap(arg[argidx].defvalue.val);
15.2246 - /* address of the value on the heap in PRI */
15.2247 - heapalloc++;
15.2248 - nest_stkusage++;
15.2249 - } else {
15.2250 - int dummytag=arg[argidx].tags[0];
15.2251 - ldconst(arg[argidx].defvalue.val,sPRI);
15.2252 - assert(arg[argidx].numtags>0);
15.2253 - check_userop(NULL,arg[argidx].defvalue_tag,arg[argidx].tags[0],2,NULL,&dummytag);
15.2254 - assert(dummytag==arg[argidx].tags[0]);
15.2255 - } /* if */
15.2256 - pushreg(sPRI); /* store the function argument on the stack */
15.2257 - markexpr(sPARM,NULL,0); /* mark the end of a sub-expression */
15.2258 - nest_stkusage++;
15.2259 - } else {
15.2260 - error(202,argidx); /* argument count mismatch */
15.2261 - } /* if */
15.2262 - if (arglist[argidx]==ARG_UNHANDLED)
15.2263 - nargs++;
15.2264 - arglist[argidx]=ARG_DONE;
15.2265 - } /* for */
15.2266 - /* now a second loop to catch the arguments with default values that are
15.2267 - * the "sizeof" or "tagof" of other arguments
15.2268 - */
15.2269 - for (argidx=0; arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS; argidx++) {
15.2270 - constvalue *asz;
15.2271 - cell array_sz;
15.2272 - if (arglist[argidx]==ARG_DONE)
15.2273 - continue; /* already seen and handled this argument */
15.2274 - stgmark((char)(sEXPRSTART+argidx));/* mark beginning of new expression in stage */
15.2275 - assert(arg[argidx].ident==iVARIABLE); /* if "sizeof", must be single cell */
15.2276 - /* if unseen, must be "sizeof" or "tagof" */
15.2277 - assert((arg[argidx].hasdefault & uSIZEOF)!=0 || (arg[argidx].hasdefault & uTAGOF)!=0);
15.2278 - if ((arg[argidx].hasdefault & uSIZEOF)!=0) {
15.2279 - /* find the argument; if it isn't found, the argument's default value
15.2280 - * was a "sizeof" of a non-array (a warning for this was already given
15.2281 - * when declaring the function)
15.2282 - */
15.2283 - asz=find_constval(&arrayszlst,arg[argidx].defvalue.size.symname,
15.2284 - arg[argidx].defvalue.size.level);
15.2285 - if (asz!=NULL) {
15.2286 - array_sz=asz->value;
15.2287 - if (array_sz==0)
15.2288 - error(224,arg[argidx].name); /* indeterminate array size in "sizeof" expression */
15.2289 - } else {
15.2290 - array_sz=1;
15.2291 - } /* if */
15.2292 - } else {
15.2293 - asz=find_constval(&taglst,arg[argidx].defvalue.size.symname,
15.2294 - arg[argidx].defvalue.size.level);
15.2295 - if (asz != NULL) {
15.2296 - exporttag(asz->value);
15.2297 - array_sz=asz->value | PUBLICTAG; /* must be set, because it just was exported */
15.2298 - } else {
15.2299 - array_sz=0;
15.2300 - } /* if */
15.2301 - } /* if */
15.2302 - ldconst(array_sz,sPRI);
15.2303 - pushreg(sPRI); /* store the function argument on the stack */
15.2304 - markexpr(sPARM,NULL,0);
15.2305 - nest_stkusage++;
15.2306 - if (arglist[argidx]==ARG_UNHANDLED)
15.2307 - nargs++;
15.2308 - arglist[argidx]=ARG_DONE;
15.2309 - } /* for */
15.2310 - stgmark(sENDREORDER); /* mark end of reversed evaluation */
15.2311 - pushval((cell)nargs*sizeof(cell));
15.2312 - nest_stkusage++;
15.2313 - ffcall(sym,NULL,nargs);
15.2314 - if (sc_status!=statSKIP)
15.2315 - markusage(sym,uREAD); /* do not mark as "used" when this call itself is skipped */
15.2316 - if ((sym->usage & uNATIVE)!=0 &&sym->x.lib!=NULL)
15.2317 - sym->x.lib->value += 1; /* increment "usage count" of the library */
15.2318 - modheap(-heapalloc*sizeof(cell));
15.2319 - if (symret!=NULL)
15.2320 - popreg(sPRI); /* pop hidden parameter as function result */
15.2321 - sideeffect=TRUE; /* assume functions carry out a side-effect */
15.2322 - delete_consttable(&arrayszlst); /* clear list of array sizes */
15.2323 - delete_consttable(&taglst); /* clear list of parameter tags */
15.2324 -
15.2325 - /* maintain max. amount of memory used */
15.2326 - {
15.2327 - long totalsize;
15.2328 - totalsize=declared+decl_heap+1; /* local variables & return value size,
15.2329 - * +1 for PROC opcode */
15.2330 - if (lval_result->ident==iREFARRAY)
15.2331 - totalsize++; /* add hidden parameter (on the stack) */
15.2332 - if ((sym->usage & uNATIVE)==0)
15.2333 - totalsize++; /* add "call" opcode */
15.2334 - totalsize+=nest_stkusage;
15.2335 - assert(curfunc!=NULL);
15.2336 - if (curfunc->x.stacksize<totalsize)
15.2337 - curfunc->x.stacksize=totalsize;
15.2338 - nest_stkusage-=nargs+heapalloc+1; /* stack/heap space, +1 for argcount param */
15.2339 - /* if there is a syntax error in the script, the stack calculation is
15.2340 - * probably incorrect; but we may not allow it to drop below zero
15.2341 - */
15.2342 - if (nest_stkusage<0)
15.2343 - nest_stkusage=0;
15.2344 - }
15.2345 -
15.2346 - /* scrap any arrays left on the heap, with the exception of the array that
15.2347 - * this function has as a result (in other words, scrap all arrays on the
15.2348 - * heap that caused by expressions in the function arguments)
15.2349 - */
15.2350 - assert(decl_heap>=locheap);
15.2351 - modheap((locheap-decl_heap)*sizeof(cell)); /* remove heap space, so negative delta */
15.2352 - decl_heap=locheap;
15.2353 - nesting--;
15.2354 -}
15.2355 -
15.2356 -/* dbltest
15.2357 - *
15.2358 - * Returns a non-zero value if lval1 an array and lval2 is not an array and
15.2359 - * the operation is addition or subtraction.
15.2360 - *
15.2361 - * Returns the "shift" count (1 for 16-bit, 2 for 32-bit) to align a cell
15.2362 - * to an array offset.
15.2363 - */
15.2364 -static int dbltest(void (*oper)(),value *lval1,value *lval2)
15.2365 -{
15.2366 - if ((oper!=ob_add) && (oper!=ob_sub))
15.2367 - return 0;
15.2368 - if (lval1->ident!=iARRAY)
15.2369 - return 0;
15.2370 - if (lval2->ident==iARRAY)
15.2371 - return 0;
15.2372 - return sizeof(cell)/2; /* 1 for 16-bit, 2 for 32-bit */
15.2373 -}
15.2374 -
15.2375 -/* commutative
15.2376 - *
15.2377 - * Test whether an operator is commutative, i.e. x oper y == y oper x.
15.2378 - * Commutative operators are: + (addition)
15.2379 - * * (multiplication)
15.2380 - * == (equality)
15.2381 - * != (inequality)
15.2382 - * & (bitwise and)
15.2383 - * ^ (bitwise xor)
15.2384 - * | (bitwise or)
15.2385 - *
15.2386 - * If in an expression, code for the left operand has been generated and
15.2387 - * the right operand is a constant and the operator is commutative, the
15.2388 - * precautionary "push" of the primary register is scrapped and the constant
15.2389 - * is read into the secondary register immediately.
15.2390 - */
15.2391 -static int commutative(void (*oper)())
15.2392 -{
15.2393 - return oper==ob_add || oper==os_mult
15.2394 - || oper==ob_eq || oper==ob_ne
15.2395 - || oper==ob_and || oper==ob_xor || oper==ob_or;
15.2396 -}
15.2397 -
15.2398 -/* constant
15.2399 - *
15.2400 - * Generates code to fetch a number, a literal character (which is returned
15.2401 - * by lex() as a number as well) or a literal string (lex() stores the
15.2402 - * strings in the literal queue). If the operand was a number, it is stored
15.2403 - * in lval->constval.
15.2404 - *
15.2405 - * The function returns 1 if the token was a constant or a string, 0
15.2406 - * otherwise.
15.2407 - */
15.2408 -static int constant(value *lval)
15.2409 -{
15.2410 - int tok,index,ident;
15.2411 - cell val,item,cidx;
15.2412 - char *st;
15.2413 - symbol *sym;
15.2414 - int cmptag=lval->cmptag;
15.2415 -
15.2416 - tok=lex(&val,&st);
15.2417 - if (tok==tSYMBOL && (sym=findconst(st,&cmptag))!=0) {
15.2418 - if (cmptag>1)
15.2419 - error(91,sym->name); /* ambiguity: multiple matching constants (different tags) */
15.2420 - lval->constval=sym->addr;
15.2421 - ldconst(lval->constval,sPRI);
15.2422 - lval->ident=iCONSTEXPR;
15.2423 - lval->tag=sym->tag;
15.2424 - lval->sym=sym;
15.2425 - markusage(sym,uREAD);
15.2426 - } else if (tok==tNUMBER) {
15.2427 - lval->constval=val;
15.2428 - ldconst(lval->constval,sPRI);
15.2429 - lval->ident=iCONSTEXPR;
15.2430 - } else if (tok==tRATIONAL) {
15.2431 - lval->constval=val;
15.2432 - ldconst(lval->constval,sPRI);
15.2433 - lval->ident=iCONSTEXPR;
15.2434 - lval->tag=sc_rationaltag;
15.2435 - } else if (tok==tSTRING) {
15.2436 - /* lex() stores starting index of string in the literal table in 'val' */
15.2437 - ldconst((val+glb_declared)*sizeof(cell),sPRI);
15.2438 - lval->ident=iARRAY; /* pretend this is a global array */
15.2439 - lval->constval=val-litidx; /* constval == the negative value of the
15.2440 - * size of the literal array; using a negative
15.2441 - * value distinguishes between literal arrays
15.2442 - * and literal strings (this was done for
15.2443 - * array assignment). */
15.2444 - } else if (tok=='{') {
15.2445 - int tag,lasttag=-1;
15.2446 - val=litidx;
15.2447 - do {
15.2448 - /* cannot call constexpr() here, because "staging" is already turned
15.2449 - * on at this point */
15.2450 - assert(staging);
15.2451 - stgget(&index,&cidx); /* mark position in code generator */
15.2452 - ident=expression(&item,&tag,NULL,FALSE);
15.2453 - stgdel(index,cidx); /* scratch generated code */
15.2454 - if (ident!=iCONSTEXPR)
15.2455 - error(8); /* must be constant expression */
15.2456 - if (lasttag<0)
15.2457 - lasttag=tag;
15.2458 - else if (!matchtag(lasttag,tag,FALSE))
15.2459 - error(213); /* tagname mismatch */
15.2460 - litadd(item); /* store expression result in literal table */
15.2461 - } while (matchtoken(','));
15.2462 - if (!needtoken('}'))
15.2463 - lexclr(FALSE);
15.2464 - ldconst((val+glb_declared)*sizeof(cell),sPRI);
15.2465 - lval->ident=iARRAY; /* pretend this is a global array */
15.2466 - lval->constval=litidx-val; /* constval == the size of the literal array */
15.2467 - } else {
15.2468 - return FALSE; /* no, it cannot be interpreted as a constant */
15.2469 - } /* if */
15.2470 - return TRUE; /* yes, it was a constant value */
15.2471 -}
15.2472 -
16.1 --- a/compiler-init/sc4.c Sat Jul 15 05:02:38 2006 +0000
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,1331 +0,0 @@
16.4 -/* Pawn compiler - code generation (unoptimized "assembler" code)
16.5 - *
16.6 - * Copyright (c) ITB CompuPhase, 1997-2006
16.7 - *
16.8 - * This software is provided "as-is", without any express or implied warranty.
16.9 - * In no event will the authors be held liable for any damages arising from
16.10 - * the use of this software.
16.11 - *
16.12 - * Permission is granted to anyone to use this software for any purpose,
16.13 - * including commercial applications, and to alter it and redistribute it
16.14 - * freely, subject to the following restrictions:
16.15 - *
16.16 - * 1. The origin of this software must not be misrepresented; you must not
16.17 - * claim that you wrote the original software. If you use this software in
16.18 - * a product, an acknowledgment in the product documentation would be
16.19 - * appreciated but is not required.
16.20 - * 2. Altered source versions must be plainly marked as such, and must not be
16.21 - * misrepresented as being the original software.
16.22 - * 3. This notice may not be removed or altered from any source distribution.
16.23 - *
16.24 - * Version: $Id: sc4.c 3579 2006-06-06 13:35:29Z thiadmer $
16.25 - */
16.26 -#include <assert.h>
16.27 -#include <ctype.h>
16.28 -#include <stdio.h>
16.29 -#include <stdlib.h> /* for _MAX_PATH */
16.30 -#include <string.h>
16.31 -#if defined FORTIFY
16.32 - #include <alloc/fortify.h>
16.33 -#endif
16.34 -#include "sc.h"
16.35 -
16.36 -static int fcurseg; /* the file number (fcurrent) for the active segment */
16.37 -
16.38 -
16.39 -/* When a subroutine returns to address 0, the AMX must halt. In earlier
16.40 - * releases, the RET and RETN opcodes checked for the special case 0 address.
16.41 - * Today, the compiler simply generates a HALT instruction at address 0. So
16.42 - * a subroutine can savely return to 0, and then encounter a HALT.
16.43 - */
16.44 -SC_FUNC void writeleader(symbol *root)
16.45 -{
16.46 - int lbl_nostate,lbl_table;
16.47 - int statecount;
16.48 - symbol *sym;
16.49 - constvalue *fsa, *state, *stlist;
16.50 - int fsa_id,listid;
16.51 - char lbl_default[sNAMEMAX+1];
16.52 -
16.53 - assert(code_idx==0);
16.54 -
16.55 - begcseg();
16.56 - stgwrite(";program exit point\n");
16.57 - stgwrite("\thalt 0\n\n");
16.58 - code_idx+=opcodes(1)+opargs(1); /* calculate code length */
16.59 -
16.60 - /* check whether there are any functions that have states */
16.61 - for (sym=root->next; sym!=NULL; sym=sym->next)
16.62 - if (sym->ident==iFUNCTN && (sym->usage & (uPUBLIC | uREAD))!=0 && sym->states!=NULL)
16.63 - break;
16.64 - if (sym==NULL)
16.65 - return; /* no function has states, nothing to do next */
16.66 -
16.67 - /* generate an error function that is called for an undefined state */
16.68 - stgwrite("\n;exit point for functions called from the wrong state\n");
16.69 - lbl_nostate=getlabel();
16.70 - setlabel(lbl_nostate);
16.71 - stgwrite("\thalt ");
16.72 - outval(AMX_ERR_INVSTATE,TRUE);
16.73 - code_idx+=opcodes(1)+opargs(1); /* calculate code length */
16.74 -
16.75 - /* write the "state-selectors" table with all automatons (update the
16.76 - * automatons structure too, as we are now assigning the address to
16.77 - * each automaton state-selector variable)
16.78 - */
16.79 - assert(glb_declared==0);
16.80 - begdseg();
16.81 - for (fsa=sc_automaton_tab.next; fsa!=NULL; fsa=fsa->next) {
16.82 - defstorage();
16.83 - stgwrite("0\t; automaton ");
16.84 - if (strlen(fsa->name)==0)
16.85 - stgwrite("(anonymous)");
16.86 - else
16.87 - stgwrite(fsa->name);
16.88 - stgwrite("\n");
16.89 - fsa->value=glb_declared*sizeof(cell);
16.90 - glb_declared++;
16.91 - } /* for */
16.92 -
16.93 - /* write stubs and jump tables for all state functions */
16.94 - begcseg();
16.95 - for (sym=root->next; sym!=NULL; sym=sym->next) {
16.96 - if (sym->ident==iFUNCTN && (sym->usage & (uPUBLIC | uREAD))!=0 && sym->states!=NULL) {
16.97 - stlist=sym->states->next;
16.98 - assert(stlist!=NULL); /* there should be at least one state item */
16.99 - listid=stlist->index;
16.100 - assert(listid==-1 || listid>0);
16.101 - if (listid==-1 && stlist->next!=NULL) {
16.102 - /* first index is the "fallback", take the next one (if available) */
16.103 - stlist=stlist->next;
16.104 - listid=stlist->index;
16.105 - } /* if */
16.106 - if (listid==-1) {
16.107 - /* first index is the fallback, there is no second... */
16.108 - strcpy(stlist->name,"0"); /* insert dummy label number */
16.109 - /* this is an error, but we postpone adding the error message until the
16.110 - * function definition
16.111 - */
16.112 - continue;
16.113 - } /* if */
16.114 - /* generate label numbers for all statelist ids */
16.115 - for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) {
16.116 - assert(strlen(stlist->name)==0);
16.117 - strcpy(stlist->name,itoh(getlabel()));
16.118 - } /* for */
16.119 - if (strcmp(sym->name,uENTRYFUNC)==0)
16.120 - continue; /* do not generate stubs for this special function */
16.121 - sym->addr=code_idx; /* fix the function address now */
16.122 - /* get automaton id for this function */
16.123 - assert(listid>0);
16.124 - fsa_id=state_getfsa(listid);
16.125 - assert(fsa_id>=0); /* automaton 0 exists */
16.126 - fsa=automaton_findid(fsa_id);
16.127 - /* count the number of states actually used; at the sane time, check
16.128 - * whether there is a default state function
16.129 - */
16.130 - statecount=0;
16.131 - strcpy(lbl_default,itoh(lbl_nostate));
16.132 - for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) {
16.133 - if (stlist->index==-1) {
16.134 - assert(strlen(stlist->name)<sizeof lbl_default);
16.135 - strcpy(lbl_default,stlist->name);
16.136 - } else {
16.137 - statecount+=state_count(stlist->index);
16.138 - } /* if */
16.139 - } /* for */
16.140 - /* generate a stub entry for the functions */
16.141 - stgwrite("\tload.pri ");
16.142 - outval(fsa->value,FALSE);
16.143 - stgwrite("\t; ");
16.144 - stgwrite(sym->name);
16.145 - stgwrite("\n");
16.146 - code_idx+=opcodes(1)+opargs(1); /* calculate code length */
16.147 - lbl_table=getlabel();
16.148 - ffswitch(lbl_table);
16.149 - /* generate the jump table */
16.150 - setlabel(lbl_table);
16.151 - ffcase(statecount,lbl_default,TRUE);
16.152 - for (state=sc_state_tab.next; state!=NULL; state=state->next) {
16.153 - if (state->index==fsa_id) {
16.154 - /* find the label for this list id */
16.155 - for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) {
16.156 - if (stlist->index!=-1 && state_inlist(stlist->index,(int)state->value)) {
16.157 - ffcase(state->value,stlist->name,FALSE);
16.158 - break;
16.159 - } /* if */
16.160 - } /* for */
16.161 - if (stlist==NULL && strtol(lbl_default,NULL,16)==lbl_nostate)
16.162 - error(230,state->name,sym->name); /* unimplemented state, no fallback */
16.163 - } /* if (state belongs to automaton of function) */
16.164 - } /* for (state) */
16.165 - stgwrite("\n");
16.166 - } /* if (is function, used & having states) */
16.167 - } /* for (sym) */
16.168 -}
16.169 -
16.170 -/* writetrailer
16.171 - * Not much left of this once important function.
16.172 - *
16.173 - * Global references: pc_stksize (referred to only)
16.174 - * sc_dataalign (referred to only)
16.175 - * code_idx (altered)
16.176 - * glb_declared (altered)
16.177 - */
16.178 -SC_FUNC void writetrailer(void)
16.179 -{
16.180 - assert(sc_dataalign % opcodes(1) == 0); /* alignment must be a multiple of
16.181 - * the opcode size */
16.182 - assert(sc_dataalign!=0);
16.183 -
16.184 - /* pad code to align data segment */
16.185 - if ((code_idx % sc_dataalign)!=0) {
16.186 - begcseg();
16.187 - while ((code_idx % sc_dataalign)!=0)
16.188 - nooperation();
16.189 - } /* if */
16.190 -
16.191 - /* pad data segment to align the stack and the heap */
16.192 - assert(litidx==0); /* literal queue should have been emptied */
16.193 - assert(sc_dataalign % sizeof(cell) == 0);
16.194 - if (((glb_declared*sizeof(cell)) % sc_dataalign)!=0) {
16.195 - begdseg();
16.196 - defstorage();
16.197 - while (((glb_declared*sizeof(cell)) % sc_dataalign)!=0) {
16.198 - stgwrite("0 ");
16.199 - glb_declared++;
16.200 - } /* while */
16.201 - } /* if */
16.202 -
16.203 - stgwrite("\nSTKSIZE "); /* write stack size (align stack top) */
16.204 - outval(pc_stksize - (pc_stksize % sc_dataalign), TRUE);
16.205 -}
16.206 -
16.207 -/*
16.208 - * Start (or restart) the CODE segment.
16.209 - *
16.210 - * In fact, the code and data segment specifiers are purely informational;
16.211 - * the "DUMP" instruction itself already specifies that the following values
16.212 - * should go to the data segment. All other instructions go to the code
16.213 - * segment.
16.214 - *
16.215 - * Global references: curseg
16.216 - * fcurrent
16.217 - */
16.218 -SC_FUNC void begcseg(void)
16.219 -{
16.220 - if (curseg!=sIN_CSEG || fcurrent!=fcurseg) {
16.221 - stgwrite("\n");
16.222 - stgwrite("CODE ");
16.223 - outval(fcurrent,FALSE);
16.224 - stgwrite("\t; ");
16.225 - outval(code_idx,TRUE);
16.226 - curseg=sIN_CSEG;
16.227 - fcurseg=fcurrent;
16.228 - } /* endif */
16.229 -}
16.230 -
16.231 -/*
16.232 - * Start (or restart) the DATA segment.
16.233 - *
16.234 - * Global references: curseg
16.235 - */
16.236 -SC_FUNC void begdseg(void)
16.237 -{
16.238 - if (curseg!=sIN_DSEG || fcurrent!=fcurseg) {
16.239 - stgwrite("\n");
16.240 - stgwrite("DATA ");
16.241 - outval(fcurrent,FALSE);
16.242 - stgwrite("\t; ");
16.243 - outval((glb_declared-litidx)*sizeof(cell),TRUE);
16.244 - curseg=sIN_DSEG;
16.245 - fcurseg=fcurrent;
16.246 - } /* if */
16.247 -}
16.248 -
16.249 -SC_FUNC void setline(int chkbounds)
16.250 -{
16.251 - if ((sc_debug & sSYMBOLIC)!=0 || chkbounds && (sc_debug & sCHKBOUNDS)!=0) {
16.252 - /* generate a "break" (start statement) opcode rather than a "line" opcode
16.253 - * because earlier versions of Small/Pawn have an incompatible version of the
16.254 - * line opcode
16.255 - */
16.256 - stgwrite("\tbreak\t; ");
16.257 - outval(code_idx,TRUE);
16.258 - code_idx+=opcodes(1);
16.259 - } /* if */
16.260 -}
16.261 -
16.262 -SC_FUNC void setfiledirect(char *name)
16.263 -{
16.264 - if (sc_status==statFIRST && sc_listing) {
16.265 - assert(name!=NULL);
16.266 - pc_writeasm(outf,"#file ");
16.267 - pc_writeasm(outf,name);
16.268 - pc_writeasm(outf,"\n");
16.269 - } /* if */
16.270 -}
16.271 -
16.272 -SC_FUNC void setlinedirect(int line)
16.273 -{
16.274 - if (sc_status==statFIRST && sc_listing) {
16.275 - char string[40];
16.276 - sprintf(string,"#line %d\n",line);
16.277 - pc_writeasm(outf,string);
16.278 - } /* if */
16.279 -}
16.280 -
16.281 -/* setlabel
16.282 - *
16.283 - * Post a code label (specified as a number), on a new line.
16.284 - */
16.285 -SC_FUNC void setlabel(int number)
16.286 -{
16.287 - assert(number>=0);
16.288 - stgwrite("l.");
16.289 - stgwrite((char *)itoh(number));
16.290 - /* To assist verification of the assembled code, put the address of the
16.291 - * label as a comment. However, labels that occur inside an expression
16.292 - * may move (through optimization or through re-ordering). So write the
16.293 - * address only if it is known to accurate.
16.294 - */
16.295 - if (!staging) {
16.296 - stgwrite("\t\t; ");
16.297 - outval(code_idx,FALSE);
16.298 - } /* if */
16.299 - stgwrite("\n");
16.300 -}
16.301 -
16.302 -/* Write a token that signifies the start or end of an expression or special
16.303 - * statement. This allows several simple optimizations by the peephole
16.304 - * optimizer.
16.305 - */
16.306 -SC_FUNC void markexpr(optmark type,const char *name,cell offset)
16.307 -{
16.308 - switch (type) {
16.309 - case sEXPR:
16.310 - stgwrite("\t;$exp\n");
16.311 - break;
16.312 - case sPARM:
16.313 - stgwrite("\t;$par\n");
16.314 - break;
16.315 - case sLDECL:
16.316 - assert(name!=NULL);
16.317 - stgwrite("\t;$lcl ");
16.318 - stgwrite(name);
16.319 - stgwrite(" ");
16.320 - outval(offset,TRUE);
16.321 - break;
16.322 - default:
16.323 - assert(0);
16.324 - } /* switch */
16.325 -}
16.326 -
16.327 -/* startfunc - declare a CODE entry point (function start)
16.328 - *
16.329 - * Global references: funcstatus (referred to only)
16.330 - */
16.331 -SC_FUNC void startfunc(char *fname)
16.332 -{
16.333 - stgwrite("\tproc");
16.334 - if (sc_asmfile) {
16.335 - char symname[2*sNAMEMAX+16];
16.336 - funcdisplayname(symname,fname);
16.337 - stgwrite("\t; ");
16.338 - stgwrite(symname);
16.339 - } /* if */
16.340 - stgwrite("\n");
16.341 - code_idx+=opcodes(1);
16.342 -}
16.343 -
16.344 -/* endfunc
16.345 - *
16.346 - * Declare a CODE ending point (function end)
16.347 - */
16.348 -SC_FUNC void endfunc(void)
16.349 -{
16.350 - stgwrite("\n"); /* skip a line */
16.351 -}
16.352 -
16.353 -/* alignframe
16.354 - *
16.355 - * Aligns the frame (and the stack) of the current function to a multiple
16.356 - * of the specified byte count. Two caveats: the alignment ("numbytes") should
16.357 - * be a power of 2, and this alignment must be done right after the frame
16.358 - * is set up (before the first variable is declared)
16.359 - */
16.360 -SC_FUNC void alignframe(int numbytes)
16.361 -{
16.362 - #if !defined NDEBUG
16.363 - /* "numbytes" should be a power of 2 for this code to work */
16.364 - int i,count=0;
16.365 - for (i=0; i<sizeof numbytes*8; i++)
16.366 - if (numbytes & (1 << i))
16.367 - count++;
16.368 - assert(count==1);
16.369 - #endif
16.370 -
16.371 - stgwrite("\tlctrl 4\n"); /* get STK in PRI */
16.372 - stgwrite("\tconst.alt "); /* get ~(numbytes-1) in ALT */
16.373 - outval(~(numbytes-1),TRUE);
16.374 - stgwrite("\tand\n"); /* PRI = STK "and" ~(numbytes-1) */
16.375 - stgwrite("\tsctrl 4\n"); /* set the new value of STK ... */
16.376 - stgwrite("\tsctrl 5\n"); /* ... and FRM */
16.377 - code_idx+=opcodes(5)+opargs(4);
16.378 -}
16.379 -
16.380 -/* rvalue
16.381 - *
16.382 - * Generate code to get the value of a symbol into "primary".
16.383 - */
16.384 -SC_FUNC void rvalue(value *lval)
16.385 -{
16.386 - symbol *sym;
16.387 -
16.388 - sym=lval->sym;
16.389 - if (lval->ident==iARRAYCELL) {
16.390 - /* indirect fetch, address already in PRI */
16.391 - stgwrite("\tload.i\n");
16.392 - code_idx+=opcodes(1);
16.393 - } else if (lval->ident==iARRAYCHAR) {
16.394 - /* indirect fetch of a character from a pack, address already in PRI */
16.395 - stgwrite("\tlodb.i ");
16.396 - outval(sCHARBITS/8,TRUE); /* read one or two bytes */
16.397 - code_idx+=opcodes(1)+opargs(1);
16.398 - } else if (lval->ident==iREFERENCE) {
16.399 - /* indirect fetch, but address not yet in PRI */
16.400 - assert(sym!=NULL);
16.401 - assert(sym->vclass==sLOCAL);/* global references don't exist in Pawn */
16.402 - if (sym->vclass==sLOCAL)
16.403 - stgwrite("\tlref.s.pri ");
16.404 - else
16.405 - stgwrite("\tlref.pri ");
16.406 - outval(sym->addr,TRUE);
16.407 - markusage(sym,uREAD);
16.408 - code_idx+=opcodes(1)+opargs(1);
16.409 - } else {
16.410 - /* direct or stack relative fetch */
16.411 - assert(sym!=NULL);
16.412 - if (sym->vclass==sLOCAL)
16.413 - stgwrite("\tload.s.pri ");
16.414 - else
16.415 - stgwrite("\tload.pri ");
16.416 - outval(sym->addr,TRUE);
16.417 - markusage(sym,uREAD);
16.418 - code_idx+=opcodes(1)+opargs(1);
16.419 - } /* if */
16.420 -}
16.421 -
16.422 -/* Get the address of a symbol into the primary or alternate register (used
16.423 - * for arrays, and for passing arguments by reference).
16.424 - */
16.425 -SC_FUNC void address(symbol *sym,regid reg)
16.426 -{
16.427 - assert(sym!=NULL);
16.428 - assert(reg==sPRI || reg==sALT);
16.429 - /* the symbol can be a local array, a global array, or an array
16.430 - * that is passed by reference.
16.431 - */
16.432 - if (sym->ident==iREFARRAY || sym->ident==iREFERENCE) {
16.433 - /* reference to a variable or to an array; currently this is
16.434 - * always a local variable */
16.435 - switch (reg) {
16.436 - case sPRI:
16.437 - stgwrite("\tload.s.pri ");
16.438 - break;
16.439 - case sALT:
16.440 - stgwrite("\tload.s.alt ");
16.441 - break;
16.442 - } /* switch */
16.443 - } else {
16.444 - /* a local array or local variable */
16.445 - switch (reg) {
16.446 - case sPRI:
16.447 - if (sym->vclass==sLOCAL)
16.448 - stgwrite("\taddr.pri ");
16.449 - else
16.450 - stgwrite("\tconst.pri ");
16.451 - break;
16.452 - case sALT:
16.453 - if (sym->vclass==sLOCAL)
16.454 - stgwrite("\taddr.alt ");
16.455 - else
16.456 - stgwrite("\tconst.alt ");
16.457 - break;
16.458 - } /* switch */
16.459 - } /* if */
16.460 - outval(sym->addr,TRUE);
16.461 - markusage(sym,uREAD);
16.462 - code_idx+=opcodes(1)+opargs(1);
16.463 -}
16.464 -
16.465 -/* store
16.466 - *
16.467 - * Saves the contents of "primary" into a memory cell, either directly
16.468 - * or indirectly (at the address given in the alternate register).
16.469 - */
16.470 -SC_FUNC void store(value *lval)
16.471 -{
16.472 - symbol *sym;
16.473 -
16.474 - sym=lval->sym;
16.475 - if (lval->ident==iARRAYCELL) {
16.476 - /* store at address in ALT */
16.477 - stgwrite("\tstor.i\n");
16.478 - code_idx+=opcodes(1);
16.479 - } else if (lval->ident==iARRAYCHAR) {
16.480 - /* store at address in ALT */
16.481 - stgwrite("\tstrb.i ");
16.482 - outval(sCHARBITS/8,TRUE); /* write one or two bytes */
16.483 - code_idx+=opcodes(1)+opargs(1);
16.484 - } else if (lval->ident==iREFERENCE) {
16.485 - assert(sym!=NULL);
16.486 - if (sym->vclass==sLOCAL)
16.487 - stgwrite("\tsref.s.pri ");
16.488 - else
16.489 - stgwrite("\tsref.pri ");
16.490 - outval(sym->addr,TRUE);
16.491 - code_idx+=opcodes(1)+opargs(1);
16.492 - } else {
16.493 - assert(sym!=NULL);
16.494 - markusage(sym,uWRITTEN);
16.495 - if (sym->vclass==sLOCAL)
16.496 - stgwrite("\tstor.s.pri ");
16.497 - else
16.498 - stgwrite("\tstor.pri ");
16.499 - outval(sym->addr,TRUE);
16.500 - code_idx+=opcodes(1)+opargs(1);
16.501 - } /* if */
16.502 -}
16.503 -
16.504 -/* Get a cell from a fixed address in memory */
16.505 -SC_FUNC void loadreg(cell address,regid reg)
16.506 -{
16.507 - assert(reg==sPRI || reg==sALT);
16.508 - if (reg==sPRI)
16.509 - stgwrite("\tload.pri ");
16.510 - else
16.511 - stgwrite("\tload.alt ");
16.512 - outval(address,TRUE);
16.513 - code_idx+=opcodes(1)+opargs(1);
16.514 -}
16.515 -
16.516 -/* Store a cell into a fixed address in memory */
16.517 -SC_FUNC void storereg(cell address,regid reg)
16.518 -{
16.519 - assert(reg==sPRI || reg==sALT);
16.520 - if (reg==sPRI)
16.521 - stgwrite("\tstor.pri ");
16.522 - else
16.523 - stgwrite("\tstor.alt ");
16.524 - outval(address,TRUE);
16.525 - code_idx+=opcodes(1)+opargs(1);
16.526 -}
16.527 -
16.528 -/* source must in PRI, destination address in ALT. The "size"
16.529 - * parameter is in bytes, not cells.
16.530 - */
16.531 -SC_FUNC void memcopy(cell size)
16.532 -{
16.533 - stgwrite("\tmovs ");
16.534 - outval(size,TRUE);
16.535 -
16.536 - code_idx+=opcodes(1)+opargs(1);
16.537 -}
16.538 -
16.539 -/* Address of the source must already have been loaded in PRI
16.540 - * "size" is the size in bytes (not cells).
16.541 - */
16.542 -SC_FUNC void copyarray(symbol *sym,cell size)
16.543 -{
16.544 - assert(sym!=NULL);
16.545 - /* the symbol can be a local array, a global array, or an array
16.546 - * that is passed by reference.
16.547 - */
16.548 - if (sym->ident==iREFARRAY) {
16.549 - /* reference to an array; currently this is always a local variable */
16.550 - assert(sym->vclass==sLOCAL); /* symbol must be stack relative */
16.551 - stgwrite("\tload.s.alt ");
16.552 - } else {
16.553 - /* a local or global array */
16.554 - if (sym->vclass==sLOCAL)
16.555 - stgwrite("\taddr.alt ");
16.556 - else
16.557 - stgwrite("\tconst.alt ");
16.558 - } /* if */
16.559 - outval(sym->addr,TRUE);
16.560 - markusage(sym,uWRITTEN);
16.561 -
16.562 - code_idx+=opcodes(1)+opargs(1);
16.563 - memcopy(size);
16.564 -}
16.565 -
16.566 -SC_FUNC void fillarray(symbol *sym,cell size,cell value)
16.567 -{
16.568 - ldconst(value,sPRI); /* load value in PRI */
16.569 -
16.570 - assert(sym!=NULL);
16.571 - /* the symbol can be a local array, a global array, or an array
16.572 - * that is passed by reference.
16.573 - */
16.574 - if (sym->ident==iREFARRAY) {
16.575 - /* reference to an array; currently this is always a local variable */
16.576 - assert(sym->vclass==sLOCAL); /* symbol must be stack relative */
16.577 - stgwrite("\tload.s.alt ");
16.578 - } else {
16.579 - /* a local or global array */
16.580 - if (sym->vclass==sLOCAL)
16.581 - stgwrite("\taddr.alt ");
16.582 - else
16.583 - stgwrite("\tconst.alt ");
16.584 - } /* if */
16.585 - outval(sym->addr,TRUE);
16.586 - markusage(sym,uWRITTEN);
16.587 -
16.588 - assert(size>0);
16.589 - stgwrite("\tfill ");
16.590 - outval(size,TRUE);
16.591 -
16.592 - code_idx+=opcodes(2)+opargs(2);
16.593 -}
16.594 -
16.595 -/* Instruction to get an immediate value into the primary or the alternate
16.596 - * register
16.597 - */
16.598 -SC_FUNC void ldconst(cell val,regid reg)
16.599 -{
16.600 - assert(reg==sPRI || reg==sALT);
16.601 - switch (reg) {
16.602 - case sPRI:
16.603 - if (val==0) {
16.604 - stgwrite("\tzero.pri\n");
16.605 - code_idx+=opcodes(1);
16.606 - } else {
16.607 - stgwrite("\tconst.pri ");
16.608 - outval(val, TRUE);
16.609 - code_idx+=opcodes(1)+opargs(1);
16.610 - } /* if */
16.611 - break;
16.612 - case sALT:
16.613 - if (val==0) {
16.614 - stgwrite("\tzero.alt\n");
16.615 - code_idx+=opcodes(1);
16.616 - } else {
16.617 - stgwrite("\tconst.alt ");
16.618 - outval(val, TRUE);
16.619 - code_idx+=opcodes(1)+opargs(1);
16.620 - } /* if */
16.621 - break;
16.622 - } /* switch */
16.623 -}
16.624 -
16.625 -/* Copy value in alternate register to the primary register */
16.626 -SC_FUNC void moveto1(void)
16.627 -{
16.628 - stgwrite("\tmove.pri\n");
16.629 - code_idx+=opcodes(1)+opargs(0);
16.630 -}
16.631 -
16.632 -/* Push primary or the alternate register onto the stack
16.633 - */
16.634 -SC_FUNC void pushreg(regid reg)
16.635 -{
16.636 - assert(reg==sPRI || reg==sALT);
16.637 - switch (reg) {
16.638 - case sPRI:
16.639 - stgwrite("\tpush.pri\n");
16.640 - break;
16.641 - case sALT:
16.642 - stgwrite("\tpush.alt\n");
16.643 - break;
16.644 - } /* switch */
16.645 - code_idx+=opcodes(1);
16.646 -}
16.647 -
16.648 -/*
16.649 - * Push a constant value onto the stack
16.650 - */
16.651 -SC_FUNC void pushval(cell val)
16.652 -{
16.653 - stgwrite("\tpush.c ");
16.654 - outval(val, TRUE);
16.655 - code_idx+=opcodes(1)+opargs(1);
16.656 -}
16.657 -
16.658 -/* Pop stack into the primary or the alternate register
16.659 - */
16.660 -SC_FUNC void popreg(regid reg)
16.661 -{
16.662 - assert(reg==sPRI || reg==sALT);
16.663 - switch (reg) {
16.664 - case sPRI:
16.665 - stgwrite("\tpop.pri\n");
16.666 - break;
16.667 - case sALT:
16.668 - stgwrite("\tpop.alt\n");
16.669 - break;
16.670 - } /* switch */
16.671 - code_idx+=opcodes(1);
16.672 -}
16.673 -
16.674 -/*
16.675 - * swap the top-of-stack with the value in primary register
16.676 - */
16.677 -SC_FUNC void swap1(void)
16.678 -{
16.679 - stgwrite("\tswap.pri\n");
16.680 - code_idx+=opcodes(1);
16.681 -}
16.682 -
16.683 -/* Switch statements
16.684 - * The "switch" statement generates a "case" table using the "CASE" opcode.
16.685 - * The case table contains a list of records, each record holds a comparison
16.686 - * value and a label to branch to on a match. The very first record is an
16.687 - * exception: it holds the size of the table (excluding the first record) and
16.688 - * the label to branch to when none of the values in the case table match.
16.689 - * The case table is sorted on the comparison value. This allows more advanced
16.690 - * abstract machines to sift the case table with a binary search.
16.691 - */
16.692 -SC_FUNC void ffswitch(int label)
16.693 -{
16.694 - stgwrite("\tswitch ");
16.695 - outval(label,TRUE); /* the label is the address of the case table */
16.696 - code_idx+=opcodes(1)+opargs(1);
16.697 -}
16.698 -
16.699 -SC_FUNC void ffcase(cell value,char *labelname,int newtable)
16.700 -{
16.701 - if (newtable) {
16.702 - stgwrite("\tcasetbl\n");
16.703 - code_idx+=opcodes(1);
16.704 - } /* if */
16.705 - stgwrite("\tcase ");
16.706 - outval(value,FALSE);
16.707 - stgwrite(" ");
16.708 - stgwrite(labelname);
16.709 - stgwrite("\n");
16.710 - code_idx+=opcodes(0)+opargs(2);
16.711 -}
16.712 -
16.713 -/*
16.714 - * Call specified function
16.715 - */
16.716 -SC_FUNC void ffcall(symbol *sym,const char *label,int numargs)
16.717 -{
16.718 - char symname[2*sNAMEMAX+16];
16.719 -
16.720 - assert(sym!=NULL);
16.721 - assert(sym->ident==iFUNCTN);
16.722 - if (sc_asmfile)
16.723 - funcdisplayname(symname,sym->name);
16.724 - if ((sym->usage & uNATIVE)!=0) {
16.725 - /* reserve a SYSREQ id if called for the first time */
16.726 - assert(label==NULL);
16.727 - if (sc_status==statWRITE && (sym->usage & uREAD)==0 && sym->addr>=0)
16.728 - sym->addr=ntv_funcid++;
16.729 - stgwrite("\tsysreq.c ");
16.730 - outval(sym->addr,FALSE);
16.731 - if (sc_asmfile) {
16.732 - stgwrite("\t; ");
16.733 - stgwrite(symname);
16.734 - } /* if */
16.735 - stgwrite("\n"); /* write on a separate line, to mark a sequence point for the peephole optimizer */
16.736 - stgwrite("\tstack ");
16.737 - outval((numargs+1)*sizeof(cell), TRUE);
16.738 - code_idx+=opcodes(2)+opargs(2);
16.739 - } else {
16.740 - /* normal function */
16.741 - stgwrite("\tcall ");
16.742 - if (label!=NULL) {
16.743 - stgwrite("l.");
16.744 - stgwrite(label);
16.745 - } else {
16.746 - stgwrite(sym->name);
16.747 - } /* if */
16.748 - if (sc_asmfile
16.749 - && (label!=NULL || !isalpha(sym->name[0]) && sym->name[0]!='_' && sym->name[0]!=sc_ctrlchar))
16.750 - {
16.751 - stgwrite("\t; ");
16.752 - stgwrite(symname);
16.753 - } /* if */
16.754 - stgwrite("\n");
16.755 - code_idx+=opcodes(1)+opargs(1);
16.756 - } /* if */
16.757 -}
16.758 -
16.759 -/* Return from function
16.760 - *
16.761 - * Global references: funcstatus (referred to only)
16.762 - */
16.763 -SC_FUNC void ffret(int remparams)
16.764 -{
16.765 - if (remparams)
16.766 - stgwrite("\tretn\n");
16.767 - else
16.768 - stgwrite("\tret\n");
16.769 - code_idx+=opcodes(1);
16.770 -}
16.771 -
16.772 -SC_FUNC void ffabort(int reason)
16.773 -{
16.774 - stgwrite("\thalt ");
16.775 - outval(reason,TRUE);
16.776 - code_idx+=opcodes(1)+opargs(1);
16.777 -}
16.778 -
16.779 -SC_FUNC void ffbounds(cell size)
16.780 -{
16.781 - if ((sc_debug & sCHKBOUNDS)!=0) {
16.782 - stgwrite("\tbounds ");
16.783 - outval(size,TRUE);
16.784 - code_idx+=opcodes(1)+opargs(1);
16.785 - } /* if */
16.786 -}
16.787 -
16.788 -/*
16.789 - * Jump to local label number (the number is converted to a name)
16.790 - */
16.791 -SC_FUNC void jumplabel(int number)
16.792 -{
16.793 - stgwrite("\tjump ");
16.794 - outval(number,TRUE);
16.795 - code_idx+=opcodes(1)+opargs(1);
16.796 -}
16.797 -
16.798 -/*
16.799 - * Define storage (global and static variables)
16.800 - */
16.801 -SC_FUNC void defstorage(void)
16.802 -{
16.803 - stgwrite("dump ");
16.804 -}
16.805 -
16.806 -/*
16.807 - * Inclrement/decrement stack pointer. Note that this routine does
16.808 - * nothing if the delta is zero.
16.809 - */
16.810 -SC_FUNC void modstk(int delta)
16.811 -{
16.812 - if (delta) {
16.813 - stgwrite("\tstack ");
16.814 - outval(delta, TRUE);
16.815 - code_idx+=opcodes(1)+opargs(1);
16.816 - } /* if */
16.817 -}
16.818 -
16.819 -/* set the stack to a hard offset from the frame */
16.820 -SC_FUNC void setstk(cell value)
16.821 -{
16.822 - stgwrite("\tlctrl 5\n"); /* get FRM in PRI */
16.823 - assert(value<=0); /* STK should always become <= FRM */
16.824 - if (value<0) {
16.825 - stgwrite("\tadd.c ");
16.826 - outval(value, TRUE); /* add (negative) offset */
16.827 - code_idx+=opcodes(1)+opargs(1);
16.828 - // ??? write zeros in the space between STK and the value in PRI (the new stk)
16.829 - // get value of STK in ALT
16.830 - // zero PRI
16.831 - // need new FILL opcode that takes a variable size
16.832 - } /* if */
16.833 - stgwrite("\tsctrl 4\n"); /* store in STK */
16.834 - code_idx+=opcodes(2)+opargs(2);
16.835 -}
16.836 -
16.837 -SC_FUNC void modheap(int delta)
16.838 -{
16.839 - if (delta) {
16.840 - stgwrite("\theap ");
16.841 - outval(delta, TRUE);
16.842 - code_idx+=opcodes(1)+opargs(1);
16.843 - } /* if */
16.844 -}
16.845 -
16.846 -SC_FUNC void setheap_pri(void)
16.847 -{
16.848 - stgwrite("\theap "); /* ALT = HEA++ */
16.849 - outval(sizeof(cell), TRUE);
16.850 - stgwrite("\tstor.i\n"); /* store PRI (default value) at address ALT */
16.851 - stgwrite("\tmove.pri\n"); /* move ALT to PRI: PRI contains the address */
16.852 - code_idx+=opcodes(3)+opargs(1);
16.853 -}
16.854 -
16.855 -SC_FUNC void setheap(cell value)
16.856 -{
16.857 - stgwrite("\tconst.pri "); /* load default value in PRI */
16.858 - outval(value, TRUE);
16.859 - code_idx+=opcodes(1)+opargs(1);
16.860 - setheap_pri();
16.861 -}
16.862 -
16.863 -/*
16.864 - * Convert a cell number to a "byte" address; i.e. double or quadruple
16.865 - * the primary register.
16.866 - */
16.867 -SC_FUNC void cell2addr(void)
16.868 -{
16.869 - #if PAWN_CELL_SIZE==16
16.870 - stgwrite("\tshl.c.pri 1\n");
16.871 - #elif PAWN_CELL_SIZE==32
16.872 - stgwrite("\tshl.c.pri 2\n");
16.873 - #elif PAWN_CELL_SIZE==64
16.874 - stgwrite("\tshl.c.pri 3\n");
16.875 - #else
16.876 - #error Unsupported cell size
16.877 - #endif
16.878 - code_idx+=opcodes(1)+opargs(1);
16.879 -}
16.880 -
16.881 -/*
16.882 - * Double or quadruple the alternate register.
16.883 - */
16.884 -SC_FUNC void cell2addr_alt(void)
16.885 -{
16.886 - #if PAWN_CELL_SIZE==16
16.887 - stgwrite("\tshl.c.alt 1\n");
16.888 - #elif PAWN_CELL_SIZE==32
16.889 - stgwrite("\tshl.c.alt 2\n");
16.890 - #elif PAWN_CELL_SIZE==64
16.891 - stgwrite("\tshl.c.alt 3\n");
16.892 - #else
16.893 - #error Unsupported cell size
16.894 - #endif
16.895 - code_idx+=opcodes(1)+opargs(1);
16.896 -}
16.897 -
16.898 -/*
16.899 - * Convert "distance of addresses" to "number of cells" in between.
16.900 - * Or convert a number of packed characters to the number of cells (with
16.901 - * truncation).
16.902 - */
16.903 -SC_FUNC void addr2cell(void)
16.904 -{
16.905 - #if PAWN_CELL_SIZE==16
16.906 - stgwrite("\tshr.c.pri 1\n");
16.907 - #elif PAWN_CELL_SIZE==32
16.908 - stgwrite("\tshr.c.pri 2\n");
16.909 - #elif PAWN_CELL_SIZE==64
16.910 - stgwrite("\tshr.c.pri 3\n");
16.911 - #else
16.912 - #error Unsupported cell size
16.913 - #endif
16.914 - code_idx+=opcodes(1)+opargs(1);
16.915 -}
16.916 -
16.917 -/* Convert from character index to byte address. This routine does
16.918 - * nothing if a character has the size of a byte.
16.919 - */
16.920 -SC_FUNC void char2addr(void)
16.921 -{
16.922 - #if sCHARBITS==16
16.923 - stgwrite("\tshl.c.pri 1\n");
16.924 - code_idx+=opcodes(1)+opargs(1);
16.925 - #endif
16.926 -}
16.927 -
16.928 -/* Align PRI (which should hold a character index) to an address.
16.929 - * The first character in a "pack" occupies the highest bits of
16.930 - * the cell. This is at the lower memory address on Big Endian
16.931 - * computers and on the higher address on Little Endian computers.
16.932 - * The ALIGN.pri/alt instructions must solve this machine dependence;
16.933 - * that is, on Big Endian computers, ALIGN.pri/alt shuold do nothing
16.934 - * and on Little Endian computers they should toggle the address.
16.935 - */
16.936 -SC_FUNC void charalign(void)
16.937 -{
16.938 - stgwrite("\talign.pri ");
16.939 - outval(sCHARBITS/8,TRUE);
16.940 - code_idx+=opcodes(1)+opargs(1);
16.941 -}
16.942 -
16.943 -/*
16.944 - * Add a constant to the primary register.
16.945 - */
16.946 -SC_FUNC void addconst(cell value)
16.947 -{
16.948 - if (value!=0) {
16.949 - stgwrite("\tadd.c ");
16.950 - outval(value,TRUE);
16.951 - code_idx+=opcodes(1)+opargs(1);
16.952 - } /* if */
16.953 -}
16.954 -
16.955 -/*
16.956 - * signed multiply of primary and secundairy registers (result in primary)
16.957 - */
16.958 -SC_FUNC void os_mult(void)
16.959 -{
16.960 - stgwrite("\tsmul\n");
16.961 - code_idx+=opcodes(1);
16.962 -}
16.963 -
16.964 -/*
16.965 - * signed divide of alternate register by primary register (quotient in
16.966 - * primary; remainder in alternate)
16.967 - */
16.968 -SC_FUNC void os_div(void)
16.969 -{
16.970 - stgwrite("\tsdiv.alt\n");
16.971 - code_idx+=opcodes(1);
16.972 -}
16.973 -
16.974 -/*
16.975 - * modulus of (alternate % primary), result in primary (signed)
16.976 - */
16.977 -SC_FUNC void os_mod(void)
16.978 -{
16.979 - stgwrite("\tsdiv.alt\n");
16.980 - stgwrite("\tmove.pri\n"); /* move ALT to PRI */
16.981 - code_idx+=opcodes(2);
16.982 -}
16.983 -
16.984 -/*
16.985 - * Add primary and alternate registers (result in primary).
16.986 - */
16.987 -SC_FUNC void ob_add(void)
16.988 -{
16.989 - stgwrite("\tadd\n");
16.990 - code_idx+=opcodes(1);
16.991 -}
16.992 -
16.993 -/*
16.994 - * subtract primary register from alternate register (result in primary)
16.995 - */
16.996 -SC_FUNC void ob_sub(void)
16.997 -{
16.998 - stgwrite("\tsub.alt\n");
16.999 - code_idx+=opcodes(1);
16.1000 -}
16.1001 -
16.1002 -/*
16.1003 - * arithmic shift left alternate register the number of bits
16.1004 - * given in the primary register (result in primary).
16.1005 - * There is no need for a "logical shift left" routine, since
16.1006 - * logical shift left is identical to arithmic shift left.
16.1007 - */
16.1008 -SC_FUNC void ob_sal(void)
16.1009 -{
16.1010 - stgwrite("\txchg\n");
16.1011 - stgwrite("\tshl\n");
16.1012 - code_idx+=opcodes(2);
16.1013 -}
16.1014 -
16.1015 -/*
16.1016 - * arithmic shift right alternate register the number of bits
16.1017 - * given in the primary register (result in primary).
16.1018 - */
16.1019 -SC_FUNC void os_sar(void)
16.1020 -{
16.1021 - stgwrite("\txchg\n");
16.1022 - stgwrite("\tsshr\n");
16.1023 - code_idx+=opcodes(2);
16.1024 -}
16.1025 -
16.1026 -/*
16.1027 - * logical (unsigned) shift right of the alternate register by the
16.1028 - * number of bits given in the primary register (result in primary).
16.1029 - */
16.1030 -SC_FUNC void ou_sar(void)
16.1031 -{
16.1032 - stgwrite("\txchg\n");
16.1033 - stgwrite("\tshr\n");
16.1034 - code_idx+=opcodes(2);
16.1035 -}
16.1036 -
16.1037 -/*
16.1038 - * inclusive "or" of primary and alternate registers (result in primary)
16.1039 - */
16.1040 -SC_FUNC void ob_or(void)
16.1041 -{
16.1042 - stgwrite("\tor\n");
16.1043 - code_idx+=opcodes(1);
16.1044 -}
16.1045 -
16.1046 -/*
16.1047 - * "exclusive or" of primary and alternate registers (result in primary)
16.1048 - */
16.1049 -SC_FUNC void ob_xor(void)
16.1050 -{
16.1051 - stgwrite("\txor\n");
16.1052 - code_idx+=opcodes(1);
16.1053 -}
16.1054 -
16.1055 -/*
16.1056 - * "and" of primary and secundairy registers (result in primary)
16.1057 - */
16.1058 -SC_FUNC void ob_and(void)
16.1059 -{
16.1060 - stgwrite("\tand\n");
16.1061 - code_idx+=opcodes(1);
16.1062 -}
16.1063 -
16.1064 -/*
16.1065 - * test ALT==PRI; result in primary register (1 or 0).
16.1066 - */
16.1067 -SC_FUNC void ob_eq(void)
16.1068 -{
16.1069 - stgwrite("\teq\n");
16.1070 - code_idx+=opcodes(1);
16.1071 -}
16.1072 -
16.1073 -/*
16.1074 - * test ALT!=PRI
16.1075 - */
16.1076 -SC_FUNC void ob_ne(void)
16.1077 -{
16.1078 - stgwrite("\tneq\n");
16.1079 - code_idx+=opcodes(1);
16.1080 -}
16.1081 -
16.1082 -/* The abstract machine defines the relational instructions so that PRI is
16.1083 - * on the left side and ALT on the right side of the operator. For example,
16.1084 - * SLESS sets PRI to either 1 or 0 depending on whether the expression
16.1085 - * "PRI < ALT" is true.
16.1086 - *
16.1087 - * The compiler generates comparisons with ALT on the left side of the
16.1088 - * relational operator and PRI on the right side. The XCHG instruction
16.1089 - * prefixing the relational operators resets this. We leave it to the
16.1090 - * peephole optimizer to choose more compact instructions where possible.
16.1091 - */
16.1092 -
16.1093 -/* Relational operator prefix for chained relational expressions. The
16.1094 - * "suffix" code restores the stack.
16.1095 - * For chained relational operators, the goal is to keep the comparison
16.1096 - * result "so far" in PRI and the value of the most recent operand in
16.1097 - * ALT, ready for a next comparison.
16.1098 - * The "prefix" instruction pushed the comparison result (PRI) onto the
16.1099 - * stack and moves the value of ALT into PRI. If there is a next comparison,
16.1100 - * PRI can now serve as the "left" operand of the relational operator.
16.1101 - */
16.1102 -SC_FUNC void relop_prefix(void)
16.1103 -{
16.1104 - stgwrite("\tpush.pri\n");
16.1105 - stgwrite("\tmove.pri\n");
16.1106 - code_idx+=opcodes(2);
16.1107 -}
16.1108 -
16.1109 -SC_FUNC void relop_suffix(void)
16.1110 -{
16.1111 - stgwrite("\tswap.alt\n");
16.1112 - stgwrite("\tand\n");
16.1113 - stgwrite("\tpop.alt\n");
16.1114 - code_idx+=opcodes(3);
16.1115 -}
16.1116 -
16.1117 -/*
16.1118 - * test ALT<PRI (signed)
16.1119 - */
16.1120 -SC_FUNC void os_lt(void)
16.1121 -{
16.1122 - stgwrite("\txchg\n");
16.1123 - stgwrite("\tsless\n");
16.1124 - code_idx+=opcodes(2);
16.1125 -}
16.1126 -
16.1127 -/*
16.1128 - * test ALT<=PRI (signed)
16.1129 - */
16.1130 -SC_FUNC void os_le(void)
16.1131 -{
16.1132 - stgwrite("\txchg\n");
16.1133 - stgwrite("\tsleq\n");
16.1134 - code_idx+=opcodes(2);
16.1135 -}
16.1136 -
16.1137 -/*
16.1138 - * test ALT>PRI (signed)
16.1139 - */
16.1140 -SC_FUNC void os_gt(void)
16.1141 -{
16.1142 - stgwrite("\txchg\n");
16.1143 - stgwrite("\tsgrtr\n");
16.1144 - code_idx+=opcodes(2);
16.1145 -}
16.1146 -
16.1147 -/*
16.1148 - * test ALT>=PRI (signed)
16.1149 - */
16.1150 -SC_FUNC void os_ge(void)
16.1151 -{
16.1152 - stgwrite("\txchg\n");
16.1153 - stgwrite("\tsgeq\n");
16.1154 - code_idx+=opcodes(2);
16.1155 -}
16.1156 -
16.1157 -/*
16.1158 - * logical negation of primary register
16.1159 - */
16.1160 -SC_FUNC void lneg(void)
16.1161 -{
16.1162 - stgwrite("\tnot\n");
16.1163 - code_idx+=opcodes(1);
16.1164 -}
16.1165 -
16.1166 -/*
16.1167 - * two's complement primary register
16.1168 - */
16.1169 -SC_FUNC void neg(void)
16.1170 -{
16.1171 - stgwrite("\tneg\n");
16.1172 - code_idx+=opcodes(1);
16.1173 -}
16.1174 -
16.1175 -/*
16.1176 - * one's complement of primary register
16.1177 - */
16.1178 -SC_FUNC void invert(void)
16.1179 -{
16.1180 - stgwrite("\tinvert\n");
16.1181 - code_idx+=opcodes(1);
16.1182 -}
16.1183 -
16.1184 -/*
16.1185 - * nop
16.1186 - */
16.1187 -SC_FUNC void nooperation(void)
16.1188 -{
16.1189 - stgwrite("\tnop\n");
16.1190 - code_idx+=opcodes(1);
16.1191 -}
16.1192 -
16.1193 -
16.1194 -/* increment symbol
16.1195 - */
16.1196 -SC_FUNC void inc(value *lval)
16.1197 -{
16.1198 - symbol *sym;
16.1199 -
16.1200 - sym=lval->sym;
16.1201 - if (lval->ident==iARRAYCELL) {
16.1202 - /* indirect increment, address already in PRI */
16.1203 - stgwrite("\tinc.i\n");
16.1204 - code_idx+=opcodes(1);
16.1205 - } else if (lval->ident==iARRAYCHAR) {
16.1206 - /* indirect increment of single character, address already in PRI */
16.1207 - stgwrite("\tpush.pri\n");
16.1208 - stgwrite("\tpush.alt\n");
16.1209 - stgwrite("\tmove.alt\n"); /* copy address */
16.1210 - stgwrite("\tlodb.i "); /* read from PRI into PRI */
16.1211 - outval(sCHARBITS/8,TRUE); /* read one or two bytes */
16.1212 - stgwrite("\tinc.pri\n");
16.1213 - stgwrite("\tstrb.i "); /* write PRI to ALT */
16.1214 - outval(sCHARBITS/8,TRUE); /* write one or two bytes */
16.1215 - stgwrite("\tpop.alt\n");
16.1216 - stgwrite("\tpop.pri\n");
16.1217 - code_idx+=opcodes(8)+opargs(2);
16.1218 - } else if (lval->ident==iREFERENCE) {
16.1219 - assert(sym!=NULL);
16.1220 - stgwrite("\tpush.pri\n");
16.1221 - /* load dereferenced value */
16.1222 - assert(sym->vclass==sLOCAL); /* global references don't exist in Pawn */
16.1223 - if (sym->vclass==sLOCAL)
16.1224 - stgwrite("\tlref.s.pri ");
16.1225 - else
16.1226 - stgwrite("\tlref.pri ");
16.1227 - outval(sym->addr,TRUE);
16.1228 - /* increment */
16.1229 - stgwrite("\tinc.pri\n");
16.1230 - /* store dereferenced value */
16.1231 - if (sym->vclass==sLOCAL)
16.1232 - stgwrite("\tsref.s.pri ");
16.1233 - else
16.1234 - stgwrite("\tsref.pri ");
16.1235 - outval(sym->addr,TRUE);
16.1236 - stgwrite("\tpop.pri\n");
16.1237 - code_idx+=opcodes(5)+opargs(2);
16.1238 - } else {
16.1239 - /* local or global variable */
16.1240 - assert(sym!=NULL);
16.1241 - if (sym->vclass==sLOCAL)
16.1242 - stgwrite("\tinc.s ");
16.1243 - else
16.1244 - stgwrite("\tinc ");
16.1245 - outval(sym->addr,TRUE);
16.1246 - code_idx+=opcodes(1)+opargs(1);
16.1247 - } /* if */
16.1248 -}
16.1249 -
16.1250 -/* decrement symbol
16.1251 - *
16.1252 - * in case of an integer pointer, the symbol must be incremented by 2.
16.1253 - */
16.1254 -SC_FUNC void dec(value *lval)
16.1255 -{
16.1256 - symbol *sym;
16.1257 -
16.1258 - sym=lval->sym;
16.1259 - if (lval->ident==iARRAYCELL) {
16.1260 - /* indirect decrement, address already in PRI */
16.1261 - stgwrite("\tdec.i\n");
16.1262 - code_idx+=opcodes(1);
16.1263 - } else if (lval->ident==iARRAYCHAR) {
16.1264 - /* indirect decrement of single character, address already in PRI */
16.1265 - stgwrite("\tpush.pri\n");
16.1266 - stgwrite("\tpush.alt\n");
16.1267 - stgwrite("\tmove.alt\n"); /* copy address */
16.1268 - stgwrite("\tlodb.i "); /* read from PRI into PRI */
16.1269 - outval(sCHARBITS/8,TRUE); /* read one or two bytes */
16.1270 - stgwrite("\tdec.pri\n");
16.1271 - stgwrite("\tstrb.i "); /* write PRI to ALT */
16.1272 - outval(sCHARBITS/8,TRUE); /* write one or two bytes */
16.1273 - stgwrite("\tpop.alt\n");
16.1274 - stgwrite("\tpop.pri\n");
16.1275 - code_idx+=opcodes(8)+opargs(2);
16.1276 - } else if (lval->ident==iREFERENCE) {
16.1277 - assert(sym!=NULL);
16.1278 - stgwrite("\tpush.pri\n");
16.1279 - /* load dereferenced value */
16.1280 - assert(sym->vclass==sLOCAL); /* global references don't exist in Pawn */
16.1281 - if (sym->vclass==sLOCAL)
16.1282 - stgwrite("\tlref.s.pri ");
16.1283 - else
16.1284 - stgwrite("\tlref.pri ");
16.1285 - outval(sym->addr,TRUE);
16.1286 - /* decrement */
16.1287 - stgwrite("\tdec.pri\n");
16.1288 - /* store dereferenced value */
16.1289 - if (sym->vclass==sLOCAL)
16.1290 - stgwrite("\tsref.s.pri ");
16.1291 - else
16.1292 - stgwrite("\tsref.pri ");
16.1293 - outval(sym->addr,TRUE);
16.1294 - stgwrite("\tpop.pri\n");
16.1295 - code_idx+=opcodes(5)+opargs(2);
16.1296 - } else {
16.1297 - /* local or global variable */
16.1298 - assert(sym!=NULL);
16.1299 - if (sym->vclass==sLOCAL)
16.1300 - stgwrite("\tdec.s ");
16.1301 - else
16.1302 - stgwrite("\tdec ");
16.1303 - outval(sym->addr,TRUE);
16.1304 - code_idx+=opcodes(1)+opargs(1);
16.1305 - } /* if */
16.1306 -}
16.1307 -
16.1308 -/*
16.1309 - * Jumps to "label" if PRI != 0
16.1310 - */
16.1311 -SC_FUNC void jmp_ne0(int number)
16.1312 -{
16.1313 - stgwrite("\tjnz ");
16.1314 - outval(number,TRUE);
16.1315 - code_idx+=opcodes(1)+opargs(1);
16.1316 -}
16.1317 -
16.1318 -/*
16.1319 - * Jumps to "label" if PRI == 0
16.1320 - */
16.1321 -SC_FUNC void jmp_eq0(int number)
16.1322 -{
16.1323 - stgwrite("\tjzer ");
16.1324 - outval(number,TRUE);
16.1325 - code_idx+=opcodes(1)+opargs(1);
16.1326 -}
16.1327 -
16.1328 -/* write a value in hexadecimal; optionally adds a newline */
16.1329 -SC_FUNC void outval(cell val,int newline)
16.1330 -{
16.1331 - stgwrite(itoh(val));
16.1332 - if (newline)
16.1333 - stgwrite("\n");
16.1334 -}
17.1 --- a/compiler-init/sc5.c Sat Jul 15 05:02:38 2006 +0000
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,228 +0,0 @@
17.4 -/* Pawn compiler - Error message system
17.5 - * In fact a very simple system, using only 'panic mode'.
17.6 - *
17.7 - * Copyright (c) ITB CompuPhase, 1997-2006
17.8 - *
17.9 - * This software is provided "as-is", without any express or implied warranty.
17.10 - * In no event will the authors be held liable for any damages arising from
17.11 - * the use of this software.
17.12 - *
17.13 - * Permission is granted to anyone to use this software for any purpose,
17.14 - * including commercial applications, and to alter it and redistribute it
17.15 - * freely, subject to the following restrictions:
17.16 - *
17.17 - * 1. The origin of this software must not be misrepresented; you must not
17.18 - * claim that you wrote the original software. If you use this software in
17.19 - * a product, an acknowledgment in the product documentation would be
17.20 - * appreciated but is not required.
17.21 - * 2. Altered source versions must be plainly marked as such, and must not be
17.22 - * misrepresented as being the original software.
17.23 - * 3. This notice may not be removed or altered from any source distribution.
17.24 - *
17.25 - * Version: $Id: sc5.c 3579 2006-06-06 13:35:29Z thiadmer $
17.26 - */
17.27 -#include <assert.h>
17.28 -#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
17.29 - #include <io.h>
17.30 -#endif
17.31 -#if defined LINUX || defined __GNUC__
17.32 - #include <unistd.h>
17.33 -#endif
17.34 -#include <stdio.h>
17.35 -#include <stdlib.h>
17.36 -#include <stdarg.h> /* ANSI standardized variable argument list functions */
17.37 -#include <string.h>
17.38 -#if defined FORTIFY
17.39 - #include <alloc/fortify.h>
17.40 -#endif
17.41 -#include "sc.h"
17.42 -
17.43 -#if defined _MSC_VER
17.44 - #pragma warning(push)
17.45 - #pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
17.46 -#endif
17.47 -
17.48 -#include "sc5.scp"
17.49 -
17.50 -#if defined _MSC_VER
17.51 - #pragma warning(pop)
17.52 -#endif
17.53 -
17.54 -#define NUM_WARNINGS (sizeof warnmsg / sizeof warnmsg[0])
17.55 -static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */
17.56 -
17.57 -static int errflag;
17.58 -static int errstart; /* line number at which the instruction started */
17.59 -static int errline; /* forced line number for the error message */
17.60 -
17.61 -/* error
17.62 - *
17.63 - * Outputs an error message (note: msg is passed optionally).
17.64 - * If an error is found, the variable "errflag" is set and subsequent
17.65 - * errors are ignored until lex() finds a semicolumn or a keyword
17.66 - * (lex() resets "errflag" in that case).
17.67 - *
17.68 - * Global references: inpfname (reffered to only)
17.69 - * fline (reffered to only)
17.70 - * fcurrent (reffered to only)
17.71 - * errflag (altered)
17.72 - */
17.73 -SC_FUNC int error(int number,...)
17.74 -{
17.75 -static char *prefix[3]={ "error", "fatal error", "warning" };
17.76 -static int lastline,errorcount;
17.77 -static short lastfile;
17.78 - char *msg,*pre;
17.79 - va_list argptr;
17.80 - char string[128];
17.81 -
17.82 - /* errflag is reset on each semicolon.
17.83 - * In a two-pass compiler, an error should not be reported twice. Therefore
17.84 - * the error reporting is enabled only in the second pass (and only when
17.85 - * actually producing output). Fatal errors may never be ignored.
17.86 - */
17.87 - if ((errflag || sc_status!=statWRITE) && (number<100 || number>=200))
17.88 - return 0;
17.89 -
17.90 - /* also check for disabled warnings */
17.91 - if (number>=200) {
17.92 - int index=(number-200)/8;
17.93 - int mask=1 << ((number-200)%8);
17.94 - if ((warndisable[index] & mask)!=0)
17.95 - return 0;
17.96 - } /* if */
17.97 -
17.98 - if (number<100){
17.99 - msg=errmsg[number-1];
17.100 - pre=prefix[0];
17.101 - errflag=TRUE; /* set errflag (skip rest of erroneous expression) */
17.102 - errnum++;
17.103 - } else if (number<200){
17.104 - msg=fatalmsg[number-100];
17.105 - pre=prefix[1];
17.106 - errnum++; /* a fatal error also counts as an error */
17.107 - } else {
17.108 - msg=warnmsg[number-200];
17.109 - pre=prefix[2];
17.110 - warnnum++;
17.111 - } /* if */
17.112 -
17.113 - strexpand(string,(unsigned char *)msg,sizeof string,SCPACK_TABLE);
17.114 -
17.115 - assert(errstart<=fline);
17.116 - if (errline>0)
17.117 - errstart=errline;
17.118 - else
17.119 - errline=fline;
17.120 - assert(errstart<=errline);
17.121 - va_start(argptr,number);
17.122 - if (strlen(errfname)==0) {
17.123 - int start= (errstart==errline) ? -1 : errstart;
17.124 - if (pc_error(number,string,inpfname,start,errline,argptr)) {
17.125 - if (outf!=NULL) {
17.126 - pc_closeasm(outf,TRUE);
17.127 - outf=NULL;
17.128 - } /* if */
17.129 - longjmp(errbuf,3); /* user abort */
17.130 - } /* if */
17.131 - } else {
17.132 - FILE *fp=fopen(errfname,"a");
17.133 - if (fp!=NULL) {
17.134 - if (errstart>=0 && errstart!=errline)
17.135 - fprintf(fp,"%s(%d -- %d) : %s %03d: ",inpfname,errstart,errline,pre,number);
17.136 - else
17.137 - fprintf(fp,"%s(%d) : %s %03d: ",inpfname,errline,pre,number);
17.138 - vfprintf(fp,string,argptr);
17.139 - fclose(fp);
17.140 - } /* if */
17.141 - } /* if */
17.142 - va_end(argptr);
17.143 -
17.144 - if (number>=100 && number<200 || errnum>25){
17.145 - if (strlen(errfname)==0) {
17.146 - va_start(argptr,number);
17.147 - pc_error(0,"\nCompilation aborted.",NULL,0,0,argptr);
17.148 - va_end(argptr);
17.149 - } /* if */
17.150 - if (outf!=NULL) {
17.151 - pc_closeasm(outf,TRUE);
17.152 - outf=NULL;
17.153 - } /* if */
17.154 - longjmp(errbuf,2); /* fatal error, quit */
17.155 - } /* if */
17.156 -
17.157 - errline=-1;
17.158 - /* check whether we are seeing many errors on the same line */
17.159 - if ((errstart<0 && lastline!=fline) || lastline<errstart || lastline>fline || fcurrent!=lastfile)
17.160 - errorcount=0;
17.161 - lastline=fline;
17.162 - lastfile=fcurrent;
17.163 - if (number<200)
17.164 - errorcount++;
17.165 - if (errorcount>=3)
17.166 - error(107); /* too many error/warning messages on one line */
17.167 -
17.168 - return 0;
17.169 -}
17.170 -
17.171 -SC_FUNC void errorset(int code,int line)
17.172 -{
17.173 - switch (code) {
17.174 - case sRESET:
17.175 - errflag=FALSE; /* start reporting errors */
17.176 - break;
17.177 - case sFORCESET:
17.178 - errflag=TRUE; /* stop reporting errors */
17.179 - break;
17.180 - case sEXPRMARK:
17.181 - errstart=fline; /* save start line number */
17.182 - break;
17.183 - case sEXPRRELEASE:
17.184 - errstart=-1; /* forget start line number */
17.185 - errline=-1;
17.186 - break;
17.187 - case sSETPOS:
17.188 - errline=line;
17.189 - break;
17.190 - } /* switch */
17.191 -}
17.192 -
17.193 -/* sc_enablewarning()
17.194 - * Enables or disables a warning (errors cannot be disabled).
17.195 - * Initially all warnings are enabled. The compiler does this by setting bits
17.196 - * for the *disabled* warnings and relying on the array to be zero-initialized.
17.197 - *
17.198 - * Parameter enable can be:
17.199 - * o 0 for disable
17.200 - * o 1 for enable
17.201 - * o 2 for toggle
17.202 - */
17.203 -int pc_enablewarning(int number,int enable)
17.204 -{
17.205 - int index;
17.206 - unsigned char mask;
17.207 -
17.208 - if (number<200)
17.209 - return FALSE; /* errors and fatal errors cannot be disabled */
17.210 - number -= 200;
17.211 - if (number>=NUM_WARNINGS)
17.212 - return FALSE;
17.213 -
17.214 - index=number/8;
17.215 - mask=(unsigned char)(1 << (number%8));
17.216 - switch (enable) {
17.217 - case 0:
17.218 - warndisable[index] |= mask;
17.219 - break;
17.220 - case 1:
17.221 - warndisable[index] &= (unsigned char)~mask;
17.222 - break;
17.223 - case 2:
17.224 - warndisable[index] ^= mask;
17.225 - break;
17.226 - } /* switch */
17.227 -
17.228 - return TRUE;
17.229 -}
17.230 -
17.231 -#undef SCPACK_TABLE
18.1 --- a/compiler-init/sc5.scp Sat Jul 15 05:02:38 2006 +0000
18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3 @@ -1,344 +0,0 @@
18.4 -/* Pawn compiler - Error message strings (plain and compressed formats)
18.5 - *
18.6 - * Copyright (c) ITB CompuPhase, 2000-2006
18.7 - *
18.8 - * This software is provided "as-is", without any express or implied warranty.
18.9 - * In no event will the authors be held liable for any damages arising from
18.10 - * the use of this software.
18.11 - *
18.12 - * Permission is granted to anyone to use this software for any purpose,
18.13 - * including commercial applications, and to alter it and redistribute it
18.14 - * freely, subject to the following restrictions:
18.15 - *
18.16 - * 1. The origin of this software must not be misrepresented; you must not
18.17 - * claim that you wrote the original software. If you use this software in
18.18 - * a product, an acknowledgment in the product documentation would be
18.19 - * appreciated but is not required.
18.20 - * 2. Altered source versions must be plainly marked as such, and must not be
18.21 - * misrepresented as being the original software.
18.22 - * 3. This notice may not be removed or altered from any source distribution.
18.23 - *
18.24 - * Version: $Id: sc5.sch 3590 2006-06-24 14:16:39Z thiadmer $
18.25 - */
18.26 -
18.27 -SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]);
18.28 -
18.29 -#define SCPACK_TABLE errstr_table
18.30 -/*-*SCPACK start of pair table, do not change or remove this line */
18.31 -unsigned char errstr_table[][2] = {
18.32 - {101,32}, {111,110}, {116,32}, {105,110}, {97,114}, {116,105}, {100,32}, {115,32}, {101,114}, {97,108}, {101,110}, {37,115}, {133,129}, {34,139}, {141,34}, {117,110},
18.33 - {110,111}, {114,101}, {115,105}, {121,32}, {97,116}, {111,114}, {97,110}, {32,142}, {109,98}, {115,116}, {41,10}, {100,101}, {109,138}, {101,134}, {98,108}, {140,32},
18.34 - {111,108}, {114,97}, {144,130}, {118,137}, {143,99}, {102,164}, {115,121}, {166,152}, {167,160}, {117,115}, {97,32}, {115,146}, {97,158}, {149,32}, {132,161}, {105,134},
18.35 - {103,32}, {163,175}, {103,117}, {178,156}, {136,32}, {132,179}, {131,177}, {111,102}, {116,104}, {101,120}, {105,135}, {165,159}, {101,100}, {99,104}, {118,132}, {168,151},
18.36 - {105,172}, {190,192}, {155,102}, {174,147}, {183,32}, {109,97}, {116,111}, {99,129}, {101,135}, {181,130}, {98,128}, {115,10}, {112,145}, {153,148}, {44,32}, {40,191},
18.37 - {169,130}, {151,10}, {101,10}, {207,154}, {109,208}, {116,97}, {105,99}, {194,131}, {193,128}, {34,32}, {129,32}, {132,97}, {100,105}, {146,122}, {110,32}, {137,32},
18.38 - {104,97}, {101,108}, {117,108}, {99,111}, {108,111}, {109,148}, {199,153}, {58,209}, {111,112}, {97,115}, {108,128}, {232,136}, {230,150}, {150,32}, {204,171}, {131,176},
18.39 - {212,202}, {102,105}, {119,105}, {185,238}, {109,112}, {116,136}, {165,140}, {197,147}, {102,149}, {111,32}, {131,32}, {213,176}, {110,117}, {115,117}, {118,128}
18.40 -};
18.41 -/*-*SCPACK end of pair table, do not change or remove this line */
18.42 -
18.43 -static char *errmsg[] = {
18.44 -#ifdef SCPACK
18.45 -/*001*/ "expected token: \"%s\", but found \"%s\"\n",
18.46 -/*002*/ "only a single statement (or expression) can follow each \"case\"\n",
18.47 -/*003*/ "declaration of a local variable must appear in a compound block\n",
18.48 -/*004*/ "function \"%s\" is not implemented\n",
18.49 -/*005*/ "function may not have arguments\n",
18.50 -/*006*/ "must be assigned to an array\n",
18.51 -/*007*/ "operator cannot be redefined\n",
18.52 -/*008*/ "must be a constant expression; assumed zero\n",
18.53 -/*009*/ "invalid array size (negative, zero or out of bounds)\n",
18.54 -/*010*/ "invalid function or declaration\n",
18.55 -/*011*/ "invalid outside functions\n",
18.56 -/*012*/ "invalid function call, not a valid address\n",
18.57 -/*013*/ "no entry point (no public functions)\n",
18.58 -/*014*/ "invalid statement; not in switch\n",
18.59 -/*015*/ "\"default\" case must be the last case in switch statement\n",
18.60 -/*016*/ "multiple defaults in \"switch\"\n",
18.61 -/*017*/ "undefined symbol \"%s\"\n",
18.62 -/*018*/ "initialization data exceeds declared size\n",
18.63 -/*019*/ "not a label: \"%s\"\n",
18.64 -/*020*/ "invalid symbol name \"%s\"\n",
18.65 -/*021*/ "symbol already defined: \"%s\"\n",
18.66 -/*022*/ "must be lvalue (non-constant)\n",
18.67 -/*023*/ "array assignment must be simple assignment\n",
18.68 -/*024*/ "\"break\" or \"continue\" is out of context\n",
18.69 -/*025*/ "function heading differs from prototype\n",
18.70 -/*026*/ "no matching \"#if...\"\n",
18.71 -/*027*/ "invalid character constant\n",
18.72 -/*028*/ "invalid subscript (not an array or too many subscripts): \"%s\"\n",
18.73 -/*029*/ "invalid expression, assumed zero\n",
18.74 -/*030*/ "compound statement not closed at the end of file (started at line %d)\n",
18.75 -/*031*/ "unknown directive\n",
18.76 -/*032*/ "array index out of bounds (variable \"%s\")\n",
18.77 -/*033*/ "array must be indexed (variable \"%s\")\n",
18.78 -/*034*/ "argument does not have a default value (argument %d)\n",
18.79 -/*035*/ "argument type mismatch (argument %d)\n",
18.80 -/*036*/ "empty statement\n",
18.81 -/*037*/ "invalid string (possibly non-terminated string)\n",
18.82 -/*038*/ "extra characters on line\n",
18.83 -/*039*/ "constant symbol has no size\n",
18.84 -/*040*/ "duplicate \"case\" label (value %d)\n",
18.85 -/*041*/ "invalid ellipsis, array size is not known\n",
18.86 -/*042*/ "invalid combination of class specifiers\n",
18.87 -/*043*/ "character constant exceeds range for packed string\n",
18.88 -/*044*/ "positional parameters must precede all named parameters\n",
18.89 -/*045*/ "too many function arguments\n",
18.90 -/*046*/ "unknown array size (variable \"%s\")\n",
18.91 -/*047*/ "array sizes do not match, or destination array is too small\n",
18.92 -/*048*/ "array dimensions do not match\n",
18.93 -/*049*/ "invalid line continuation\n",
18.94 -/*050*/ "invalid range\n",
18.95 -/*051*/ "invalid subscript, use \"[ ]\" operators on major dimensions\n",
18.96 -/*052*/ "multi-dimensional arrays must be fully initialized\n",
18.97 -/*053*/ "exceeding maximum number of dimensions\n",
18.98 -/*054*/ "unmatched closing brace (\"}\")\n",
18.99 -/*055*/ "start of function body without function header\n",
18.100 -/*056*/ "arrays, local variables and function arguments cannot be public (variable \"%s\")\n",
18.101 -/*057*/ "unfinished expression before compiler directive\n",
18.102 -/*058*/ "duplicate argument; same argument is passed twice\n",
18.103 -/*059*/ "function argument may not have a default value (variable \"%s\")\n",
18.104 -/*060*/ "multiple \"#else\" directives between \"#if ... #endif\"\n",
18.105 -/*061*/ "\"#elseif\" directive follows an \"#else\" directive\n",
18.106 -/*062*/ "number of operands does not fit the operator\n",
18.107 -/*063*/ "function result tag of operator \"%s\" must be \"%s\"\n",
18.108 -/*064*/ "cannot change predefined operators\n",
18.109 -/*065*/ "function argument may only have a single tag (argument %d)\n",
18.110 -/*066*/ "function argument may not be a reference argument or an array (argument \"%s\")\n",
18.111 -/*067*/ "variable cannot be both a reference and an array (variable \"%s\")\n",
18.112 -/*068*/ "invalid rational number precision in #pragma\n",
18.113 -/*069*/ "rational number format already defined\n",
18.114 -/*070*/ "rational number support was not enabled\n",
18.115 -/*071*/ "user-defined operator must be declared before use (function \"%s\")\n",
18.116 -/*072*/ "\"sizeof\" operator is invalid on \"function\" symbols\n",
18.117 -/*073*/ "function argument must be an array (argument \"%s\")\n",
18.118 -/*074*/ "#define pattern must start with an alphabetic character\n",
18.119 -/*075*/ "input line too long (after substitutions)\n",
18.120 -/*076*/ "syntax error in the expression, or invalid function call\n",
18.121 -/*077*/ "malformed UTF-8 encoding, or corrupted file: %s\n",
18.122 -/*078*/ "function uses both \"return\" and \"return <value>\"\n",
18.123 -/*079*/ "inconsistent return types (array & non-array)\n",
18.124 -/*080*/ "unknown symbol, or not a constant symbol (symbol \"%s\")\n",
18.125 -/*081*/ "cannot take a tag as a default value for an indexed array parameter (symbol \"%s\")\n",
18.126 -/*082*/ "user-defined operators and native functions may not have states\n",
18.127 -/*083*/ "a function or variable may only belong to a single automaton (symbol \"%s\")\n",
18.128 -/*084*/ "state conflict: one of the states is already assigned to another implementation (symbol \"%s\")\n",
18.129 -/*085*/ "no states are defined for symbol \"%s\"\n",
18.130 -/*086*/ "unknown automaton \"%s\"\n",
18.131 -/*087*/ "unknown state \"%s\" for automaton \"%s\"\n",
18.132 -/*088*/ "public variables and local variables may not have states (symbol \"%s\")\n",
18.133 -/*089*/ "state variables may not be initialized (symbol \"%s\")\n",
18.134 -/*090*/ "public functions may not return arrays (symbol \"%s\")\n",
18.135 -/*091*/ "ambiguous constant; tag override is required (symbol \"%s\")\n",
18.136 -/*092*/ "number of arguments does not match definition\n"
18.137 -#else
18.138 - "\271pect\235\306k\212:\227\316bu\202fo\217\206\216\012",
18.139 - "\201l\223\252s\203g\352\315e\234\202(\255\363\201) c\355f\240\344w ea\275 \042c\351e\042\012",
18.140 - "\233cl\333\237\304\252\344c\337\330\324appe\204 \372\252\343\364o\217\206\236ock\012",
18.141 - "\366\227 \272\242i\364le\234t\274\012",
18.142 - "\273\367\242\340\376\265t\313",
18.143 - "\360a\253gn\235\306 \355\256y\012",
18.144 - "\353\224\255c\226\242\312\221\327\274\012",
18.145 - "\360\252\354\202\363\201; \351\375m\235z\210o\012",
18.146 - "\266\303\335\200(nega\205ve\316z\210\371\255ou\202\304bo\217ds\232",
18.147 - "\266\273\255\233cl\333\214\012",
18.148 - "\266out\222d\200\366\313",
18.149 - "\266\273c\211l\316\242\252\261add\221s\313",
18.150 - "\220 \212tr\223po\203\202(\220 pu\236\326 \366s\232",
18.151 - "\266\315e\234t; \242\372s\362t\275\012",
18.152 - "\042\302a\342t\331c\351\200\360\270\200l\351\202c\351\200\372s\362t\275 \315e\234t\012",
18.153 - "m\342\205p\352\302a\342t\207\372\042s\362t\275\042\012",
18.154 - "\217\327\235\277\012",
18.155 - "\203i\205\211iza\237d\224\252\271ce\274\207\233cl\204\235\335\322",
18.156 - "\242\252lab\341\347",
18.157 - "\266\250 nam\200\216\012",
18.158 - "\250 \211\221ad\223\327\274\347",
18.159 - "\360l\243u\200(n\201-\354t\232",
18.160 - "\303a\253gn\234\202\360\222\364\352a\253gn\234t\012",
18.161 - "\042b\221ak\331\255\042\307t\203ue\331\272ou\202\304\307t\271t\012",
18.162 - "\273head\357\334ff\210\207from pro\306typ\322",
18.163 - "\220 \345\275\357\042#if...\042\012",
18.164 - "\266\275\333ct\264\354t\012",
18.165 - "\266\375bscrip\202(\242\355\303\255\306\371m\226\223\375bscripts)\347",
18.166 - "\266\363\201\316\351\375m\235z\210o\012",
18.167 - "\343\364o\217\206\315e\234\202\242c\344s\235a\202\270\200\212\206\304\361\352(\231\204t\235a\202l\203\200%d\232",
18.168 - "\217k\220w\336\334\221c\205v\322",
18.169 - "\303\203\233x ou\202\304bo\217d\207(\330\216\232",
18.170 - "\303\360\203\233x\235(\330\216\232",
18.171 - "\311do\310\242\340\376\252\302a\342\202\243u\200(\311%d\232",
18.172 - "\311typ\200mis\345\275 (\311%d\232",
18.173 - "e\364t\223\315e\234t\012",
18.174 - "\266\231r\357(po\253\236\223n\201-\365m\203\224\235\231r\203g\232",
18.175 - "\271t\241 \275\333c\365\207\332l\203\322",
18.176 - "\354\202\250 \340\207\220 \335\322",
18.177 - "dupl\326\224\200\042c\351e\331lab\341 (\243u\200%d\232",
18.178 - "\266\341lip\222s\316\303\335\200\272\242k\220wn\012",
18.179 - "\266\343\230\203a\237\304cl\351\207speci\361\210\313",
18.180 - "\275\333ct\264\354\202\271ce\274\207r\226g\200f\255pack\235\231r\203g\012",
18.181 - "po\222\214\337p\333me\365\207\324\314c\274\200\211l nam\235p\333me\365\313",
18.182 - "\306\371m\226\223\273\265t\313",
18.183 - "\217k\220w\336\303\335\200(\330\216\232",
18.184 - "\303\335\310d\371\242\345\275\316\255\233\231\203a\237\303\272\306\371sm\211l\012",
18.185 - "\303\334\234\222\201\207d\371\242\345\275\012",
18.186 - "\266l\203\200\307t\203ua\214\012",
18.187 - "\266r\226g\322",
18.188 - "\266\375bscript\316\251\200\042[ ]\331\353\224\225\207\332\305j\255\334\234\222\201\313",
18.189 - "m\342\205-\334\234\222\201\337\256y\207\360f\342l\223\203i\205\211iz\274\012",
18.190 - "\271ce\274\357\305ximum \374\230\264\304\334\234\222\201\313",
18.191 - "\217\345\275\235c\344s\357b\241c\200(\042}\042\232",
18.192 - "\231\204\202\304\273bod\223\362\270ou\202\273head\210\012",
18.193 - "\256ys\316\344c\337\301\310\226\206\273\265t\207c\226\242\312pu\236\326 (\330\216\232",
18.194 - "\217f\203ish\235\363\332be\370\200\343\364il\264\334\221c\205v\322",
18.195 - "dupl\326\224\200\265t; sam\200\311\272p\351s\235tw\326\322",
18.196 - "\273\311\367\242\340\376\252\302a\342\202\243u\200(\330\216\232",
18.197 - "m\342\205p\352\042#\341se\331\334\221c\205v\310betwe\212 \042#if ... #\212\334f\042\012",
18.198 - "\042#\341seif\331\334\221c\205\376f\240\344w\207\355\042#\341se\331\334\221c\205v\322",
18.199 - "\374\230\264\304\353\226d\207do\310\242\361\202\270\200\353\224\225\012",
18.200 - "\273\221s\342\202\373\304\353\224\225\227 \360\216\012",
18.201 - "c\226\242\275\226g\200\314\327\235\353\224\225\313",
18.202 - "\273\311\367\201l\223\340\376\252s\203g\352\373(\311%d\232",
18.203 - "\273\311\367\242\312\252\221f\210\212c\200\311\255\355\303(\311\216\232",
18.204 - "\330c\226\242\312bo\270 \252\221f\210\212c\200\226\206\355\303(\330\216\232",
18.205 - "\266\241\214\337\374\230\264\314ci\222\332\372#p\241g\305\012",
18.206 - "\241\214\337\374\230\264\370\305\202\211\221ad\223\327\274\012",
18.207 - "\241\214\337\374\230\264\375pp\225\202wa\207\242\212\254\274\012",
18.208 - "\251\210-\327\235\353\224\255\360\233cl\204\235be\370\200\251\200(\366\227\232",
18.209 - "\042\335e\267\331\353\224\255\272\266\332\042\366\331\250\313",
18.210 - "\273\311\360\355\303(\311\216\232",
18.211 - "#\327\200p\224\365\336\324\231\204\202\362\270 \355\211p\340be\205c \275\333c\365\012",
18.212 - "\203pu\202l\203\200\306\371l\201\260(aft\264\375bs\205tu\214s\232",
18.213 - "\246n\325x \210r\255\372\270\200\363\201\316\255\266\273c\211l\012",
18.214 - "m\211\370m\235UTF-8 \212\343d\203g\316\255c\225rupt\235\361le: \213\012",
18.215 - "\273\251\310bo\270 \042\221turn\331\226\206\042\221tur\336<\243ue>\042\012",
18.216 - "\203\307\222\231\212\202\221tur\336typ\310(\303& n\201-\256y\232",
18.217 - "\217k\220w\336\250\316\255\242\252\354\202\250 \323",
18.218 - "c\226\242\325k\200\252\373a\207\252\302a\342\202\243u\200f\255\355\203\233x\235\303p\333met\264\323",
18.219 - "\251\210-\327\235\353\224\225\207\226\206na\205\376\366\207\367\242\340\376\315e\313",
18.220 - "\252\273\255\330\367\201l\223b\341\201\260\306 \252s\203g\352au\306\345\332\323",
18.221 - "\315\200\307fl\326t: \201\200\304\270\200\315\310\272\211\221ad\223a\253gn\235\306 a\220\270\264i\364le\234\325\237\323",
18.222 - "\220 \315\310\204\200\327\235f\255\277\012",
18.223 - "\217k\220w\336au\306\345\201\321",
18.224 - "\217k\220w\336\315\200\216 f\255au\306\345\201\321",
18.225 - "pu\236\326 \301\310\226\206\344c\337\301\310\367\242\340\376\315\310\323",
18.226 - "\315\200\301\310\367\242\312\203i\205\211iz\235\323",
18.227 - "pu\236\326 \366\207\367\242\221tur\336\256y\207\323",
18.228 - "a\230i\262ou\207\354t; \373ov\210rid\200\272\221qui\221\206\323",
18.229 - "\374\230\264\304\265t\207do\310\242\345\275 \327i\214\012",
18.230 -#endif
18.231 - };
18.232 -
18.233 -static char *fatalmsg[] = {
18.234 -#ifdef SCPACK
18.235 -/*100*/ "cannot read from file: \"%s\"\n",
18.236 -/*101*/ "cannot write to file: \"%s\"\n",
18.237 -/*102*/ "table overflow: \"%s\"\n",
18.238 - /* table can be: loop table
18.239 - * literal table
18.240 - * staging buffer
18.241 - * option table (response file)
18.242 - * peephole optimizer table
18.243 - */
18.244 -/*103*/ "insufficient memory\n",
18.245 -/*104*/ "invalid assembler instruction \"%s\"\n",
18.246 -/*105*/ "numeric overflow, exceeding capacity\n",
18.247 -/*106*/ "compiled script exceeds the maximum memory size (%ld bytes)\n",
18.248 -/*107*/ "too many error messages on one line\n",
18.249 -/*108*/ "codepage mapping file not found\n",
18.250 -/*109*/ "invalid path: \"%s\"\n",
18.251 -/*110*/ "assertion failed: %s\n",
18.252 -/*111*/ "user error: %s\n",
18.253 -#else
18.254 - "c\226\242\221a\206from \361le\347",
18.255 - "c\226\242writ\200\306 \361le\347",
18.256 - "t\254\200ov\210f\344w\347",
18.257 - "\203\375ff\326i\212\202mem\225y\012",
18.258 - "\266\351se\230l\264\203\231ruc\214\321",
18.259 - "\374m\210\326 ov\210f\344w\316\271ce\274\357capacity\012",
18.260 - "\343\364il\235scrip\202\271ce\274\207\270\200\305ximum mem\225\223\335\200(%l\206bytes\232",
18.261 - "\306\371m\226\223\210r\255messag\310\332\201\200l\203\322",
18.262 - "\343\233pag\200\305pp\357\361\352\242fo\217d\012",
18.263 - "\266p\224h\347",
18.264 - "\351s\210\237fail\274: \213\012",
18.265 - "\251\264\210r\225: \213\012"
18.266 -#endif
18.267 - };
18.268 -
18.269 -static char *warnmsg[] = {
18.270 -#ifdef SCPACK
18.271 -/*200*/ "symbol \"%s\" is truncated to %d characters\n",
18.272 -/*201*/ "redefinition of constant/macro (symbol \"%s\")\n",
18.273 -/*202*/ "number of arguments does not match definition\n",
18.274 -/*203*/ "symbol is never used: \"%s\"\n",
18.275 -/*204*/ "symbol is assigned a value that is never used: \"%s\"\n",
18.276 -/*205*/ "redundant code: constant expression is zero\n",
18.277 -/*206*/ "redundant test: constant expression is non-zero\n",
18.278 -/*207*/ "unknown #pragma\n",
18.279 -/*208*/ "function with tag result used before definition, forcing reparse\n",
18.280 -/*209*/ "function \"%s\" should return a value\n",
18.281 -/*210*/ "possible use of symbol before initialization: \"%s\"\n",
18.282 -/*211*/ "possibly unintended assignment\n",
18.283 -/*212*/ "possibly unintended bitwise operation\n",
18.284 -/*213*/ "tag mismatch\n",
18.285 -/*214*/ "possibly a \"const\" array argument was intended: \"%s\"\n",
18.286 -/*215*/ "expression has no effect\n",
18.287 -/*216*/ "nested comment\n",
18.288 -/*217*/ "loose indentation\n",
18.289 -/*218*/ "old style prototypes used with optional semicolumns\n",
18.290 -/*219*/ "local variable \"%s\" shadows a variable at a preceding level\n",
18.291 -/*220*/ "expression with tag override must appear between parentheses\n",
18.292 -/*221*/ "label name \"%s\" shadows tag name\n",
18.293 -/*222*/ "number of digits exceeds rational number precision\n",
18.294 -/*223*/ "redundant \"sizeof\": argument size is always 1 (symbol \"%s\")\n",
18.295 -/*224*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n",
18.296 -/*225*/ "unreachable code\n",
18.297 -/*226*/ "a variable is assigned to itself (symbol \"%s\")\n",
18.298 -/*227*/ "more initiallers than enum fields\n",
18.299 -/*228*/ "length of initialler exceeds size of the enum field\n",
18.300 -/*229*/ "index tag mismatch (symbol \"%s\")\n",
18.301 -/*230*/ "no implementation for state \"%s\" in function \"%s\", no fall-back\n",
18.302 -/*231*/ "state specification on forward declaration is ignored\n",
18.303 -/*232*/ "output file is written, but with compact encoding disabled\n",
18.304 -/*233*/ "state variable \"%s\" shadows a global variable\n",
18.305 -/*234*/ "function is depricated (symbol \"%s\") %s\n",
18.306 -/*235*/ "public function lacks forward declaration (symbol \"%s\")\n",
18.307 -/*236*/ "unknown parameter in substitution (incorrect #define pattern)\n"
18.308 -#else
18.309 - "\277 \272tr\244\224\235\306 %\206\275\333c\365\313",
18.310 - "\221\327i\237\304\354t/\305cr\371\323",
18.311 - "\374\230\264\304\265t\207do\310\242\345\275 \327i\214\012",
18.312 - "\250 \272nev\264\251\274\347",
18.313 - "\250 \272a\253gn\235\252\243u\200\270a\202\272nev\264\251\274\347",
18.314 - "\221d\217d\226\202\343\233: \354\202\363\332\272z\210o\012",
18.315 - "\221d\217d\226\202te\231: \354\202\363\332\272n\201-z\210o\012",
18.316 - "\217k\220w\336#p\241g\305\012",
18.317 - "\273\362\270 \373\221s\342\202\251\235be\370\200\327i\214\316\370c\357\221p\204s\322",
18.318 - "\366\227 sho\342\206\221tur\336\252\243u\322",
18.319 - "po\253\236\200\251\200\304\250 be\370\200\203i\205\211iza\214\347",
18.320 - "po\253\236\223\217\203t\212\233\206a\253gn\234t\012",
18.321 - "po\253\236\223\217\203t\212\233\206bit\362s\200\353a\214\012",
18.322 - "\373mis\345\275\012",
18.323 - "po\253\236\223\252\042\346\331\303\311wa\207\203t\212\233d\347",
18.324 - "\363\332\340\207\220 effect\012",
18.325 - "ne\231\235\343m\234t\012",
18.326 - "\344os\200\203d\212\325\214\012",
18.327 - "\240\206\231y\352pro\306typ\310\251\235\362\270 \350\214\337sem\326\240umn\313",
18.328 - "\344c\337\330\216 s\340dow\207\252\330a\202\252\314c\274\357lev\341\012",
18.329 - "\363\332\362\270 \373ov\210rid\200\324appe\204 betwe\212 p\204\212\270ese\313",
18.330 - "lab\341 nam\200\216 s\340dow\207\373nam\322",
18.331 - "\374\230\264\304\334git\207\271ce\274\207\241\214\337\374\230\264\314ci\222\201\012",
18.332 - "\221d\217d\226\202\042\335e\267\042: \311\335\200\272\211way\2071 \323",
18.333 - "\203\233\365m\203\224\200\303\335\200\372\042\335e\267\331\363\332\323",
18.334 - "\217\221a\275\254\200\343\233\012",
18.335 - "\252\330\272a\253gn\235\306 its\341f \323",
18.336 - "m\225\200\203i\205\211l\210\207\270\355\212um \361\341d\313",
18.337 - "l\212g\270 \304\203i\205\211l\264\271ce\274\207\335\200\304\270\200\212um \361\341d\012",
18.338 - "\203\233x \373mis\345\275 \323",
18.339 - "\220 i\364le\234\325\237f\255\315\200\216 \372\366\227\316\220 f\211l-back\012",
18.340 - "\315\200specif\326a\237\332\370w\204\206\233cl\333\237\272ig\220\221d\012",
18.341 - "outpu\202\361\352\272writt\212\316bu\202\362\270 \343\364ac\202\212\343d\357\334s\254\274\012",
18.342 - "\315\200\330\216 s\340dow\207\252g\344b\337\301\322",
18.343 - "\273\272\233pr\326\224\235\317) \213\012",
18.344 - "pu\236\326 \273lack\207\370w\204\206\233cl\333\237\323",
18.345 - "\217k\220w\336p\333met\264\372\375bs\205tu\237(\203c\225\221c\202#\327\200p\224\365n\232"
18.346 -#endif
18.347 - };
19.1 --- a/compiler-init/sc6.c Sat Jul 15 05:02:38 2006 +0000
19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
19.3 @@ -1,1298 +0,0 @@
19.4 -/* Pawn compiler - Binary code generation (the "assembler")
19.5 - *
19.6 - * Copyright (c) ITB CompuPhase, 1997-2006
19.7 - *
19.8 - * This software is provided "as-is", without any express or implied warranty.
19.9 - * In no event will the authors be held liable for any damages arising from
19.10 - * the use of this software.
19.11 - *
19.12 - * Permission is granted to anyone to use this software for any purpose,
19.13 - * including commercial applications, and to alter it and redistribute it
19.14 - * freely, subject to the following restrictions:
19.15 - *
19.16 - * 1. The origin of this software must not be misrepresented; you must not
19.17 - * claim that you wrote the original software. If you use this software in
19.18 - * a product, an acknowledgment in the product documentation would be
19.19 - * appreciated but is not required.
19.20 - * 2. Altered source versions must be plainly marked as such, and must not be
19.21 - * misrepresented as being the original software.
19.22 - * 3. This notice may not be removed or altered from any source distribution.
19.23 - *
19.24 - * Version: $Id: sc6.c 3579 2006-06-06 13:35:29Z thiadmer $
19.25 - */
19.26 -#include <assert.h>
19.27 -#include <stdio.h>
19.28 -#include <stdlib.h> /* for macro max() */
19.29 -#include <stddef.h> /* for macro offsetof() */
19.30 -#include <string.h>
19.31 -#include <ctype.h>
19.32 -#if defined FORTIFY
19.33 - #include <alloc/fortify.h>
19.34 -#endif
19.35 -#include "lstring.h"
19.36 -#include "sc.h"
19.37 -#include "amxdbg.h"
19.38 -#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
19.39 - #include <sclinux.h>
19.40 -#endif
19.41 -
19.42 -
19.43 -static void append_dbginfo(FILE *fout);
19.44 -
19.45 -
19.46 -typedef cell (*OPCODE_PROC)(FILE *fbin,char *params,cell opcode);
19.47 -
19.48 -typedef struct {
19.49 - cell opcode;
19.50 - char *name;
19.51 - int segment; /* sIN_CSEG=parse in cseg, sIN_DSEG=parse in dseg */
19.52 - OPCODE_PROC func;
19.53 -} OPCODEC;
19.54 -
19.55 -static cell codeindex; /* similar to "code_idx" */
19.56 -static cell *lbltab; /* label table */
19.57 -static int writeerror;
19.58 -static int bytes_in, bytes_out;
19.59 -static jmp_buf compact_err;
19.60 -
19.61 -/* apparently, strtol() does not work correctly on very large (unsigned)
19.62 - * hexadecimal values */
19.63 -static ucell hex2long(const char *s,char **n)
19.64 -{
19.65 - ucell result=0L;
19.66 - int negate=FALSE;
19.67 - int digit;
19.68 -
19.69 - /* ignore leading whitespace */
19.70 - while (*s==' ' || *s=='\t')
19.71 - s++;
19.72 -
19.73 - /* allow a negation sign to create the two's complement of numbers */
19.74 - if (*s=='-') {
19.75 - negate=TRUE;
19.76 - s++;
19.77 - } /* if */
19.78 -
19.79 - assert((*s>='0' && *s<='9') || (*s>='a' && *s<='f') || (*s>='a' && *s<='f'));
19.80 - for ( ;; ) {
19.81 - if (*s>='0' && *s<='9')
19.82 - digit=*s-'0';
19.83 - else if (*s>='a' && *s<='f')
19.84 - digit=*s-'a' + 10;
19.85 - else if (*s>='A' && *s<='F')
19.86 - digit=*s-'A' + 10;
19.87 - else
19.88 - break; /* probably whitespace */
19.89 - result=(result<<4) | digit;
19.90 - s++;
19.91 - } /* for */
19.92 - if (n!=NULL)
19.93 - *n=(char*)s;
19.94 - if (negate)
19.95 - result=(~result)+1; /* take two's complement of the result */
19.96 - return (ucell)result;
19.97 -}
19.98 -
19.99 -static ucell getparam(const char *s,char **n)
19.100 -{
19.101 - ucell result=0;
19.102 - for ( ;; ) {
19.103 - result+=hex2long(s,(char**)&s);
19.104 - if (*s!='+')
19.105 - break;
19.106 - s++;
19.107 - } /* for */
19.108 - if (n!=NULL)
19.109 - *n=(char*)s;
19.110 - return result;
19.111 -}
19.112 -
19.113 -#if BYTE_ORDER==BIG_ENDIAN
19.114 -static uint16_t *align16(uint16_t *v)
19.115 -{
19.116 - unsigned char *s = (unsigned char *)v;
19.117 - unsigned char t;
19.118 -
19.119 - /* swap two bytes */
19.120 - t=s[0];
19.121 - s[0]=s[1];
19.122 - s[1]=t;
19.123 - return v;
19.124 -}
19.125 -
19.126 -static uint32_t *align32(uint32_t *v)
19.127 -{
19.128 - unsigned char *s = (unsigned char *)v;
19.129 - unsigned char t;
19.130 -
19.131 - /* swap outer two bytes */
19.132 - t=s[0];
19.133 - s[0]=s[3];
19.134 - s[3]=t;
19.135 - /* swap inner two bytes */
19.136 - t=s[1];
19.137 - s[1]=s[2];
19.138 - s[2]=t;
19.139 - return v;
19.140 -}
19.141 -
19.142 -#if PAWN_CELL_SIZE>=64
19.143 -static uint64_t *align64(uint64_t *v)
19.144 -{
19.145 - unsigned char *s = (unsigned char *)v;
19.146 - unsigned char t;
19.147 -
19.148 - t=s[0];
19.149 - s[0]=s[7];
19.150 - s[7]=t;
19.151 -
19.152 - t=s[1];
19.153 - s[1]=s[6];
19.154 - s[6]=t;
19.155 -
19.156 - t=s[2];
19.157 - s[2]=s[5];
19.158 - s[5]=t;
19.159 -
19.160 - t=s[3];
19.161 - s[3]=s[4];
19.162 - s[4]=t;
19.163 -
19.164 - return v;
19.165 -}
19.166 -#endif
19.167 -
19.168 - #if PAWN_CELL_SIZE==16
19.169 - #define aligncell(v) align16(v)
19.170 - #elif PAWN_CELL_SIZE==32
19.171 - #define aligncell(v) align32(v)
19.172 - #elif PAWN_CELL_SIZE==64
19.173 - #define aligncell(v) align64(v)
19.174 - #endif
19.175 -#else
19.176 - #define align16(v) (v)
19.177 - #define align32(v) (v)
19.178 - #define aligncell(v) (v)
19.179 -#endif
19.180 -
19.181 -static char *skipwhitespace(char *str)
19.182 -{
19.183 - while (isspace(*str))
19.184 - str++;
19.185 - return str;
19.186 -}
19.187 -
19.188 -static char *stripcomment(char *str)
19.189 -{
19.190 - char *ptr=strchr(str,';');
19.191 - if (ptr!=NULL) {
19.192 - *ptr++='\n'; /* terminate the line, but leave the '\n' */
19.193 - *ptr='\0';
19.194 - } /* if */
19.195 - return str;
19.196 -}
19.197 -
19.198 -static void write_encoded(FILE *fbin,ucell *c,int num)
19.199 -{
19.200 - #if PAWN_CELL_SIZE == 16
19.201 - #define ENC_MAX 3 /* a 16-bit cell is encoded in max. 3 bytes */
19.202 - #define ENC_MASK 0x03 /* after 2x7 bits, 2 bits remain to make 16 bits */
19.203 - #elif PAWN_CELL_SIZE == 32
19.204 - #define ENC_MAX 5 /* a 32-bit cell is encoded in max. 5 bytes */
19.205 - #define ENC_MASK 0x0f /* after 4x7 bits, 4 bits remain to make 32 bits */
19.206 - #elif PAWN_CELL_SIZE == 64
19.207 - #define ENC_MAX 10 /* a 32-bit cell is encoded in max. 10 bytes */
19.208 - #define ENC_MASK 0x01 /* after 9x7 bits, 1 bit remains to make 64 bits */
19.209 - #endif
19.210 -
19.211 - assert(fbin!=NULL);
19.212 - while (num-->0) {
19.213 - if (sc_compress) {
19.214 - ucell p=(ucell)*c;
19.215 - unsigned char t[ENC_MAX];
19.216 - unsigned char code;
19.217 - int index;
19.218 - for (index=0; index<ENC_MAX; index++) {
19.219 - t[index]=(unsigned char)(p & 0x7f); /* store 7 bits */
19.220 - p>>=7;
19.221 - } /* for */
19.222 - /* skip leading zeros */
19.223 - while (index>1 && t[index-1]==0 && (t[index-2] & 0x40)==0)
19.224 - index--;
19.225 - /* skip leading -1s */
19.226 - if (index==ENC_MAX && t[index-1]==ENC_MASK && (t[index-2] & 0x40)!=0)
19.227 - index--;
19.228 - while (index>1 && t[index-1]==0x7f && (t[index-2] & 0x40)!=0)
19.229 - index--;
19.230 - /* write high byte first, write continuation bits */
19.231 - assert(index>0);
19.232 - while (index-->0) {
19.233 - code=(unsigned char)((index==0) ? t[index] : (t[index]|0x80));
19.234 - writeerror |= !pc_writebin(fbin,&code,1);
19.235 - bytes_out++;
19.236 - } /* while */
19.237 - bytes_in+=sizeof *c;
19.238 - assert(AMX_COMPACTMARGIN>2);
19.239 - if (bytes_out-bytes_in>=AMX_COMPACTMARGIN-2)
19.240 - longjmp(compact_err,1);
19.241 - } else {
19.242 - assert((pc_lengthbin(fbin) % sizeof(cell)) == 0);
19.243 - writeerror |= !pc_writebin(fbin,aligncell(c),sizeof *c);
19.244 - } /* if */
19.245 - c++;
19.246 - } /* while */
19.247 -}
19.248 -
19.249 -#if defined __BORLANDC__ || defined __WATCOMC__
19.250 - #pragma argsused
19.251 -#endif
19.252 -static cell noop(FILE *fbin,char *params,cell opcode)
19.253 -{
19.254 - return 0;
19.255 -}
19.256 -
19.257 -#if defined __BORLANDC__ || defined __WATCOMC__
19.258 - #pragma argsused
19.259 -#endif
19.260 -static cell set_currentfile(FILE *fbin,char *params,cell opcode)
19.261 -{
19.262 - fcurrent=(short)getparam(params,NULL);
19.263 - return 0;
19.264 -}
19.265 -
19.266 -#if defined __BORLANDC__ || defined __WATCOMC__
19.267 - #pragma argsused
19.268 -#endif
19.269 -static cell parm0(FILE *fbin,char *params,cell opcode)
19.270 -{
19.271 - if (fbin!=NULL)
19.272 - write_encoded(fbin,(ucell*)&opcode,1);
19.273 - return opcodes(1);
19.274 -}
19.275 -
19.276 -static cell parm1(FILE *fbin,char *params,cell opcode)
19.277 -{
19.278 - ucell p=getparam(params,NULL);
19.279 - if (fbin!=NULL) {
19.280 - write_encoded(fbin,(ucell*)&opcode,1);
19.281 - write_encoded(fbin,&p,1);
19.282 - } /* if */
19.283 - return opcodes(1)+opargs(1);
19.284 -}
19.285 -
19.286 -static cell parm2(FILE *fbin,char *params,cell opcode)
19.287 -{
19.288 - ucell p1=getparam(params,¶ms);
19.289 - ucell p2=getparam(params,NULL);
19.290 - if (fbin!=NULL) {
19.291 - write_encoded(fbin,(ucell*)&opcode,1);
19.292 - write_encoded(fbin,&p1,1);
19.293 - write_encoded(fbin,&p2,1);
19.294 - } /* if */
19.295 - return opcodes(1)+opargs(2);
19.296 -}
19.297 -
19.298 -static cell parm3(FILE *fbin,char *params,cell opcode)
19.299 -{
19.300 - ucell p1=getparam(params,¶ms);
19.301 - ucell p2=getparam(params,¶ms);
19.302 - ucell p3=getparam(params,NULL);
19.303 - if (fbin!=NULL) {
19.304 - write_encoded(fbin,(ucell*)&opcode,1);
19.305 - write_encoded(fbin,&p1,1);
19.306 - write_encoded(fbin,&p2,1);
19.307 - write_encoded(fbin,&p3,1);
19.308 - } /* if */
19.309 - return opcodes(1)+opargs(3);
19.310 -}
19.311 -
19.312 -static cell parm4(FILE *fbin,char *params,cell opcode)
19.313 -{
19.314 - ucell p1=getparam(params,¶ms);
19.315 - ucell p2=getparam(params,¶ms);
19.316 - ucell p3=getparam(params,¶ms);
19.317 - ucell p4=getparam(params,NULL);
19.318 - if (fbin!=NULL) {
19.319 - write_encoded(fbin,(ucell*)&opcode,1);
19.320 - write_encoded(fbin,&p1,1);
19.321 - write_encoded(fbin,&p2,1);
19.322 - write_encoded(fbin,&p3,1);
19.323 - write_encoded(fbin,&p4,1);
19.324 - } /* if */
19.325 - return opcodes(1)+opargs(4);
19.326 -}
19.327 -
19.328 -static cell parm5(FILE *fbin,char *params,cell opcode)
19.329 -{
19.330 - ucell p1=getparam(params,¶ms);
19.331 - ucell p2=getparam(params,¶ms);
19.332 - ucell p3=getparam(params,¶ms);
19.333 - ucell p4=getparam(params,¶ms);
19.334 - ucell p5=getparam(params,NULL);
19.335 - if (fbin!=NULL) {
19.336 - write_encoded(fbin,(ucell*)&opcode,1);
19.337 - write_encoded(fbin,&p1,1);
19.338 - write_encoded(fbin,&p2,1);
19.339 - write_encoded(fbin,&p3,1);
19.340 - write_encoded(fbin,&p4,1);
19.341 - write_encoded(fbin,&p5,1);
19.342 - } /* if */
19.343 - return opcodes(1)+opargs(5);
19.344 -}
19.345 -
19.346 -#if defined __BORLANDC__ || defined __WATCOMC__
19.347 - #pragma argsused
19.348 -#endif
19.349 -static cell do_dump(FILE *fbin,char *params,cell opcode)
19.350 -{
19.351 - ucell p;
19.352 - int num = 0;
19.353 -
19.354 - while (*params!='\0') {
19.355 - p=getparam(params,¶ms);
19.356 - if (fbin!=NULL)
19.357 - write_encoded(fbin,&p,1);
19.358 - num++;
19.359 - while (isspace(*params))
19.360 - params++;
19.361 - } /* while */
19.362 - return num*sizeof(cell);
19.363 -}
19.364 -
19.365 -static cell do_call(FILE *fbin,char *params,cell opcode)
19.366 -{
19.367 - char name[sNAMEMAX+1];
19.368 - int i;
19.369 - symbol *sym;
19.370 - ucell p;
19.371 -
19.372 - for (i=0; !isspace(*params); i++,params++) {
19.373 - assert(*params!='\0');
19.374 - assert(i<sNAMEMAX);
19.375 - name[i]=*params;
19.376 - } /* for */
19.377 - name[i]='\0';
19.378 -
19.379 - if (name[0]=='l' && name[1]=='.') {
19.380 - /* this is a label, not a function symbol */
19.381 - i=(int)hex2long(name+2,NULL);
19.382 - assert(i>=0 && i<sc_labnum);
19.383 - if (fbin!=NULL) {
19.384 - assert(lbltab!=NULL);
19.385 - p=lbltab[i];
19.386 - } /* if */
19.387 - } else {
19.388 - /* look up the function address; note that the correct file number must
19.389 - * already have been set (in order for static globals to be found).
19.390 - */
19.391 - sym=findglb(name,sGLOBAL);
19.392 - assert(sym!=NULL);
19.393 - assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC);
19.394 - assert(sym->vclass==sGLOBAL);
19.395 - p=sym->addr;
19.396 - } /* if */
19.397 -
19.398 - if (fbin!=NULL) {
19.399 - write_encoded(fbin,(ucell*)&opcode,1);
19.400 - write_encoded(fbin,&p,1);
19.401 - } /* if */
19.402 - return opcodes(1)+opargs(1);
19.403 -}
19.404 -
19.405 -static cell do_jump(FILE *fbin,char *params,cell opcode)
19.406 -{
19.407 - int i;
19.408 - ucell p;
19.409 -
19.410 - i=(int)hex2long(params,NULL);
19.411 - assert(i>=0 && i<sc_labnum);
19.412 -
19.413 - if (fbin!=NULL) {
19.414 - assert(lbltab!=NULL);
19.415 - p=lbltab[i];
19.416 - write_encoded(fbin,(ucell*)&opcode,1);
19.417 - write_encoded(fbin,&p,1);
19.418 - } /* if */
19.419 - return opcodes(1)+opargs(1);
19.420 -}
19.421 -
19.422 -static cell do_switch(FILE *fbin,char *params,cell opcode)
19.423 -{
19.424 - int i;
19.425 - ucell p;
19.426 -
19.427 - i=(int)hex2long(params,NULL);
19.428 - assert(i>=0 && i<sc_labnum);
19.429 -
19.430 - if (fbin!=NULL) {
19.431 - assert(lbltab!=NULL);
19.432 - p=lbltab[i];
19.433 - write_encoded(fbin,(ucell*)&opcode,1);
19.434 - write_encoded(fbin,&p,1);
19.435 - } /* if */
19.436 - return opcodes(1)+opargs(1);
19.437 -}
19.438 -
19.439 -#if defined __BORLANDC__ || defined __WATCOMC__
19.440 - #pragma argsused
19.441 -#endif
19.442 -static cell do_case(FILE *fbin,char *params,cell opcode)
19.443 -{
19.444 - int i;
19.445 - ucell p,v;
19.446 -
19.447 - v=hex2long(params,¶ms);
19.448 - i=(int)hex2long(params,NULL);
19.449 - assert(i>=0 && i<sc_labnum);
19.450 -
19.451 - if (fbin!=NULL) {
19.452 - assert(lbltab!=NULL);
19.453 - p=lbltab[i];
19.454 - write_encoded(fbin,&v,1);
19.455 - write_encoded(fbin,&p,1);
19.456 - } /* if */
19.457 - return opcodes(0)+opargs(2);
19.458 -}
19.459 -
19.460 -static OPCODEC opcodelist[] = {
19.461 - /* node for "invalid instruction" */
19.462 - { 0, NULL, 0, noop },
19.463 - /* opcodes in sorted order */
19.464 - { 78, "add", sIN_CSEG, parm0 },
19.465 - { 87, "add.c", sIN_CSEG, parm1 },
19.466 - { 14, "addr.alt", sIN_CSEG, parm1 },
19.467 - { 13, "addr.pri", sIN_CSEG, parm1 },
19.468 - { 30, "align.alt", sIN_CSEG, parm1 },
19.469 - { 29, "align.pri", sIN_CSEG, parm1 },
19.470 - { 81, "and", sIN_CSEG, parm0 },
19.471 - {121, "bounds", sIN_CSEG, parm1 },
19.472 - {137, "break", sIN_CSEG, parm0 }, /* version 8 */
19.473 - { 49, "call", sIN_CSEG, do_call },
19.474 - { 50, "call.pri", sIN_CSEG, parm0 },
19.475 - { 0, "case", sIN_CSEG, do_case },
19.476 - {130, "casetbl", sIN_CSEG, parm0 }, /* version 1 */
19.477 - {118, "cmps", sIN_CSEG, parm1 },
19.478 - { 0, "code", sIN_CSEG, set_currentfile },
19.479 - {156, "const", sIN_CSEG, parm2 }, /* version 9 */
19.480 - { 12, "const.alt", sIN_CSEG, parm1 },
19.481 - { 11, "const.pri", sIN_CSEG, parm1 },
19.482 - {157, "const.s", sIN_CSEG, parm2 }, /* version 9 */
19.483 - { 0, "data", sIN_DSEG, set_currentfile },
19.484 - {114, "dec", sIN_CSEG, parm1 },
19.485 - {113, "dec.alt", sIN_CSEG, parm0 },
19.486 - {116, "dec.i", sIN_CSEG, parm0 },
19.487 - {112, "dec.pri", sIN_CSEG, parm0 },
19.488 - {115, "dec.s", sIN_CSEG, parm1 },
19.489 - { 0, "dump", sIN_DSEG, do_dump },
19.490 - { 95, "eq", sIN_CSEG, parm0 },
19.491 - {106, "eq.c.alt", sIN_CSEG, parm1 },
19.492 - {105, "eq.c.pri", sIN_CSEG, parm1 },
19.493 -/*{124, "file", sIN_CSEG, do_file }, */
19.494 - {119, "fill", sIN_CSEG, parm1 },
19.495 - {100, "geq", sIN_CSEG, parm0 },
19.496 - { 99, "grtr", sIN_CSEG, parm0 },
19.497 - {120, "halt", sIN_CSEG, parm1 },
19.498 - { 45, "heap", sIN_CSEG, parm1 },
19.499 - { 27, "idxaddr", sIN_CSEG, parm0 },
19.500 - { 28, "idxaddr.b", sIN_CSEG, parm1 },
19.501 - {109, "inc", sIN_CSEG, parm1 },
19.502 - {108, "inc.alt", sIN_CSEG, parm0 },
19.503 - {111, "inc.i", sIN_CSEG, parm0 },
19.504 - {107, "inc.pri", sIN_CSEG, parm0 },
19.505 - {110, "inc.s", sIN_CSEG, parm1 },
19.506 - { 86, "invert", sIN_CSEG, parm0 },
19.507 - { 55, "jeq", sIN_CSEG, do_jump },
19.508 - { 60, "jgeq", sIN_CSEG, do_jump },
19.509 - { 59, "jgrtr", sIN_CSEG, do_jump },
19.510 - { 58, "jleq", sIN_CSEG, do_jump },
19.511 - { 57, "jless", sIN_CSEG, do_jump },
19.512 - { 56, "jneq", sIN_CSEG, do_jump },
19.513 - { 54, "jnz", sIN_CSEG, do_jump },
19.514 - { 52, "jrel", sIN_CSEG, parm1 }, /* always a number */
19.515 - { 64, "jsgeq", sIN_CSEG, do_jump },
19.516 - { 63, "jsgrtr", sIN_CSEG, do_jump },
19.517 - { 62, "jsleq", sIN_CSEG, do_jump },
19.518 - { 61, "jsless", sIN_CSEG, do_jump },
19.519 - { 51, "jump", sIN_CSEG, do_jump },
19.520 - {128, "jump.pri", sIN_CSEG, parm0 }, /* version 1 */
19.521 - { 53, "jzer", sIN_CSEG, do_jump },
19.522 - { 31, "lctrl", sIN_CSEG, parm1 },
19.523 - { 98, "leq", sIN_CSEG, parm0 },
19.524 - { 97, "less", sIN_CSEG, parm0 },
19.525 - { 25, "lidx", sIN_CSEG, parm0 },
19.526 - { 26, "lidx.b", sIN_CSEG, parm1 },
19.527 -/*{125, "line", sIN_CSEG, parm2 }, */
19.528 - { 2, "load.alt", sIN_CSEG, parm1 },
19.529 - {154, "load.both", sIN_CSEG, parm2 }, /* version 9 */
19.530 - { 9, "load.i", sIN_CSEG, parm0 },
19.531 - { 1, "load.pri", sIN_CSEG, parm1 },
19.532 - { 4, "load.s.alt", sIN_CSEG, parm1 },
19.533 - {155, "load.s.both",sIN_CSEG, parm2 }, /* version 9 */
19.534 - { 3, "load.s.pri", sIN_CSEG, parm1 },
19.535 - { 10, "lodb.i", sIN_CSEG, parm1 },
19.536 - { 6, "lref.alt", sIN_CSEG, parm1 },
19.537 - { 5, "lref.pri", sIN_CSEG, parm1 },
19.538 - { 8, "lref.s.alt", sIN_CSEG, parm1 },
19.539 - { 7, "lref.s.pri", sIN_CSEG, parm1 },
19.540 - { 34, "move.alt", sIN_CSEG, parm0 },
19.541 - { 33, "move.pri", sIN_CSEG, parm0 },
19.542 - {117, "movs", sIN_CSEG, parm1 },
19.543 - { 85, "neg", sIN_CSEG, parm0 },
19.544 - { 96, "neq", sIN_CSEG, parm0 },
19.545 - {134, "nop", sIN_CSEG, parm0 }, /* version 6 */
19.546 - { 84, "not", sIN_CSEG, parm0 },
19.547 - { 82, "or", sIN_CSEG, parm0 },
19.548 - { 43, "pop.alt", sIN_CSEG, parm0 },
19.549 - { 42, "pop.pri", sIN_CSEG, parm0 },
19.550 - { 46, "proc", sIN_CSEG, parm0 },
19.551 - { 40, "push", sIN_CSEG, parm1 },
19.552 - {133, "push.adr", sIN_CSEG, parm1 }, /* version 4 */
19.553 - { 37, "push.alt", sIN_CSEG, parm0 },
19.554 - { 39, "push.c", sIN_CSEG, parm1 },
19.555 - { 36, "push.pri", sIN_CSEG, parm0 },
19.556 - { 38, "push.r", sIN_CSEG, parm1 }, /* obsolete (never generated) */
19.557 - { 41, "push.s", sIN_CSEG, parm1 },
19.558 - {139, "push2", sIN_CSEG, parm2 }, /* version 9 */
19.559 - {141, "push2.adr", sIN_CSEG, parm2 }, /* version 9 */
19.560 - {138, "push2.c", sIN_CSEG, parm2 }, /* version 9 */
19.561 - {140, "push2.s", sIN_CSEG, parm2 }, /* version 9 */
19.562 - {143, "push3", sIN_CSEG, parm3 }, /* version 9 */
19.563 - {145, "push3.adr", sIN_CSEG, parm3 }, /* version 9 */
19.564 - {142, "push3.c", sIN_CSEG, parm3 }, /* version 9 */
19.565 - {144, "push3.s", sIN_CSEG, parm3 }, /* version 9 */
19.566 - {147, "push4", sIN_CSEG, parm4 }, /* version 9 */
19.567 - {149, "push4.adr", sIN_CSEG, parm4 }, /* version 9 */
19.568 - {146, "push4.c", sIN_CSEG, parm4 }, /* version 9 */
19.569 - {148, "push4.s", sIN_CSEG, parm4 }, /* version 9 */
19.570 - {151, "push5", sIN_CSEG, parm5 }, /* version 9 */
19.571 - {153, "push5.adr", sIN_CSEG, parm5 }, /* version 9 */
19.572 - {150, "push5.c", sIN_CSEG, parm5 }, /* version 9 */
19.573 - {152, "push5.s", sIN_CSEG, parm5 }, /* version 9 */
19.574 - { 47, "ret", sIN_CSEG, parm0 },
19.575 - { 48, "retn", sIN_CSEG, parm0 },
19.576 - { 32, "sctrl", sIN_CSEG, parm1 },
19.577 - { 73, "sdiv", sIN_CSEG, parm0 },
19.578 - { 74, "sdiv.alt", sIN_CSEG, parm0 },
19.579 - {104, "sgeq", sIN_CSEG, parm0 },
19.580 - {103, "sgrtr", sIN_CSEG, parm0 },
19.581 - { 65, "shl", sIN_CSEG, parm0 },
19.582 - { 69, "shl.c.alt", sIN_CSEG, parm1 },
19.583 - { 68, "shl.c.pri", sIN_CSEG, parm1 },
19.584 - { 66, "shr", sIN_CSEG, parm0 },
19.585 - { 71, "shr.c.alt", sIN_CSEG, parm1 },
19.586 - { 70, "shr.c.pri", sIN_CSEG, parm1 },
19.587 - { 94, "sign.alt", sIN_CSEG, parm0 },
19.588 - { 93, "sign.pri", sIN_CSEG, parm0 },
19.589 - {102, "sleq", sIN_CSEG, parm0 },
19.590 - {101, "sless", sIN_CSEG, parm0 },
19.591 - { 72, "smul", sIN_CSEG, parm0 },
19.592 - { 88, "smul.c", sIN_CSEG, parm1 },
19.593 -/*{127, "srange", sIN_CSEG, parm2 }, -- version 1 */
19.594 - { 20, "sref.alt", sIN_CSEG, parm1 },
19.595 - { 19, "sref.pri", sIN_CSEG, parm1 },
19.596 - { 22, "sref.s.alt", sIN_CSEG, parm1 },
19.597 - { 21, "sref.s.pri", sIN_CSEG, parm1 },
19.598 - { 67, "sshr", sIN_CSEG, parm0 },
19.599 - { 44, "stack", sIN_CSEG, parm1 },
19.600 - { 0, "stksize", 0, noop },
19.601 - { 16, "stor.alt", sIN_CSEG, parm1 },
19.602 - { 23, "stor.i", sIN_CSEG, parm0 },
19.603 - { 15, "stor.pri", sIN_CSEG, parm1 },
19.604 - { 18, "stor.s.alt", sIN_CSEG, parm1 },
19.605 - { 17, "stor.s.pri", sIN_CSEG, parm1 },
19.606 - { 24, "strb.i", sIN_CSEG, parm1 },
19.607 - { 79, "sub", sIN_CSEG, parm0 },
19.608 - { 80, "sub.alt", sIN_CSEG, parm0 },
19.609 - {132, "swap.alt", sIN_CSEG, parm0 }, /* version 4 */
19.610 - {131, "swap.pri", sIN_CSEG, parm0 }, /* version 4 */
19.611 - {129, "switch", sIN_CSEG, do_switch }, /* version 1 */
19.612 -/*{126, "symbol", sIN_CSEG, do_symbol }, */
19.613 -/*{136, "symtag", sIN_CSEG, parm1 }, -- version 7 */
19.614 - {123, "sysreq.c", sIN_CSEG, parm1 },
19.615 - {135, "sysreq.n", sIN_CSEG, parm2 }, /* version 9 (replaces SYSREQ.d from earlier version) */
19.616 - {122, "sysreq.pri", sIN_CSEG, parm0 },
19.617 - { 76, "udiv", sIN_CSEG, parm0 },
19.618 - { 77, "udiv.alt", sIN_CSEG, parm0 },
19.619 - { 75, "umul", sIN_CSEG, parm0 },
19.620 - { 35, "xchg", sIN_CSEG, parm0 },
19.621 - { 83, "xor", sIN_CSEG, parm0 },
19.622 - { 91, "zero", sIN_CSEG, parm1 },
19.623 - { 90, "zero.alt", sIN_CSEG, parm0 },
19.624 - { 89, "zero.pri", sIN_CSEG, parm0 },
19.625 - { 92, "zero.s", sIN_CSEG, parm1 },
19.626 -};
19.627 -
19.628 -#define MAX_INSTR_LEN 30
19.629 -static int findopcode(char *instr,int maxlen)
19.630 -{
19.631 - int low,high,mid,cmp;
19.632 - char str[MAX_INSTR_LEN];
19.633 -
19.634 - if (maxlen>=MAX_INSTR_LEN)
19.635 - return 0;
19.636 - strlcpy(str,instr,maxlen+1);
19.637 - /* look up the instruction with a binary search
19.638 - * the assembler is case insensitive to instructions (but case sensitive
19.639 - * to symbols)
19.640 - */
19.641 - low=1; /* entry 0 is reserved (for "not found") */
19.642 - high=(sizeof opcodelist / sizeof opcodelist[0])-1;
19.643 - while (low<high) {
19.644 - mid=(low+high)/2;
19.645 - assert(opcodelist[mid].name!=NULL);
19.646 - cmp=stricmp(str,opcodelist[mid].name);
19.647 - if (cmp>0)
19.648 - low=mid+1;
19.649 - else
19.650 - high=mid;
19.651 - } /* while */
19.652 -
19.653 - assert(low==high);
19.654 - if (stricmp(str,opcodelist[low].name)==0)
19.655 - return low; /* found */
19.656 - return 0; /* not found, return special index */
19.657 -}
19.658 -
19.659 -SC_FUNC int assemble(FILE *fout,FILE *fin)
19.660 -{
19.661 - AMX_HEADER hdr;
19.662 - AMX_FUNCSTUBNT func;
19.663 - int numpublics,numnatives,numlibraries,numpubvars,numtags,padding;
19.664 - long nametablesize,nameofs;
19.665 - #if PAWN_CELL_SIZE > 32
19.666 - char line[512];
19.667 - #else
19.668 - char line[256];
19.669 - #endif
19.670 - char *instr,*params;
19.671 - int i,pass,size;
19.672 - int16_t count;
19.673 - symbol *sym, **nativelist;
19.674 - constvalue *constptr;
19.675 - cell mainaddr;
19.676 - char nullchar = 0;
19.677 -
19.678 - /* if compression failed, restart the assembly with compaction switched off */
19.679 - if (setjmp(compact_err)!=0) {
19.680 - assert(sc_compress); /* cannot arrive here if compact encoding was disabled */
19.681 - sc_compress=FALSE;
19.682 - pc_resetbin(fout,0);
19.683 - error(232); /* disabled compact encoding */
19.684 - } /* if */
19.685 -
19.686 - #if !defined NDEBUG
19.687 - /* verify that the opcode list is sorted (skip entry 1; it is reserved
19.688 - * for a non-existant opcode)
19.689 - */
19.690 - assert(opcodelist[1].name!=NULL);
19.691 - for (i=2; i<(sizeof opcodelist / sizeof opcodelist[0]); i++) {
19.692 - assert(opcodelist[i].name!=NULL);
19.693 - assert(stricmp(opcodelist[i].name,opcodelist[i-1].name)>0);
19.694 - } /* for */
19.695 - #endif
19.696 -
19.697 - writeerror=FALSE;
19.698 - nametablesize=sizeof(int16_t);
19.699 - numpublics=0;
19.700 - numnatives=0;
19.701 - numpubvars=0;
19.702 - mainaddr=-1;
19.703 - /* count number of public and native functions and public variables */
19.704 - for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
19.705 - int match=0;
19.706 - if (sym->ident==iFUNCTN) {
19.707 - if ((sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)!=0 && sym->addr>=0)
19.708 - match=++numnatives;
19.709 - if ((sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0)
19.710 - match=++numpublics;
19.711 - if (strcmp(sym->name,uMAINFUNC)==0) {
19.712 - assert(sym->vclass==sGLOBAL);
19.713 - mainaddr=sym->addr;
19.714 - } /* if */
19.715 - } else if (sym->ident==iVARIABLE) {
19.716 - if ((sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0)
19.717 - match=++numpubvars;
19.718 - } /* if */
19.719 - if (match) {
19.720 - char alias[sNAMEMAX+1];
19.721 - assert(sym!=NULL);
19.722 - if ((sym->usage & uNATIVE)==0 || !lookup_alias(alias,sym->name)) {
19.723 - assert(strlen(sym->name)<=sNAMEMAX);
19.724 - strcpy(alias,sym->name);
19.725 - } /* if */
19.726 - nametablesize+=strlen(alias)+1;
19.727 - } /* if */
19.728 - } /* for */
19.729 - assert(numnatives==ntv_funcid);
19.730 -
19.731 - /* count number of libraries */
19.732 - numlibraries=0;
19.733 - if (pc_addlibtable) {
19.734 - for (constptr=libname_tab.next; constptr!=NULL; constptr=constptr->next) {
19.735 - if (constptr->value>0) {
19.736 - assert(strlen(constptr->name)>0);
19.737 - numlibraries++;
19.738 - nametablesize+=strlen(constptr->name)+1;
19.739 - } /* if */
19.740 - } /* for */
19.741 - } /* if */
19.742 -
19.743 - /* count number of public tags */
19.744 - numtags=0;
19.745 - for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) {
19.746 - if ((constptr->value & PUBLICTAG)!=0) {
19.747 - assert(strlen(constptr->name)>0);
19.748 - numtags++;
19.749 - nametablesize+=strlen(constptr->name)+1;
19.750 - } /* if */
19.751 - } /* for */
19.752 -
19.753 - /* pad the header to sc_dataalign
19.754 - * => thereby the code segment is aligned
19.755 - * => since the code segment is padded to a sc_dataalign boundary, the data segment is aligned
19.756 - * => and thereby the stack top is aligned too
19.757 - */
19.758 - assert(sc_dataalign!=0);
19.759 - padding= (int)(sc_dataalign - (sizeof hdr + nametablesize) % sc_dataalign);
19.760 - if (padding==sc_dataalign)
19.761 - padding=0;
19.762 -
19.763 - /* write the abstract machine header */
19.764 - memset(&hdr, 0, sizeof hdr);
19.765 - hdr.magic=(unsigned short)AMX_MAGIC;
19.766 - hdr.file_version=(char)((pc_optimize<=sOPTIMIZE_NOMACRO) ? MAX_FILE_VER_JIT : CUR_FILE_VERSION);
19.767 - hdr.amx_version=(char)((pc_optimize<=sOPTIMIZE_NOMACRO) ? MIN_AMX_VER_JIT : MIN_AMX_VERSION);
19.768 - hdr.flags=(short)(sc_debug & sSYMBOLIC);
19.769 - if (sc_compress)
19.770 - hdr.flags|=AMX_FLAG_COMPACT;
19.771 - if (sc_debug==0)
19.772 - hdr.flags|=AMX_FLAG_NOCHECKS;
19.773 - if (pc_memflags & suSLEEP_INSTR)
19.774 - hdr.flags|=AMX_FLAG_SLEEP;
19.775 - hdr.defsize=sizeof(AMX_FUNCSTUBNT);
19.776 - hdr.publics=sizeof hdr; /* public table starts right after the header */
19.777 - hdr.natives=hdr.publics + numpublics*sizeof(AMX_FUNCSTUBNT);
19.778 - hdr.libraries=hdr.natives + numnatives*sizeof(AMX_FUNCSTUBNT);
19.779 - hdr.pubvars=hdr.libraries + numlibraries*sizeof(AMX_FUNCSTUBNT);
19.780 - hdr.tags=hdr.pubvars + numpubvars*sizeof(AMX_FUNCSTUBNT);
19.781 - hdr.nametable=hdr.tags + numtags*sizeof(AMX_FUNCSTUBNT);
19.782 - hdr.cod=hdr.nametable + nametablesize + padding;
19.783 - hdr.dat=hdr.cod + code_idx;
19.784 - hdr.hea=hdr.dat + glb_declared*sizeof(cell);
19.785 - hdr.stp=hdr.hea + pc_stksize*sizeof(cell);
19.786 - hdr.cip=mainaddr;
19.787 - hdr.size=hdr.hea; /* preset, this is incorrect in case of compressed output */
19.788 - pc_writebin(fout,&hdr,sizeof hdr);
19.789 -
19.790 - /* dump zeros up to the rest of the header, so that we can easily "seek" */
19.791 - for (nameofs=sizeof hdr; nameofs<hdr.cod; nameofs++)
19.792 - pc_writebin(fout, &nullchar, 1);
19.793 - nameofs=hdr.nametable+sizeof(int16_t);
19.794 -
19.795 - /* write the public functions table */
19.796 - count=0;
19.797 - for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
19.798 - if (sym->ident==iFUNCTN
19.799 - && (sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0)
19.800 - {
19.801 - assert(sym->vclass==sGLOBAL);
19.802 - func.address=sym->addr;
19.803 - func.nameofs=nameofs;
19.804 - #if BYTE_ORDER==BIG_ENDIAN
19.805 - align32(&func.address);
19.806 - align32(&func.nameofs);
19.807 - #endif
19.808 - pc_resetbin(fout,hdr.publics+count*sizeof(AMX_FUNCSTUBNT));
19.809 - pc_writebin(fout,&func,sizeof func);
19.810 - pc_resetbin(fout,nameofs);
19.811 - pc_writebin(fout,sym->name,strlen(sym->name)+1);
19.812 - nameofs+=strlen(sym->name)+1;
19.813 - count++;
19.814 - } /* if */
19.815 - } /* for */
19.816 -
19.817 - /* write the natives table */
19.818 - /* The native functions must be written in sorted order. (They are
19.819 - * sorted on their "id", not on their name). A nested loop to find
19.820 - * each successive function would be an O(n^2) operation. But we
19.821 - * do not really need to sort, because the native function id's
19.822 - * are sequential and there are no duplicates. So we first walk
19.823 - * through the complete symbol list and store a pointer to every
19.824 - * native function of interest in a temporary table, where its id
19.825 - * serves as the index in the table. Now we can walk the table and
19.826 - * have all native functions in sorted order.
19.827 - */
19.828 - if (numnatives>0) {
19.829 - nativelist=(symbol **)malloc(numnatives*sizeof(symbol *));
19.830 - if (nativelist==NULL)
19.831 - error(103); /* insufficient memory */
19.832 - #if !defined NDEBUG
19.833 - memset(nativelist,0,numnatives*sizeof(symbol *)); /* for NULL checking */
19.834 - #endif
19.835 - for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
19.836 - if (sym->ident==iFUNCTN && (sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)!=0 && sym->addr>=0) {
19.837 - assert(sym->addr < numnatives);
19.838 - nativelist[(int)sym->addr]=sym;
19.839 - } /* if */
19.840 - } /* for */
19.841 - count=0;
19.842 - for (i=0; i<numnatives; i++) {
19.843 - char alias[sNAMEMAX+1];
19.844 - sym=nativelist[i];
19.845 - assert(sym!=NULL);
19.846 - if (!lookup_alias(alias,sym->name)) {
19.847 - assert(strlen(sym->name)<=sNAMEMAX);
19.848 - strcpy(alias,sym->name);
19.849 - } /* if */
19.850 - assert(sym->vclass==sGLOBAL);
19.851 - func.address=0;
19.852 - func.nameofs=nameofs;
19.853 - #if BYTE_ORDER==BIG_ENDIAN
19.854 - align32(&func.address);
19.855 - align32(&func.nameofs);
19.856 - #endif
19.857 - pc_resetbin(fout,hdr.natives+count*sizeof(AMX_FUNCSTUBNT));
19.858 - pc_writebin(fout,&func,sizeof func);
19.859 - pc_resetbin(fout,nameofs);
19.860 - pc_writebin(fout,alias,strlen(alias)+1);
19.861 - nameofs+=strlen(alias)+1;
19.862 - count++;
19.863 - } /* for */
19.864 - free(nativelist);
19.865 - } /* if */
19.866 -
19.867 - /* write the libraries table */
19.868 - if (pc_addlibtable) {
19.869 - count=0;
19.870 - for (constptr=libname_tab.next; constptr!=NULL; constptr=constptr->next) {
19.871 - if (constptr->value>0) {
19.872 - assert(strlen(constptr->name)>0);
19.873 - func.address=0;
19.874 - func.nameofs=nameofs;
19.875 - #if BYTE_ORDER==BIG_ENDIAN
19.876 - align32(&func.address);
19.877 - align32(&func.nameofs);
19.878 - #endif
19.879 - pc_resetbin(fout,hdr.libraries+count*sizeof(AMX_FUNCSTUBNT));
19.880 - pc_writebin(fout,&func,sizeof func);
19.881 - pc_resetbin(fout,nameofs);
19.882 - pc_writebin(fout,constptr->name,strlen(constptr->name)+1);
19.883 - nameofs+=strlen(constptr->name)+1;
19.884 - count++;
19.885 - } /* if */
19.886 - } /* for */
19.887 - } /* if */
19.888 -
19.889 - /* write the public variables table */
19.890 - count=0;
19.891 - for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
19.892 - if (sym->ident==iVARIABLE && (sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0) {
19.893 - assert((sym->usage & uDEFINE)!=0);
19.894 - assert(sym->vclass==sGLOBAL);
19.895 - func.address=sym->addr;
19.896 - func.nameofs=nameofs;
19.897 - #if BYTE_ORDER==BIG_ENDIAN
19.898 - align32(&func.address);
19.899 - align32(&func.nameofs);
19.900 - #endif
19.901 - pc_resetbin(fout,hdr.pubvars+count*sizeof(AMX_FUNCSTUBNT));
19.902 - pc_writebin(fout,&func,sizeof func);
19.903 - pc_resetbin(fout,nameofs);
19.904 - pc_writebin(fout,sym->name,strlen(sym->name)+1);
19.905 - nameofs+=strlen(sym->name)+1;
19.906 - count++;
19.907 - } /* if */
19.908 - } /* for */
19.909 -
19.910 - /* write the public tagnames table */
19.911 - count=0;
19.912 - for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) {
19.913 - if ((constptr->value & PUBLICTAG)!=0) {
19.914 - assert(strlen(constptr->name)>0);
19.915 - func.address=constptr->value & TAGMASK;
19.916 - func.nameofs=nameofs;
19.917 - #if BYTE_ORDER==BIG_ENDIAN
19.918 - align32(&func.address);
19.919 - align32(&func.nameofs);
19.920 - #endif
19.921 - pc_resetbin(fout,hdr.tags+count*sizeof(AMX_FUNCSTUBNT));
19.922 - pc_writebin(fout,&func,sizeof func);
19.923 - pc_resetbin(fout,nameofs);
19.924 - pc_writebin(fout,constptr->name,strlen(constptr->name)+1);
19.925 - nameofs+=strlen(constptr->name)+1;
19.926 - count++;
19.927 - } /* if */
19.928 - } /* for */
19.929 -
19.930 - /* write the "maximum name length" field in the name table */
19.931 - assert(nameofs==hdr.nametable+nametablesize);
19.932 - pc_resetbin(fout,hdr.nametable);
19.933 - count=sNAMEMAX;
19.934 - #if BYTE_ORDER==BIG_ENDIAN
19.935 - align16(&count);
19.936 - #endif
19.937 - pc_writebin(fout,&count,sizeof count);
19.938 - pc_resetbin(fout,hdr.cod);
19.939 -
19.940 - /* First pass: relocate all labels */
19.941 - /* This pass is necessary because the code addresses of labels is only known
19.942 - * after the peephole optimization flag. Labels can occur inside expressions
19.943 - * (e.g. the conditional operator), which are optimized.
19.944 - */
19.945 - lbltab=NULL;
19.946 - if (sc_labnum>0) {
19.947 - /* only very short programs have zero labels; no first pass is needed
19.948 - * if there are no labels */
19.949 - lbltab=(cell *)malloc(sc_labnum*sizeof(cell));
19.950 - if (lbltab==NULL)
19.951 - error(103); /* insufficient memory */
19.952 - codeindex=0;
19.953 - pc_resetasm(fin);
19.954 - while (pc_readasm(fin,line,sizeof line)!=NULL) {
19.955 - stripcomment(line);
19.956 - instr=skipwhitespace(line);
19.957 - /* ignore empty lines */
19.958 - if (*instr=='\0')
19.959 - continue;
19.960 - if (tolower(*instr)=='l' && *(instr+1)=='.') {
19.961 - int lindex=(int)hex2long(instr+2,NULL);
19.962 - assert(lindex>=0 && lindex<sc_labnum);
19.963 - lbltab[lindex]=codeindex;
19.964 - } else {
19.965 - /* get to the end of the instruction (make use of the '\n' that fgets()
19.966 - * added at the end of the line; this way we will *always* drop on a
19.967 - * whitespace character) */
19.968 - for (params=instr; *params!='\0' && !isspace(*params); params++)
19.969 - /* nothing */;
19.970 - assert(params>instr);
19.971 - i=findopcode(instr,(int)(params-instr));
19.972 - if (opcodelist[i].name==NULL) {
19.973 - *params='\0';
19.974 - error(104,instr); /* invalid assembler instruction */
19.975 - } /* if */
19.976 - if (opcodelist[i].segment==sIN_CSEG)
19.977 - codeindex+=opcodelist[i].func(NULL,skipwhitespace(params),opcodelist[i].opcode);
19.978 - } /* if */
19.979 - } /* while */
19.980 - } /* if */
19.981 -
19.982 - /* Second pass (actually 2 more passes, one for all code and one for all data) */
19.983 - bytes_in=0;
19.984 - bytes_out=0;
19.985 - for (pass=sIN_CSEG; pass<=sIN_DSEG; pass++) {
19.986 - pc_resetasm(fin);
19.987 - while (pc_readasm(fin,line,sizeof line)!=NULL) {
19.988 - stripcomment(line);
19.989 - instr=skipwhitespace(line);
19.990 - /* ignore empty lines and labels (labels have a special syntax, so these
19.991 - * must be parsed separately) */
19.992 - if (*instr=='\0' || tolower(*instr)=='l' && *(instr+1)=='.')
19.993 - continue;
19.994 - /* get to the end of the instruction (make use of the '\n' that fgets()
19.995 - * added at the end of the line; this way we will *always* drop on a
19.996 - * whitespace character) */
19.997 - for (params=instr; *params!='\0' && !isspace(*params); params++)
19.998 - /* nothing */;
19.999 - assert(params>instr);
19.1000 - i=findopcode(instr,(int)(params-instr));
19.1001 - assert(opcodelist[i].name!=NULL);
19.1002 - if (opcodelist[i].segment==pass)
19.1003 - opcodelist[i].func(fout,skipwhitespace(params),opcodelist[i].opcode);
19.1004 - } /* while */
19.1005 - } /* for */
19.1006 - if (bytes_out-bytes_in>0)
19.1007 - error(106); /* compression buffer overflow */
19.1008 -
19.1009 - if (lbltab!=NULL) {
19.1010 - free(lbltab);
19.1011 - #if !defined NDEBUG
19.1012 - lbltab=NULL;
19.1013 - #endif
19.1014 - } /* if */
19.1015 -
19.1016 - if (sc_compress)
19.1017 - hdr.size=pc_lengthbin(fout);/* get this value before appending debug info */
19.1018 - if (!writeerror && (sc_debug & sSYMBOLIC)!=0)
19.1019 - append_dbginfo(fout); /* optionally append debug file */
19.1020 -
19.1021 - if (writeerror)
19.1022 - error(101,"disk full");
19.1023 -
19.1024 - /* adjust the header */
19.1025 - size=(int)hdr.cod; /* save, the value in the header may be swapped */
19.1026 - #if BYTE_ORDER==BIG_ENDIAN
19.1027 - align32(&hdr.size);
19.1028 - align16(&hdr.magic);
19.1029 - align16(&hdr.flags);
19.1030 - align16(&hdr.defsize);
19.1031 - align32(&hdr.publics);
19.1032 - align32(&hdr.natives);
19.1033 - align32(&hdr.libraries);
19.1034 - align32(&hdr.pubvars);
19.1035 - align32(&hdr.tags);
19.1036 - align32(&hdr.nametable);
19.1037 - align32(&hdr.cod);
19.1038 - align32(&hdr.dat);
19.1039 - align32(&hdr.hea);
19.1040 - align32(&hdr.stp);
19.1041 - align32(&hdr.cip);
19.1042 - #endif
19.1043 - pc_resetbin(fout,0);
19.1044 - pc_writebin(fout,&hdr,sizeof hdr);
19.1045 -
19.1046 - /* return the size of the header (including name tables, but excluding code
19.1047 - * or data sections)
19.1048 - */
19.1049 - return size;
19.1050 -}
19.1051 -
19.1052 -static void append_dbginfo(FILE *fout)
19.1053 -{
19.1054 - AMX_DBG_HDR dbghdr;
19.1055 - AMX_DBG_LINE dbgline;
19.1056 - AMX_DBG_SYMBOL dbgsym;
19.1057 - AMX_DBG_SYMDIM dbgidxtag[sDIMEN_MAX];
19.1058 - int index,dim,dbgsymdim;
19.1059 - char *str,*prevstr,*name,*prevname;
19.1060 - ucell codeidx,previdx;
19.1061 - constvalue *constptr;
19.1062 - char symname[2*sNAMEMAX+16];
19.1063 - int16_t id1,id2;
19.1064 - ucell address;
19.1065 -
19.1066 - /* header with general information */
19.1067 - memset(&dbghdr, 0, sizeof dbghdr);
19.1068 - dbghdr.size=sizeof dbghdr;
19.1069 - dbghdr.magic=AMX_DBG_MAGIC;
19.1070 - dbghdr.file_version=CUR_FILE_VERSION;
19.1071 - dbghdr.amx_version=MIN_AMX_VERSION;
19.1072 -
19.1073 - /* first pass: collect the number of items in various tables */
19.1074 -
19.1075 - /* file table */
19.1076 - previdx=0;
19.1077 - prevstr=NULL;
19.1078 - prevname=NULL;
19.1079 - for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
19.1080 - assert(str!=NULL);
19.1081 - assert(str[0]!='\0' && str[1]==':');
19.1082 - if (str[0]=='F') {
19.1083 - codeidx=hex2long(str+2,&name);
19.1084 - if (codeidx!=previdx) {
19.1085 - if (prevstr!=NULL) {
19.1086 - assert(prevname!=NULL);
19.1087 - dbghdr.files++;
19.1088 - dbghdr.size+=sizeof(cell)+strlen(prevname)+1;
19.1089 - } /* if */
19.1090 - previdx=codeidx;
19.1091 - } /* if */
19.1092 - prevstr=str;
19.1093 - prevname=skipwhitespace(name);
19.1094 - } /* if */
19.1095 - } /* for */
19.1096 - if (prevstr!=NULL) {
19.1097 - assert(prevname!=NULL);
19.1098 - dbghdr.files++;
19.1099 - dbghdr.size+=sizeof(cell)+strlen(prevname)+1;
19.1100 - } /* if */
19.1101 -
19.1102 - /* line number table */
19.1103 - for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
19.1104 - assert(str!=NULL);
19.1105 - assert(str[0]!='\0' && str[1]==':');
19.1106 - if (str[0]=='L') {
19.1107 - dbghdr.lines++;
19.1108 - dbghdr.size+=sizeof(AMX_DBG_LINE);
19.1109 - } /* if */
19.1110 - } /* for */
19.1111 -
19.1112 - /* symbol table */
19.1113 - for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
19.1114 - assert(str!=NULL);
19.1115 - assert(str[0]!='\0' && str[1]==':');
19.1116 - if (str[0]=='S') {
19.1117 - dbghdr.symbols++;
19.1118 - name=strchr(str+2,':');
19.1119 - assert(name!=NULL);
19.1120 - dbghdr.size+=sizeof(AMX_DBG_SYMBOL)+strlen(skipwhitespace(name+1));
19.1121 - if ((prevstr=strchr(name,'['))!=NULL)
19.1122 - while ((prevstr=strchr(prevstr+1,':'))!=NULL)
19.1123 - dbghdr.size+=sizeof(AMX_DBG_SYMDIM);
19.1124 - } /* if */
19.1125 - } /* for */
19.1126 -
19.1127 - /* tag table */
19.1128 - for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) {
19.1129 - assert(strlen(constptr->name)>0);
19.1130 - dbghdr.tags++;
19.1131 - dbghdr.size+=sizeof(AMX_DBG_TAG)+strlen(constptr->name);
19.1132 - } /* for */
19.1133 -
19.1134 - /* automaton table */
19.1135 - for (constptr=sc_automaton_tab.next; constptr!=NULL; constptr=constptr->next) {
19.1136 - assert(constptr->index==0 && strlen(constptr->name)==0 || strlen(constptr->name)>0);
19.1137 - dbghdr.automatons++;
19.1138 - dbghdr.size+=sizeof(AMX_DBG_MACHINE)+strlen(constptr->name);
19.1139 - } /* for */
19.1140 -
19.1141 - /* state table */
19.1142 - for (constptr=sc_state_tab.next; constptr!=NULL; constptr=constptr->next) {
19.1143 - assert(strlen(constptr->name)>0);
19.1144 - dbghdr.states++;
19.1145 - dbghdr.size+=sizeof(AMX_DBG_STATE)+strlen(constptr->name);
19.1146 - } /* for */
19.1147 -
19.1148 -
19.1149 - /* pass 2: generate the tables */
19.1150 - #if BYTE_ORDER==BIG_ENDIAN
19.1151 - align32((uint32_t*)&dbghdr.size);
19.1152 - align16(&dbghdr.magic);
19.1153 - align16(&dbghdr.flags);
19.1154 - align16(&dbghdr.files);
19.1155 - align16(&dbghdr.lines);
19.1156 - align16(&dbghdr.symbols);
19.1157 - align16(&dbghdr.tags);
19.1158 - align16(&dbghdr.automatons);
19.1159 - align16(&dbghdr.states);
19.1160 - #endif
19.1161 - writeerror |= !pc_writebin(fout,&dbghdr,sizeof dbghdr);
19.1162 -
19.1163 - /* file table */
19.1164 - previdx=0;
19.1165 - prevstr=NULL;
19.1166 - prevname=NULL;
19.1167 - for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
19.1168 - assert(str!=NULL);
19.1169 - assert(str[0]!='\0' && str[1]==':');
19.1170 - if (str[0]=='F') {
19.1171 - codeidx=hex2long(str+2,&name);
19.1172 - if (codeidx!=previdx) {
19.1173 - if (prevstr!=NULL) {
19.1174 - assert(prevname!=NULL);
19.1175 - #if BYTE_ORDER==BIG_ENDIAN
19.1176 - aligncell(&previdx);
19.1177 - #endif
19.1178 - writeerror |= !pc_writebin(fout,&previdx,sizeof previdx);
19.1179 - writeerror |= !pc_writebin(fout,prevname,strlen(prevname)+1);
19.1180 - } /* if */
19.1181 - previdx=codeidx;
19.1182 - } /* if */
19.1183 - prevstr=str;
19.1184 - prevname=skipwhitespace(name);
19.1185 - } /* if */
19.1186 - } /* for */
19.1187 - if (prevstr!=NULL) {
19.1188 - assert(prevname!=NULL);
19.1189 - #if BYTE_ORDER==BIG_ENDIAN
19.1190 - aligncell(&previdx);
19.1191 - #endif
19.1192 - writeerror |= !pc_writebin(fout,&previdx,sizeof previdx);
19.1193 - writeerror |= !pc_writebin(fout,prevname,strlen(prevname)+1);
19.1194 - } /* if */
19.1195 -
19.1196 - /* line number table */
19.1197 - for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
19.1198 - assert(str!=NULL);
19.1199 - assert(str[0]!='\0' && str[1]==':');
19.1200 - if (str[0]=='L') {
19.1201 - dbgline.address=hex2long(str+2,&str);
19.1202 - dbgline.line=(int32_t)hex2long(str,NULL);
19.1203 - #if BYTE_ORDER==BIG_ENDIAN
19.1204 - aligncell(&dbgline.address);
19.1205 - align32(&dbgline.line);
19.1206 - #endif
19.1207 - writeerror |= !pc_writebin(fout,&dbgline,sizeof dbgline);
19.1208 - } /* if */
19.1209 - } /* for */
19.1210 -
19.1211 - /* symbol table */
19.1212 - for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
19.1213 - assert(str!=NULL);
19.1214 - assert(str[0]!='\0' && str[1]==':');
19.1215 - if (str[0]=='S') {
19.1216 - dbgsym.address=hex2long(str+2,&str);
19.1217 - dbgsym.tag=(int16_t)hex2long(str,&str);
19.1218 - str=skipwhitespace(str);
19.1219 - assert(*str==':');
19.1220 - name=skipwhitespace(str+1);
19.1221 - str=strchr(name,' ');
19.1222 - assert(str!=NULL);
19.1223 - assert((int)(str-name)<sizeof symname);
19.1224 - strlcpy(symname,name,(int)(str-name)+1);
19.1225 - dbgsym.codestart=hex2long(str,&str);
19.1226 - dbgsym.codeend=hex2long(str,&str);
19.1227 - dbgsym.ident=(char)hex2long(str,&str);
19.1228 - dbgsym.vclass=(char)hex2long(str,&str);
19.1229 - dbgsym.dim=0;
19.1230 - str=skipwhitespace(str);
19.1231 - if (*str=='[') {
19.1232 - while (*(str=skipwhitespace(str+1))!=']') {
19.1233 - dbgidxtag[dbgsym.dim].tag=(int16_t)hex2long(str,&str);
19.1234 - str=skipwhitespace(str);
19.1235 - assert(*str==':');
19.1236 - dbgidxtag[dbgsym.dim].size=hex2long(str+1,&str);
19.1237 - dbgsym.dim++;
19.1238 - } /* while */
19.1239 - } /* if */
19.1240 - dbgsymdim = dbgsym.dim;
19.1241 - #if BYTE_ORDER==BIG_ENDIAN
19.1242 - aligncell(&dbgsym.address);
19.1243 - align16(&dbgsym.tag);
19.1244 - aligncell(&dbgsym.codestart);
19.1245 - aligncell(&dbgsym.codeend);
19.1246 - align16(&dbgsym.dim);
19.1247 - #endif
19.1248 - writeerror |= !pc_writebin(fout,&dbgsym,offsetof(AMX_DBG_SYMBOL, name));
19.1249 - writeerror |= !pc_writebin(fout,symname,strlen(symname)+1);
19.1250 - for (dim=0; dim<dbgsymdim; dim++) {
19.1251 - #if BYTE_ORDER==BIG_ENDIAN
19.1252 - align16(&dbgidxtag[dim].tag);
19.1253 - aligncell(&dbgidxtag[dim].size);
19.1254 - #endif
19.1255 - writeerror |= !pc_writebin(fout,&dbgidxtag[dim],sizeof dbgidxtag[dim]);
19.1256 - } /* for */
19.1257 - } /* if */
19.1258 - } /* for */
19.1259 -
19.1260 - /* tag table */
19.1261 - for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) {
19.1262 - assert(strlen(constptr->name)>0);
19.1263 - id1=(int16_t)(constptr->value & TAGMASK);
19.1264 - #if BYTE_ORDER==BIG_ENDIAN
19.1265 - align16(&id1);
19.1266 - #endif
19.1267 - writeerror |= !pc_writebin(fout,&id1,sizeof id1);
19.1268 - writeerror |= !pc_writebin(fout,constptr->name,strlen(constptr->name)+1);
19.1269 - } /* for */
19.1270 -
19.1271 - /* automaton table */
19.1272 - for (constptr=sc_automaton_tab.next; constptr!=NULL; constptr=constptr->next) {
19.1273 - assert(constptr->index==0 && strlen(constptr->name)==0 || strlen(constptr->name)>0);
19.1274 - id1=(int16_t)constptr->index;
19.1275 - address=(ucell)constptr->value;
19.1276 - #if BYTE_ORDER==BIG_ENDIAN
19.1277 - align16(&id1);
19.1278 - aligncell(&address);
19.1279 - #endif
19.1280 - writeerror |= !pc_writebin(fout,&id1,sizeof id1);
19.1281 - writeerror |= !pc_writebin(fout,&address,sizeof address);
19.1282 - writeerror |= !pc_writebin(fout,constptr->name,strlen(constptr->name)+1);
19.1283 - } /* for */
19.1284 -
19.1285 - /* state table */
19.1286 - for (constptr=sc_state_tab.next; constptr!=NULL; constptr=constptr->next) {
19.1287 - assert(strlen(constptr->name)>0);
19.1288 - id1=(int16_t)constptr->value;
19.1289 - id2=(int16_t)constptr->index;
19.1290 - address=(ucell)constptr->value;
19.1291 - #if BYTE_ORDER==BIG_ENDIAN
19.1292 - align16(&id1);
19.1293 - align16(&id2);
19.1294 - #endif
19.1295 - writeerror |= !pc_writebin(fout,&id1,sizeof id1);
19.1296 - writeerror |= !pc_writebin(fout,&id2,sizeof id2);
19.1297 - writeerror |= !pc_writebin(fout,constptr->name,strlen(constptr->name)+1);
19.1298 - } /* for */
19.1299 -
19.1300 - delete_dbgstringtable();
19.1301 -}
20.1 --- a/compiler-init/sc7.c Sat Jul 15 05:02:38 2006 +0000
20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
20.3 @@ -1,703 +0,0 @@
20.4 -/* Pawn compiler - Staging buffer and optimizer
20.5 - *
20.6 - * The staging buffer
20.7 - * ------------------
20.8 - * The staging buffer allows buffered output of generated code, deletion
20.9 - * of redundant code, optimization by a tinkering process and reversing
20.10 - * the ouput of evaluated expressions (which is used for the reversed
20.11 - * evaluation of arguments in functions).
20.12 - * Initially, stgwrite() writes to the file directly, but after a call to
20.13 - * stgset(TRUE), output is redirected to the buffer. After a call to
20.14 - * stgset(FALSE), stgwrite()'s output is directed to the file again. Thus
20.15 - * only one routine is used for writing to the output, which can be
20.16 - * buffered output or direct output.
20.17 - *
20.18 - * staging buffer variables: stgbuf - the buffer
20.19 - * stgidx - current index in the staging buffer
20.20 - * staging - if true, write to the staging buffer;
20.21 - * if false, write to file directly.
20.22 - *
20.23 - * The peephole optimizer uses a dual "pipeline". The staging buffer (described
20.24 - * above) gets optimized for each expression or sub-expression in a function
20.25 - * call. The peephole optimizer is recursive, but it does not span multiple
20.26 - * sub-expressions. However, the data gets written to a second buffer that
20.27 - * behaves much like the staging buffer. This second buffer gathers all
20.28 - * optimized strings from the staging buffer for a complete expression. The
20.29 - * peephole optmizer then runs over this second buffer to find optimzations
20.30 - * across function parameter boundaries.
20.31 - *
20.32 - *
20.33 - * Copyright (c) ITB CompuPhase, 1997-2006
20.34 - *
20.35 - * This software is provided "as-is", without any express or implied warranty.
20.36 - * In no event will the authors be held liable for any damages arising from
20.37 - * the use of this software.
20.38 - *
20.39 - * Permission is granted to anyone to use this software for any purpose,
20.40 - * including commercial applications, and to alter it and redistribute it
20.41 - * freely, subject to the following restrictions:
20.42 - *
20.43 - * 1. The origin of this software must not be misrepresented; you must not
20.44 - * claim that you wrote the original software. If you use this software in
20.45 - * a product, an acknowledgment in the product documentation would be
20.46 - * appreciated but is not required.
20.47 - * 2. Altered source versions must be plainly marked as such, and must not be
20.48 - * misrepresented as being the original software.
20.49 - * 3. This notice may not be removed or altered from any source distribution.
20.50 - *
20.51 - * Version: $Id: sc7.c 3579 2006-06-06 13:35:29Z thiadmer $
20.52 - */
20.53 -#include <assert.h>
20.54 -#include <stdio.h>
20.55 -#include <stdlib.h> /* for atoi() */
20.56 -#include <string.h>
20.57 -#include <ctype.h>
20.58 -#if defined FORTIFY
20.59 - #include <alloc/fortify.h>
20.60 -#endif
20.61 -#include "sc.h"
20.62 -
20.63 -#if defined _MSC_VER
20.64 - #pragma warning(push)
20.65 - #pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
20.66 -#endif
20.67 -
20.68 -#include "sc7.scp"
20.69 -
20.70 -#if defined _MSC_VER
20.71 - #pragma warning(pop)
20.72 -#endif
20.73 -
20.74 -static int stgstring(char *start,char *end);
20.75 -static void stgopt(char *start,char *end,int (*outputfunc)(char *str));
20.76 -
20.77 -
20.78 -#define sSTG_GROW 512
20.79 -#define sSTG_MAX 20480
20.80 -
20.81 -static char *stgbuf=NULL;
20.82 -static int stgmax=0; /* current size of the staging buffer */
20.83 -
20.84 -static char *stgpipe=NULL;
20.85 -static int pipemax=0; /* current size of the stage pipe, a second staging buffer */
20.86 -static int pipeidx=0;
20.87 -
20.88 -#define CHECK_STGBUFFER(index) if ((int)(index)>=stgmax) grow_stgbuffer(&stgbuf, stgmax, (index)+1)
20.89 -#define CHECK_STGPIPE(index) if ((int)(index)>=pipemax) grow_stgbuffer(&stgpipe, pipemax, (index)+1)
20.90 -
20.91 -static void grow_stgbuffer(char **buffer, int curmax, int requiredsize)
20.92 -{
20.93 - char *p;
20.94 - int clear= (*buffer==NULL); /* if previously none, empty buffer explicitly */
20.95 -
20.96 - assert(curmax<requiredsize);
20.97 - /* if the staging buffer (holding intermediate code for one line) grows
20.98 - * over a few kBytes, there is probably a run-away expression
20.99 - */
20.100 - if (requiredsize>sSTG_MAX)
20.101 - error(102,"staging buffer"); /* staging buffer overflow (fatal error) */
20.102 - curmax=requiredsize+sSTG_GROW;
20.103 - if (*buffer!=NULL)
20.104 - p=(char *)realloc(*buffer,curmax*sizeof(char));
20.105 - else
20.106 - p=(char *)malloc(curmax*sizeof(char));
20.107 - if (p==NULL)
20.108 - error(102,"staging buffer"); /* staging buffer overflow (fatal error) */
20.109 - *buffer=p;
20.110 - if (clear)
20.111 - **buffer='\0';
20.112 -}
20.113 -
20.114 -SC_FUNC void stgbuffer_cleanup(void)
20.115 -{
20.116 - if (stgbuf!=NULL) {
20.117 - free(stgbuf);
20.118 - stgbuf=NULL;
20.119 - stgmax=0;
20.120 - } /* if */
20.121 - if (stgpipe!=NULL) {
20.122 - free(stgpipe);
20.123 - stgpipe=NULL;
20.124 - pipemax=0;
20.125 - pipeidx=0;
20.126 - } /* if */
20.127 -}
20.128 -
20.129 -/* the variables "stgidx" and "staging" are declared in "scvars.c" */
20.130 -
20.131 -/* stgmark
20.132 - *
20.133 - * Copies a mark into the staging buffer. At this moment there are three
20.134 - * possible marks:
20.135 - * sSTARTREORDER identifies the beginning of a series of expression
20.136 - * strings that must be written to the output file in
20.137 - * reordered order
20.138 - * sENDREORDER identifies the end of 'reverse evaluation'
20.139 - * sEXPRSTART + idx only valid within a block that is evaluated in
20.140 - * reordered order, it identifies the start of an
20.141 - * expression; the "idx" value is the argument position
20.142 - *
20.143 - * Global references: stgidx (altered)
20.144 - * stgbuf (altered)
20.145 - * staging (referred to only)
20.146 - */
20.147 -SC_FUNC void stgmark(char mark)
20.148 -{
20.149 - if (staging) {
20.150 - CHECK_STGBUFFER(stgidx);
20.151 - stgbuf[stgidx++]=mark;
20.152 - } /* if */
20.153 -}
20.154 -
20.155 -static int rebuffer(char *str)
20.156 -{
20.157 - if (sc_status==statWRITE) {
20.158 - if (pipeidx>=2 && stgpipe[pipeidx-1]=='\0' && stgpipe[pipeidx-2]!='\n')
20.159 - pipeidx-=1; /* overwrite last '\0' */
20.160 - while (*str!='\0') { /* copy to staging buffer */
20.161 - CHECK_STGPIPE(pipeidx);
20.162 - stgpipe[pipeidx++]=*str++;
20.163 - } /* while */
20.164 - CHECK_STGPIPE(pipeidx);
20.165 - stgpipe[pipeidx++]='\0';
20.166 - } /* if */
20.167 - return TRUE;
20.168 -}
20.169 -
20.170 -static int filewrite(char *str)
20.171 -{
20.172 - if (sc_status==statWRITE)
20.173 - return pc_writeasm(outf,str);
20.174 - return TRUE;
20.175 -}
20.176 -
20.177 -/* stgwrite
20.178 - *
20.179 - * Writes the string "st" to the staging buffer or to the output file. In the
20.180 - * case of writing to the staging buffer, the terminating byte of zero is
20.181 - * copied too, but... the optimizer can only work on complete lines (not on
20.182 - * fractions of it. Therefore if the string is staged, if the last character
20.183 - * written to the buffer is a '\0' and the previous-to-last is not a '\n',
20.184 - * the string is concatenated to the last string in the buffer (the '\0' is
20.185 - * overwritten). This also means an '\n' used in the middle of a string isn't
20.186 - * recognized and could give wrong results with the optimizer.
20.187 - * Even when writing to the output file directly, all strings are buffered
20.188 - * until a whole line is complete.
20.189 - *
20.190 - * Global references: stgidx (altered)
20.191 - * stgbuf (altered)
20.192 - * staging (referred to only)
20.193 - */
20.194 -SC_FUNC void stgwrite(const char *st)
20.195 -{
20.196 - int len;
20.197 -
20.198 - if (staging) {
20.199 - assert(stgidx==0 || stgbuf!=NULL); /* staging buffer must be valid if there is (apparently) something in it */
20.200 - if (stgidx>=2 && stgbuf[stgidx-1]=='\0' && stgbuf[stgidx-2]!='\n')
20.201 - stgidx-=1; /* overwrite last '\0' */
20.202 - while (*st!='\0') { /* copy to staging buffer */
20.203 - CHECK_STGBUFFER(stgidx);
20.204 - stgbuf[stgidx++]=*st++;
20.205 - } /* while */
20.206 - CHECK_STGBUFFER(stgidx);
20.207 - stgbuf[stgidx++]='\0';
20.208 - } else {
20.209 - len=(stgbuf!=NULL) ? strlen(stgbuf) : 0;
20.210 - CHECK_STGBUFFER(len+strlen(st)+1);
20.211 - strcat(stgbuf,st);
20.212 - len=strlen(stgbuf);
20.213 - if (len>0 && stgbuf[len-1]=='\n') {
20.214 - filewrite(stgbuf);
20.215 - stgbuf[0]='\0';
20.216 - } /* if */
20.217 - } /* if */
20.218 -}
20.219 -
20.220 -/* stgout
20.221 - *
20.222 - * Writes the staging buffer to the output file via stgstring() (for
20.223 - * reversing expressions in the buffer) and stgopt() (for optimizing). It
20.224 - * resets "stgidx".
20.225 - *
20.226 - * Global references: stgidx (altered)
20.227 - * stgbuf (referred to only)
20.228 - * staging (referred to only)
20.229 - */
20.230 -SC_FUNC void stgout(int index)
20.231 -{
20.232 - int reordered=0;
20.233 - int idx;
20.234 -
20.235 - if (!staging)
20.236 - return;
20.237 - assert(pipeidx==0);
20.238 -
20.239 - /* first pass: sub-expressions */
20.240 - if (sc_status==statWRITE)
20.241 - reordered=stgstring(&stgbuf[index],&stgbuf[stgidx]);
20.242 - stgidx=index;
20.243 -
20.244 - /* second pass: optimize the buffer created in the first pass */
20.245 - if (sc_status==statWRITE) {
20.246 - if (reordered) {
20.247 - stgopt(stgpipe,stgpipe+pipeidx,filewrite);
20.248 - } else {
20.249 - /* there is no sense in re-optimizing if the order of the sub-expressions
20.250 - * did not change; so output directly
20.251 - */
20.252 - for (idx=0; idx<pipeidx; idx+=strlen(stgpipe+idx)+1)
20.253 - filewrite(stgpipe+idx);
20.254 - } /* if */
20.255 - } /* if */
20.256 - pipeidx=0; /* reset second pipe */
20.257 -}
20.258 -
20.259 -typedef struct {
20.260 - char *start,*end;
20.261 -} argstack;
20.262 -
20.263 -/* stgstring
20.264 - *
20.265 - * Analyses whether code strings should be output to the file as they appear
20.266 - * in the staging buffer or whether portions of it should be re-ordered.
20.267 - * Re-ordering takes place in function argument lists; Pawn passes arguments
20.268 - * to functions from right to left. When arguments are "named" rather than
20.269 - * positional, the order in the source stream is indeterminate.
20.270 - * This function calls itself recursively in case it needs to re-order code
20.271 - * strings, and it uses a private stack (or list) to mark the start and the
20.272 - * end of expressions in their correct (reversed) order.
20.273 - * In any case, stgstring() sends a block as large as possible to the
20.274 - * optimizer stgopt().
20.275 - *
20.276 - * In "reorder" mode, each set of code strings must start with the token
20.277 - * sEXPRSTART, even the first. If the token sSTARTREORDER is represented
20.278 - * by '[', sENDREORDER by ']' and sEXPRSTART by '|' the following applies:
20.279 - * '[]...' valid, but useless; no output
20.280 - * '[|...] valid, but useless; only one string
20.281 - * '[|...|...] valid and usefull
20.282 - * '[...|...] invalid, first string doesn't start with '|'
20.283 - * '[|...|] invalid
20.284 - */
20.285 -static int stgstring(char *start,char *end)
20.286 -{
20.287 - char *ptr;
20.288 - int nest,argc,arg;
20.289 - argstack *stack;
20.290 - int reordered=0;
20.291 -
20.292 - while (start<end) {
20.293 - if (*start==sSTARTREORDER) {
20.294 - start+=1; /* skip token */
20.295 - /* allocate a argstack with sMAXARGS items */
20.296 - stack=(argstack *)malloc(sMAXARGS*sizeof(argstack));
20.297 - if (stack==NULL)
20.298 - error(103); /* insufficient memory */
20.299 - reordered=1; /* mark that the expression is reordered */
20.300 - nest=1; /* nesting counter */
20.301 - argc=0; /* argument counter */
20.302 - arg=-1; /* argument index; no valid argument yet */
20.303 - do {
20.304 - switch (*start) {
20.305 - case sSTARTREORDER:
20.306 - nest++;
20.307 - start++;
20.308 - break;
20.309 - case sENDREORDER:
20.310 - nest--;
20.311 - start++;
20.312 - break;
20.313 - default:
20.314 - if ((*start & sEXPRSTART)==sEXPRSTART) {
20.315 - if (nest==1) {
20.316 - if (arg>=0)
20.317 - stack[arg].end=start-1; /* finish previous argument */
20.318 - arg=(unsigned char)*start - sEXPRSTART;
20.319 - stack[arg].start=start+1;
20.320 - if (arg>=argc)
20.321 - argc=arg+1;
20.322 - } /* if */
20.323 - start++;
20.324 - } else {
20.325 - start+=strlen(start)+1;
20.326 - } /* if */
20.327 - } /* switch */
20.328 - } while (nest); /* enddo */
20.329 - if (arg>=0)
20.330 - stack[arg].end=start-1; /* finish previous argument */
20.331 - while (argc>0) {
20.332 - argc--;
20.333 - stgstring(stack[argc].start,stack[argc].end);
20.334 - } /* while */
20.335 - free(stack);
20.336 - } else {
20.337 - ptr=start;
20.338 - while (ptr<end && *ptr!=sSTARTREORDER)
20.339 - ptr+=strlen(ptr)+1;
20.340 - stgopt(start,ptr,rebuffer);
20.341 - start=ptr;
20.342 - } /* if */
20.343 - } /* while */
20.344 - return reordered;
20.345 -}
20.346 -
20.347 -/* stgdel
20.348 - *
20.349 - * Scraps code from the staging buffer by resetting "stgidx" to "index".
20.350 - *
20.351 - * Global references: stgidx (altered)
20.352 - * staging (reffered to only)
20.353 - */
20.354 -SC_FUNC void stgdel(int index,cell code_index)
20.355 -{
20.356 - if (staging) {
20.357 - stgidx=index;
20.358 - code_idx=code_index;
20.359 - } /* if */
20.360 -}
20.361 -
20.362 -SC_FUNC int stgget(int *index,cell *code_index)
20.363 -{
20.364 - if (staging) {
20.365 - *index=stgidx;
20.366 - *code_index=code_idx;
20.367 - } /* if */
20.368 - return staging;
20.369 -}
20.370 -
20.371 -/* stgset
20.372 - *
20.373 - * Sets staging on or off. If it's turned off, the staging buffer must be
20.374 - * initialized to an empty string. If it's turned on, the routine makes sure
20.375 - * the index ("stgidx") is set to 0 (it should already be 0).
20.376 - *
20.377 - * Global references: staging (altered)
20.378 - * stgidx (altered)
20.379 - * stgbuf (contents altered)
20.380 - */
20.381 -SC_FUNC void stgset(int onoff)
20.382 -{
20.383 - staging=onoff;
20.384 - if (staging){
20.385 - assert(stgidx==0);
20.386 - stgidx=0;
20.387 - CHECK_STGBUFFER(stgidx);
20.388 - /* write any contents that may be put in the buffer by stgwrite()
20.389 - * when "staging" was 0
20.390 - */
20.391 - if (strlen(stgbuf)>0)
20.392 - filewrite(stgbuf);
20.393 - } /* if */
20.394 - stgbuf[0]='\0';
20.395 -}
20.396 -
20.397 -/* phopt_init
20.398 - * Initialize all sequence strings of the peehole optimizer. The strings
20.399 - * are embedded in the .EXE file in compressed format, here we expand
20.400 - * them (and allocate memory for the sequences).
20.401 - */
20.402 -static SEQUENCE *sequences;
20.403 -
20.404 -SC_FUNC int phopt_init(void)
20.405 -{
20.406 - int number, i, len;
20.407 - char str[160];
20.408 -
20.409 - /* count number of sequences */
20.410 - for (number=0; sequences_cmp[number].find!=NULL; number++)
20.411 - /* nothing */;
20.412 - number++; /* include an item for the NULL terminator */
20.413 -
20.414 - if ((sequences=(SEQUENCE*)malloc(number * sizeof(SEQUENCE)))==NULL)
20.415 - return FALSE;
20.416 -
20.417 - /* pre-initialize all to NULL (in case of failure) */
20.418 - for (i=0; i<number; i++) {
20.419 - sequences[i].find=NULL;
20.420 - sequences[i].replace=NULL;
20.421 - sequences[i].savesize=0;
20.422 - } /* for */
20.423 -
20.424 - /* expand all strings */
20.425 - for (i=0; i<number-1; i++) {
20.426 - len = strexpand(str,(unsigned char*)sequences_cmp[i].find,sizeof str,SCPACK_TABLE);
20.427 - assert(len<=sizeof str);
20.428 - assert(len==(int)strlen(str)+1);
20.429 - sequences[i].find=(char*)malloc(len);
20.430 - if (sequences[i].find!=NULL)
20.431 - strcpy(sequences[i].find,str);
20.432 - len = strexpand(str,(unsigned char*)sequences_cmp[i].replace,sizeof str,SCPACK_TABLE);
20.433 - assert(len<=sizeof str);
20.434 - assert(len==(int)strlen(str)+1);
20.435 - sequences[i].replace=(char*)malloc(len);
20.436 - if (sequences[i].replace!=NULL)
20.437 - strcpy(sequences[i].replace,str);
20.438 - sequences[i].savesize=sequences_cmp[i].savesize;
20.439 - if (sequences[i].find==NULL || sequences[i].replace==NULL)
20.440 - return phopt_cleanup();
20.441 - } /* for */
20.442 -
20.443 - return TRUE;
20.444 -}
20.445 -
20.446 -SC_FUNC int phopt_cleanup(void)
20.447 -{
20.448 - int i;
20.449 - if (sequences!=NULL) {
20.450 - i=0;
20.451 - while (sequences[i].find!=NULL || sequences[i].replace!=NULL) {
20.452 - if (sequences[i].find!=NULL)
20.453 - free(sequences[i].find);
20.454 - if (sequences[i].replace!=NULL)
20.455 - free(sequences[i].replace);
20.456 - i++;
20.457 - } /* while */
20.458 - free(sequences);
20.459 - sequences=NULL;
20.460 - } /* if */
20.461 - return FALSE;
20.462 -}
20.463 -
20.464 -#define MAX_OPT_VARS 5
20.465 -#define MAX_OPT_CAT 5 /* max. values that are concatenated */
20.466 -#if sNAMEMAX > (PAWN_CELL_SIZE/4) * MAX_OPT_CAT
20.467 - #define MAX_ALIAS sNAMEMAX
20.468 -#else
20.469 - #define MAX_ALIAS (PAWN_CELL_SIZE/4) * MAX_OPT_CAT
20.470 -#endif
20.471 -
20.472 -static int matchsequence(char *start,char *end,char *pattern,
20.473 - char symbols[MAX_OPT_VARS][MAX_ALIAS+1],
20.474 - int *match_length)
20.475 -{
20.476 - int var,i;
20.477 - char str[MAX_ALIAS+1];
20.478 - char *start_org=start;
20.479 - cell value;
20.480 - char *ptr;
20.481 -
20.482 - *match_length=0;
20.483 - for (var=0; var<MAX_OPT_VARS; var++)
20.484 - symbols[var][0]='\0';
20.485 -
20.486 - while (*start=='\t' || *start==' ')
20.487 - start++;
20.488 - while (*pattern) {
20.489 - if (start>=end)
20.490 - return FALSE;
20.491 - switch (*pattern) {
20.492 - case '%': /* new "symbol" */
20.493 - pattern++;
20.494 - assert(isdigit(*pattern));
20.495 - var=atoi(pattern) - 1;
20.496 - assert(var>=0 && var<MAX_OPT_VARS);
20.497 - assert(*start=='-' || alphanum(*start));
20.498 - for (i=0; start<end && (*start=='-' || *start=='+' || alphanum(*start)); i++,start++) {
20.499 - assert(i<=MAX_ALIAS);
20.500 - str[i]=*start;
20.501 - } /* for */
20.502 - str[i]='\0';
20.503 - if (symbols[var][0]!='\0') {
20.504 - if (strcmp(symbols[var],str)!=0)
20.505 - return FALSE; /* symbols should be identical */
20.506 - } else {
20.507 - strcpy(symbols[var],str);
20.508 - } /* if */
20.509 - break;
20.510 - case '-':
20.511 - value=-strtol(pattern+1,&pattern,16);
20.512 - ptr=itoh((ucell)value);
20.513 - while (*ptr!='\0') {
20.514 - if (tolower(*start) != tolower(*ptr))
20.515 - return FALSE;
20.516 - start++;
20.517 - ptr++;
20.518 - } /* while */
20.519 - pattern--; /* there is an increment following at the end of the loop */
20.520 - break;
20.521 - case ' ':
20.522 - if (*start!='\t' && *start!=' ')
20.523 - return FALSE;
20.524 - while (start<end && (*start=='\t' || *start==' '))
20.525 - start++;
20.526 - break;
20.527 - case '!':
20.528 - while (start<end && (*start=='\t' || *start==' '))
20.529 - start++; /* skip trailing white space */
20.530 - if (*start==';')
20.531 - while (start<end && *start!='\n')
20.532 - start++; /* skip trailing comment */
20.533 - if (*start!='\n')
20.534 - return FALSE;
20.535 - assert(*(start+1)=='\0');
20.536 - start+=2; /* skip '\n' and '\0' */
20.537 - if (*(pattern+1)!='\0')
20.538 - while (start<end && *start=='\t' || *start==' ')
20.539 - start++; /* skip leading white space of next instruction */
20.540 - break;
20.541 - default:
20.542 - if (tolower(*start) != tolower(*pattern))
20.543 - return FALSE;
20.544 - start++;
20.545 - } /* switch */
20.546 - pattern++;
20.547 - } /* while */
20.548 -
20.549 - *match_length=(int)(start-start_org);
20.550 - return TRUE;
20.551 -}
20.552 -
20.553 -static char *replacesequence(char *pattern,char symbols[MAX_OPT_VARS][MAX_ALIAS+1],int *repl_length)
20.554 -{
20.555 - char *lptr;
20.556 - int var;
20.557 - char *buffer;
20.558 -
20.559 - /* calculate the length of the new buffer
20.560 - * this is the length of the pattern plus the length of all symbols (note
20.561 - * that the same symbol may occur multiple times in the pattern) plus
20.562 - * line endings and startings ('\t' to start a line and '\n\0' to end one)
20.563 - */
20.564 - assert(repl_length!=NULL);
20.565 - *repl_length=0;
20.566 - lptr=pattern;
20.567 - while (*lptr) {
20.568 - switch (*lptr) {
20.569 - case '%':
20.570 - lptr++; /* skip '%' */
20.571 - assert(isdigit(*lptr));
20.572 - var=atoi(lptr) - 1;
20.573 - assert(var>=0 && var<MAX_OPT_VARS);
20.574 - assert(symbols[var][0]!='\0'); /* variable should be defined */
20.575 - *repl_length+=strlen(symbols[var]);
20.576 - break;
20.577 - case '!':
20.578 - *repl_length+=3; /* '\t', '\n' & '\0' */
20.579 - break;
20.580 - default:
20.581 - *repl_length+=1;
20.582 - } /* switch */
20.583 - lptr++;
20.584 - } /* while */
20.585 -
20.586 - /* allocate a buffer to replace the sequence in */
20.587 - if ((buffer=(char*)malloc(*repl_length))==NULL)
20.588 - return (char*)error(103);
20.589 -
20.590 - /* replace the pattern into this temporary buffer */
20.591 - lptr=buffer;
20.592 - *lptr++='\t'; /* the "replace" patterns do not have tabs */
20.593 - while (*pattern) {
20.594 - assert((int)(lptr-buffer)<*repl_length);
20.595 - switch (*pattern) {
20.596 - case '%':
20.597 - /* write out the symbol */
20.598 - pattern++;
20.599 - assert(isdigit(*pattern));
20.600 - var=atoi(pattern) - 1;
20.601 - assert(var>=0 && var<MAX_OPT_VARS);
20.602 - assert(symbols[var][0]!='\0'); /* variable should be defined */
20.603 - strcpy(lptr,symbols[var]);
20.604 - lptr+=strlen(symbols[var]);
20.605 - break;
20.606 - case '!':
20.607 - /* finish the line, optionally start the next line with an indent */
20.608 - *lptr++='\n';
20.609 - *lptr++='\0';
20.610 - if (*(pattern+1)!='\0')
20.611 - *lptr++='\t';
20.612 - break;
20.613 - default:
20.614 - *lptr++=*pattern;
20.615 - } /* switch */
20.616 - pattern++;
20.617 - } /* while */
20.618 -
20.619 - assert((int)(lptr-buffer)==*repl_length);
20.620 - return buffer;
20.621 -}
20.622 -
20.623 -static void strreplace(char *dest,char *replace,int sub_length,int repl_length,int dest_length)
20.624 -{
20.625 - int offset=sub_length-repl_length;
20.626 - if (offset>0) { /* delete a section */
20.627 - memmove(dest,dest+offset,dest_length-offset);
20.628 - memset(dest+dest_length-offset,0xcc,offset); /* not needed, but for cleanlyness */
20.629 - } else if (offset<0) { /* insert a section */
20.630 - memmove(dest-offset, dest, dest_length);
20.631 - } /* if */
20.632 - memcpy(dest, replace, repl_length);
20.633 -}
20.634 -
20.635 -/* stgopt
20.636 - *
20.637 - * Optimizes the staging buffer by checking for series of instructions that
20.638 - * can be coded more compact. The routine expects the lines in the staging
20.639 - * buffer to be separated with '\n' and '\0' characters.
20.640 - *
20.641 - * The longest sequences should probably be checked first.
20.642 - */
20.643 -
20.644 -static void stgopt(char *start,char *end,int (*outputfunc)(char *str))
20.645 -{
20.646 - char symbols[MAX_OPT_VARS][MAX_ALIAS+1];
20.647 - int seq,match_length,repl_length;
20.648 - int matches;
20.649 - char *debut=start; /* save original start of the buffer */
20.650 -
20.651 - assert(sequences!=NULL);
20.652 - /* do not match anything if debug-level is maximum */
20.653 - if (pc_optimize>sOPTIMIZE_NONE && sc_status==statWRITE) {
20.654 - do {
20.655 - matches=0;
20.656 - start=debut;
20.657 - while (start<end) {
20.658 - seq=0;
20.659 - while (sequences[seq].find!=NULL) {
20.660 - assert(seq>=0);
20.661 - if (*sequences[seq].find=='\0') {
20.662 - if (pc_optimize==sOPTIMIZE_NOMACRO) {
20.663 - break; /* don't look further */
20.664 - } else {
20.665 - seq++; /* continue with next string */
20.666 - continue;
20.667 - } /* if */
20.668 - } /* if */
20.669 - if (matchsequence(start,end,sequences[seq].find,symbols,&match_length)) {
20.670 - char *replace=replacesequence(sequences[seq].replace,symbols,&repl_length);
20.671 - /* If the replacement is bigger than the original section, we may need
20.672 - * to "grow" the staging buffer. This is quite complex, due to the
20.673 - * re-ordering of expressions that can also happen in the staging
20.674 - * buffer. In addition, it should not happen: the peephole optimizer
20.675 - * must replace sequences with *shorter* sequences, not longer ones.
20.676 - * So, I simply forbid sequences that are longer than the ones they
20.677 - * are meant to replace.
20.678 - */
20.679 - assert(match_length>=repl_length);
20.680 - if (match_length>=repl_length) {
20.681 - strreplace(start,replace,match_length,repl_length,(int)(end-start));
20.682 - end-=match_length-repl_length;
20.683 - free(replace);
20.684 - code_idx-=sequences[seq].savesize;
20.685 - seq=0; /* restart search for matches */
20.686 - matches++;
20.687 - } else {
20.688 - /* actually, we should never get here (match_length<repl_length) */
20.689 - assert(0);
20.690 - seq++;
20.691 - } /* if */
20.692 - } else {
20.693 - seq++;
20.694 - } /* if */
20.695 - } /* while */
20.696 - assert(sequences[seq].find==NULL || *sequences[seq].find=='\0' && pc_optimize==sOPTIMIZE_NOMACRO);
20.697 - start += strlen(start) + 1; /* to next string */
20.698 - } /* while (start<end) */
20.699 - } while (matches>0);
20.700 - } /* if (pc_optimize>sOPTIMIZE_NONE && sc_status==statWRITE) */
20.701 -
20.702 - for (start=debut; start<end; start+=strlen(start)+1)
20.703 - outputfunc(start);
20.704 -}
20.705 -
20.706 -#undef SCPACK_TABLE
21.1 --- a/compiler-init/sc7.scp Sat Jul 15 05:02:38 2006 +0000
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,2022 +0,0 @@
21.4 -/* Pawn compiler - Peephole optimizer "sequences" strings (plain
21.5 - * and compressed formats)
21.6 - *
21.7 - * Copyright (c) ITB CompuPhase, 2000-2006
21.8 - *
21.9 - * This software is provided "as-is", without any express or implied warranty.
21.10 - * In no event will the authors be held liable for any damages arising from
21.11 - * the use of this software.
21.12 - *
21.13 - * Permission is granted to anyone to use this software for any purpose,
21.14 - * including commercial applications, and to alter it and redistribute it
21.15 - * freely, subject to the following restrictions:
21.16 - *
21.17 - * 1. The origin of this software must not be misrepresented; you must not
21.18 - * claim that you wrote the original software. If you use this software in
21.19 - * a product, an acknowledgment in the product documentation would be
21.20 - * appreciated but is not required.
21.21 - * 2. Altered source versions must be plainly marked as such, and must not be
21.22 - * misrepresented as being the original software.
21.23 - * 3. This notice may not be removed or altered from any source distribution.
21.24 - *
21.25 - * Version: $Id: sc7.sch 3577 2006-06-02 16:22:52Z thiadmer $
21.26 - */
21.27 -
21.28 -SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]);
21.29 -
21.30 -#define SCPACK_TERMINATOR , /* end each section with a comma */
21.31 -
21.32 -#define SCPACK_TABLE sequences_table
21.33 -/*-*SCPACK start of pair table, do not change or remove this line */
21.34 -unsigned char sequences_table[][2] = {
21.35 - {49,33}, {37,128}, {32,129}, {32,37}, {114,105}, {112,132}, {46,133}, {97,100}, {46,97}, {136,108}, {137,116}, {115,104}, {111,135}, {117,139}, {112,141}, {108,140},
21.36 - {131,50}, {144,33}, {46,115}, {138,33}, {59,36}, {134,130}, {143,146}, {115,116}, {134,145}, {110,151}, {111,153}, {99,154}, {112,147}, {135,100}, {134,33}, {114,33},
21.37 - {111,156}, {112,160}, {46,99}, {138,130}, {142,158}, {131,51}, {150,152}, {112,33}, {120,167}, {101,168}, {148,169}, {97,159}, {112,171}, {148,172}, {165,33}, {173,142},
21.38 - {122,101}, {176,114}, {101,113}, {110,100}, {149,164}, {157,114}, {33,161}, {131,49}, {103,33}, {157,33}, {104,184}, {99,186}, {120,187}, {98,111}, {118,101}, {111,190},
21.39 - {109,191}, {130,170}, {131,52}, {106,177}, {138,145}, {180,166}, {192,147}, {108,162}, {163,166}, {143,149}, {115,174}, {117,179}, {139,199}, {203,202}, {189,205}, {105,100},
21.40 - {115,103}, {115,108}, {207,120}, {195,130}, {46,135}, {178,33}, {212,114}, {204,134}, {155,149}, {142,162}, {183,145}, {150,149}, {143,152}, {194,33}, {130,175}, {97,179},
21.41 - {177,111}, {182,185}, {143,46}, {183,144}, {155,152}, {145,175}, {114,101}, {230,102}, {108,231}, {101,115}, {233,115}, {114,116}, {142,147}, {105,33}, {155,163}, {178,130},
21.42 - {215,32}, {240,50}, {143,196}, {155,197}, {181,197}, {181,200}, {108,210}, {46,98}, {241,225}, {208,235}, {209,234}, {224,158}, {143,163}, {150,163}, {155,200}
21.43 -};
21.44 -/*-*SCPACK end of pair table, do not change or remove this line */
21.45 -
21.46 -#define seqsize(o,p) (opcodes(o)+opargs(p))
21.47 -typedef struct {
21.48 - char *find;
21.49 - char *replace;
21.50 - int savesize; /* number of bytes saved (in bytecode) */
21.51 -} SEQUENCE;
21.52 -static SEQUENCE sequences_cmp[] = {
21.53 - /* A very common sequence in four varieties
21.54 - * load.s.pri n1 load.s.pri n2
21.55 - * push.pri load.s.alt n1
21.56 - * load.s.pri n2 -
21.57 - * pop.alt -
21.58 - * --------------------------------------
21.59 - * load.pri n1 load.s.pri n2
21.60 - * push.pri load.alt n1
21.61 - * load.s.pri n2 -
21.62 - * pop.alt -
21.63 - * --------------------------------------
21.64 - * load.s.pri n1 load.pri n2
21.65 - * push.pri load.s.alt n1
21.66 - * load.pri n2 -
21.67 - * pop.alt -
21.68 - * --------------------------------------
21.69 - * load.pri n1 load.pri n2
21.70 - * push.pri load.alt n1
21.71 - * load.pri n2 -
21.72 - * pop.alt -
21.73 - */
21.74 - {
21.75 - #ifdef SCPACK
21.76 - "load.s.pri %1!push.pri!load.s.pri %2!pop.alt!",
21.77 - "load.s.pri %2!load.s.alt %1!",
21.78 - #else
21.79 - "\226\305\241",
21.80 - "\246\375",
21.81 - #endif
21.82 - seqsize(4,2) - seqsize(2,2)
21.83 - },
21.84 - {
21.85 - #ifdef SCPACK
21.86 - "load.pri %1!push.pri!load.s.pri %2!pop.alt!",
21.87 - "load.s.pri %2!load.alt %1!",
21.88 - #else
21.89 - "\217\305\241",
21.90 - "\246\374",
21.91 - #endif
21.92 - seqsize(4,2) - seqsize(2,2)
21.93 - },
21.94 - {
21.95 - #ifdef SCPACK
21.96 - "load.s.pri %1!push.pri!load.pri %2!pop.alt!",
21.97 - "load.pri %2!load.s.alt %1!",
21.98 - #else
21.99 - "\226\264\334\241",
21.100 - "\334\375",
21.101 - #endif
21.102 - seqsize(4,2) - seqsize(2,2)
21.103 - },
21.104 - {
21.105 - #ifdef SCPACK
21.106 - "load.pri %1!push.pri!load.pri %2!pop.alt!",
21.107 - "load.pri %2!load.alt %1!",
21.108 - #else
21.109 - "\217\264\334\241",
21.110 - "\334\374",
21.111 - #endif
21.112 - seqsize(4,2) - seqsize(2,2)
21.113 - },
21.114 - /* (#1#) The above also occurs with "addr.pri" (array
21.115 - * indexing) as the first line; so that adds 2 cases.
21.116 - */
21.117 - {
21.118 - #ifdef SCPACK
21.119 - "addr.pri %1!push.pri!load.s.pri %2!pop.alt!",
21.120 - "addr.alt %1!load.s.pri %2!",
21.121 - #else
21.122 - "\364\241",
21.123 - "\365",
21.124 - #endif
21.125 - seqsize(4,2) - seqsize(2,2)
21.126 - },
21.127 - {
21.128 - #ifdef SCPACK
21.129 - "addr.pri %1!push.pri!load.pri %2!pop.alt!",
21.130 - "addr.alt %1!load.pri %2!",
21.131 - #else
21.132 - "\265\264\334\241",
21.133 - "\265\243\334",
21.134 - #endif
21.135 - seqsize(4,2) - seqsize(2,2)
21.136 - },
21.137 - /* And the same sequence with const.pri as either the first
21.138 - * or the second load instruction: four more cases.
21.139 - */
21.140 - {
21.141 - #ifdef SCPACK
21.142 - "const.pri %1!push.pri!load.s.pri %2!pop.alt!",
21.143 - "load.s.pri %2!const.alt %1!",
21.144 - #else
21.145 - "\363\241",
21.146 - "\246\356",
21.147 - #endif
21.148 - seqsize(4,2) - seqsize(2,2)
21.149 - },
21.150 - {
21.151 - #ifdef SCPACK
21.152 - "const.pri %1!push.pri!load.pri %2!pop.alt!",
21.153 - "load.pri %2!const.alt %1!",
21.154 - #else
21.155 - "\233\264\334\241",
21.156 - "\334\356",
21.157 - #endif
21.158 - seqsize(4,2) - seqsize(2,2)
21.159 - },
21.160 - {
21.161 - #ifdef SCPACK
21.162 - "load.s.pri %1!push.pri!const.pri %2!pop.alt!",
21.163 - "const.pri %2!load.s.alt %1!",
21.164 - #else
21.165 - "\226\264\344\241",
21.166 - "\344\375",
21.167 - #endif
21.168 - seqsize(4,2) - seqsize(2,2)
21.169 - },
21.170 - {
21.171 - #ifdef SCPACK
21.172 - "load.pri %1!push.pri!const.pri %2!pop.alt!",
21.173 - "const.pri %2!load.alt %1!",
21.174 - #else
21.175 - "\217\264\344\241",
21.176 - "\344\374",
21.177 - #endif
21.178 - seqsize(4,2) - seqsize(2,2)
21.179 - },
21.180 - /* The same as above, but now with "addr.pri" (array
21.181 - * indexing) on the first line and const.pri on
21.182 - * the second.
21.183 - */
21.184 - {
21.185 - #ifdef SCPACK
21.186 - "addr.pri %1!push.pri!const.pri %2!pop.alt!",
21.187 - "addr.alt %1!const.pri %2!",
21.188 - #else
21.189 - "\265\264\344\241",
21.190 - "\265\243\344",
21.191 - #endif
21.192 - seqsize(4,2) - seqsize(2,2)
21.193 - },
21.194 - {
21.195 - #ifdef SCPACK
21.196 - "addr.pri %1!push.pri!zero.pri!pop.alt!",
21.197 - "addr.alt %1!zero.pri!",
21.198 - #else
21.199 - "\265\264\373\241",
21.200 - "\265\243\373",
21.201 - #endif
21.202 - seqsize(4,1) - seqsize(2,1)
21.203 - },
21.204 - /* ??? add references */
21.205 - /* Chained relational operators can contain sequences like:
21.206 - * move.pri load.s.pri n1
21.207 - * push.pri -
21.208 - * load.s.pri n1 -
21.209 - * pop.alt -
21.210 - * The above also accurs for "load.pri" and for "const.pri",
21.211 - * so add another two cases.
21.212 - */
21.213 - {
21.214 - #ifdef SCPACK
21.215 - "move.pri!push.pri!load.s.pri %1!pop.alt!",
21.216 - "load.s.pri %1!",
21.217 - #else
21.218 - "\300\236\244\333\241",
21.219 - "\333",
21.220 - #endif
21.221 - seqsize(4,1) - seqsize(1,1)
21.222 - },
21.223 - {
21.224 - #ifdef SCPACK
21.225 - "move.pri!push.pri!load.pri %1!pop.alt!",
21.226 - "load.pri %1!",
21.227 - #else
21.228 - "\300\236\244\311\241",
21.229 - "\311",
21.230 - #endif
21.231 - seqsize(4,1) - seqsize(1,1)
21.232 - },
21.233 - {
21.234 - #ifdef SCPACK
21.235 - "move.pri!push.pri!const.pri %1!pop.alt!",
21.236 - "const.pri %1!",
21.237 - #else
21.238 - "\300\236\244\330\241",
21.239 - "\330",
21.240 - #endif
21.241 - seqsize(4,1) - seqsize(1,1)
21.242 - },
21.243 - /* More optimizations for chained relational operators; the
21.244 - * continuation sequences can be simplified if they turn out
21.245 - * to be termination sequences:
21.246 - * xchg sless also for sless, sgeq and sleq
21.247 - * sgrtr pop.alt
21.248 - * swap.alt and
21.249 - * and ;$exp
21.250 - * pop.alt -
21.251 - * ;$exp -
21.252 - * --------------------------------------
21.253 - * xchg sless also for sless, sgeq and sleq
21.254 - * sgrtr pop.alt
21.255 - * swap.alt and
21.256 - * and jzer n1
21.257 - * pop.alt -
21.258 - * jzer n1 -
21.259 - * --------------------------------------
21.260 - * xchg jsgeq n1 also for sless, sgeq and sleq
21.261 - * sgrtr ;$exp (occurs for non-chained comparisons)
21.262 - * jzer n1 -
21.263 - * ;$exp -
21.264 - * --------------------------------------
21.265 - * xchg sless also for sless, sgeq and sleq
21.266 - * sgrtr ;$exp (occurs for non-chained comparisons)
21.267 - * ;$exp -
21.268 - */
21.269 - {
21.270 - #ifdef SCPACK
21.271 - "xchg!sgrtr!swap.alt!and!pop.alt!;$exp!",
21.272 - "sless!pop.alt!and!;$exp!",
21.273 - #else
21.274 - "\274\371\237swa\234\337\266\252",
21.275 - "\372\266\337!\252",
21.276 - #endif
21.277 - seqsize(5,0) - seqsize(3,0)
21.278 - },
21.279 - {
21.280 - #ifdef SCPACK
21.281 - "xchg!sless!swap.alt!and!pop.alt!;$exp!",
21.282 - "sgrtr!pop.alt!and!;$exp!",
21.283 - #else
21.284 - "\274\372!swa\234\337\266\252",
21.285 - "\371\237\241\337!\252",
21.286 - #endif
21.287 - seqsize(5,0) - seqsize(3,0)
21.288 - },
21.289 - {
21.290 - #ifdef SCPACK
21.291 - "xchg!sgeq!swap.alt!and!pop.alt!;$exp!",
21.292 - "sleq!pop.alt!and!;$exp!",
21.293 - #else
21.294 - "\274\320\325swa\234\337\266\252",
21.295 - "\321\262\266\337!\252",
21.296 - #endif
21.297 - seqsize(5,0) - seqsize(3,0)
21.298 - },
21.299 - {
21.300 - #ifdef SCPACK
21.301 - "xchg!sleq!swap.alt!and!pop.alt!;$exp!",
21.302 - "sgeq!pop.alt!and!;$exp!",
21.303 - #else
21.304 - "\274\321\325swa\234\337\266\252",
21.305 - "\320\262\266\337!\252",
21.306 - #endif
21.307 - seqsize(5,0) - seqsize(3,0)
21.308 - },
21.309 - {
21.310 - #ifdef SCPACK
21.311 - "xchg!sgrtr!swap.alt!and!pop.alt!jzer %1!",
21.312 - "sless!pop.alt!and!jzer %1!",
21.313 - #else
21.314 - "\274\371\237swa\234\337\266\323",
21.315 - "\372\266\337!\323",
21.316 - #endif
21.317 - seqsize(5,0) - seqsize(3,0)
21.318 - },
21.319 - {
21.320 - #ifdef SCPACK
21.321 - "xchg!sless!swap.alt!and!pop.alt!jzer %1!",
21.322 - "sgrtr!pop.alt!and!jzer %1!",
21.323 - #else
21.324 - "\274\372!swa\234\337\266\323",
21.325 - "\371\237\241\337!\323",
21.326 - #endif
21.327 - seqsize(5,0) - seqsize(3,0)
21.328 - },
21.329 - {
21.330 - #ifdef SCPACK
21.331 - "xchg!sgeq!swap.alt!and!pop.alt!jzer %1!",
21.332 - "sleq!pop.alt!and!jzer %1!",
21.333 - #else
21.334 - "\274\320\325swa\234\337\266\323",
21.335 - "\321\262\266\337!\323",
21.336 - #endif
21.337 - seqsize(5,0) - seqsize(3,0)
21.338 - },
21.339 - {
21.340 - #ifdef SCPACK
21.341 - "xchg!sleq!swap.alt!and!pop.alt!jzer %1!",
21.342 - "sgeq!pop.alt!and!jzer %1!",
21.343 - #else
21.344 - "\274\321\325swa\234\337\266\323",
21.345 - "\320\262\266\337!\323",
21.346 - #endif
21.347 - seqsize(5,0) - seqsize(3,0)
21.348 - },
21.349 - {
21.350 - #ifdef SCPACK
21.351 - "xchg!sgrtr!jzer %1!;$exp!",
21.352 - "jsgeq %1!;$exp!",
21.353 - #else
21.354 - "\274\371\237\303\301",
21.355 - "j\320\262\301",
21.356 - #endif
21.357 - seqsize(3,1) - seqsize(1,1)
21.358 - },
21.359 - {
21.360 - #ifdef SCPACK
21.361 - "xchg!sless!jzer %1!;$exp!",
21.362 - "jsleq %1!;$exp!",
21.363 - #else
21.364 - "\274\372!\303\301",
21.365 - "j\321\262\301",
21.366 - #endif
21.367 - seqsize(3,1) - seqsize(1,1)
21.368 - },
21.369 - {
21.370 - #ifdef SCPACK
21.371 - "xchg!sgeq!jzer %1!;$exp!",
21.372 - "jsgrtr %1!;$exp!",
21.373 - #else
21.374 - "\274\320\325\303\301",
21.375 - "j\371r\301",
21.376 - #endif
21.377 - seqsize(3,1) - seqsize(1,1)
21.378 - },
21.379 - {
21.380 - #ifdef SCPACK
21.381 - "xchg!sleq!jzer %1!;$exp!",
21.382 - "jsless %1!;$exp!",
21.383 - #else
21.384 - "\274\321\325\303\301",
21.385 - "j\372\301",
21.386 - #endif
21.387 - seqsize(3,1) - seqsize(1,1)
21.388 - },
21.389 - {
21.390 - #ifdef SCPACK
21.391 - "xchg!sgrtr!;$exp!",
21.392 - "sless!;$exp!",
21.393 - #else
21.394 - "\274\371\237\252",
21.395 - "\372!\252",
21.396 - #endif
21.397 - seqsize(2,0) - seqsize(1,0)
21.398 - },
21.399 - {
21.400 - #ifdef SCPACK
21.401 - "xchg!sless!;$exp!",
21.402 - "sgrtr!;$exp!",
21.403 - #else
21.404 - "\274\372!\252",
21.405 - "\371\237\252",
21.406 - #endif
21.407 - seqsize(2,0) - seqsize(1,0)
21.408 - },
21.409 - {
21.410 - #ifdef SCPACK
21.411 - "xchg!sgeq!;$exp!",
21.412 - "sleq!;$exp!",
21.413 - #else
21.414 - "\274\320\325\252",
21.415 - "\321\325\252",
21.416 - #endif
21.417 - seqsize(2,0) - seqsize(1,0)
21.418 - },
21.419 - {
21.420 - #ifdef SCPACK
21.421 - "xchg!sleq!;$exp!",
21.422 - "sgeq!;$exp!",
21.423 - #else
21.424 - "\274\321\325\252",
21.425 - "\320\325\252",
21.426 - #endif
21.427 - seqsize(2,0) - seqsize(1,0)
21.428 - },
21.429 - /* The entry to chained operators is also opt to optimization
21.430 - * load.s.pri n1 load.s.pri n2
21.431 - * load.s.alt n2 load.s.alt n1
21.432 - * xchg -
21.433 - * --------------------------------------
21.434 - * load.s.pri n1 load.pri n2
21.435 - * load.alt n2 load.s.alt n1
21.436 - * xchg -
21.437 - * --------------------------------------
21.438 - * load.s.pri n1 const.pri n2
21.439 - * const.alt n2 load.s.alt n1
21.440 - * xchg -
21.441 - * --------------------------------------
21.442 - * and all permutations...
21.443 - */
21.444 - {
21.445 - #ifdef SCPACK
21.446 - "load.s.pri %1!load.s.alt %2!xchg!",
21.447 - "load.s.pri %2!load.s.alt %1!",
21.448 - #else
21.449 - "\333\226\304\274",
21.450 - "\246\375",
21.451 - #endif
21.452 - seqsize(3,2) - seqsize(2,2)
21.453 - },
21.454 - {
21.455 - #ifdef SCPACK
21.456 - "load.s.pri %1!load.alt %2!xchg!",
21.457 - "load.pri %2!load.s.alt %1!",
21.458 - #else
21.459 - "\333\362\274",
21.460 - "\334\375",
21.461 - #endif
21.462 - seqsize(3,2) - seqsize(2,2)
21.463 - },
21.464 - {
21.465 - #ifdef SCPACK
21.466 - "load.s.pri %1!const.alt %2!xchg!",
21.467 - "const.pri %2!load.s.alt %1!",
21.468 - #else
21.469 - "\333\233\304\274",
21.470 - "\344\375",
21.471 - #endif
21.472 - seqsize(3,2) - seqsize(2,2)
21.473 - },
21.474 - {
21.475 - #ifdef SCPACK
21.476 - "load.pri %1!load.s.alt %2!xchg!",
21.477 - "load.s.pri %2!load.alt %1!",
21.478 - #else
21.479 - "\311\226\304\274",
21.480 - "\246\374",
21.481 - #endif
21.482 - seqsize(3,2) - seqsize(2,2)
21.483 - },
21.484 - {
21.485 - #ifdef SCPACK
21.486 - "load.pri %1!load.alt %2!xchg!",
21.487 - "load.pri %2!load.alt %1!",
21.488 - #else
21.489 - "\311\362\274",
21.490 - "\334\374",
21.491 - #endif
21.492 - seqsize(3,2) - seqsize(2,2)
21.493 - },
21.494 - {
21.495 - #ifdef SCPACK
21.496 - "load.pri %1!const.alt %2!xchg!",
21.497 - "const.pri %2!load.alt %1!",
21.498 - #else
21.499 - "\311\233\304\274",
21.500 - "\344\374",
21.501 - #endif
21.502 - seqsize(3,2) - seqsize(2,2)
21.503 - },
21.504 - {
21.505 - #ifdef SCPACK
21.506 - "const.pri %1!load.s.alt %2!xchg!",
21.507 - "load.s.pri %2!const.alt %1!",
21.508 - #else
21.509 - "\330\226\304\274",
21.510 - "\246\356",
21.511 - #endif
21.512 - seqsize(3,2) - seqsize(2,2)
21.513 - },
21.514 - {
21.515 - #ifdef SCPACK
21.516 - "const.pri %1!load.alt %2!xchg!",
21.517 - "load.pri %2!const.alt %1!",
21.518 - #else
21.519 - "\330\362\274",
21.520 - "\334\356",
21.521 - #endif
21.522 - seqsize(3,2) - seqsize(2,2)
21.523 - },
21.524 - /* some sequences where PRI is moved to ALT can be optimized
21.525 - * further when considering what follows
21.526 - * move.alt const.alt n1
21.527 - * const.pri %1 -
21.528 - * xchg -
21.529 - * (also for load.s.pri and load.pri)
21.530 - * --------------------------------------
21.531 - * lref.pri %1 lref.alt %1
21.532 - * move.alt [load.pri %2]
21.533 - * [load.pri %2] -
21.534 - * (where [load.pri %2] may also be another operatrion loading PRI)
21.535 - */
21.536 - {
21.537 - #ifdef SCPACK
21.538 - "move.alt!const.pri %1!xchg!",
21.539 - "const.alt %1!",
21.540 - #else
21.541 - "\306\330\274",
21.542 - "\356",
21.543 - #endif
21.544 - seqsize(3,1) - seqsize(1,1)
21.545 - },
21.546 - {
21.547 - #ifdef SCPACK
21.548 - "move.alt!load.pri %1!xchg!",
21.549 - "load.alt %1!",
21.550 - #else
21.551 - "\306\311\274",
21.552 - "\374",
21.553 - #endif
21.554 - seqsize(3,1) - seqsize(1,1)
21.555 - },
21.556 - {
21.557 - #ifdef SCPACK
21.558 - "move.alt!load.s.pri %1!xchg!",
21.559 - "load.s.alt %1!",
21.560 - #else
21.561 - "\306\333\274",
21.562 - "\375",
21.563 - #endif
21.564 - seqsize(3,1) - seqsize(1,1)
21.565 - },
21.566 - /* ----- */
21.567 - {
21.568 - #ifdef SCPACK
21.569 - "lref.pri %1!move.alt!load.pri %2!",
21.570 - "lref.alt %1!load.pri %2!",
21.571 - #else
21.572 - "\350\225\306\334",
21.573 - "\350\243\334",
21.574 - #endif
21.575 - seqsize(3,2) - seqsize(2,2)
21.576 - },
21.577 - {
21.578 - #ifdef SCPACK
21.579 - "lref.pri %1!move.alt!load.s.pri %2!",
21.580 - "lref.alt %1!load.s.pri %2!",
21.581 - #else
21.582 - "\350\225\306\246",
21.583 - "\350\310",
21.584 - #endif
21.585 - seqsize(3,2) - seqsize(2,2)
21.586 - },
21.587 - {
21.588 - #ifdef SCPACK
21.589 - "lref.pri %1!move.alt!const.pri %2!",
21.590 - "lref.alt %1!const.pri %2!",
21.591 - #else
21.592 - "\350\225\306\344",
21.593 - "\350\243\344",
21.594 - #endif
21.595 - seqsize(3,2) - seqsize(2,2)
21.596 - },
21.597 - {
21.598 - #ifdef SCPACK
21.599 - "lref.s.pri %1!move.alt!load.pri %2!",
21.600 - "lref.s.alt %1!load.pri %2!",
21.601 - #else
21.602 - "\350\222\225\306\334",
21.603 - "\350\222\243\334",
21.604 - #endif
21.605 - seqsize(3,2) - seqsize(2,2)
21.606 - },
21.607 - {
21.608 - #ifdef SCPACK
21.609 - "lref.s.pri %1!move.alt!load.s.pri %2!",
21.610 - "lref.s.alt %1!load.s.pri %2!",
21.611 - #else
21.612 - "\350\222\225\306\246",
21.613 - "\350\222\310",
21.614 - #endif
21.615 - seqsize(3,2) - seqsize(2,2)
21.616 - },
21.617 - {
21.618 - #ifdef SCPACK
21.619 - "lref.s.pri %1!move.alt!const.pri %2!",
21.620 - "lref.s.alt %1!const.pri %2!",
21.621 - #else
21.622 - "\350\222\225\306\344",
21.623 - "\350\222\243\344",
21.624 - #endif
21.625 - seqsize(3,2) - seqsize(2,2)
21.626 - },
21.627 - /* Array indexing can merit from special instructions.
21.628 - * Simple indexed array lookup can be optimized quite
21.629 - * a bit.
21.630 - * addr.pri n1 addr.alt n1
21.631 - * push.pri load.s.pri n2
21.632 - * load.s.pri n2 bounds n3
21.633 - * bounds n3 lidx.b n4
21.634 - * shl.c.pri n4 -
21.635 - * pop.alt -
21.636 - * add -
21.637 - * load.i -
21.638 - *
21.639 - * And to prepare for storing a value in an array
21.640 - * addr.pri n1 addr.alt n1
21.641 - * push.pri load.s.pri n2
21.642 - * load.s.pri n2 bounds n3
21.643 - * bounds n3 idxaddr.b n4
21.644 - * shl.c.pri n4 -
21.645 - * pop.alt -
21.646 - * add -
21.647 - *
21.648 - * Notes (additional cases):
21.649 - * 1. instruction addr.pri can also be const.pri (for
21.650 - * global arrays)
21.651 - * 2. the bounds instruction can be absent
21.652 - * 3. when "n4" (the shift value) is the 2 (with 32-bit cells), use the
21.653 - * even more optimal instructions LIDX and IDDXADDR
21.654 - *
21.655 - * If the array index is more complex, one can only optimize
21.656 - * the last four instructions:
21.657 - * shl.c.pri n1 pop.alt
21.658 - * pop.alt lidx.b n1
21.659 - * add -
21.660 - * loadi -
21.661 - * --------------------------------------
21.662 - * shl.c.pri n1 pop.alt
21.663 - * pop.alt idxaddr.b n1
21.664 - * add -
21.665 - */
21.666 -#if !defined BIT16
21.667 - /* loading from array, "cell" shifted */
21.668 - {
21.669 - #ifdef SCPACK
21.670 - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!load.i!",
21.671 - "addr.alt %1!load.s.pri %2!bounds %3!lidx!",
21.672 - #else
21.673 - "\364\316\370\342\355",
21.674 - "\365\316\366!",
21.675 - #endif
21.676 - seqsize(8,4) - seqsize(4,3)
21.677 - },
21.678 - {
21.679 - #ifdef SCPACK
21.680 - "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!load.i!",
21.681 - "const.alt %1!load.s.pri %2!bounds %3!lidx!",
21.682 - #else
21.683 - "\363\316\370\342\355",
21.684 - "\376\316\366!",
21.685 - #endif
21.686 - seqsize(8,4) - seqsize(4,3)
21.687 - },
21.688 - {
21.689 - #ifdef SCPACK
21.690 - "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!load.i!",
21.691 - "addr.alt %1!load.s.pri %2!lidx!",
21.692 - #else
21.693 - "\364\370\342\355",
21.694 - "\365\366!",
21.695 - #endif
21.696 - seqsize(7,3) - seqsize(3,2)
21.697 - },
21.698 - {
21.699 - #ifdef SCPACK
21.700 - "const.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!load.i!",
21.701 - "const.alt %1!load.s.pri %2!lidx!",
21.702 - #else
21.703 - "\363\370\342\355",
21.704 - "\376\366!",
21.705 - #endif
21.706 - seqsize(7,3) - seqsize(3,2)
21.707 - },
21.708 -#endif
21.709 - /* loading from array, not "cell" shifted */
21.710 - {
21.711 - #ifdef SCPACK
21.712 - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!load.i!",
21.713 - "addr.alt %1!load.s.pri %2!bounds %3!lidx.b %4!",
21.714 - #else
21.715 - "\364\316\327\302\341\342\355",
21.716 - "\365\316\366\367\335",
21.717 - #endif
21.718 - seqsize(8,4) - seqsize(4,4)
21.719 - },
21.720 - {
21.721 - #ifdef SCPACK
21.722 - "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!load.i!",
21.723 - "const.alt %1!load.s.pri %2!bounds %3!lidx.b %4!",
21.724 - #else
21.725 - "\363\316\327\302\341\342\355",
21.726 - "\376\316\366\367\335",
21.727 - #endif
21.728 - seqsize(8,4) - seqsize(4,4)
21.729 - },
21.730 - {
21.731 - #ifdef SCPACK
21.732 - "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!load.i!",
21.733 - "addr.alt %1!load.s.pri %2!lidx.b %3!",
21.734 - #else
21.735 - "\364\327\256\241\271\342\355",
21.736 - "\365\366\367\256",
21.737 - #endif
21.738 - seqsize(7,3) - seqsize(3,3)
21.739 - },
21.740 - {
21.741 - #ifdef SCPACK
21.742 - "const.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!load.i!",
21.743 - "const.alt %1!load.s.pri %2!lidx.b %3!",
21.744 - #else
21.745 - "\363\327\256\241\271\342\355",
21.746 - "\376\366\367\256",
21.747 - #endif
21.748 - seqsize(7,3) - seqsize(3,3)
21.749 - },
21.750 -#if !defined BIT16
21.751 - /* array index calculation for storing a value, "cell" aligned */
21.752 - {
21.753 - #ifdef SCPACK
21.754 - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!",
21.755 - "addr.alt %1!load.s.pri %2!bounds %3!idxaddr!",
21.756 - #else
21.757 - "\364\316\370",
21.758 - "\365\316\322\235\237",
21.759 - #endif
21.760 - seqsize(7,4) - seqsize(4,3)
21.761 - },
21.762 - {
21.763 - #ifdef SCPACK
21.764 - "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!",
21.765 - "const.alt %1!load.s.pri %2!bounds %3!idxaddr!",
21.766 - #else
21.767 - "\363\316\370",
21.768 - "\376\316\322\235\237",
21.769 - #endif
21.770 - seqsize(7,4) - seqsize(4,3)
21.771 - },
21.772 - {
21.773 - #ifdef SCPACK
21.774 - "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!",
21.775 - "addr.alt %1!load.s.pri %2!idxaddr!",
21.776 - #else
21.777 - "\364\370",
21.778 - "\365\322\235\237",
21.779 - #endif
21.780 - seqsize(6,3) - seqsize(3,2)
21.781 - },
21.782 - {
21.783 - #ifdef SCPACK
21.784 - "const.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!",
21.785 - "const.alt %1!load.s.pri %2!idxaddr!",
21.786 - #else
21.787 - "\363\370",
21.788 - "\376\322\235\237",
21.789 - #endif
21.790 - seqsize(6,3) - seqsize(3,2)
21.791 - },
21.792 -#endif
21.793 - /* array index calculation for storing a value, not "cell" packed */
21.794 - {
21.795 - #ifdef SCPACK
21.796 - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!",
21.797 - "addr.alt %1!load.s.pri %2!bounds %3!idxaddr.b %4!",
21.798 - #else
21.799 - "\364\316\327\302\341",
21.800 - "\365\316\322\265\367\335",
21.801 - #endif
21.802 - seqsize(7,4) - seqsize(4,4)
21.803 - },
21.804 - {
21.805 - #ifdef SCPACK
21.806 - "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!",
21.807 - "const.alt %1!load.s.pri %2!bounds %3!idxaddr.b %4!",
21.808 - #else
21.809 - "\363\316\327\302\341",
21.810 - "\376\316\322\265\367\335",
21.811 - #endif
21.812 - seqsize(7,4) - seqsize(4,4)
21.813 - },
21.814 - {
21.815 - #ifdef SCPACK
21.816 - "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!",
21.817 - "addr.alt %1!load.s.pri %2!idxaddr.b %3!",
21.818 - #else
21.819 - "\364\327\256\241\271",
21.820 - "\365\322\265\367\256",
21.821 - #endif
21.822 - seqsize(6,3) - seqsize(3,3)
21.823 - },
21.824 - {
21.825 - #ifdef SCPACK
21.826 - "const.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!",
21.827 - "const.alt %1!load.s.pri %2!idxaddr.b %3!",
21.828 - #else
21.829 - "\363\327\256\241\271",
21.830 - "\376\322\265\367\256",
21.831 - #endif
21.832 - seqsize(6,3) - seqsize(3,3)
21.833 - },
21.834 -#if !defined BIT16
21.835 - /* the shorter array indexing sequences, see above for comments */
21.836 - {
21.837 - #ifdef SCPACK
21.838 - "shl.c.pri 2!pop.alt!add!loadi!",
21.839 - "pop.alt!lidx!",
21.840 - #else
21.841 - "\370\217\355",
21.842 - "\241\366!",
21.843 - #endif
21.844 - seqsize(4,1) - seqsize(2,0)
21.845 - },
21.846 - {
21.847 - #ifdef SCPACK
21.848 - "shl.c.pri 2!pop.alt!add!",
21.849 - "pop.alt!idxaddr!",
21.850 - #else
21.851 - "\370",
21.852 - "\241\322\235\237",
21.853 - #endif
21.854 - seqsize(3,1) - seqsize(2,0)
21.855 - },
21.856 -#endif
21.857 - {
21.858 - #ifdef SCPACK
21.859 - "shl.c.pri %1!pop.alt!add!loadi!",
21.860 - "pop.alt!lidx.b %1!",
21.861 - #else
21.862 - "\314\225\241\271\217\355",
21.863 - "\241\366\367\202",
21.864 - #endif
21.865 - seqsize(4,1) - seqsize(2,1)
21.866 - },
21.867 - {
21.868 - #ifdef SCPACK
21.869 - "shl.c.pri %1!pop.alt!add!",
21.870 - "pop.alt!idxaddr.b %1!",
21.871 - #else
21.872 - "\314\225\241\271",
21.873 - "\241\322\265\367\202",
21.874 - #endif
21.875 - seqsize(3,1) - seqsize(2,1)
21.876 - },
21.877 - /* For packed arrays, there is another case (packed arrays
21.878 - * do not take advantage of the LIDX or IDXADDR instructions).
21.879 - * addr.pri n1 addr.alt n1
21.880 - * push.pri load.s.pri n2
21.881 - * load.s.pri n2 bounds n3
21.882 - * bounds n3 -
21.883 - * pop.alt -
21.884 - *
21.885 - * Notes (additional cases):
21.886 - * 1. instruction addr.pri can also be const.pri (for
21.887 - * global arrays)
21.888 - * 2. the bounds instruction can be absent, but that
21.889 - * case is already handled (see #1#)
21.890 - */
21.891 - {
21.892 - #ifdef SCPACK
21.893 - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!pop.alt!",
21.894 - "addr.alt %1!load.s.pri %2!bounds %3!",
21.895 - #else
21.896 - "\364\316\241",
21.897 - "\365\316",
21.898 - #endif
21.899 - seqsize(5,3) - seqsize(3,3)
21.900 - },
21.901 - {
21.902 - #ifdef SCPACK
21.903 - "const.pri %1!push.pri!load.s.pri %2!bounds %3!pop.alt!",
21.904 - "const.alt %1!load.s.pri %2!bounds %3!",
21.905 - #else
21.906 - "\363\316\241",
21.907 - "\376\316",
21.908 - #endif
21.909 - seqsize(5,3) - seqsize(3,3)
21.910 - },
21.911 - /* Declaration of simple variables often follows the sequence:
21.912 - * ;$lcl <name> <stk> ;$lcl <name> <stk>
21.913 - * stack -4 push.c <constval>
21.914 - * const.pri <constval> ;$exp
21.915 - * stor.s.pri <stk> -
21.916 - * ;$exp -
21.917 - */
21.918 - {
21.919 - #ifdef SCPACK
21.920 - ";$lcl %1 %2!stack -4!const.pri %3!stor.s.pri %2!;$exp!",
21.921 - ";$lcl %1 %2!push.c %3!;$exp!",
21.922 - #else
21.923 - "\224lcl\332\227ack -4!\233\206\256\227or\222\230\252",
21.924 - "\224lcl\332\331\256\252",
21.925 - #endif
21.926 - seqsize(3,3) - seqsize(1,1)
21.927 - },
21.928 - {
21.929 - #ifdef SCPACK
21.930 - ";$lcl %1 %2!stack -4!zero.pri!stor.s.pri %2!;$exp!",
21.931 - ";$lcl %1 %2!push.c 0!;$exp!",
21.932 - #else
21.933 - "\224lcl\332\227ack -4!\373\227or\222\230\252",
21.934 - "\224lcl\332\331 0!\252",
21.935 - #endif
21.936 - seqsize(3,2) - seqsize(1,1)
21.937 - },
21.938 - /* During a calculation, the intermediate result must sometimes
21.939 - * be moved from PRI to ALT, like in:
21.940 - * push.pri move.alt
21.941 - * load.s.pri n1 load.s.pri n1
21.942 - * pop.alt -
21.943 - *
21.944 - * The above also accurs for "load.pri" and for "const.pri",
21.945 - * so add another two cases.
21.946 - */
21.947 - {
21.948 - #ifdef SCPACK
21.949 - "push.pri!load.s.pri %1!pop.alt!",
21.950 - "move.alt!load.s.pri %1!",
21.951 - #else
21.952 - "\244\333\241",
21.953 - "\306\333",
21.954 - #endif
21.955 - seqsize(3,1) - seqsize(2,1)
21.956 - },
21.957 - {
21.958 - #ifdef SCPACK
21.959 - "push.pri!load.pri %1!pop.alt!",
21.960 - "move.alt!load.pri %1!",
21.961 - #else
21.962 - "\244\311\241",
21.963 - "\306\311",
21.964 - #endif
21.965 - seqsize(3,1) - seqsize(2,1)
21.966 - },
21.967 - {
21.968 - #ifdef SCPACK
21.969 - "push.pri!const.pri %1!pop.alt!",
21.970 - "move.alt!const.pri %1!",
21.971 - #else
21.972 - "\244\330\241",
21.973 - "\306\330",
21.974 - #endif
21.975 - seqsize(3,1) - seqsize(2,1)
21.976 - },
21.977 - {
21.978 - #ifdef SCPACK
21.979 - "push.pri!zero.pri!pop.alt!",
21.980 - "move.alt!zero.pri!",
21.981 - #else
21.982 - "\244\373\241",
21.983 - "\306\373",
21.984 - #endif
21.985 - seqsize(3,0) - seqsize(2,0)
21.986 - },
21.987 - /* saving PRI and then loading from its address
21.988 - * occurs when indexing a multi-dimensional array
21.989 - */
21.990 - {
21.991 - #ifdef SCPACK
21.992 - "push.pri!load.i!pop.alt!",
21.993 - "move.alt!load.i!",
21.994 - #else
21.995 - "\244\342i\266",
21.996 - "\306\342\355",
21.997 - #endif
21.998 - seqsize(3,0) - seqsize(2,0)
21.999 - },
21.1000 - /* An even simpler PUSH/POP optimization (occurs in
21.1001 - * switch statements):
21.1002 - * push.pri move.alt
21.1003 - * pop.alt -
21.1004 - */
21.1005 - {
21.1006 - #ifdef SCPACK
21.1007 - "push.pri!pop.alt!",
21.1008 - "move.alt!",
21.1009 - #else
21.1010 - "\244\241",
21.1011 - "\306",
21.1012 - #endif
21.1013 - seqsize(2,0) - seqsize(1,0)
21.1014 - },
21.1015 - /* Some simple arithmetic sequences
21.1016 - */
21.1017 - {
21.1018 - #ifdef SCPACK
21.1019 - "move.alt!load.s.pri %1!add!",
21.1020 - "load.s.alt %1!add!",
21.1021 - #else
21.1022 - "\306\333\271",
21.1023 - "\375\271",
21.1024 - #endif
21.1025 - seqsize(3,1) - seqsize(2,1)
21.1026 - },
21.1027 - {
21.1028 - #ifdef SCPACK
21.1029 - "move.alt!load.pri %1!add!",
21.1030 - "load.alt %1!add!",
21.1031 - #else
21.1032 - "\306\311\271",
21.1033 - "\374\271",
21.1034 - #endif
21.1035 - seqsize(3,1) - seqsize(2,1)
21.1036 - },
21.1037 - {
21.1038 - #ifdef SCPACK
21.1039 - "move.alt!const.pri %1!add!",
21.1040 - "const.alt %1!add!",
21.1041 - #else
21.1042 - "\306\330\271",
21.1043 - "\356\271",
21.1044 - #endif
21.1045 - seqsize(3,1) - seqsize(2,1)
21.1046 - },
21.1047 - {
21.1048 - #ifdef SCPACK
21.1049 - "move.alt!load.s.pri %1!sub.alt!",
21.1050 - "load.s.alt %1!sub!",
21.1051 - #else
21.1052 - "\306\333sub\223",
21.1053 - "\375sub!",
21.1054 - #endif
21.1055 - seqsize(3,1) - seqsize(2,1)
21.1056 - },
21.1057 - {
21.1058 - #ifdef SCPACK
21.1059 - "move.alt!load.pri %1!sub.alt!",
21.1060 - "load.alt %1!sub!",
21.1061 - #else
21.1062 - "\306\311sub\223",
21.1063 - "\374sub!",
21.1064 - #endif
21.1065 - seqsize(3,1) - seqsize(2,1)
21.1066 - },
21.1067 - {
21.1068 - #ifdef SCPACK
21.1069 - "move.alt!const.pri %1!sub.alt!",
21.1070 - "const.alt %1!sub!",
21.1071 - #else
21.1072 - "\306\330sub\223",
21.1073 - "\356sub!",
21.1074 - #endif
21.1075 - seqsize(3,1) - seqsize(2,1)
21.1076 - },
21.1077 - /* User-defined operators first load the operands into registers and
21.1078 - * then have them pushed onto the stack. This can give rise to sequences
21.1079 - * like:
21.1080 - * const.pri n1 push.c n1
21.1081 - * const.alt n2 push.c n2
21.1082 - * push.pri -
21.1083 - * push.alt -
21.1084 - * A similar sequence occurs with the two PUSH.pri/alt instructions inverted.
21.1085 - * The first, second, or both CONST.pri/alt instructions can also be
21.1086 - * LOAD.pri/alt.
21.1087 - * This gives 2 x 4 cases.
21.1088 - */
21.1089 - {
21.1090 - #ifdef SCPACK
21.1091 - "const.pri %1!const.alt %2!push.pri!push.alt!",
21.1092 - "push.c %1!push.c %2!",
21.1093 - #else
21.1094 - "\330\233\304\244\354",
21.1095 - "\331\202\331\221",
21.1096 - #endif
21.1097 - seqsize(4,2) - seqsize(2,2)
21.1098 - },
21.1099 - {
21.1100 - #ifdef SCPACK
21.1101 - "const.pri %1!const.alt %2!push.alt!push.pri!",
21.1102 - "push.c %2!push.c %1!",
21.1103 - #else
21.1104 - "\330\233\304\354\244",
21.1105 - "\331\221\331\202",
21.1106 - #endif
21.1107 - seqsize(4,2) - seqsize(2,2)
21.1108 - },
21.1109 - {
21.1110 - #ifdef SCPACK
21.1111 - "const.pri %1!load.alt %2!push.pri!push.alt!",
21.1112 - "push.c %1!push %2!",
21.1113 - #else
21.1114 - "\330\362\244\354",
21.1115 - "\331\202\216\221",
21.1116 - #endif
21.1117 - seqsize(4,2) - seqsize(2,2)
21.1118 - },
21.1119 - {
21.1120 - #ifdef SCPACK
21.1121 - "const.pri %1!load.alt %2!push.alt!push.pri!",
21.1122 - "push %2!push.c %1!",
21.1123 - #else
21.1124 - "\330\362\354\244",
21.1125 - "\216\221\331\202",
21.1126 - #endif
21.1127 - seqsize(4,2) - seqsize(2,2)
21.1128 - },
21.1129 - {
21.1130 - #ifdef SCPACK
21.1131 - "load.pri %1!const.alt %2!push.pri!push.alt!",
21.1132 - "push %1!push.c %2!",
21.1133 - #else
21.1134 - "\311\233\304\244\354",
21.1135 - "\216\202\331\221",
21.1136 - #endif
21.1137 - seqsize(4,2) - seqsize(2,2)
21.1138 - },
21.1139 - {
21.1140 - #ifdef SCPACK
21.1141 - "load.pri %1!const.alt %2!push.alt!push.pri!",
21.1142 - "push.c %2!push %1!",
21.1143 - #else
21.1144 - "\311\233\304\354\244",
21.1145 - "\331\221\216\202",
21.1146 - #endif
21.1147 - seqsize(4,2) - seqsize(2,2)
21.1148 - },
21.1149 - {
21.1150 - #ifdef SCPACK
21.1151 - "load.pri %1!load.alt %2!push.pri!push.alt!",
21.1152 - "push %1!push %2!",
21.1153 - #else
21.1154 - "\311\362\244\354",
21.1155 - "\216\202\216\221",
21.1156 - #endif
21.1157 - seqsize(4,2) - seqsize(2,2)
21.1158 - },
21.1159 - {
21.1160 - #ifdef SCPACK
21.1161 - "load.pri %1!load.alt %2!push.alt!push.pri!",
21.1162 - "push %2!push %1!",
21.1163 - #else
21.1164 - "\311\362\354\244",
21.1165 - "\216\221\216\202",
21.1166 - #endif
21.1167 - seqsize(4,2) - seqsize(2,2)
21.1168 - },
21.1169 - /* Function calls (parameters are passed on the stack)
21.1170 - * load.s.pri n1 push.s n1
21.1171 - * push.pri -
21.1172 - * --------------------------------------
21.1173 - * load.pri n1 push n1
21.1174 - * push.pri -
21.1175 - * --------------------------------------
21.1176 - * const.pri n1 push.c n1
21.1177 - * push.pri -
21.1178 - * --------------------------------------
21.1179 - * zero.pri push.c 0
21.1180 - * push.pri -
21.1181 - * --------------------------------------
21.1182 - * addr.pri n1 push.adr n1
21.1183 - * push.pri -
21.1184 - *
21.1185 - * However, PRI must not be needed after this instruction
21.1186 - * if this shortcut is used. Check for the ;$par comment.
21.1187 - */
21.1188 - {
21.1189 - #ifdef SCPACK
21.1190 - "load.s.pri %1!push.pri!;$par!",
21.1191 - "push.s %1!;$par!",
21.1192 - #else
21.1193 - "\226\264\255",
21.1194 - "\216\222\202\255",
21.1195 - #endif
21.1196 - seqsize(2,1) - seqsize(1,1)
21.1197 - },
21.1198 - {
21.1199 - #ifdef SCPACK
21.1200 - "load.pri %1!push.pri!;$par!",
21.1201 - "push %1!;$par!",
21.1202 - #else
21.1203 - "\217\264\255",
21.1204 - "\216\202\255",
21.1205 - #endif
21.1206 - seqsize(2,1) - seqsize(1,1)
21.1207 - },
21.1208 - {
21.1209 - #ifdef SCPACK
21.1210 - "const.pri %1!push.pri!;$par!",
21.1211 - "push.c %1!;$par!",
21.1212 - #else
21.1213 - "\233\264\255",
21.1214 - "\331\202\255",
21.1215 - #endif
21.1216 - seqsize(2,1) - seqsize(1,1)
21.1217 - },
21.1218 - {
21.1219 - #ifdef SCPACK
21.1220 - "zero.pri!push.pri!;$par!",
21.1221 - "push.c 0!;$par!",
21.1222 - #else
21.1223 - "\373\244\255",
21.1224 - "\331 0!\255",
21.1225 - #endif
21.1226 - seqsize(2,0) - seqsize(1,1)
21.1227 - },
21.1228 - {
21.1229 - #ifdef SCPACK
21.1230 - "addr.pri %1!push.pri!;$par!",
21.1231 - "push.adr %1!;$par!",
21.1232 - #else
21.1233 - "\265\264\255",
21.1234 - "\216\326\202\255",
21.1235 - #endif
21.1236 - seqsize(2,1) - seqsize(1,1)
21.1237 - },
21.1238 - /* References with a default value generate new cells on the heap
21.1239 - * dynamically. That code often ends with:
21.1240 - * move.pri push.alt
21.1241 - * push.pri -
21.1242 - */
21.1243 - {
21.1244 - #ifdef SCPACK
21.1245 - "move.pri!push.pri!",
21.1246 - "push.alt!",
21.1247 - #else
21.1248 - "\300\236\244",
21.1249 - "\354",
21.1250 - #endif
21.1251 - seqsize(2,0) - seqsize(1,0)
21.1252 - },
21.1253 - /* Simple arithmetic operations on constants. Noteworthy is the
21.1254 - * subtraction of a constant, since it is converted to the addition
21.1255 - * of the inverse value.
21.1256 - * const.alt n1 add.c n1
21.1257 - * add -
21.1258 - * --------------------------------------
21.1259 - * const.alt n1 add.c -n1
21.1260 - * sub -
21.1261 - * --------------------------------------
21.1262 - * const.alt n1 smul.c n1
21.1263 - * smul -
21.1264 - * --------------------------------------
21.1265 - * const.alt n1 eq.c.pri n1
21.1266 - * eq -
21.1267 - */
21.1268 - {
21.1269 - #ifdef SCPACK
21.1270 - "const.alt %1!add!",
21.1271 - "add.c %1!",
21.1272 - #else
21.1273 - "\356\271",
21.1274 - "\235\242\202",
21.1275 - #endif
21.1276 - seqsize(2,1) - seqsize(1,1)
21.1277 - },
21.1278 - {
21.1279 - #ifdef SCPACK
21.1280 - "const.alt %1!sub!",
21.1281 - "add.c -%1!",
21.1282 - #else
21.1283 - "\356sub!",
21.1284 - "\235\242 -\201",
21.1285 - #endif
21.1286 - seqsize(2,1) - seqsize(1,1)
21.1287 - },
21.1288 - {
21.1289 - #ifdef SCPACK
21.1290 - "const.alt %1!smul!",
21.1291 - "smul.c %1!",
21.1292 - #else
21.1293 - "\356smul!",
21.1294 - "smu\307\202",
21.1295 - #endif
21.1296 - seqsize(2,1) - seqsize(1,1)
21.1297 - },
21.1298 - {
21.1299 - #ifdef SCPACK
21.1300 - "const.alt %1!eq!",
21.1301 - "eq.c.pri %1!",
21.1302 - #else
21.1303 - "\356\325",
21.1304 - "\262\242\225",
21.1305 - #endif
21.1306 - seqsize(2,1) - seqsize(1,1)
21.1307 - },
21.1308 - /* Some operations use the alternative subtraction operation --these
21.1309 - * can also be optimized.
21.1310 - * const.pri n1 load.s.pri n2
21.1311 - * load.s.alt n2 add.c -n1
21.1312 - * sub.alt -
21.1313 - * --------------------------------------
21.1314 - * const.pri n1 load.pri n2
21.1315 - * load.alt n2 add.c -n1
21.1316 - * sub.alt -
21.1317 - */
21.1318 - {
21.1319 - #ifdef SCPACK
21.1320 - "const.pri %1!load.s.alt %2!sub.alt!",
21.1321 - "load.s.pri %2!add.c -%1!",
21.1322 - #else
21.1323 - "\330\226\304sub\223",
21.1324 - "\246\235\242 -\201",
21.1325 - #endif
21.1326 - seqsize(3,2) - seqsize(2,2)
21.1327 - },
21.1328 - {
21.1329 - #ifdef SCPACK
21.1330 - "const.pri %1!load.alt %2!sub.alt!",
21.1331 - "load.pri %2!add.c -%1!",
21.1332 - #else
21.1333 - "\330\362sub\223",
21.1334 - "\334\235\242 -\201",
21.1335 - #endif
21.1336 - seqsize(3,2) - seqsize(2,2)
21.1337 - },
21.1338 - /* With arrays indexed with constants that come from enumerations, it happens
21.1339 - * multiple add.c opcodes follow in sequence.
21.1340 - * add.c n1 add.c n1+n2
21.1341 - * add.c n2 -
21.1342 - */
21.1343 - {
21.1344 - #ifdef SCPACK
21.1345 - "add.c %1!add.c %2!",
21.1346 - "add.c %1+%2!",
21.1347 - #else
21.1348 - "\235\242\202\235\242\221",
21.1349 - "\235\242\267+%2!",
21.1350 - #endif
21.1351 - seqsize(2,2) - seqsize(1,1)
21.1352 - },
21.1353 - /* Compare and jump
21.1354 - * eq jneq n1
21.1355 - * jzer n1 -
21.1356 - * --------------------------------------
21.1357 - * eq jeq n1
21.1358 - * jnz n1 -
21.1359 - * --------------------------------------
21.1360 - * neq jeq n1
21.1361 - * jzer n1 -
21.1362 - * --------------------------------------
21.1363 - * neq jneq n1
21.1364 - * jnz n1 -
21.1365 - * Compares followed by jzer occur much more
21.1366 - * often than compares followed with jnz. So we
21.1367 - * take the easy route here.
21.1368 - * less jgeq n1
21.1369 - * jzer n1 -
21.1370 - * --------------------------------------
21.1371 - * leq jgrtr n1
21.1372 - * jzer n1 -
21.1373 - * --------------------------------------
21.1374 - * grtr jleq n1
21.1375 - * jzer n1 -
21.1376 - * --------------------------------------
21.1377 - * geq jless n1
21.1378 - * jzer n1 -
21.1379 - * --------------------------------------
21.1380 - * sless jsgeq n1
21.1381 - * jzer n1 -
21.1382 - * --------------------------------------
21.1383 - * sleq jsgrtr n1
21.1384 - * jzer n1 -
21.1385 - * --------------------------------------
21.1386 - * sgrtr jsleq n1
21.1387 - * jzer n1 -
21.1388 - * --------------------------------------
21.1389 - * sgeq jsless n1
21.1390 - * jzer n1 -
21.1391 - */
21.1392 - {
21.1393 - #ifdef SCPACK
21.1394 - "eq!jzer %1!",
21.1395 - "jneq %1!",
21.1396 - #else
21.1397 - "\325\323",
21.1398 - "jn\357",
21.1399 - #endif
21.1400 - seqsize(2,1) - seqsize(1,1)
21.1401 - },
21.1402 - {
21.1403 - #ifdef SCPACK
21.1404 - "eq!jnz %1!",
21.1405 - "jeq %1!",
21.1406 - #else
21.1407 - "\325jnz\202",
21.1408 - "j\357",
21.1409 - #endif
21.1410 - seqsize(2,1) - seqsize(1,1)
21.1411 - },
21.1412 - {
21.1413 - #ifdef SCPACK
21.1414 - "neq!jzer %1!",
21.1415 - "jeq %1!",
21.1416 - #else
21.1417 - "n\325\323",
21.1418 - "j\357",
21.1419 - #endif
21.1420 - seqsize(2,1) - seqsize(1,1)
21.1421 - },
21.1422 - {
21.1423 - #ifdef SCPACK
21.1424 - "neq!jnz %1!",
21.1425 - "jneq %1!",
21.1426 - #else
21.1427 - "n\325jnz\202",
21.1428 - "jn\357",
21.1429 - #endif
21.1430 - seqsize(2,1) - seqsize(1,1)
21.1431 - },
21.1432 - {
21.1433 - #ifdef SCPACK
21.1434 - "less!jzer %1!",
21.1435 - "jgeq %1!",
21.1436 - #else
21.1437 - "l\352!\323",
21.1438 - "jg\357",
21.1439 - #endif
21.1440 - seqsize(2,1) - seqsize(1,1)
21.1441 - },
21.1442 - {
21.1443 - #ifdef SCPACK
21.1444 - "leq!jzer %1!",
21.1445 - "jgrtr %1!",
21.1446 - #else
21.1447 - "l\325\323",
21.1448 - "jg\353r\202",
21.1449 - #endif
21.1450 - seqsize(2,1) - seqsize(1,1)
21.1451 - },
21.1452 - {
21.1453 - #ifdef SCPACK
21.1454 - "grtr!jzer %1!",
21.1455 - "jleq %1!",
21.1456 - #else
21.1457 - "g\353\237\323",
21.1458 - "jl\357",
21.1459 - #endif
21.1460 - seqsize(2,1) - seqsize(1,1)
21.1461 - },
21.1462 - {
21.1463 - #ifdef SCPACK
21.1464 - "geq!jzer %1!",
21.1465 - "jless %1!",
21.1466 - #else
21.1467 - "g\325\323",
21.1468 - "jl\352\202",
21.1469 - #endif
21.1470 - seqsize(2,1) - seqsize(1,1)
21.1471 - },
21.1472 - {
21.1473 - #ifdef SCPACK
21.1474 - "sless!jzer %1!",
21.1475 - "jsgeq %1!",
21.1476 - #else
21.1477 - "\372!\323",
21.1478 - "j\320\357",
21.1479 - #endif
21.1480 - seqsize(2,1) - seqsize(1,1)
21.1481 - },
21.1482 - {
21.1483 - #ifdef SCPACK
21.1484 - "sleq!jzer %1!",
21.1485 - "jsgrtr %1!",
21.1486 - #else
21.1487 - "\321\325\323",
21.1488 - "j\371r\202",
21.1489 - #endif
21.1490 - seqsize(2,1) - seqsize(1,1)
21.1491 - },
21.1492 - {
21.1493 - #ifdef SCPACK
21.1494 - "sgrtr!jzer %1!",
21.1495 - "jsleq %1!",
21.1496 - #else
21.1497 - "\371\237\323",
21.1498 - "j\321\357",
21.1499 - #endif
21.1500 - seqsize(2,1) - seqsize(1,1)
21.1501 - },
21.1502 - {
21.1503 - #ifdef SCPACK
21.1504 - "sgeq!jzer %1!",
21.1505 - "jsless %1!",
21.1506 - #else
21.1507 - "\320\325\323",
21.1508 - "j\372\202",
21.1509 - #endif
21.1510 - seqsize(2,1) - seqsize(1,1)
21.1511 - },
21.1512 - /* Test for zero (common case, especially for strings)
21.1513 - * E.g. the test expression of: "for (i=0; str{i}!=0; ++i)"
21.1514 - *
21.1515 - * zero.alt jzer n1
21.1516 - * jeq n1 -
21.1517 - * --------------------------------------
21.1518 - * zero.alt jnz n1
21.1519 - * jneq n1 -
21.1520 - */
21.1521 - {
21.1522 - #ifdef SCPACK
21.1523 - "zero.alt!jeq %1!",
21.1524 - "jzer %1!",
21.1525 - #else
21.1526 - "\340\223j\357",
21.1527 - "\323",
21.1528 - #endif
21.1529 - seqsize(2,1) - seqsize(1,1)
21.1530 - },
21.1531 - {
21.1532 - #ifdef SCPACK
21.1533 - "zero.alt!jneq %1!",
21.1534 - "jnz %1!",
21.1535 - #else
21.1536 - "\340\223jn\357",
21.1537 - "jnz\202",
21.1538 - #endif
21.1539 - seqsize(2,1) - seqsize(1,1)
21.1540 - },
21.1541 - /* Incrementing and decrementing leaves a value in
21.1542 - * in PRI which may not be used (for example, as the
21.1543 - * third expression in a "for" loop).
21.1544 - * inc n1 inc n1 ; ++n
21.1545 - * load.pri n1 ;$exp
21.1546 - * ;$exp -
21.1547 - * --------------------------------------
21.1548 - * load.pri n1 inc n1 ; n++, e.g. "for (n=0; n<10; n++)"
21.1549 - * inc n1 ;$exp
21.1550 - * ;$exp -
21.1551 - * Plus the varieties for stack relative increments
21.1552 - * and decrements.
21.1553 - */
21.1554 - {
21.1555 - #ifdef SCPACK
21.1556 - "inc %1!load.pri %1!;$exp!",
21.1557 - "inc %1!;$exp!",
21.1558 - #else
21.1559 - "inc\202\311\252",
21.1560 - "inc\301",
21.1561 - #endif
21.1562 - seqsize(2,2) - seqsize(1,1)
21.1563 - },
21.1564 - {
21.1565 - #ifdef SCPACK
21.1566 - "load.pri %1!inc %1!;$exp!",
21.1567 - "inc %1!;$exp!",
21.1568 - #else
21.1569 - "\311inc\301",
21.1570 - "inc\301",
21.1571 - #endif
21.1572 - seqsize(2,2) - seqsize(1,1)
21.1573 - },
21.1574 - {
21.1575 - #ifdef SCPACK
21.1576 - "inc.s %1!load.s.pri %1!;$exp!",
21.1577 - "inc.s %1!;$exp!",
21.1578 - #else
21.1579 - "inc\222\202\333\252",
21.1580 - "inc\222\301",
21.1581 - #endif
21.1582 - seqsize(2,2) - seqsize(1,1)
21.1583 - },
21.1584 - {
21.1585 - #ifdef SCPACK
21.1586 - "load.s.pri %1!inc.s %1!;$exp!",
21.1587 - "inc.s %1!;$exp!",
21.1588 - #else
21.1589 - "\333inc\222\301",
21.1590 - "inc\222\301",
21.1591 - #endif
21.1592 - seqsize(2,2) - seqsize(1,1)
21.1593 - },
21.1594 - {
21.1595 - #ifdef SCPACK
21.1596 - "dec %1!load.pri %1!;$exp!",
21.1597 - "dec %1!;$exp!",
21.1598 - #else
21.1599 - "dec\202\311\252",
21.1600 - "dec\301",
21.1601 - #endif
21.1602 - seqsize(2,2) - seqsize(1,1)
21.1603 - },
21.1604 - {
21.1605 - #ifdef SCPACK
21.1606 - "load.pri %1!dec %1!;$exp!",
21.1607 - "dec %1!;$exp!",
21.1608 - #else
21.1609 - "\311dec\301",
21.1610 - "dec\301",
21.1611 - #endif
21.1612 - seqsize(2,2) - seqsize(1,1)
21.1613 - },
21.1614 - {
21.1615 - #ifdef SCPACK
21.1616 - "dec.s %1!load.s.pri %1!;$exp!",
21.1617 - "dec.s %1!;$exp!",
21.1618 - #else
21.1619 - "dec\222\202\333\252",
21.1620 - "dec\222\301",
21.1621 - #endif
21.1622 - seqsize(2,2) - seqsize(1,1)
21.1623 - },
21.1624 - {
21.1625 - #ifdef SCPACK
21.1626 - "load.s.pri %1!dec.s %1!;$exp!",
21.1627 - "dec.s %1!;$exp!",
21.1628 - #else
21.1629 - "\333dec\222\301",
21.1630 - "dec\222\301",
21.1631 - #endif
21.1632 - seqsize(2,2) - seqsize(1,1)
21.1633 - },
21.1634 - /* ??? the same (increments and decrements) for references */
21.1635 - /* Loading the constant zero has a special opcode.
21.1636 - * When storing zero in memory, the value of PRI must not be later on.
21.1637 - * const.pri 0 zero n1
21.1638 - * stor.pri n1 ;$exp
21.1639 - * ;$exp -
21.1640 - * --------------------------------------
21.1641 - * const.pri 0 zero.s n1
21.1642 - * stor.s.pri n1 ;$exp
21.1643 - * ;$exp -
21.1644 - * --------------------------------------
21.1645 - * zero.pri zero n1
21.1646 - * stor.pri n1 ;$exp
21.1647 - * ;$exp -
21.1648 - * --------------------------------------
21.1649 - * zero.pri zero.s n1
21.1650 - * stor.s.pri n1 ;$exp
21.1651 - * ;$exp -
21.1652 - * --------------------------------------
21.1653 - * const.pri 0 zero.pri
21.1654 - * --------------------------------------
21.1655 - * const.alt 0 zero.alt
21.1656 - * The last two alternatives save more memory than they save
21.1657 - * time, but anyway...
21.1658 - */
21.1659 - {
21.1660 - #ifdef SCPACK
21.1661 - "const.pri 0!stor.pri %1!;$exp!",
21.1662 - "zero %1!;$exp!",
21.1663 - #else
21.1664 - "\233\206 0!\227or\225\252",
21.1665 - "\340\301",
21.1666 - #endif
21.1667 - seqsize(2,2) - seqsize(1,1)
21.1668 - },
21.1669 - {
21.1670 - #ifdef SCPACK
21.1671 - "const.pri 0!stor.s.pri %1!;$exp!",
21.1672 - "zero.s %1!;$exp!",
21.1673 - #else
21.1674 - "\233\206 0!\227or\222\225\252",
21.1675 - "\340\222\301",
21.1676 - #endif
21.1677 - seqsize(2,2) - seqsize(1,1)
21.1678 - },
21.1679 - {
21.1680 - #ifdef SCPACK
21.1681 - "zero.pri!stor.pri %1!;$exp!",
21.1682 - "zero %1!;$exp!",
21.1683 - #else
21.1684 - "\373\227or\225\252",
21.1685 - "\340\301",
21.1686 - #endif
21.1687 - seqsize(2,1) - seqsize(1,1)
21.1688 - },
21.1689 - {
21.1690 - #ifdef SCPACK
21.1691 - "zero.pri!stor.s.pri %1!;$exp!",
21.1692 - "zero.s %1!;$exp!",
21.1693 - #else
21.1694 - "\373\227or\222\225\252",
21.1695 - "\340\222\301",
21.1696 - #endif
21.1697 - seqsize(2,1) - seqsize(1,1)
21.1698 - },
21.1699 - {
21.1700 - #ifdef SCPACK
21.1701 - "const.pri 0!",
21.1702 - "zero.pri!",
21.1703 - #else
21.1704 - "\233\206 0!",
21.1705 - "\373",
21.1706 - #endif
21.1707 - seqsize(1,1) - seqsize(1,0)
21.1708 - },
21.1709 - {
21.1710 - #ifdef SCPACK
21.1711 - "const.alt 0!",
21.1712 - "zero.alt!",
21.1713 - #else
21.1714 - "\233\212 0!",
21.1715 - "\340\223",
21.1716 - #endif
21.1717 - seqsize(1,1) - seqsize(1,0)
21.1718 - },
21.1719 -
21.1720 - /* ------------------ */
21.1721 - /* Macro instructions */
21.1722 - /* ------------------ */
21.1723 -
21.1724 - { "", "", 0 }, /* separator, so optimizer can stop before generating macro opcodes */
21.1725 -
21.1726 - /* optimizing the calling of native functions (which always have a parameter
21.1727 - * count pushed before, and the stack pointer restored afterwards
21.1728 - */
21.1729 - {
21.1730 - #ifdef SCPACK
21.1731 - "push.c %1!sysreq.c %2!stack %3!", //note: %3 == %1 + 4
21.1732 - "sysreq.n %2 %1!",
21.1733 - #else
21.1734 - "\331\202sysr\262\242\221\227ack\256",
21.1735 - "sysr\262.n\220\202",
21.1736 - #endif
21.1737 - seqsize(3,3) - seqsize(1,2)
21.1738 - },
21.1739 - /* ----- */
21.1740 - /* Functions with many parameters with the same "type" have sequences like:
21.1741 - * push.c n1 push3.c n1 n2 n3
21.1742 - * ;$par ;$par
21.1743 - * push.c n2 -
21.1744 - * ;$par -
21.1745 - * push.c n3 -
21.1746 - * ;$par -
21.1747 - * etc. etc.
21.1748 - *
21.1749 - * Similar sequences occur with PUSH, PUSH.s and PUSHADDR
21.1750 - */
21.1751 - {
21.1752 - #ifdef SCPACK
21.1753 - "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!push.c %4!;$par!push.c %5!",
21.1754 - "push5.c %1 %2 %3 %4 %5!",
21.1755 - #else
21.1756 - "\331\336\242\345\242\256\257\242\335\257\242\2035!",
21.1757 - "\2165\242\343\245\302\2035!",
21.1758 - #endif
21.1759 - seqsize(5,5) - seqsize(1,5)
21.1760 - },
21.1761 - {
21.1762 - #ifdef SCPACK
21.1763 - "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!push.c %4!",
21.1764 - "push4.c %1 %2 %3 %4!",
21.1765 - #else
21.1766 - "\331\336\242\345\242\256\257\242\335",
21.1767 - "\2164\242\343\245\335",
21.1768 - #endif
21.1769 - seqsize(4,4) - seqsize(1,4)
21.1770 - },
21.1771 - {
21.1772 - #ifdef SCPACK
21.1773 - "push.c %1!;$par!push.c %2!;$par!push.c %3!",
21.1774 - "push3.c %1 %2 %3!",
21.1775 - #else
21.1776 - "\331\336\242\345\242\256",
21.1777 - "\2163\242\343\256",
21.1778 - #endif
21.1779 - seqsize(3,3) - seqsize(1,3)
21.1780 - },
21.1781 - {
21.1782 - #ifdef SCPACK
21.1783 - "push.c %1!;$par!push.c %2!",
21.1784 - "push2.c %1 %2!",
21.1785 - #else
21.1786 - "\331\336\242\221",
21.1787 - "\2162\242\332",
21.1788 - #endif
21.1789 - seqsize(2,2) - seqsize(1,2)
21.1790 - },
21.1791 - /* ----- */
21.1792 - {
21.1793 - #ifdef SCPACK
21.1794 - "push %1!;$par!push %2!;$par!push %3!;$par!push %4!;$par!push %5!",
21.1795 - "push5 %1 %2 %3 %4 %5!",
21.1796 - #else
21.1797 - "\216\336\345\256\257\335\257\2035!",
21.1798 - "\2165\343\245\302\2035!",
21.1799 - #endif
21.1800 - seqsize(5,5) - seqsize(1,5)
21.1801 - },
21.1802 - {
21.1803 - #ifdef SCPACK
21.1804 - "push %1!;$par!push %2!;$par!push %3!;$par!push %4!",
21.1805 - "push4 %1 %2 %3 %4!",
21.1806 - #else
21.1807 - "\216\336\345\256\257\335",
21.1808 - "\2164\343\245\335",
21.1809 - #endif
21.1810 - seqsize(4,4) - seqsize(1,4)
21.1811 - },
21.1812 - {
21.1813 - #ifdef SCPACK
21.1814 - "push %1!;$par!push %2!;$par!push %3!",
21.1815 - "push3 %1 %2 %3!",
21.1816 - #else
21.1817 - "\216\336\345\256",
21.1818 - "\2163\343\256",
21.1819 - #endif
21.1820 - seqsize(3,3) - seqsize(1,3)
21.1821 - },
21.1822 - {
21.1823 - #ifdef SCPACK
21.1824 - "push %1!;$par!push %2!",
21.1825 - "push2 %1 %2!",
21.1826 - #else
21.1827 - "\216\336\221",
21.1828 - "\2162\332",
21.1829 - #endif
21.1830 - seqsize(2,2) - seqsize(1,2)
21.1831 - },
21.1832 - /* ----- */
21.1833 - {
21.1834 - #ifdef SCPACK
21.1835 - "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!push.s %4!;$par!push.s %5!",
21.1836 - "push5.s %1 %2 %3 %4 %5!",
21.1837 - #else
21.1838 - "\216\222\336\222\345\222\256\257\222\335\257\222\2035!",
21.1839 - "\2165\222\343\245\302\2035!",
21.1840 - #endif
21.1841 - seqsize(5,5) - seqsize(1,5)
21.1842 - },
21.1843 - {
21.1844 - #ifdef SCPACK
21.1845 - "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!push.s %4!",
21.1846 - "push4.s %1 %2 %3 %4!",
21.1847 - #else
21.1848 - "\216\222\336\222\345\222\256\257\222\335",
21.1849 - "\2164\222\343\245\335",
21.1850 - #endif
21.1851 - seqsize(4,4) - seqsize(1,4)
21.1852 - },
21.1853 - {
21.1854 - #ifdef SCPACK
21.1855 - "push.s %1!;$par!push.s %2!;$par!push.s %3!",
21.1856 - "push3.s %1 %2 %3!",
21.1857 - #else
21.1858 - "\216\222\336\222\345\222\256",
21.1859 - "\2163\222\343\256",
21.1860 - #endif
21.1861 - seqsize(3,3) - seqsize(1,3)
21.1862 - },
21.1863 - {
21.1864 - #ifdef SCPACK
21.1865 - "push.s %1!;$par!push.s %2!",
21.1866 - "push2.s %1 %2!",
21.1867 - #else
21.1868 - "\216\222\336\222\221",
21.1869 - "\2162\222\332",
21.1870 - #endif
21.1871 - seqsize(2,2) - seqsize(1,2)
21.1872 - },
21.1873 - /* ----- */
21.1874 - {
21.1875 - #ifdef SCPACK
21.1876 - "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!push.adr %4!;$par!push.adr %5!",
21.1877 - "push5.adr %1 %2 %3 %4 %5!",
21.1878 - #else
21.1879 - "\216\326\336\326\345\326\256\257\326\335\257\326\2035!",
21.1880 - "\2165\326\343\245\302\2035!",
21.1881 - #endif
21.1882 - seqsize(5,5) - seqsize(1,5)
21.1883 - },
21.1884 - {
21.1885 - #ifdef SCPACK
21.1886 - "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!push.adr %4!",
21.1887 - "push4.adr %1 %2 %3 %4!",
21.1888 - #else
21.1889 - "\216\326\336\326\345\326\256\257\326\335",
21.1890 - "\2164\326\343\245\335",
21.1891 - #endif
21.1892 - seqsize(4,4) - seqsize(1,4)
21.1893 - },
21.1894 - {
21.1895 - #ifdef SCPACK
21.1896 - "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!",
21.1897 - "push3.adr %1 %2 %3!",
21.1898 - #else
21.1899 - "\216\326\336\326\345\326\256",
21.1900 - "\2163\326\343\256",
21.1901 - #endif
21.1902 - seqsize(3,3) - seqsize(1,3)
21.1903 - },
21.1904 - {
21.1905 - #ifdef SCPACK
21.1906 - "push.adr %1!;$par!push.adr %2!",
21.1907 - "push2.adr %1 %2!",
21.1908 - #else
21.1909 - "\216\326\336\326\221",
21.1910 - "\2162\326\332",
21.1911 - #endif
21.1912 - seqsize(2,2) - seqsize(1,2)
21.1913 - },
21.1914 - /* Loading two registers at a time
21.1915 - * load.pri n1 load.both n1 n2
21.1916 - * load.alt n2 -
21.1917 - * --------------------------------------
21.1918 - * load.alt n2 load.both n1 n2
21.1919 - * load.pri n1 -
21.1920 - * --------------------------------------
21.1921 - * load.s.pri n1 load.s.both n1 n2
21.1922 - * load.s.alt n2 -
21.1923 - * --------------------------------------
21.1924 - * load.s.alt n2 load.s.both n1 n2
21.1925 - * load.s.pri n1 -
21.1926 - */
21.1927 - {
21.1928 - #ifdef SCPACK
21.1929 - "load.pri %1!load.alt %2!",
21.1930 - "load.both %1 %2!",
21.1931 - #else
21.1932 - "\311\362",
21.1933 - "\342\275th\332",
21.1934 - #endif
21.1935 - seqsize(2,2) - seqsize(1,2)
21.1936 - },
21.1937 - {
21.1938 - #ifdef SCPACK
21.1939 - "load.alt %2!load.pri %1!",
21.1940 - "load.both %1 %2!",
21.1941 - #else
21.1942 - "\362\311",
21.1943 - "\342\275th\332",
21.1944 - #endif
21.1945 - seqsize(2,2) - seqsize(1,2)
21.1946 - },
21.1947 - {
21.1948 - #ifdef SCPACK
21.1949 - "load.s.pri %1!load.s.alt %2!",
21.1950 - "load.s.both %1 %2!",
21.1951 - #else
21.1952 - "\333\226\304",
21.1953 - "\226.\275th\332",
21.1954 - #endif
21.1955 - seqsize(2,2) - seqsize(1,2)
21.1956 - },
21.1957 - {
21.1958 - #ifdef SCPACK
21.1959 - "load.s.alt %2!load.s.pri %1!",
21.1960 - "load.s.both %1 %2!",
21.1961 - #else
21.1962 - "\226\304\333",
21.1963 - "\226.\275th\332",
21.1964 - #endif
21.1965 - seqsize(2,2) - seqsize(1,2)
21.1966 - },
21.1967 - /* Loading two registers and then pushing them occurs with user operators
21.1968 - * load.both n1 n2 push2 n1 n2
21.1969 - * push.pri -
21.1970 - * push.alt -
21.1971 - * --------------------------------------
21.1972 - * load.s.both n1 n2 push2.s n1 n2
21.1973 - * push.pri -
21.1974 - * push.alt -
21.1975 - */
21.1976 - {
21.1977 - #ifdef SCPACK
21.1978 - "load.both %1 %2!push.pri!push.alt!",
21.1979 - "push2 %1 %2!",
21.1980 - #else
21.1981 - "\342\275th\332\244\354",
21.1982 - "\2162\332",
21.1983 - #endif
21.1984 - seqsize(3,2) - seqsize(1,2)
21.1985 - },
21.1986 - {
21.1987 - #ifdef SCPACK
21.1988 - "load.s.both %1 %2!push.pri!push.alt!",
21.1989 - "push2.s %1 %2!",
21.1990 - #else
21.1991 - "\226.\275th\332\244\354",
21.1992 - "\2162\222\332",
21.1993 - #endif
21.1994 - seqsize(3,2) - seqsize(1,2)
21.1995 - },
21.1996 - /* Load a constant in a variable
21.1997 - * const.pri n1 const n2 n1
21.1998 - * stor.pri n2 -
21.1999 - * --------------------------------------
21.2000 - * const.pri n1 const.s n2 n1
21.2001 - * stor.s.pri n2 -
21.2002 - */
21.2003 - {
21.2004 - #ifdef SCPACK
21.2005 - "const.pri %1!stor.pri %2!",
21.2006 - "const %2 %1!",
21.2007 - #else
21.2008 - "\330\227or\230",
21.2009 - "\233\220\202",
21.2010 - #endif
21.2011 - seqsize(2,2) - seqsize(1,2)
21.2012 - },
21.2013 - {
21.2014 - #ifdef SCPACK
21.2015 - "const.pri %1!stor.s.pri %2!",
21.2016 - "const.s %2 %1!",
21.2017 - #else
21.2018 - "\330\227or\222\230",
21.2019 - "\233\222\220\202",
21.2020 - #endif
21.2021 - seqsize(2,2) - seqsize(1,2)
21.2022 - },
21.2023 - /* ----- */
21.2024 - { NULL, NULL, 0 }
21.2025 -};
22.1 --- a/compiler-init/scexpand.c Sat Jul 15 05:02:38 2006 +0000
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,68 +0,0 @@
22.4 -/* expand.c -- Byte Pair Encoding decompression */
22.5 -/* Copyright 1996 Philip Gage */
22.6 -
22.7 -/* Byte Pair Compression appeared in the September 1997
22.8 - * issue of C/C++ Users Journal. The original source code
22.9 - * may still be found at the web site of the magazine
22.10 - * (www.cuj.com).
22.11 - *
22.12 - * The decompressor has been modified by me (Thiadmer
22.13 - * Riemersma) to accept a string as input, instead of a
22.14 - * complete file.
22.15 - */
22.16 -#include <assert.h>
22.17 -#include <stdio.h>
22.18 -#include "sc.h"
22.19 -
22.20 -#define STACKSIZE 16
22.21 -
22.22 -SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2])
22.23 -{
22.24 - unsigned char stack[STACKSIZE];
22.25 - short c, top = 0;
22.26 - int len;
22.27 -
22.28 - assert(maxlen > 0);
22.29 - len = 1; /* already 1 byte for '\0' */
22.30 - for (;;) {
22.31 -
22.32 - /* Pop byte from stack or read byte from the input string */
22.33 - if (top)
22.34 - c = stack[--top];
22.35 - else if ((c = *(unsigned char *)source++) == '\0')
22.36 - break;
22.37 -
22.38 - /* Push pair on stack or output byte to the output string */
22.39 - if (c > 127) {
22.40 - assert(top+2 <= STACKSIZE);
22.41 - stack[top++] = pairtable[c-128][1];
22.42 - stack[top++] = pairtable[c-128][0];
22.43 - }
22.44 - else {
22.45 - len++;
22.46 - if (maxlen > 1) { /* reserve one byte for the '\0' */
22.47 - *dest++ = (char)c;
22.48 - maxlen--;
22.49 - }
22.50 - }
22.51 - }
22.52 - *dest = '\0';
22.53 - return len; /* return number of bytes decoded */
22.54 -}
22.55 -
22.56 -#if 0 /*for testing*/
22.57 -#include "sc5.scp"
22.58 -
22.59 -int main (int argc, char **argv)
22.60 -{
22.61 - int i;
22.62 - char str[128];
22.63 -
22.64 - for (i=0; i<58; i++) {
22.65 - strexpand(str, errmsg[i], sizeof str, SCPACK_TABLE);
22.66 - printf("%s", str);
22.67 - } /* for */
22.68 - return 0;
22.69 -}
22.70 -#endif
22.71 -
23.1 --- a/compiler-init/sci18n.c Sat Jul 15 05:02:38 2006 +0000
23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
23.3 @@ -1,428 +0,0 @@
23.4 -/* Codepage translation to Unicode, and UTF-8 support
23.5 - *
23.6 - * The translation is based on codepage mapping files that are distributed
23.7 - * by the Unicode consortium, see ftp://ftp.unicode.org/Public/MAPPINGS/.
23.8 - *
23.9 - * Character sets with a maximum of 256 codes are translated via a lookup
23.10 - * table (these are Single-Byte Character Sets). Character sets like Shift-JIS
23.11 - * with single-byte characters and multi-byte characters (introduced by a
23.12 - * leader byte) are split into two tables: the 256-entry lookup table for
23.13 - * the single-byte characters and an extended table for the multi-byte
23.14 - * characters. The extended table is allocated dynamically; the lookup table
23.15 - * is allocated statically, so loading SBCS tables cannot fail (if the tables
23.16 - * themselves are valid, of course).
23.17 - *
23.18 - * Copyright (c) ITB CompuPhase, 2004-2006
23.19 - *
23.20 - * This software is provided "as-is", without any express or implied warranty.
23.21 - * In no event will the authors be held liable for any damages arising from
23.22 - * the use of this software.
23.23 - *
23.24 - * Permission is granted to anyone to use this software for any purpose,
23.25 - * including commercial applications, and to alter it and redistribute it
23.26 - * freely, subject to the following restrictions:
23.27 - *
23.28 - * 1. The origin of this software must not be misrepresented; you must not
23.29 - * claim that you wrote the original software. If you use this software in
23.30 - * a product, an acknowledgment in the product documentation would be
23.31 - * appreciated but is not required.
23.32 - * 2. Altered source versions must be plainly marked as such, and must not be
23.33 - * misrepresented as being the original software.
23.34 - * 3. This notice may not be removed or altered from any source distribution.
23.35 - *
23.36 - * Version: $Id: CODEPAGE.C,v 1.0 2004-02-18 12:13:04+01 thiadmer Exp thiadmer $
23.37 - */
23.38 -#include <assert.h>
23.39 -#include <stdio.h>
23.40 -#include <stddef.h>
23.41 -#include <stdlib.h>
23.42 -#include <string.h>
23.43 -#include "sc.h"
23.44 -
23.45 -#if !defined TRUE
23.46 - #define FALSE 0
23.47 - #define TRUE 1
23.48 -#endif
23.49 -#if !defined _MAX_PATH
23.50 - #define _MAX_PATH 250
23.51 -#endif
23.52 -#if !defined DIRSEP_CHAR
23.53 - #if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
23.54 - #define DIRSEP_CHAR '/'
23.55 - #elif defined macintosh
23.56 - #define DIRSEP_CHAR ':'
23.57 - #else
23.58 - #define DIRSEP_CHAR '\\'
23.59 - #endif
23.60 -#endif
23.61 -
23.62 -#if !defined ELEMENTS
23.63 - #define ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
23.64 -#endif
23.65 -
23.66 -#if !defined NO_CODEPAGE
23.67 -
23.68 -#if !defined MAXCODEPAGE
23.69 - #define MAXCODEPAGE 12 /* typically "cp" + 4 digits + ".txt" */
23.70 -#endif
23.71 -#define INVALID 0xffffu /* 0xffff and 0xfffe are invalid Unicode characters */
23.72 -#define LEADBYTE 0xfffeu
23.73 -
23.74 -struct wordpair {
23.75 - unsigned short index;
23.76 - wchar_t code;
23.77 -};
23.78 -static char cprootpath[_MAX_PATH] = { DIRSEP_CHAR, '\0' };
23.79 -static wchar_t bytetable[256];
23.80 -static struct wordpair *wordtable = NULL;
23.81 -static unsigned wordtablesize = 0;
23.82 -static unsigned wordtabletop = 0;
23.83 -
23.84 -
23.85 -/* read in a line delimited by '\r' or '\n'; do NOT store the '\r' or '\n' into
23.86 - * the string and ignore empty lines
23.87 - * returns 1 for success and 0 for failure
23.88 - */
23.89 -static int cp_readline(FILE *fp,char *string,size_t size)
23.90 -{
23.91 - size_t count=0;
23.92 - int c;
23.93 - assert(size>1);
23.94 - while ((c=fgetc(fp))!=EOF && count<size-1) {
23.95 - if (c=='\r' || c=='\n') {
23.96 - if (count>0) /* '\r' or '\n' ends a string */
23.97 - break;
23.98 - /* if count==0, the line started with a '\r' or '\n', or perhaps line
23.99 - * ends in the file are '\r\n' and we read and stopped on the '\r' of
23.100 - * the preceding line
23.101 - */
23.102 - } else {
23.103 - string[count++]=(char)c;
23.104 - } /* if */
23.105 - } /* while */
23.106 - string[count]='\0';
23.107 - return count>0;
23.108 -}
23.109 -
23.110 -/* cp_path() sets the directory where all codepage files must be found (if
23.111 - * the parameter to cp_set() specifies a full path, that is used instead).
23.112 - * The path is specified into two parts: root and directory; the full path
23.113 - * for the codepage direcory is just the concatenation of the two, with a
23.114 - * directory separator in between. The directory is given in two parts,
23.115 - * because often a program already retrieves its "home" directory and the
23.116 - * codepages are most conveniently stored in a subdirectory of this home
23.117 - * directory.
23.118 - */
23.119 -SC_FUNC int cp_path(const char *root, const char *directory)
23.120 -{
23.121 - size_t len1,len2;
23.122 - int add_slash1,add_slash2;
23.123 -
23.124 - len1= (root!=NULL) ? strlen(root) : 0;
23.125 - add_slash1= (len1==0 || root[len1-1]!=DIRSEP_CHAR);
23.126 - len2= (directory!=NULL) ? strlen(directory) : 0;
23.127 - add_slash2= (len2>0 && root[len2-1]!=DIRSEP_CHAR);
23.128 - if (len1+add_slash1+len2+add_slash2>=(_MAX_PATH-MAXCODEPAGE))
23.129 - return FALSE; /* full filename may not fit */
23.130 - if (root!=NULL)
23.131 - strcpy(cprootpath,root);
23.132 - if (add_slash1) {
23.133 - assert(len1==0 || cprootpath[len1]=='\0');
23.134 - cprootpath[len1]=DIRSEP_CHAR;
23.135 - cprootpath[len1+1]='\0';
23.136 - } /* if */
23.137 - if (directory!=NULL)
23.138 - strcat(cprootpath,directory);
23.139 - if (add_slash2) {
23.140 - assert(cprootpath[len1+add_slash1+len2]=='\0');
23.141 - cprootpath[len1+add_slash1+len2]=DIRSEP_CHAR;
23.142 - cprootpath[len1+add_slash1+len2+1]='\0';
23.143 - } /* if */
23.144 - cp_set(NULL); /* start with a "linear" table (no translation) */
23.145 - return TRUE;
23.146 -}
23.147 -
23.148 -/* cp_set() loads a codepage from a file. The name parameter may be a
23.149 - * filename (including a full path) or it may be a partial codepage name.
23.150 - * If the name parameter is NULL, the codepage is cleared to be a "linear"
23.151 - * table (no translation).
23.152 - * The following files are attempted to open (where <name> specifies the
23.153 - * value of the parameter):
23.154 - * <name>
23.155 - * <cprootpath>/<name>
23.156 - * <cprootpath>/<name>.txt
23.157 - * <cprootpath>/cp<name>
23.158 - * <cprootpath>/cp<name>.txt
23.159 - */
23.160 -SC_FUNC int cp_set(const char *name)
23.161 -{
23.162 - char filename[_MAX_PATH];
23.163 - FILE *fp=NULL;
23.164 - unsigned index;
23.165 -
23.166 - /* for name==NULL, set up an identity table */
23.167 - if (name==NULL || *name=='\0') {
23.168 - if (wordtable!=NULL) {
23.169 - free(wordtable);
23.170 - wordtable=NULL;
23.171 - wordtablesize=0;
23.172 - wordtabletop=0;
23.173 - } /* if */
23.174 - for (index=0; index<ELEMENTS(bytetable); index++)
23.175 - bytetable[index]=(wchar_t)index;
23.176 - return TRUE;
23.177 - } /* if */
23.178 -
23.179 - /* try to open the file as-is */
23.180 - if (strchr(name,DIRSEP_CHAR)!=NULL)
23.181 - fp=fopen(name,"rt");
23.182 - if (fp==NULL) {
23.183 - /* try opening the file in the "root path" for codepages */
23.184 - if (strlen(name)>MAXCODEPAGE)
23.185 - return 0;
23.186 - assert(strlen(name)+strlen(cprootpath)<_MAX_PATH);
23.187 - strcpy(filename,cprootpath);
23.188 - strcat(filename,name);
23.189 - fp=fopen(filename,"rt");
23.190 - } /* if */
23.191 - if (fp==NULL) {
23.192 - /* try opening the file in the "root path" for codepages, with a ".txt" extension */
23.193 - if (strlen(name)+4>=MAXCODEPAGE)
23.194 - return 0;
23.195 - assert(strlen(filename)+4<_MAX_PATH);
23.196 - strcat(filename,".txt");
23.197 - fp=fopen(filename,"rt");
23.198 - } /* if */
23.199 - if (fp==NULL) {
23.200 - /* try opening the file in the "root path" for codepages, with "cp" prefixed before the name */
23.201 - if (strlen(name)+2>MAXCODEPAGE)
23.202 - return 0;
23.203 - assert(2+strlen(name)+strlen(cprootpath)<_MAX_PATH);
23.204 - strcpy(filename,cprootpath);
23.205 - strcat(filename,"cp");
23.206 - strcat(filename,name);
23.207 - fp=fopen(filename,"rt");
23.208 - } /* if */
23.209 - if (fp==NULL) {
23.210 - /* try opening the file in the "root path" for codepages, with "cp" prefixed an ".txt" appended */
23.211 - if (strlen(name)+2+4>MAXCODEPAGE)
23.212 - return 0;
23.213 - assert(strlen(filename)+4<_MAX_PATH);
23.214 - strcat(filename,".txt");
23.215 - fp=fopen(filename,"rt");
23.216 - } /* if */
23.217 - if (fp==NULL)
23.218 - return FALSE; /* all failed */
23.219 -
23.220 - /* clear the tables */
23.221 - for (index=0; index<ELEMENTS(bytetable); index++)
23.222 - bytetable[index]=INVALID; /* special code meaning "not found" */
23.223 - assert(wordtablesize==0 && wordtabletop==0 && wordtable==NULL
23.224 - || wordtablesize>0 && wordtable!=NULL);
23.225 - if (wordtable!=NULL) {
23.226 - free(wordtable);
23.227 - wordtable=NULL;
23.228 - wordtablesize=0;
23.229 - wordtabletop=0;
23.230 - } /* if */
23.231 -
23.232 - /* read in the table */
23.233 - while (cp_readline(fp,filename,sizeof filename)) {
23.234 - char *ptr;
23.235 - if ((ptr=strchr(filename,'#'))!=NULL)
23.236 - *ptr='\0'; /* strip of comment */
23.237 - for (ptr=filename; *ptr>0 && *ptr<' '; ptr++)
23.238 - /* nothing */; /* skip leading whitespace */
23.239 - if (*ptr!='\0') {
23.240 - /* content on line */
23.241 - unsigned code=LEADBYTE;
23.242 - int num=sscanf(ptr,"%i %i",&index,&code);
23.243 - /* if sscanf() returns 1 and the index is in range 0..255, then the
23.244 - * code is a DBCS lead byte; if sscanf() returns 2 and index>=256, this
23.245 - * is a double byte pair (lead byte + follower)
23.246 - */
23.247 - if (num>=1 && index<256) {
23.248 - bytetable[index]=(wchar_t)code;
23.249 - } else if (num==2 && index>=256 && index<LEADBYTE) {
23.250 - /* store the DBCS character in wordtable */
23.251 - if (wordtabletop>=wordtablesize) {
23.252 - /* grow the list */
23.253 - int newsize;
23.254 - struct wordpair *newblock;
23.255 - newsize= (wordtablesize==0) ? 128 : 2*wordtablesize;
23.256 - newblock=(struct wordpair *)malloc(newsize*sizeof(*wordtable));
23.257 - if (newblock!=NULL) {
23.258 - memcpy(newblock,wordtable,wordtabletop*sizeof(*wordtable));
23.259 - free(wordtable);
23.260 - wordtable=newblock;
23.261 - wordtablesize=newsize;
23.262 - } /* if */
23.263 - } /* if */
23.264 - if (wordtabletop<wordtablesize) {
23.265 - /* insert at sorted position */
23.266 - int pos=wordtabletop;
23.267 - assert(wordtable!=NULL);
23.268 - while (pos>0 && (unsigned)wordtable[pos-1].index>index) {
23.269 - wordtable[pos]=wordtable[pos-1];
23.270 - pos--;
23.271 - } /* while */
23.272 - wordtable[pos].index=(unsigned short)index;
23.273 - wordtable[pos].code=(wchar_t)code;
23.274 - } /* if */
23.275 - } /* if */
23.276 - } /* if */
23.277 - } /* while */
23.278 -
23.279 - fclose(fp);
23.280 - return TRUE;
23.281 -}
23.282 -
23.283 -SC_FUNC cell cp_translate(const unsigned char *string,const unsigned char **endptr)
23.284 -{
23.285 - wchar_t result;
23.286 -
23.287 - result=bytetable[*string++];
23.288 - /* check whether this is a leader code */
23.289 - if ((unsigned)result==LEADBYTE && wordtable!=NULL) {
23.290 - /* look up the code via binary search */
23.291 - int low,high,mid;
23.292 - unsigned short index=(unsigned short)(((*(string-1)) << 8) | *string);
23.293 - string++;
23.294 - assert(wordtabletop>0);
23.295 - low=0;
23.296 - high=wordtabletop-1;
23.297 - while (low<high) {
23.298 - mid=(low+high)/2;
23.299 - assert(low<=mid && mid<high);
23.300 - if (index>wordtable[mid].index)
23.301 - low=mid+1;
23.302 - else
23.303 - high=mid;
23.304 - } /* while */
23.305 - assert(low==high);
23.306 - if (wordtable[low].index==index)
23.307 - result=wordtable[low].code;
23.308 - } /* if */
23.309 -
23.310 - if (endptr!=NULL)
23.311 - *endptr=string;
23.312 - return (cell)result;
23.313 -}
23.314 -
23.315 -#endif /* NO_CODEPAGE */
23.316 -
23.317 -#if !defined NO_UTF8
23.318 -SC_FUNC cell get_utf8_char(const unsigned char *string,const unsigned char **endptr)
23.319 -{
23.320 - int follow=0;
23.321 - long lowmark=0;
23.322 - unsigned char ch;
23.323 - cell result=0;
23.324 -
23.325 - if (endptr!=NULL)
23.326 - *endptr=string;
23.327 -
23.328 - for ( ;; ) {
23.329 - ch=*string++;
23.330 -
23.331 - if (follow>0 && (ch & 0xc0)==0x80) {
23.332 - /* leader code is active, combine with earlier code */
23.333 - result=(result << 6) | (ch & 0x3f);
23.334 - if (--follow==0) {
23.335 - /* encoding a character in more bytes than is strictly needed,
23.336 - * is not really valid UTF-8; we are strict here to increase
23.337 - * the chance of heuristic dectection of non-UTF-8 text
23.338 - * (JAVA writes zero bytes as a 2-byte code UTF-8, which is invalid)
23.339 - */
23.340 - if (result<lowmark)
23.341 - return -1;
23.342 - /* the code positions 0xd800--0xdfff and 0xfffe & 0xffff do not
23.343 - * exist in UCS-4 (and hence, they do not exist in Unicode)
23.344 - */
23.345 - if (result>=0xd800 && result<=0xdfff || result==0xfffe || result==0xffff)
23.346 - return -1;
23.347 - } /* if */
23.348 - break;
23.349 - } else if (follow==0 && (ch & 0x80)==0x80) {
23.350 - /* UTF-8 leader code */
23.351 - if ((ch & 0xe0)==0xc0) {
23.352 - /* 110xxxxx 10xxxxxx */
23.353 - follow=1;
23.354 - lowmark=0x80L;
23.355 - result=ch & 0x1f;
23.356 - } else if ((ch & 0xf0)==0xe0) {
23.357 - /* 1110xxxx 10xxxxxx 10xxxxxx (16 bits, BMP plane) */
23.358 - follow=2;
23.359 - lowmark=0x800L;
23.360 - result=ch & 0x0f;
23.361 - } else if ((ch & 0xf8)==0xf0) {
23.362 - /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
23.363 - follow=3;
23.364 - lowmark=0x10000L;
23.365 - result=ch & 0x07;
23.366 - } else if ((ch & 0xfc)==0xf8) {
23.367 - /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
23.368 - follow=4;
23.369 - lowmark=0x200000L;
23.370 - result=ch & 0x03;
23.371 - } else if ((ch & 0xfe)==0xfc) {
23.372 - /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (32 bits) */
23.373 - follow=5;
23.374 - lowmark=0x4000000L;
23.375 - result=ch & 0x01;
23.376 - } else {
23.377 - /* this is invalid UTF-8 */
23.378 - return -1;
23.379 - } /* if */
23.380 - } else if (follow==0 && (ch & 0x80)==0x00) {
23.381 - /* 0xxxxxxx (US-ASCII) */
23.382 - result=ch;
23.383 - break;
23.384 - } else {
23.385 - /* this is invalid UTF-8 */
23.386 - return -1;
23.387 - } /* if */
23.388 -
23.389 - } /* for */
23.390 -
23.391 - if (endptr!=NULL)
23.392 - *endptr=string;
23.393 - return result;
23.394 -}
23.395 -#endif
23.396 -
23.397 -SC_FUNC int scan_utf8(FILE *fp,const char *filename)
23.398 -{
23.399 - #if defined NO_UTF8
23.400 - return 0;
23.401 - #else
23.402 - void *resetpos=pc_getpossrc(fp);
23.403 - int utf8=TRUE;
23.404 - int firstchar=TRUE,bom_found=FALSE;
23.405 - const unsigned char *ptr;
23.406 -
23.407 - while (utf8 && pc_readsrc(fp,pline,sLINEMAX)!=NULL) {
23.408 - ptr=pline;
23.409 - if (firstchar) {
23.410 - /* check whether the very first character on the very first line
23.411 - * starts with a BYTE order mark
23.412 - */
23.413 - cell c=get_utf8_char(ptr,&ptr);
23.414 - bom_found= (c==0xfeff);
23.415 - utf8= (c>=0);
23.416 - firstchar=FALSE;
23.417 - } /* if */
23.418 - while (utf8 && *ptr!='\0')
23.419 - utf8= (get_utf8_char(ptr,&ptr)>=0);
23.420 - } /* while */
23.421 - pc_resetsrc(fp,resetpos);
23.422 - if (bom_found) {
23.423 - unsigned char bom[3];
23.424 - if (!utf8)
23.425 - error(77,filename); /* malformed UTF-8 encoding */
23.426 - pc_readsrc(fp,bom,3);
23.427 - assert(bom[0]==0xef && bom[1]==0xbb && bom[2]==0xbf);
23.428 - } /* if */
23.429 - return utf8;
23.430 - #endif /* NO_UTF8 */
23.431 -}
24.1 --- a/compiler-init/sclist.c Sat Jul 15 05:02:38 2006 +0000
24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
24.3 @@ -1,486 +0,0 @@
24.4 -/* Pawn compiler - maintenance of various lists
24.5 - *
24.6 - * o Name list (aliases)
24.7 - * o Include path list
24.8 - * o Macro defintions (text substitutions)
24.9 - *
24.10 - * Copyright (c) ITB CompuPhase, 2001-2006
24.11 - *
24.12 - * This software is provided "as-is", without any express or implied warranty.
24.13 - * In no event will the authors be held liable for any damages arising from
24.14 - * the use of this software.
24.15 - *
24.16 - * Permission is granted to anyone to use this software for any purpose,
24.17 - * including commercial applications, and to alter it and redistribute it
24.18 - * freely, subject to the following restrictions:
24.19 - *
24.20 - * 1. The origin of this software must not be misrepresented; you must not
24.21 - * claim that you wrote the original software. If you use this software in
24.22 - * a product, an acknowledgment in the product documentation would be
24.23 - * appreciated but is not required.
24.24 - * 2. Altered source versions must be plainly marked as such, and must not be
24.25 - * misrepresented as being the original software.
24.26 - * 3. This notice may not be removed or altered from any source distribution.
24.27 - *
24.28 - * Version: $Id: sclist.c 3579 2006-06-06 13:35:29Z thiadmer $
24.29 - */
24.30 -#include <assert.h>
24.31 -#include <limits.h>
24.32 -#include <stdlib.h>
24.33 -#include <string.h>
24.34 -#include "sc.h"
24.35 -
24.36 -#if defined FORTIFY
24.37 - #include <alloc/fortify.h>
24.38 -#endif
24.39 -
24.40 -/* a "private" implementation of strdup(), so that porting
24.41 - * to other memory allocators becomes easier.
24.42 - * By S�ren Hannibal.
24.43 - */
24.44 -SC_FUNC char* duplicatestring(const char* sourcestring)
24.45 -{
24.46 - char* result=(char*)malloc(strlen(sourcestring)+1);
24.47 - strcpy(result,sourcestring);
24.48 - return result;
24.49 -}
24.50 -
24.51 -
24.52 -static stringpair *insert_stringpair(stringpair *root,char *first,char *second,int matchlength)
24.53 -{
24.54 - stringpair *cur,*pred;
24.55 -
24.56 - assert(root!=NULL);
24.57 - assert(first!=NULL);
24.58 - assert(second!=NULL);
24.59 - /* create a new node, and check whether all is okay */
24.60 - if ((cur=(stringpair*)malloc(sizeof(stringpair)))==NULL)
24.61 - return NULL;
24.62 - cur->first=duplicatestring(first);
24.63 - cur->second=duplicatestring(second);
24.64 - cur->matchlength=matchlength;
24.65 - if (cur->first==NULL || cur->second==NULL) {
24.66 - if (cur->first!=NULL)
24.67 - free(cur->first);
24.68 - if (cur->second!=NULL)
24.69 - free(cur->second);
24.70 - free(cur);
24.71 - return NULL;
24.72 - } /* if */
24.73 - /* link the node to the tree, find the position */
24.74 - for (pred=root; pred->next!=NULL && strcmp(pred->next->first,first)<0; pred=pred->next)
24.75 - /* nothing */;
24.76 - cur->next=pred->next;
24.77 - pred->next=cur;
24.78 - return cur;
24.79 -}
24.80 -
24.81 -static void delete_stringpairtable(stringpair *root)
24.82 -{
24.83 - stringpair *cur, *next;
24.84 -
24.85 - assert(root!=NULL);
24.86 - cur=root->next;
24.87 - while (cur!=NULL) {
24.88 - next=cur->next;
24.89 - assert(cur->first!=NULL);
24.90 - assert(cur->second!=NULL);
24.91 - free(cur->first);
24.92 - free(cur->second);
24.93 - free(cur);
24.94 - cur=next;
24.95 - } /* while */
24.96 - memset(root,0,sizeof(stringpair));
24.97 -}
24.98 -
24.99 -static stringpair *find_stringpair(stringpair *cur,char *first,int matchlength)
24.100 -{
24.101 - int result=0;
24.102 -
24.103 - assert(matchlength>0); /* the function cannot handle zero-length comparison */
24.104 - assert(first!=NULL);
24.105 - while (cur!=NULL && result<=0) {
24.106 - result=(int)*cur->first - (int)*first;
24.107 - if (result==0 && matchlength==cur->matchlength) {
24.108 - result=strncmp(cur->first,first,matchlength);
24.109 - if (result==0)
24.110 - return cur;
24.111 - } /* if */
24.112 - cur=cur->next;
24.113 - } /* while */
24.114 - return NULL;
24.115 -}
24.116 -
24.117 -static int delete_stringpair(stringpair *root,stringpair *item)
24.118 -{
24.119 - stringpair *cur;
24.120 -
24.121 - assert(root!=NULL);
24.122 - cur=root;
24.123 - while (cur->next!=NULL) {
24.124 - if (cur->next==item) {
24.125 - cur->next=item->next; /* unlink from list */
24.126 - assert(item->first!=NULL);
24.127 - assert(item->second!=NULL);
24.128 - free(item->first);
24.129 - free(item->second);
24.130 - free(item);
24.131 - return TRUE;
24.132 - } /* if */
24.133 - cur=cur->next;
24.134 - } /* while */
24.135 - return FALSE;
24.136 -}
24.137 -
24.138 -/* ----- string list functions ----------------------------------- */
24.139 -static stringlist *insert_string(stringlist *root,char *string)
24.140 -{
24.141 - stringlist *cur;
24.142 -
24.143 - assert(string!=NULL);
24.144 - if ((cur=(stringlist*)malloc(sizeof(stringlist)))==NULL)
24.145 - error(103); /* insufficient memory (fatal error) */
24.146 - if ((cur->line=duplicatestring(string))==NULL)
24.147 - error(103); /* insufficient memory (fatal error) */
24.148 - /* insert as "last" */
24.149 - assert(root!=NULL);
24.150 - while (root->next!=NULL)
24.151 - root=root->next;
24.152 - cur->next=root->next;
24.153 - root->next=cur;
24.154 - return cur;
24.155 -}
24.156 -
24.157 -static char *get_string(stringlist *root,int index)
24.158 -{
24.159 - stringlist *cur;
24.160 -
24.161 - assert(root!=NULL);
24.162 - cur=root->next;
24.163 - while (cur!=NULL && index-->0)
24.164 - cur=cur->next;
24.165 - if (cur!=NULL) {
24.166 - assert(cur->line!=NULL);
24.167 - return cur->line;
24.168 - } /* if */
24.169 - return NULL;
24.170 -}
24.171 -
24.172 -static int delete_string(stringlist *root,int index)
24.173 -{
24.174 - stringlist *cur,*item;
24.175 -
24.176 - assert(root!=NULL);
24.177 - for (cur=root; cur->next!=NULL && index>0; cur=cur->next,index--)
24.178 - /* nothing */;
24.179 - if (cur->next!=NULL) {
24.180 - item=cur->next;
24.181 - cur->next=item->next; /* unlink from list */
24.182 - assert(item->line!=NULL);
24.183 - free(item->line);
24.184 - free(item);
24.185 - return TRUE;
24.186 - } /* if */
24.187 - return FALSE;
24.188 -}
24.189 -
24.190 -SC_FUNC void delete_stringtable(stringlist *root)
24.191 -{
24.192 - stringlist *cur,*next;
24.193 -
24.194 - assert(root!=NULL);
24.195 - cur=root->next;
24.196 - while (cur!=NULL) {
24.197 - next=cur->next;
24.198 - assert(cur->line!=NULL);
24.199 - free(cur->line);
24.200 - free(cur);
24.201 - cur=next;
24.202 - } /* while */
24.203 - memset(root,0,sizeof(stringlist));
24.204 -}
24.205 -
24.206 -
24.207 -/* ----- alias table --------------------------------------------- */
24.208 -static stringpair alias_tab = {NULL, NULL, NULL}; /* alias table */
24.209 -
24.210 -SC_FUNC stringpair *insert_alias(char *name,char *alias)
24.211 -{
24.212 - stringpair *cur;
24.213 -
24.214 - assert(name!=NULL);
24.215 - assert(strlen(name)<=sNAMEMAX);
24.216 - assert(alias!=NULL);
24.217 - assert(strlen(alias)<=sNAMEMAX);
24.218 - if ((cur=insert_stringpair(&alias_tab,name,alias,strlen(name)))==NULL)
24.219 - error(103); /* insufficient memory (fatal error) */
24.220 - return cur;
24.221 -}
24.222 -
24.223 -SC_FUNC int lookup_alias(char *target,char *name)
24.224 -{
24.225 - stringpair *cur=find_stringpair(alias_tab.next,name,strlen(name));
24.226 - if (cur!=NULL) {
24.227 - assert(strlen(cur->second)<=sNAMEMAX);
24.228 - strcpy(target,cur->second);
24.229 - } /* if */
24.230 - return cur!=NULL;
24.231 -}
24.232 -
24.233 -SC_FUNC void delete_aliastable(void)
24.234 -{
24.235 - delete_stringpairtable(&alias_tab);
24.236 -}
24.237 -
24.238 -/* ----- include paths list -------------------------------------- */
24.239 -static stringlist includepaths = {NULL, NULL}; /* directory list for include files */
24.240 -
24.241 -SC_FUNC stringlist *insert_path(char *path)
24.242 -{
24.243 - return insert_string(&includepaths,path);
24.244 -}
24.245 -
24.246 -SC_FUNC char *get_path(int index)
24.247 -{
24.248 - return get_string(&includepaths,index);
24.249 -}
24.250 -
24.251 -SC_FUNC void delete_pathtable(void)
24.252 -{
24.253 - delete_stringtable(&includepaths);
24.254 - assert(includepaths.next==NULL);
24.255 -}
24.256 -
24.257 -
24.258 -/* ----- text substitution patterns ------------------------------ */
24.259 -#if !defined NO_DEFINE
24.260 -
24.261 -static stringpair substpair = { NULL, NULL, NULL}; /* list of substitution pairs */
24.262 -
24.263 -static stringpair *substindex['z'-PUBLIC_CHAR+1]; /* quick index to first character */
24.264 -static void adjustindex(char c)
24.265 -{
24.266 - stringpair *cur;
24.267 - assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_' || c==PUBLIC_CHAR);
24.268 - assert(PUBLIC_CHAR<'A' && 'A'<'_' && '_'<'z');
24.269 -
24.270 - for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next)
24.271 - /* nothing */;
24.272 - substindex[(int)c-PUBLIC_CHAR]=cur;
24.273 -}
24.274 -
24.275 -SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen)
24.276 -{
24.277 - stringpair *cur;
24.278 -
24.279 - assert(pattern!=NULL);
24.280 - assert(substitution!=NULL);
24.281 - if ((cur=insert_stringpair(&substpair,pattern,substitution,prefixlen))==NULL)
24.282 - error(103); /* insufficient memory (fatal error) */
24.283 - adjustindex(*pattern);
24.284 - return cur;
24.285 -}
24.286 -
24.287 -SC_FUNC stringpair *find_subst(char *name,int length)
24.288 -{
24.289 - stringpair *item;
24.290 - assert(name!=NULL);
24.291 - assert(length>0);
24.292 - assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
24.293 - item=substindex[(int)*name-PUBLIC_CHAR];
24.294 - if (item!=NULL)
24.295 - item=find_stringpair(item,name,length);
24.296 - return item;
24.297 -}
24.298 -
24.299 -SC_FUNC int delete_subst(char *name,int length)
24.300 -{
24.301 - stringpair *item;
24.302 - assert(name!=NULL);
24.303 - assert(length>0);
24.304 - assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
24.305 - item=substindex[(int)*name-PUBLIC_CHAR];
24.306 - if (item!=NULL)
24.307 - item=find_stringpair(item,name,length);
24.308 - if (item==NULL)
24.309 - return FALSE;
24.310 - delete_stringpair(&substpair,item);
24.311 - adjustindex(*name);
24.312 - return TRUE;
24.313 -}
24.314 -
24.315 -SC_FUNC void delete_substtable(void)
24.316 -{
24.317 - int i;
24.318 - delete_stringpairtable(&substpair);
24.319 - for (i=0; i<sizeof substindex/sizeof substindex[0]; i++)
24.320 - substindex[i]=NULL;
24.321 -}
24.322 -
24.323 -#endif /* !defined NO_SUBST */
24.324 -
24.325 -
24.326 -/* ----- input file list ----------------------------------------- */
24.327 -static stringlist sourcefiles = {NULL, NULL};
24.328 -
24.329 -SC_FUNC stringlist *insert_sourcefile(char *string)
24.330 -{
24.331 - return insert_string(&sourcefiles,string);
24.332 -}
24.333 -
24.334 -SC_FUNC char *get_sourcefile(int index)
24.335 -{
24.336 - return get_string(&sourcefiles,index);
24.337 -}
24.338 -
24.339 -SC_FUNC void delete_sourcefiletable(void)
24.340 -{
24.341 - delete_stringtable(&sourcefiles);
24.342 - assert(sourcefiles.next==NULL);
24.343 -}
24.344 -
24.345 -
24.346 -/* ----- documentation tags -------------------------------------- */
24.347 -#if !defined SC_LIGHT
24.348 -static stringlist docstrings = {NULL, NULL};
24.349 -
24.350 -SC_FUNC stringlist *insert_docstring(char *string)
24.351 -{
24.352 - return insert_string(&docstrings,string);
24.353 -}
24.354 -
24.355 -SC_FUNC char *get_docstring(int index)
24.356 -{
24.357 - return get_string(&docstrings,index);
24.358 -}
24.359 -
24.360 -SC_FUNC void delete_docstring(int index)
24.361 -{
24.362 - delete_string(&docstrings,index);
24.363 -}
24.364 -
24.365 -SC_FUNC void delete_docstringtable(void)
24.366 -{
24.367 - delete_stringtable(&docstrings);
24.368 - assert(docstrings.next==NULL);
24.369 -}
24.370 -#endif /* !defined SC_LIGHT */
24.371 -
24.372 -
24.373 -/* ----- autolisting --------------------------------------------- */
24.374 -static stringlist autolist = {NULL, NULL};
24.375 -
24.376 -SC_FUNC stringlist *insert_autolist(char *string)
24.377 -{
24.378 - return insert_string(&autolist,string);
24.379 -}
24.380 -
24.381 -SC_FUNC char *get_autolist(int index)
24.382 -{
24.383 - return get_string(&autolist,index);
24.384 -}
24.385 -
24.386 -SC_FUNC void delete_autolisttable(void)
24.387 -{
24.388 - delete_stringtable(&autolist);
24.389 - assert(autolist.next==NULL);
24.390 -}
24.391 -
24.392 -
24.393 -/* ----- debug information --------------------------------------- */
24.394 -
24.395 -/* These macros are adapted from LibDGG libdgg-int64.h, see
24.396 - * http://www.dennougedougakkai-ndd.org/pub/libdgg/
24.397 - */
24.398 -#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
24.399 - #define __STDC_FORMAT_MACROS
24.400 - #define __STDC_CONSTANT_MACROS
24.401 - #include <inttypes.h> /* automatically includes stdint.h */
24.402 -#elif (defined _MSC_VER || defined __BORLANDC__) && (defined _I64_MAX || defined HAVE_I64)
24.403 - #define PRId64 "I64d"
24.404 - #define PRIx64 "I64x"
24.405 -#else
24.406 - #define PRId64 "lld"
24.407 - #define PRIx64 "llx"
24.408 -#endif
24.409 -#if PAWN_CELL_SIZE==64
24.410 - #define PRIdC PRId64
24.411 - #define PRIxC PRIx64
24.412 -#elif PAWN_CELL_SIZE==32
24.413 - #define PRIdC "ld"
24.414 - #define PRIxC "lx"
24.415 -#else
24.416 - #define PRIdC "d"
24.417 - #define PRIxC "x"
24.418 -#endif
24.419 -
24.420 -static stringlist dbgstrings = {NULL, NULL};
24.421 -
24.422 -SC_FUNC stringlist *insert_dbgfile(const char *filename)
24.423 -{
24.424 -
24.425 - if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
24.426 - char string[_MAX_PATH+40];
24.427 - assert(filename!=NULL);
24.428 - assert(strlen(filename)+40<sizeof string);
24.429 - sprintf(string,"F:%" PRIxC " %s",code_idx,filename);
24.430 - return insert_string(&dbgstrings,string);
24.431 - } /* if */
24.432 - return NULL;
24.433 -}
24.434 -
24.435 -SC_FUNC stringlist *insert_dbgline(int linenr)
24.436 -{
24.437 - if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
24.438 - char string[40];
24.439 - if (linenr>0)
24.440 - linenr--; /* line numbers are zero-based in the debug information */
24.441 - sprintf(string,"L:%" PRIxC " %x",code_idx,linenr);
24.442 - return insert_string(&dbgstrings,string);
24.443 - } /* if */
24.444 - return NULL;
24.445 -}
24.446 -
24.447 -SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
24.448 -{
24.449 - if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
24.450 - char string[2*sNAMEMAX+128];
24.451 - char symname[2*sNAMEMAX+16];
24.452 -
24.453 - funcdisplayname(symname,sym->name);
24.454 - /* address tag:name codestart codeend ident vclass [tag:dim ...] */
24.455 - if (sym->ident==iFUNCTN) {
24.456 - sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x",
24.457 - sym->addr,sym->tag,symname,sym->addr,sym->codeaddr,sym->ident,sym->vclass);
24.458 - } else {
24.459 - sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x",
24.460 - sym->addr,sym->tag,symname,sym->codeaddr,code_idx,sym->ident,sym->vclass);
24.461 - } /* if */
24.462 - if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
24.463 - #if !defined NDEBUG
24.464 - int count=sym->dim.array.level;
24.465 - #endif
24.466 - symbol *sub;
24.467 - strcat(string," [ ");
24.468 - for (sub=sym; sub!=NULL; sub=finddepend(sub)) {
24.469 - assert(sub->dim.array.level==count--);
24.470 - sprintf(string+strlen(string),"%x:%x ",sub->x.tags.index,sub->dim.array.length);
24.471 - } /* for */
24.472 - strcat(string,"]");
24.473 - } /* if */
24.474 -
24.475 - return insert_string(&dbgstrings,string);
24.476 - } /* if */
24.477 - return NULL;
24.478 -}
24.479 -
24.480 -SC_FUNC char *get_dbgstring(int index)
24.481 -{
24.482 - return get_string(&dbgstrings,index);
24.483 -}
24.484 -
24.485 -SC_FUNC void delete_dbgstringtable(void)
24.486 -{
24.487 - delete_stringtable(&dbgstrings);
24.488 - assert(dbgstrings.next==NULL);
24.489 -}
25.1 --- a/compiler-init/scmemfil.c Sat Jul 15 05:02:38 2006 +0000
25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
25.3 @@ -1,179 +0,0 @@
25.4 -/* Pawn compiler
25.5 - *
25.6 - * Routines to maintain a "text file" in memory.
25.7 - *
25.8 - * Copyright (c) ITB CompuPhase, 2003-2006
25.9 - *
25.10 - * This software is provided 'as-is', without any express or implied warranty.
25.11 - * In no event will the authors be held liable for any damages arising from the
25.12 - * use of this software.
25.13 - *
25.14 - * Permission is granted to anyone to use this software for any purpose,
25.15 - * including commercial applications, and to alter it and redistribute it
25.16 - * freely, subject to the following restrictions:
25.17 - *
25.18 - * 1. The origin of this software must not be misrepresented; you must not
25.19 - * claim that you wrote the original software. If you use this software in
25.20 - * a product, an acknowledgment in the product documentation would be
25.21 - * appreciated but is not required.
25.22 - *
25.23 - * 2. Altered source versions must be plainly marked as such, and must not be
25.24 - * misrepresented as being the original software.
25.25 - *
25.26 - * 3. This notice may not be removed or altered from any source distribution.
25.27 - *
25.28 - * Version: $Id: scmemfil.c 3579 2006-06-06 13:35:29Z thiadmer $
25.29 - */
25.30 -
25.31 -#include <assert.h>
25.32 -#include <stdio.h>
25.33 -#include <stdlib.h>
25.34 -#include <string.h>
25.35 -#include "memfile.h"
25.36 -
25.37 -#if defined FORTIFY
25.38 - #include <alloc/fortify.h>
25.39 -#endif
25.40 -
25.41 -
25.42 -#define BUFFERSIZE 512u
25.43 -
25.44 -/* For every block, except the first:
25.45 - * buffer points to a block that is BUFFERSIZE long that holds the data
25.46 - * bufpos is the "used size" of the block
25.47 - * For the first block:
25.48 - * buffer points to the "file name"
25.49 - * bufpos is the current "file pointer"
25.50 - */
25.51 -typedef memfile_t MEMFILE;
25.52 -#define tMEMFILE 1
25.53 -
25.54 -#include "sc.h"
25.55 -
25.56 -
25.57 -MEMFILE *mfcreate(char *filename)
25.58 -{
25.59 - return memfile_creat(filename, 4096);
25.60 -}
25.61 -
25.62 -void mfclose(MEMFILE *mf)
25.63 -{
25.64 - memfile_destroy(mf);
25.65 -}
25.66 -
25.67 -int mfdump(MEMFILE *mf)
25.68 -{
25.69 - FILE *fp;
25.70 - int okay;
25.71 -
25.72 - assert(mf!=NULL);
25.73 - /* create the file */
25.74 - fp=fopen(mf->name, "wb");
25.75 - if (fp==NULL)
25.76 - return 0;
25.77 -
25.78 - okay=1;
25.79 - okay = okay & (fwrite(mf->base, mf->usedoffs, 1, fp)==(size_t)mf->usedoffs);
25.80 -
25.81 - fclose(fp);
25.82 - return okay;
25.83 -}
25.84 -
25.85 -long mflength(MEMFILE *mf)
25.86 -{
25.87 - return mf->usedoffs;
25.88 -}
25.89 -
25.90 -long mfseek(MEMFILE *mf,long offset,int whence)
25.91 -{
25.92 - long length;
25.93 -
25.94 - assert(mf!=NULL);
25.95 - if (mf->usedoffs == 0)
25.96 - return 0L; /* early exit: not a single byte in the file */
25.97 -
25.98 - /* find the size of the memory file */
25.99 - length=mflength(mf);
25.100 -
25.101 - /* convert the offset to an absolute position */
25.102 - switch (whence) {
25.103 - case SEEK_SET:
25.104 - break;
25.105 - case SEEK_CUR:
25.106 - offset+=mf->offs;
25.107 - break;
25.108 - case SEEK_END:
25.109 - assert(offset<=0);
25.110 - offset+=length;
25.111 - break;
25.112 - } /* switch */
25.113 -
25.114 - /* clamp to the file length limit */
25.115 - if (offset<0)
25.116 - offset=0;
25.117 - else if (offset>length)
25.118 - offset=length;
25.119 -
25.120 - /* set new position and return it */
25.121 - memfile_seek(mf, offset);
25.122 -
25.123 - return offset;
25.124 -}
25.125 -
25.126 -unsigned int mfwrite(MEMFILE *mf,unsigned char *buffer,unsigned int size)
25.127 -{
25.128 - return (memfile_write(mf, buffer, size) ? size : 0);
25.129 -}
25.130 -
25.131 -unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size)
25.132 -{
25.133 - return memfile_read(mf, buffer, size);
25.134 -}
25.135 -
25.136 -char *mfgets(MEMFILE *mf,char *string,unsigned int size)
25.137 -{
25.138 - char *ptr;
25.139 - unsigned int read;
25.140 - long seek;
25.141 -
25.142 - assert(mf!=NULL);
25.143 -
25.144 - read=mfread(mf,(unsigned char *)string,size);
25.145 - if (read==0)
25.146 - return NULL;
25.147 - seek=0L;
25.148 -
25.149 - /* make sure that the string is zero-terminated */
25.150 - assert(read<=size);
25.151 - if (read<size) {
25.152 - string[read]='\0';
25.153 - } else {
25.154 - string[size-1]='\0';
25.155 - seek=-1; /* undo reading the character that gets overwritten */
25.156 - } /* if */
25.157 -
25.158 - /* find the first '\n' */
25.159 - ptr=strchr(string,'\n');
25.160 - if (ptr!=NULL) {
25.161 - *(ptr+1)='\0';
25.162 - seek=(long)(ptr-string)+1-(long)read;
25.163 - } /* if */
25.164 -
25.165 - /* undo over-read */
25.166 - assert(seek<=0); /* should seek backward only */
25.167 - if (seek!=0)
25.168 - mfseek(mf,seek,SEEK_CUR);
25.169 -
25.170 - return string;
25.171 -}
25.172 -
25.173 -int mfputs(MEMFILE *mf,char *string)
25.174 -{
25.175 - unsigned int written,length;
25.176 -
25.177 - assert(mf!=NULL);
25.178 -
25.179 - length=strlen(string);
25.180 - written=mfwrite(mf,(unsigned char *)string,length);
25.181 - return written==length;
25.182 -}
26.1 --- a/compiler-init/scstate.c Sat Jul 15 05:02:38 2006 +0000
26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
26.3 @@ -1,375 +0,0 @@
26.4 -/* Pawn compiler
26.5 - *
26.6 - * Machine and state maintenance.
26.7 - *
26.8 - * Three lists are maintained here:
26.9 - * - A list of automatons (state machines): these hold a name, a unique id
26.10 - * (in the "index" field) and the memory address of a cell that holds the
26.11 - * current state of the automaton (in the "value" field).
26.12 - * - A list of states for each automaton: a name, an automaton id (in the
26.13 - * "index" field) and a unique id for the state (unique in the automaton;
26.14 - * states belonging to different automatons may have the same id).
26.15 - * - A list of state combinations. Each function may belong to a set of states.
26.16 - * This list assigns a unique id to the combination of the automaton and all
26.17 - * states.
26.18 - *
26.19 - * For a function/variable that has states, there is a fourth list, which is
26.20 - * attached to the "symbol" structure. This list contains the code label (in
26.21 - * the "name" field, only for functions), the id of the state combinations (the
26.22 - * state list id; it is stored in the "index" field) and the code address at
26.23 - * which the function starts. The latter is currently unused.
26.24 - *
26.25 - * At the start of the compiled code, a set of stub functions is generated.
26.26 - * Each stub function looks up the value of the "state selector" value for the
26.27 - * automaton, and goes with a "switch" instruction to the start address of the
26.28 - * function. This happens in SC4.C.
26.29 - *
26.30 - *
26.31 - * Copyright (c) ITB CompuPhase, 2005-2006
26.32 - *
26.33 - * This software is provided "as-is", without any express or implied warranty.
26.34 - * In no event will the authors be held liable for any damages arising from
26.35 - * the use of this software.
26.36 - *
26.37 - * Permission is granted to anyone to use this software for any purpose,
26.38 - * including commercial applications, and to alter it and redistribute it
26.39 - * freely, subject to the following restrictions:
26.40 - *
26.41 - * 1. The origin of this software must not be misrepresented; you must not
26.42 - * claim that you wrote the original software. If you use this software in
26.43 - * a product, an acknowledgment in the product documentation would be
26.44 - * appreciated but is not required.
26.45 - * 2. Altered source versions must be plainly marked as such, and must not be
26.46 - * misrepresented as being the original software.
26.47 - * 3. This notice may not be removed or altered from any source distribution.
26.48 - *
26.49 - * Version: $Id: scstate.c 3579 2006-06-06 13:35:29Z thiadmer $
26.50 - */
26.51 -#include <assert.h>
26.52 -#include <limits.h>
26.53 -#include <stdio.h>
26.54 -#include <stdlib.h>
26.55 -#include <string.h>
26.56 -#include "sc.h"
26.57 -#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
26.58 - #include <sclinux.h>
26.59 -#endif
26.60 -
26.61 -#if defined FORTIFY
26.62 - #include <alloc/fortify.h>
26.63 -#endif
26.64 -
26.65 -typedef struct s_statelist {
26.66 - struct s_statelist *next;
26.67 - int *states; /* list of states in this combination */
26.68 - int numstates; /* number of items in the above list */
26.69 - int fsa; /* automaton id */
26.70 - int listid; /* unique id for this combination list */
26.71 -} statelist;
26.72 -
26.73 -static statelist statelist_tab = { NULL, NULL, 0, 0, 0}; /* state combinations table */
26.74 -
26.75 -
26.76 -static constvalue *find_automaton(const char *name,int *last)
26.77 -{
26.78 - constvalue *ptr;
26.79 -
26.80 - assert(last!=NULL);
26.81 - *last=0;
26.82 - ptr=sc_automaton_tab.next;
26.83 - while (ptr!=NULL) {
26.84 - if (strcmp(name,ptr->name)==0)
26.85 - return ptr;
26.86 - if (ptr->index>*last)
26.87 - *last=ptr->index;
26.88 - ptr=ptr->next;
26.89 - } /* while */
26.90 - return NULL;
26.91 -}
26.92 -
26.93 -SC_FUNC constvalue *automaton_add(const char *name)
26.94 -{
26.95 - constvalue *ptr;
26.96 - int last;
26.97 -
26.98 - assert(strlen(name)<sizeof(ptr->name));
26.99 - ptr=find_automaton(name,&last);
26.100 - if (ptr==NULL) {
26.101 - assert(last+1 <= SHRT_MAX);
26.102 - ptr=append_constval(&sc_automaton_tab,name,(cell)0,(short)(last+1));
26.103 - } /* if */
26.104 - return ptr;
26.105 -}
26.106 -
26.107 -SC_FUNC constvalue *automaton_find(const char *name)
26.108 -{
26.109 - int last;
26.110 - return find_automaton(name,&last);
26.111 -}
26.112 -
26.113 -SC_FUNC constvalue *automaton_findid(int id)
26.114 -{
26.115 - constvalue *ptr;
26.116 - for (ptr=sc_automaton_tab.next; ptr!=NULL && ptr->index!=id; ptr=ptr->next)
26.117 - /* nothing */;
26.118 - return ptr;
26.119 -}
26.120 -
26.121 -
26.122 -static constvalue *find_state(const char *name,int fsa,int *last)
26.123 -{
26.124 - constvalue *ptr;
26.125 -
26.126 - assert(last!=NULL);
26.127 - *last=0;
26.128 - ptr=sc_state_tab.next;
26.129 - while (ptr!=NULL) {
26.130 - if (ptr->index==fsa) {
26.131 - if (strcmp(name,ptr->name)==0)
26.132 - return ptr;
26.133 - if ((int)ptr->value>*last)
26.134 - *last=(int)ptr->value;
26.135 - } /* if */
26.136 - ptr=ptr->next;
26.137 - } /* while */
26.138 - return NULL;
26.139 -}
26.140 -
26.141 -SC_FUNC constvalue *state_add(const char *name,int fsa)
26.142 -{
26.143 - constvalue *ptr;
26.144 - int last;
26.145 -
26.146 - assert(strlen(name)<sizeof(ptr->name));
26.147 - ptr=find_state(name,fsa,&last);
26.148 - if (ptr==NULL) {
26.149 - assert(fsa <= SHRT_MAX);
26.150 - ptr=append_constval(&sc_state_tab,name,(cell)(last+1),(short)fsa);
26.151 - } /* if */
26.152 - return ptr;
26.153 -}
26.154 -
26.155 -SC_FUNC constvalue *state_find(const char *name,int fsa_id)
26.156 -{
26.157 - int last; /* dummy */
26.158 - return find_state(name,fsa_id,&last);
26.159 -}
26.160 -
26.161 -SC_FUNC constvalue *state_findid(int id)
26.162 -{
26.163 - constvalue *ptr;
26.164 - for (ptr=sc_state_tab.next; ptr!=NULL && ptr->value!=id; ptr=ptr->next)
26.165 - /* nothing */;
26.166 - return ptr;
26.167 -}
26.168 -
26.169 -SC_FUNC void state_buildlist(int **list,int *listsize,int *count,int stateid)
26.170 -{
26.171 - int idx;
26.172 -
26.173 - assert(list!=NULL);
26.174 - assert(listsize!=NULL);
26.175 - assert(*listsize>=0);
26.176 - assert(count!=NULL);
26.177 - assert(*count>=0);
26.178 - assert(*count<=*listsize);
26.179 -
26.180 - if (*count==*listsize) {
26.181 - /* To avoid constantly calling malloc(), the list is grown by 4 states at
26.182 - * a time.
26.183 - */
26.184 - *listsize+=4;
26.185 - *list=(int*)realloc(*list,*listsize*sizeof(int));
26.186 - if (*list==NULL)
26.187 - error(103); /* insufficient memory */
26.188 - } /* if */
26.189 -
26.190 - /* find the insertion point (the list has to stay sorted) */
26.191 - for (idx=0; idx<*count && *list[idx]<stateid; idx++)
26.192 - /* nothing */;
26.193 - if (idx<*count)
26.194 - memmove(&(*list)[idx+1],&(*list)[idx],(int)((*count-idx+1)*sizeof(int)));
26.195 - (*list)[idx]=stateid;
26.196 - *count+=1;
26.197 -}
26.198 -
26.199 -static statelist *state_findlist(int *list,int count,int fsa,int *last)
26.200 -{
26.201 - statelist *ptr;
26.202 - int i;
26.203 -
26.204 - assert(count>0);
26.205 - assert(last!=NULL);
26.206 - *last=0;
26.207 - ptr=statelist_tab.next;
26.208 - while (ptr!=NULL) {
26.209 - if (ptr->listid>*last)
26.210 - *last=ptr->listid;
26.211 - if (ptr->fsa==fsa && ptr->numstates==count) {
26.212 - /* compare all states */
26.213 - for (i=0; i<count && ptr->states[i]==list[i]; i++)
26.214 - /* nothing */;
26.215 - if (i==count)
26.216 - return ptr;
26.217 - } /* if */
26.218 - ptr=ptr->next;
26.219 - } /* while */
26.220 - return NULL;
26.221 -}
26.222 -
26.223 -static statelist *state_getlist_ptr(int listid)
26.224 -{
26.225 - statelist *ptr;
26.226 -
26.227 - assert(listid>0);
26.228 - for (ptr=statelist_tab.next; ptr!=NULL && ptr->listid!=listid; ptr=ptr->next)
26.229 - /* nothing */;
26.230 - return ptr;
26.231 -}
26.232 -
26.233 -SC_FUNC int state_addlist(int *list,int count,int fsa)
26.234 -{
26.235 - statelist *ptr;
26.236 - int last;
26.237 -
26.238 - assert(list!=NULL);
26.239 - assert(count>0);
26.240 - ptr=state_findlist(list,count,fsa,&last);
26.241 - if (ptr==NULL) {
26.242 - if ((ptr=(statelist*)malloc(sizeof(statelist)))==NULL)
26.243 - error(103); /* insufficient memory */
26.244 - if ((ptr->states=(int*)malloc(count*sizeof(int)))==NULL) {
26.245 - free(ptr);
26.246 - error(103); /* insufficient memory */
26.247 - } /* if */
26.248 - memcpy(ptr->states,list,count*sizeof(int));
26.249 - ptr->numstates=count;
26.250 - ptr->fsa=fsa;
26.251 - ptr->listid=last+1;
26.252 - ptr->next=statelist_tab.next;
26.253 - statelist_tab.next=ptr;
26.254 - } /* if */
26.255 - assert(ptr!=NULL);
26.256 - return ptr->listid;
26.257 -}
26.258 -
26.259 -SC_FUNC void state_deletetable(void)
26.260 -{
26.261 - statelist *ptr;
26.262 -
26.263 - while (statelist_tab.next!=NULL) {
26.264 - ptr=statelist_tab.next;
26.265 - /* unlink first */
26.266 - statelist_tab.next=ptr->next;
26.267 - /* then delete */
26.268 - assert(ptr->states!=NULL);
26.269 - free(ptr->states);
26.270 - free(ptr);
26.271 - } /* while */
26.272 -}
26.273 -
26.274 -SC_FUNC int state_getfsa(int listid)
26.275 -{
26.276 - statelist *ptr;
26.277 -
26.278 - assert(listid>=0);
26.279 - if (listid==0)
26.280 - return -1;
26.281 -
26.282 - ptr=state_getlist_ptr(listid);
26.283 - return (ptr!=NULL) ? ptr->fsa : -1; /* fsa 0 exists */
26.284 -}
26.285 -
26.286 -SC_FUNC int state_count(int listid)
26.287 -{
26.288 - statelist *ptr=state_getlist_ptr(listid);
26.289 - if (ptr==NULL)
26.290 - return 0; /* unknown list, no states in it */
26.291 - return ptr->numstates;
26.292 -}
26.293 -
26.294 -SC_FUNC int state_inlist(int listid,int state)
26.295 -{
26.296 - statelist *ptr;
26.297 - int i;
26.298 -
26.299 - ptr=state_getlist_ptr(listid);
26.300 - if (ptr==NULL)
26.301 - return FALSE; /* unknown list, state not in it */
26.302 - for (i=0; i<ptr->numstates; i++)
26.303 - if (ptr->states[i]==state)
26.304 - return TRUE;
26.305 - return FALSE;
26.306 -}
26.307 -
26.308 -SC_FUNC int state_listitem(int listid,int index)
26.309 -{
26.310 - statelist *ptr;
26.311 -
26.312 - ptr=state_getlist_ptr(listid);
26.313 - assert(ptr!=NULL);
26.314 - assert(index>=0 && index<ptr->numstates);
26.315 - return ptr->states[index];
26.316 -}
26.317 -
26.318 -static int checkconflict(statelist *psrc,statelist *ptgt)
26.319 -{
26.320 - int s,t;
26.321 -
26.322 - assert(psrc!=NULL);
26.323 - assert(ptgt!=NULL);
26.324 - for (s=0; s<psrc->numstates; s++)
26.325 - for (t=0; t<ptgt->numstates; t++)
26.326 - if (psrc->states[s]==ptgt->states[t])
26.327 - return 1; /* state conflict */
26.328 - return 0;
26.329 -}
26.330 -
26.331 -/* This function searches whether one of the states in the list of statelist id's
26.332 - * of a symbol exists in any other statelist id's of the same function; it also
26.333 - * verifies that all definitions of the symbol are in the same automaton.
26.334 - */
26.335 -SC_FUNC void state_conflict(symbol *root)
26.336 -{
26.337 - statelist *psrc,*ptgt;
26.338 - constvalue *srcptr,*tgtptr;
26.339 - symbol *sym;
26.340 -
26.341 - assert(root!=NULL);
26.342 - for (sym=root->next; sym!=NULL; sym=sym->next) {
26.343 - if (sym->parent!=NULL || sym->ident!=iFUNCTN)
26.344 - continue; /* hierarchical data type or no function */
26.345 - if (sym->states==NULL)
26.346 - continue; /* this function has no states */
26.347 - for (srcptr=sym->states->next; srcptr!=NULL; srcptr=srcptr->next) {
26.348 - if (srcptr->index==-1)
26.349 - continue; /* state list id -1 is a special case */
26.350 - psrc=state_getlist_ptr(srcptr->index);
26.351 - assert(psrc!=NULL);
26.352 - for (tgtptr=srcptr->next; tgtptr!=NULL; tgtptr=tgtptr->next) {
26.353 - if (tgtptr->index==-1)
26.354 - continue; /* state list id -1 is a special case */
26.355 - ptgt=state_getlist_ptr(tgtptr->index);
26.356 - assert(ptgt!=NULL);
26.357 - if (psrc->fsa!=ptgt->fsa && strcmp(sym->name,uENTRYFUNC)!=0)
26.358 - error(83,sym->name); /* this function is part of another machine */
26.359 - if (checkconflict(psrc,ptgt))
26.360 - error(84,sym->name); /* state conflict */
26.361 - } /* for (tgtptr) */
26.362 - } /* for (srcptr) */
26.363 - } /* for (sym) */
26.364 -}
26.365 -
26.366 -/* check whether the two state lists (whose ids are passed in) share any
26.367 - * states
26.368 - */
26.369 -SC_FUNC int state_conflict_id(int listid1,int listid2)
26.370 -{
26.371 - statelist *psrc,*ptgt;
26.372 -
26.373 - psrc=state_getlist_ptr(listid1);
26.374 - assert(psrc!=NULL);
26.375 - ptgt=state_getlist_ptr(listid2);
26.376 - assert(ptgt!=NULL);
26.377 - return checkconflict(psrc,ptgt);
26.378 -}
27.1 --- a/compiler-init/scvars.c Sat Jul 15 05:02:38 2006 +0000
27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
27.3 @@ -1,113 +0,0 @@
27.4 -/* Pawn compiler
27.5 - *
27.6 - * Global (cross-module) variables.
27.7 - *
27.8 - * Copyright (c) ITB CompuPhase, 1997-2006
27.9 - *
27.10 - * This software is provided "as-is", without any express or implied warranty.
27.11 - * In no event will the authors be held liable for any damages arising from
27.12 - * the use of this software.
27.13 - *
27.14 - * Permission is granted to anyone to use this software for any purpose,
27.15 - * including commercial applications, and to alter it and redistribute it
27.16 - * freely, subject to the following restrictions:
27.17 - *
27.18 - * 1. The origin of this software must not be misrepresented; you must not
27.19 - * claim that you wrote the original software. If you use this software in
27.20 - * a product, an acknowledgment in the product documentation would be
27.21 - * appreciated but is not required.
27.22 - * 2. Altered source versions must be plainly marked as such, and must not be
27.23 - * misrepresented as being the original software.
27.24 - * 3. This notice may not be removed or altered from any source distribution.
27.25 - *
27.26 - * Version: $Id: scvars.c 3577 2006-06-02 16:22:52Z thiadmer $
27.27 - */
27.28 -#include <stdio.h>
27.29 -#include <stdlib.h> /* for _MAX_PATH */
27.30 -#include "sc.h"
27.31 -
27.32 -/* global variables
27.33 - *
27.34 - * All global variables that are shared amongst the compiler files are
27.35 - * declared here.
27.36 - */
27.37 -SC_VDEFINE symbol loctab; /* local symbol table */
27.38 -SC_VDEFINE symbol glbtab; /* global symbol table */
27.39 -SC_VDEFINE cell *litq; /* the literal queue */
27.40 -SC_VDEFINE unsigned char pline[sLINEMAX+1]; /* the line read from the input file */
27.41 -SC_VDEFINE const unsigned char *lptr; /* points to the current position in "pline" */
27.42 -SC_VDEFINE constvalue tagname_tab = { NULL, "", 0, 0}; /* tagname table */
27.43 -SC_VDEFINE constvalue libname_tab = { NULL, "", 0, 0}; /* library table (#pragma library "..." syntax) */
27.44 -SC_VDEFINE constvalue *curlibrary = NULL; /* current library */
27.45 -SC_VDEFINE int pc_addlibtable = TRUE; /* is the library table added to the AMX file? */
27.46 -SC_VDEFINE symbol *curfunc; /* pointer to current function */
27.47 -SC_VDEFINE char *inpfname; /* pointer to name of the file currently read from */
27.48 -SC_VDEFINE char outfname[_MAX_PATH]; /* intermediate (assembler) file name */
27.49 -SC_VDEFINE char binfname[_MAX_PATH]; /* binary file name */
27.50 -SC_VDEFINE char errfname[_MAX_PATH]; /* error file name */
27.51 -SC_VDEFINE char sc_ctrlchar = CTRL_CHAR; /* the control character (or escape character)*/
27.52 -SC_VDEFINE char sc_ctrlchar_org = CTRL_CHAR;/* the default control character */
27.53 -SC_VDEFINE int litidx = 0; /* index to literal table */
27.54 -SC_VDEFINE int litmax = sDEF_LITMAX; /* current size of the literal table */
27.55 -SC_VDEFINE int stgidx = 0; /* index to the staging buffer */
27.56 -SC_VDEFINE int sc_labnum = 0; /* number of (internal) labels */
27.57 -SC_VDEFINE int staging = 0; /* true if staging output */
27.58 -SC_VDEFINE cell declared = 0; /* number of local cells declared */
27.59 -SC_VDEFINE cell glb_declared=0; /* number of global cells declared */
27.60 -SC_VDEFINE cell code_idx = 0; /* number of bytes with generated code */
27.61 -SC_VDEFINE int ntv_funcid= 0; /* incremental number of native function */
27.62 -SC_VDEFINE int errnum = 0; /* number of errors */
27.63 -SC_VDEFINE int warnnum = 0; /* number of warnings */
27.64 -SC_VDEFINE int sc_debug = sCHKBOUNDS; /* by default: bounds checking+assertions */
27.65 -SC_VDEFINE int sc_packstr= FALSE; /* strings are packed by default? */
27.66 -SC_VDEFINE int sc_asmfile= FALSE; /* create .ASM file? */
27.67 -SC_VDEFINE int sc_listing= FALSE; /* create .LST file? */
27.68 -SC_VDEFINE int sc_compress=TRUE; /* compress bytecode? */
27.69 -SC_VDEFINE int sc_needsemicolon=TRUE;/* semicolon required to terminate expressions? */
27.70 -SC_VDEFINE int sc_dataalign=sizeof(cell);/* data alignment value */
27.71 -SC_VDEFINE int sc_alignnext=FALSE; /* must frame of the next function be aligned? */
27.72 -SC_VDEFINE int pc_docexpr=FALSE; /* must expression be attached to documentation comment? */
27.73 -SC_VDEFINE int curseg = 0; /* 1 if currently parsing CODE, 2 if parsing DATA */
27.74 -SC_VDEFINE cell pc_stksize=sDEF_AMXSTACK;/* default stack size */
27.75 -SC_VDEFINE cell pc_amxlimit=0; /* default abstract machine size limit = none */
27.76 -SC_VDEFINE cell pc_amxram=0; /* default abstract machine data size limit = none */
27.77 -SC_VDEFINE int freading = FALSE; /* Is there an input file ready for reading? */
27.78 -SC_VDEFINE int fline = 0; /* the line number in the current file */
27.79 -SC_VDEFINE short fnumber = 0; /* the file number in the file table (debugging) */
27.80 -SC_VDEFINE short fcurrent= 0; /* current file being processed (debugging) */
27.81 -SC_VDEFINE short sc_intest=FALSE; /* true if inside a test */
27.82 -SC_VDEFINE int sideeffect= 0; /* true if an expression causes a side-effect */
27.83 -SC_VDEFINE int stmtindent= 0; /* current indent of the statement */
27.84 -SC_VDEFINE int indent_nowarn=FALSE;/* skip warning "217 loose indentation" */
27.85 -SC_VDEFINE int sc_tabsize=8; /* number of spaces that a TAB represents */
27.86 -SC_VDEFINE short sc_allowtags=TRUE; /* allow/detect tagnames in lex() */
27.87 -SC_VDEFINE int sc_status; /* read/write status */
27.88 -SC_VDEFINE int sc_rationaltag=0; /* tag for rational numbers */
27.89 -SC_VDEFINE int rational_digits=0; /* number of fractional digits */
27.90 -SC_VDEFINE int sc_allowproccall=0; /* allow/detect tagnames in lex() */
27.91 -SC_VDEFINE short sc_is_utf8=FALSE; /* is this source file in UTF-8 encoding */
27.92 -SC_VDEFINE char *pc_depricate=NULL;/* if non-null, mark next declaration as depricated */
27.93 -SC_VDEFINE int sc_curstates=0; /* ID of the current state list */
27.94 -SC_VDEFINE int pc_optimize=sOPTIMIZE_NOMACRO; /* (peephole) optimization level */
27.95 -SC_VDEFINE int pc_memflags=0; /* special flags for the stack/heap usage */
27.96 -
27.97 -SC_VDEFINE constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */
27.98 -SC_VDEFINE constvalue sc_state_tab = { NULL, "", 0, 0}; /* state table */
27.99 -
27.100 -SC_VDEFINE FILE *inpf = NULL; /* file read from (source or include) */
27.101 -SC_VDEFINE FILE *inpf_org= NULL; /* main source file */
27.102 -SC_VDEFINE FILE *outf = NULL; /* (intermediate) text file written to */
27.103 -
27.104 -SC_VDEFINE jmp_buf errbuf;
27.105 -
27.106 -#if !defined SC_LIGHT
27.107 - SC_VDEFINE int sc_makereport=FALSE; /* generate a cross-reference report */
27.108 -#endif
27.109 -
27.110 -#if defined __WATCOMC__ && !defined NDEBUG
27.111 - /* Watcom's CVPACK dislikes .OBJ files without functions */
27.112 - static int dummyfunc(void)
27.113 - {
27.114 - return 0;
27.115 - }
27.116 -#endif
28.1 --- a/compiler-init/sp_file.h Sat Jul 15 05:02:38 2006 +0000
28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
28.3 @@ -1,110 +0,0 @@
28.4 -#ifndef _INCLUDE_SPFILE_H
28.5 -#define _INCLUDE_SPFILE_H
28.6 -
28.7 -#include <stddef.h>
28.8 -#if defined __GNUC__ || defined HAVE_STDINT_
28.9 -#include <stdint.h>
28.10 -#else
28.11 - #if !defined HAVE_STDINT_H
28.12 - typedef unsigned __int64 uint64_t;
28.13 - typedef __int64 int64_t;
28.14 - typedef unsigned __int32 uint32_t;
28.15 - typedef __int32 int32_t;
28.16 - typedef unsigned __int16 uint16_t;
28.17 - typedef __int16 int16_t;
28.18 - typedef unsigned __int8 uint8_t;
28.19 - typedef __int8 int8_t;
28.20 - #define HAVE_STDINT_H
28.21 - #endif
28.22 -#endif
28.23 -
28.24 -#define SPFILE_MAGIC 0xDEADC0D3
28.25 -#define SPFILE_VERSION 0x0100
28.26 -
28.27 -//:TODO: better compiler/nix support
28.28 -#if defined __linux__
28.29 - #pragma pack(1) /* structures must be packed (byte-aligned) */
28.30 -#else
28.31 - #pragma pack(push)
28.32 - #pragma pack(1) /* structures must be packed (byte-aligned) */
28.33 -#endif
28.34 -
28.35 -typedef struct sp_file_section_s
28.36 -{
28.37 - uint32_t nameoffs; /* rel offset into global string table */
28.38 - uint32_t dataoffs;
28.39 - uint32_t size;
28.40 -} sp_file_section_t;
28.41 -
28.42 -typedef struct sp_file_hdr_s
28.43 -{
28.44 - uint32_t magic;
28.45 - uint16_t version;
28.46 - uint32_t imagesize;
28.47 - uint8_t sections;
28.48 - uint32_t stringtab;
28.49 -} sp_file_hdr_t;
28.50 -
28.51 -typedef enum
28.52 -{
28.53 - SP_FILE_NONE = 0,
28.54 - SP_FILE_DEBUG = 1,
28.55 -} sp_file_flags_t;
28.56 -
28.57 -/* section is ".code" */
28.58 -typedef struct sp_file_code_s
28.59 -{
28.60 - uint32_t codesize; /* codesize in bytes */
28.61 - uint8_t cellsize; /* cellsize in bytes */
28.62 - uint8_t codeversion; /* version of opcodes supported */
28.63 - uint16_t flags; /* flags */
28.64 - uint32_t main; /* address to "main" if any */
28.65 - uint32_t disksize; /* disksize in bytes */
28.66 - uint32_t compression; /* compression */
28.67 - uint32_t code; /* rel offset to code */
28.68 -} sp_file_code_t;
28.69 -
28.70 -#define SPFILE_COMPRESSION_NONE 0
28.71 -#define SPFILE_COMPRESSION_GZ 1
28.72 -
28.73 -/* section is .data */
28.74 -typedef struct sp_file_data_s
28.75 -{
28.76 - uint32_t datasize; /* size of data section in memory */
28.77 - uint32_t memsize; /* total mem required (includes data) */
28.78 - uint32_t disksize; /* size of data on disk (compressed) */
28.79 - uint8_t compression; /* compression */
28.80 - uint32_t data; /* file offset to data (helper) */
28.81 -} sp_file_data_t;
28.82 -
28.83 -/* section is .publics */
28.84 -typedef struct sp_file_publics_s
28.85 -{
28.86 - uint32_t address; /* address rel to code section */
28.87 - uint32_t name; /* index into nametable */
28.88 -} sp_file_publics_t;
28.89 -
28.90 -/* section is .natives */
28.91 -typedef struct sp_file_natives_s
28.92 -{
28.93 - uint32_t name; /* name of native at index */
28.94 -} sp_file_natives_t;
28.95 -
28.96 -/* section is .pubvars */
28.97 -typedef struct sp_file_pubvars_s
28.98 -{
28.99 - uint32_t address; /* address rel to dat section */
28.100 - uint32_t name; /* index into nametable */
28.101 -} sp_file_pubvars_t;
28.102 -
28.103 -#if defined __linux__
28.104 - #pragma pack() /* reset default packing */
28.105 -#else
28.106 - #pragma pack(pop) /* reset previous packing */
28.107 -#endif
28.108 -
28.109 -
28.110 -/* section is .names */
28.111 -typedef char * sp_file_nametab_t;
28.112 -
28.113 -#endif //_INCLUDE_SPFILE_H
29.1 --- a/compiler-init/spcomp.sln Sat Jul 15 05:02:38 2006 +0000
29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
29.3 @@ -1,20 +0,0 @@
29.4 -
29.5 -Microsoft Visual Studio Solution File, Format Version 9.00
29.6 -# Visual Studio 2005
29.7 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spcomp", "spcomp.vcproj", "{B4C844FF-008D-4BD5-B82F-DC06E706C64B}"
29.8 -EndProject
29.9 -Global
29.10 - GlobalSection(SolutionConfigurationPlatforms) = preSolution
29.11 - Debug|Win32 = Debug|Win32
29.12 - Release|Win32 = Release|Win32
29.13 - EndGlobalSection
29.14 - GlobalSection(ProjectConfigurationPlatforms) = postSolution
29.15 - {B4C844FF-008D-4BD5-B82F-DC06E706C64B}.Debug|Win32.ActiveCfg = Debug|Win32
29.16 - {B4C844FF-008D-4BD5-B82F-DC06E706C64B}.Debug|Win32.Build.0 = Debug|Win32
29.17 - {B4C844FF-008D-4BD5-B82F-DC06E706C64B}.Release|Win32.ActiveCfg = Release|Win32
29.18 - {B4C844FF-008D-4BD5-B82F-DC06E706C64B}.Release|Win32.Build.0 = Release|Win32
29.19 - EndGlobalSection
29.20 - GlobalSection(SolutionProperties) = preSolution
29.21 - HideSolutionNode = FALSE
29.22 - EndGlobalSection
29.23 -EndGlobal
30.1 --- a/compiler-init/spcomp.vcproj Sat Jul 15 05:02:38 2006 +0000
30.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
30.3 @@ -1,409 +0,0 @@
30.4 -<?xml version="1.0" encoding="Windows-1252"?>
30.5 -<VisualStudioProject
30.6 - ProjectType="Visual C++"
30.7 - Version="8.00"
30.8 - Name="spcomp"
30.9 - ProjectGUID="{B4C844FF-008D-4BD5-B82F-DC06E706C64B}"
30.10 - RootNamespace="spcomp"
30.11 - Keyword="Win32Proj"
30.12 - >
30.13 - <Platforms>
30.14 - <Platform
30.15 - Name="Win32"
30.16 - />
30.17 - </Platforms>
30.18 - <ToolFiles>
30.19 - </ToolFiles>
30.20 - <Configurations>
30.21 - <Configuration
30.22 - Name="Debug|Win32"
30.23 - OutputDirectory="$(SolutionDir)$(ConfigurationName)"
30.24 - IntermediateDirectory="$(ConfigurationName)"
30.25 - ConfigurationType="1"
30.26 - CharacterSet="1"
30.27 - >
30.28 - <Tool
30.29 - Name="VCPreBuildEventTool"
30.30 - />
30.31 - <Tool
30.32 - Name="VCCustomBuildTool"
30.33 - />
30.34 - <Tool
30.35 - Name="VCXMLDataGeneratorTool"
30.36 - />
30.37 - <Tool
30.38 - Name="VCWebServiceProxyGeneratorTool"
30.39 - />
30.40 - <Tool
30.41 - Name="VCMIDLTool"
30.42 - />
30.43 - <Tool
30.44 - Name="VCCLCompilerTool"
30.45 - Optimization="0"
30.46 - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
30.47 - MinimalRebuild="true"
30.48 - BasicRuntimeChecks="3"
30.49 - RuntimeLibrary="1"
30.50 - UsePrecompiledHeader="0"
30.51 - WarningLevel="3"
30.52 - Detect64BitPortabilityProblems="false"
30.53 - DebugInformationFormat="4"
30.54 - />
30.55 - <Tool
30.56 - Name="VCManagedResourceCompilerTool"
30.57 - />
30.58 - <Tool
30.59 - Name="VCResourceCompilerTool"
30.60 - />
30.61 - <Tool
30.62 - Name="VCPreLinkEventTool"
30.63 - />
30.64 - <Tool
30.65 - Name="VCLinkerTool"
30.66 - LinkIncremental="2"
30.67 - GenerateDebugInformation="true"
30.68 - SubSystem="1"
30.69 - TargetMachine="1"
30.70 - />
30.71 - <Tool
30.72 - Name="VCALinkTool"
30.73 - />
30.74 - <Tool
30.75 - Name="VCManifestTool"
30.76 - />
30.77 - <Tool
30.78 - Name="VCXDCMakeTool"
30.79 - />
30.80 - <Tool
30.81 - Name="VCBscMakeTool"
30.82 - />
30.83 - <Tool
30.84 - Name="VCFxCopTool"
30.85 - />
30.86 - <Tool
30.87 - Name="VCAppVerifierTool"
30.88 - />
30.89 - <Tool
30.90 - Name="VCWebDeploymentTool"
30.91 - />
30.92 - <Tool
30.93 - Name="VCPostBuildEventTool"
30.94 - />
30.95 - </Configuration>
30.96 - <Configuration
30.97 - Name="Release|Win32"
30.98 - OutputDirectory="$(SolutionDir)$(ConfigurationName)"
30.99 - IntermediateDirectory="$(ConfigurationName)"
30.100 - ConfigurationType="1"
30.101 - CharacterSet="1"
30.102 - WholeProgramOptimization="1"
30.103 - >
30.104 - <Tool
30.105 - Name="VCPreBuildEventTool"
30.106 - />
30.107 - <Tool
30.108 - Name="VCCustomBuildTool"
30.109 - />
30.110 - <Tool
30.111 - Name="VCXMLDataGeneratorTool"
30.112 - />
30.113 - <Tool
30.114 - Name="VCWebServiceProxyGeneratorTool"
30.115 - />
30.116 - <Tool
30.117 - Name="VCMIDLTool"
30.118 - />
30.119 - <Tool
30.120 - Name="VCCLCompilerTool"
30.121 - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
30.122 - RuntimeLibrary="0"
30.123 - UsePrecompiledHeader="0"
30.124 - WarningLevel="3"
30.125 - Detect64BitPortabilityProblems="false"
30.126 - DebugInformationFormat="3"
30.127 - />
30.128 - <Tool
30.129 - Name="VCManagedResourceCompilerTool"
30.130 - />
30.131 - <Tool
30.132 - Name="VCResourceCompilerTool"
30.133 - />
30.134 - <Tool
30.135 - Name="VCPreLinkEventTool"
30.136 - />
30.137 - <Tool
30.138 - Name="VCLinkerTool"
30.139 - LinkIncremental="1"
30.140 - GenerateDebugInformation="true"
30.141 - SubSystem="1"
30.142 - OptimizeReferences="2"
30.143 - EnableCOMDATFolding="2"
30.144 - TargetMachine="1"
30.145 - />
30.146 - <Tool
30.147 - Name="VCALinkTool"
30.148 - />
30.149 - <Tool
30.150 - Name="VCManifestTool"
30.151 - />
30.152 - <Tool
30.153 - Name="VCXDCMakeTool"
30.154 - />
30.155 - <Tool
30.156 - Name="VCBscMakeTool"
30.157 - />
30.158 - <Tool
30.159 - Name="VCFxCopTool"
30.160 - />
30.161 - <Tool
30.162 - Name="VCAppVerifierTool"
30.163 - />
30.164 - <Tool
30.165 - Name="VCWebDeploymentTool"
30.166 - />
30.167 - <Tool
30.168 - Name="VCPostBuildEventTool"
30.169 - />
30.170 - </Configuration>
30.171 - </Configurations>
30.172 - <References>
30.173 - </References>
30.174 - <Files>
30.175 - <Filter
30.176 - Name="Source Files"
30.177 - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
30.178 - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
30.179 - >
30.180 - <File
30.181 - RelativePath=".\libpawnc.c"
30.182 - >
30.183 - </File>
30.184 - <File
30.185 - RelativePath=".\lstring.c"
30.186 - >
30.187 - </File>
30.188 - <File
30.189 - RelativePath=".\memfile.c"
30.190 - >
30.191 - </File>
30.192 - <File
30.193 - RelativePath=".\pawncc.c"
30.194 - >
30.195 - </File>
30.196 - <File
30.197 - RelativePath=".\sc1.c"
30.198 - >
30.199 - </File>
30.200 - <File
30.201 - RelativePath=".\sc2.c"
30.202 - >
30.203 - </File>
30.204 - <File
30.205 - RelativePath=".\sc3.c"
30.206 - >
30.207 - </File>
30.208 - <File
30.209 - RelativePath=".\sc4.c"
30.210 - >
30.211 - </File>
30.212 - <File
30.213 - RelativePath=".\sc5.c"
30.214 - >
30.215 - </File>
30.216 - <File
30.217 - RelativePath=".\sc6.c"
30.218 - >
30.219 - </File>
30.220 - <File
30.221 - RelativePath=".\sc7.c"
30.222 - >
30.223 - </File>
30.224 - <File
30.225 - RelativePath=".\scexpand.c"
30.226 - >
30.227 - </File>
30.228 - <File
30.229 - RelativePath=".\sci18n.c"
30.230 - >
30.231 - </File>
30.232 - <File
30.233 - RelativePath=".\sclist.c"
30.234 - >
30.235 - </File>
30.236 - <File
30.237 - RelativePath=".\scmemfil.c"
30.238 - >
30.239 - <FileConfiguration
30.240 - Name="Debug|Win32"
30.241 - >
30.242 - <Tool
30.243 - Name="VCCLCompilerTool"
30.244 - Detect64BitPortabilityProblems="false"
30.245 - />
30.246 - </FileConfiguration>
30.247 - </File>
30.248 - <File
30.249 - RelativePath=".\scstate.c"
30.250 - >
30.251 - </File>
30.252 - <File
30.253 - RelativePath=".\scvars.c"
30.254 - >
30.255 - </File>
30.256 - </Filter>
30.257 - <Filter
30.258 - Name="Header Files"
30.259 - Filter="h;hpp;hxx;hm;inl;inc;xsd"
30.260 - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
30.261 - >
30.262 - <File
30.263 - RelativePath=".\amx.h"
30.264 - >
30.265 - </File>
30.266 - <File
30.267 - RelativePath=".\lstring.h"
30.268 - >
30.269 - </File>
30.270 - <File
30.271 - RelativePath=".\memfile.h"
30.272 - >
30.273 - </File>
30.274 - <File
30.275 - RelativePath=".\osdefs.h"
30.276 - >
30.277 - </File>
30.278 - <File
30.279 - RelativePath=".\sc.h"
30.280 - >
30.281 - </File>
30.282 - <File
30.283 - RelativePath=".\sp_file.h"
30.284 - >
30.285 - </File>
30.286 - <File
30.287 - RelativePath=".\svnrev.h"
30.288 - >
30.289 - </File>
30.290 - </Filter>
30.291 - <Filter
30.292 - Name="Resource Files"
30.293 - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
30.294 - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
30.295 - >
30.296 - <File
30.297 - RelativePath=".\libpawnc.rc"
30.298 - >
30.299 - </File>
30.300 - <File
30.301 - RelativePath=".\sc5.scp"
30.302 - >
30.303 - </File>
30.304 - <File
30.305 - RelativePath=".\sc7.scp"
30.306 - >
30.307 - </File>
30.308 - </Filter>
30.309 - <Filter
30.310 - Name="zlib"
30.311 - >
30.312 - <Filter
30.313 - Name="Source Files"
30.314 - >
30.315 - <File
30.316 - RelativePath=".\zlib\adler32.c"
30.317 - >
30.318 - </File>
30.319 - <File
30.320 - RelativePath=".\zlib\compress.c"
30.321 - >
30.322 - </File>
30.323 - <File
30.324 - RelativePath=".\zlib\crc32.c"
30.325 - >
30.326 - </File>
30.327 - <File
30.328 - RelativePath=".\zlib\deflate.c"
30.329 - >
30.330 - </File>
30.331 - <File
30.332 - RelativePath=".\zlib\gzio.c"
30.333 - >
30.334 - </File>
30.335 - <File
30.336 - RelativePath=".\zlib\infback.c"
30.337 - >
30.338 - </File>
30.339 - <File
30.340 - RelativePath=".\zlib\inffast.c"
30.341 - >
30.342 - </File>
30.343 - <File
30.344 - RelativePath=".\zlib\inflate.c"
30.345 - >
30.346 - </File>
30.347 - <File
30.348 - RelativePath=".\zlib\inftrees.c"
30.349 - >
30.350 - </File>
30.351 - <File
30.352 - RelativePath=".\zlib\trees.c"
30.353 - >
30.354 - </File>
30.355 - <File
30.356 - RelativePath=".\zlib\uncompr.c"
30.357 - >
30.358 - </File>
30.359 - <File
30.360 - RelativePath=".\zlib\zutil.c"
30.361 - >
30.362 - </File>
30.363 - </Filter>
30.364 - <Filter
30.365 - Name="Header Files"
30.366 - >
30.367 - <File
30.368 - RelativePath=".\zlib\crc32.h"
30.369 - >
30.370 - </File>
30.371 - <File
30.372 - RelativePath=".\zlib\deflate.h"
30.373 - >
30.374 - </File>
30.375 - <File
30.376 - RelativePath=".\zlib\inffast.h"
30.377 - >
30.378 - </File>
30.379 - <File
30.380 - RelativePath=".\zlib\inffixed.h"
30.381 - >
30.382 - </File>
30.383 - <File
30.384 - RelativePath=".\zlib\inflate.h"
30.385 - >
30.386 - </File>
30.387 - <File
30.388 - RelativePath=".\zlib\inftrees.h"
30.389 - >
30.390 - </File>
30.391 - <File
30.392 - RelativePath=".\zlib\trees.h"
30.393 - >
30.394 - </File>
30.395 - <File
30.396 - RelativePath=".\zlib\zconf.h"
30.397 - >
30.398 - </File>
30.399 - <File
30.400 - RelativePath=".\zlib\zlib.h"
30.401 - >
30.402 - </File>
30.403 - <File
30.404 - RelativePath=".\zlib\zutil.h"
30.405 - >
30.406 - </File>
30.407 - </Filter>
30.408 - </Filter>
30.409 - </Files>
30.410 - <Globals>
30.411 - </Globals>
30.412 -</VisualStudioProject>
31.1 --- a/compiler-init/svnrev.h Sat Jul 15 05:02:38 2006 +0000
31.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
31.3 @@ -1,9 +0,0 @@
31.4 -#define SMC_VERSION 1
31.5 -#define SMC_REVISION 0
31.6 -#define SMC_BUILD 1
31.7 -#define SMC_VERSTRING "1.0.1.3599"
31.8 -
31.9 -#define SVN_REV 3599
31.10 -#define SVN_REVSTR "3599"
31.11 -#define SVN_REVDATE "2006-07-05"
31.12 -#define SVN_REVSTAMP 20060705L
32.1 --- a/compiler-init/zlib/adler32.c Sat Jul 15 05:02:38 2006 +0000
32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
32.3 @@ -1,149 +0,0 @@
32.4 -/* adler32.c -- compute the Adler-32 checksum of a data stream
32.5 - * Copyright (C) 1995-2004 Mark Adler
32.6 - * For conditions of distribution and use, see copyright notice in zlib.h
32.7 - */
32.8 -
32.9 -/* @(#) $Id$ */
32.10 -
32.11 -#define ZLIB_INTERNAL
32.12 -#include "zlib.h"
32.13 -
32.14 -#define BASE 65521UL /* largest prime smaller than 65536 */
32.15 -#define NMAX 5552
32.16 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
32.17 -
32.18 -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
32.19 -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
32.20 -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
32.21 -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
32.22 -#define DO16(buf) DO8(buf,0); DO8(buf,8);
32.23 -
32.24 -/* use NO_DIVIDE if your processor does not do division in hardware */
32.25 -#ifdef NO_DIVIDE
32.26 -# define MOD(a) \
32.27 - do { \
32.28 - if (a >= (BASE << 16)) a -= (BASE << 16); \
32.29 - if (a >= (BASE << 15)) a -= (BASE << 15); \
32.30 - if (a >= (BASE << 14)) a -= (BASE << 14); \
32.31 - if (a >= (BASE << 13)) a -= (BASE << 13); \
32.32 - if (a >= (BASE << 12)) a -= (BASE << 12); \
32.33 - if (a >= (BASE << 11)) a -= (BASE << 11); \
32.34 - if (a >= (BASE << 10)) a -= (BASE << 10); \
32.35 - if (a >= (BASE << 9)) a -= (BASE << 9); \
32.36 - if (a >= (BASE << 8)) a -= (BASE << 8); \
32.37 - if (a >= (BASE << 7)) a -= (BASE << 7); \
32.38 - if (a >= (BASE << 6)) a -= (BASE << 6); \
32.39 - if (a >= (BASE << 5)) a -= (BASE << 5); \
32.40 - if (a >= (BASE << 4)) a -= (BASE << 4); \
32.41 - if (a >= (BASE << 3)) a -= (BASE << 3); \
32.42 - if (a >= (BASE << 2)) a -= (BASE << 2); \
32.43 - if (a >= (BASE << 1)) a -= (BASE << 1); \
32.44 - if (a >= BASE) a -= BASE; \
32.45 - } while (0)
32.46 -# define MOD4(a) \
32.47 - do { \
32.48 - if (a >= (BASE << 4)) a -= (BASE << 4); \
32.49 - if (a >= (BASE << 3)) a -= (BASE << 3); \
32.50 - if (a >= (BASE << 2)) a -= (BASE << 2); \
32.51 - if (a >= (BASE << 1)) a -= (BASE << 1); \
32.52 - if (a >= BASE) a -= BASE; \
32.53 - } while (0)
32.54 -#else
32.55 -# define MOD(a) a %= BASE
32.56 -# define MOD4(a) a %= BASE
32.57 -#endif
32.58 -
32.59 -/* ========================================================================= */
32.60 -uLong ZEXPORT adler32(adler, buf, len)
32.61 - uLong adler;
32.62 - const Bytef *buf;
32.63 - uInt len;
32.64 -{
32.65 - unsigned long sum2;
32.66 - unsigned n;
32.67 -
32.68 - /* split Adler-32 into component sums */
32.69 - sum2 = (adler >> 16) & 0xffff;
32.70 - adler &= 0xffff;
32.71 -
32.72 - /* in case user likes doing a byte at a time, keep it fast */
32.73 - if (len == 1) {
32.74 - adler += buf[0];
32.75 - if (adler >= BASE)
32.76 - adler -= BASE;
32.77 - sum2 += adler;
32.78 - if (sum2 >= BASE)
32.79 - sum2 -= BASE;
32.80 - return adler | (sum2 << 16);
32.81 - }
32.82 -
32.83 - /* initial Adler-32 value (deferred check for len == 1 speed) */
32.84 - if (buf == Z_NULL)
32.85 - return 1L;
32.86 -
32.87 - /* in case short lengths are provided, keep it somewhat fast */
32.88 - if (len < 16) {
32.89 - while (len--) {
32.90 - adler += *buf++;
32.91 - sum2 += adler;
32.92 - }
32.93 - if (adler >= BASE)
32.94 - adler -= BASE;
32.95 - MOD4(sum2); /* only added so many BASE's */
32.96 - return adler | (sum2 << 16);
32.97 - }
32.98 -
32.99 - /* do length NMAX blocks -- requires just one modulo operation */
32.100 - while (len >= NMAX) {
32.101 - len -= NMAX;
32.102 - n = NMAX / 16; /* NMAX is divisible by 16 */
32.103 - do {
32.104 - DO16(buf); /* 16 sums unrolled */
32.105 - buf += 16;
32.106 - } while (--n);
32.107 - MOD(adler);
32.108 - MOD(sum2);
32.109 - }
32.110 -
32.111 - /* do remaining bytes (less than NMAX, still just one modulo) */
32.112 - if (len) { /* avoid modulos if none remaining */
32.113 - while (len >= 16) {
32.114 - len -= 16;
32.115 - DO16(buf);
32.116 - buf += 16;
32.117 - }
32.118 - while (len--) {
32.119 - adler += *buf++;
32.120 - sum2 += adler;
32.121 - }
32.122 - MOD(adler);
32.123 - MOD(sum2);
32.124 - }
32.125 -
32.126 - /* return recombined sums */
32.127 - return adler | (sum2 << 16);
32.128 -}
32.129 -
32.130 -/* ========================================================================= */
32.131 -uLong ZEXPORT adler32_combine(adler1, adler2, len2)
32.132 - uLong adler1;
32.133 - uLong adler2;
32.134 - z_off_t len2;
32.135 -{
32.136 - unsigned long sum1;
32.137 - unsigned long sum2;
32.138 - unsigned rem;
32.139 -
32.140 - /* the derivation of this formula is left as an exercise for the reader */
32.141 - rem = (unsigned)(len2 % BASE);
32.142 - sum1 = adler1 & 0xffff;
32.143 - sum2 = rem * sum1;
32.144 - MOD(sum2);
32.145 - sum1 += (adler2 & 0xffff) + BASE - 1;
32.146 - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
32.147 - if (sum1 > BASE) sum1 -= BASE;
32.148 - if (sum1 > BASE) sum1 -= BASE;
32.149 - if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
32.150 - if (sum2 > BASE) sum2 -= BASE;
32.151 - return sum1 | (sum2 << 16);
32.152 -}
33.1 --- a/compiler-init/zlib/compress.c Sat Jul 15 05:02:38 2006 +0000
33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
33.3 @@ -1,79 +0,0 @@
33.4 -/* compress.c -- compress a memory buffer
33.5 - * Copyright (C) 1995-2003 Jean-loup Gailly.
33.6 - * For conditions of distribution and use, see copyright notice in zlib.h
33.7 - */
33.8 -
33.9 -/* @(#) $Id$ */
33.10 -
33.11 -#define ZLIB_INTERNAL
33.12 -#include "zlib.h"
33.13 -
33.14 -/* ===========================================================================
33.15 - Compresses the source buffer into the destination buffer. The level
33.16 - parameter has the same meaning as in deflateInit. sourceLen is the byte
33.17 - length of the source buffer. Upon entry, destLen is the total size of the
33.18 - destination buffer, which must be at least 0.1% larger than sourceLen plus
33.19 - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
33.20 -
33.21 - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
33.22 - memory, Z_BUF_ERROR if there was not enough room in the output buffer,
33.23 - Z_STREAM_ERROR if the level parameter is invalid.
33.24 -*/
33.25 -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
33.26 - Bytef *dest;
33.27 - uLongf *destLen;
33.28 - const Bytef *source;
33.29 - uLong sourceLen;
33.30 - int level;
33.31 -{
33.32 - z_stream stream;
33.33 - int err;
33.34 -
33.35 - stream.next_in = (Bytef*)source;
33.36 - stream.avail_in = (uInt)sourceLen;
33.37 -#ifdef MAXSEG_64K
33.38 - /* Check for source > 64K on 16-bit machine: */
33.39 - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
33.40 -#endif
33.41 - stream.next_out = dest;
33.42 - stream.avail_out = (uInt)*destLen;
33.43 - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
33.44 -
33.45 - stream.zalloc = (alloc_func)0;
33.46 - stream.zfree = (free_func)0;
33.47 - stream.opaque = (voidpf)0;
33.48 -
33.49 - err = deflateInit(&stream, level);
33.50 - if (err != Z_OK) return err;
33.51 -
33.52 - err = deflate(&stream, Z_FINISH);
33.53 - if (err != Z_STREAM_END) {
33.54 - deflateEnd(&stream);
33.55 - return err == Z_OK ? Z_BUF_ERROR : err;
33.56 - }
33.57 - *destLen = stream.total_out;
33.58 -
33.59 - err = deflateEnd(&stream);
33.60 - return err;
33.61 -}
33.62 -
33.63 -/* ===========================================================================
33.64 - */
33.65 -int ZEXPORT compress (dest, destLen, source, sourceLen)
33.66 - Bytef *dest;
33.67 - uLongf *destLen;
33.68 - const Bytef *source;
33.69 - uLong sourceLen;
33.70 -{
33.71 - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
33.72 -}
33.73 -
33.74 -/* ===========================================================================
33.75 - If the default memLevel or windowBits for deflateInit() is changed, then
33.76 - this function needs to be updated.
33.77 - */
33.78 -uLong ZEXPORT compressBound (sourceLen)
33.79 - uLong sourceLen;
33.80 -{
33.81 - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
33.82 -}
34.1 --- a/compiler-init/zlib/crc32.c Sat Jul 15 05:02:38 2006 +0000
34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
34.3 @@ -1,423 +0,0 @@
34.4 -/* crc32.c -- compute the CRC-32 of a data stream
34.5 - * Copyright (C) 1995-2005 Mark Adler
34.6 - * For conditions of distribution and use, see copyright notice in zlib.h
34.7 - *
34.8 - * Thanks to Rodney Brown <[email protected]> for his contribution of faster
34.9 - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
34.10 - * tables for updating the shift register in one step with three exclusive-ors
34.11 - * instead of four steps with four exclusive-ors. This results in about a
34.12 - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
34.13 - */
34.14 -
34.15 -/* @(#) $Id$ */
34.16 -
34.17 -/*
34.18 - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
34.19 - protection on the static variables used to control the first-use generation
34.20 - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
34.21 - first call get_crc_table() to initialize the tables before allowing more than
34.22 - one thread to use crc32().
34.23 - */
34.24 -
34.25 -#ifdef MAKECRCH
34.26 -# include <stdio.h>
34.27 -# ifndef DYNAMIC_CRC_TABLE
34.28 -# define DYNAMIC_CRC_TABLE
34.29 -# endif /* !DYNAMIC_CRC_TABLE */
34.30 -#endif /* MAKECRCH */
34.31 -
34.32 -#include "zutil.h" /* for STDC and FAR definitions */
34.33 -
34.34 -#define local static
34.35 -
34.36 -/* Find a four-byte integer type for crc32_little() and crc32_big(). */
34.37 -#ifndef NOBYFOUR
34.38 -# ifdef STDC /* need ANSI C limits.h to determine sizes */
34.39 -# include <limits.h>
34.40 -# define BYFOUR
34.41 -# if (UINT_MAX == 0xffffffffUL)
34.42 - typedef unsigned int u4;
34.43 -# else
34.44 -# if (ULONG_MAX == 0xffffffffUL)
34.45 - typedef unsigned long u4;
34.46 -# else
34.47 -# if (USHRT_MAX == 0xffffffffUL)
34.48 - typedef unsigned short u4;
34.49 -# else
34.50 -# undef BYFOUR /* can't find a four-byte integer type! */
34.51 -# endif
34.52 -# endif
34.53 -# endif
34.54 -# endif /* STDC */
34.55 -#endif /* !NOBYFOUR */
34.56 -
34.57 -/* Definitions for doing the crc four data bytes at a time. */
34.58 -#ifdef BYFOUR
34.59 -# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
34.60 - (((w)&0xff00)<<8)+(((w)&0xff)<<24))
34.61 - local unsigned long crc32_little OF((unsigned long,
34.62 - const unsigned char FAR *, unsigned));
34.63 - local unsigned long crc32_big OF((unsigned long,
34.64 - const unsigned char FAR *, unsigned));
34.65 -# define TBLS 8
34.66 -#else
34.67 -# define TBLS 1
34.68 -#endif /* BYFOUR */
34.69 -
34.70 -/* Local functions for crc concatenation */
34.71 -local unsigned long gf2_matrix_times OF((unsigned long *mat,
34.72 - unsigned long vec));
34.73 -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
34.74 -
34.75 -#ifdef DYNAMIC_CRC_TABLE
34.76 -
34.77 -local volatile int crc_table_empty = 1;
34.78 -local unsigned long FAR crc_table[TBLS][256];
34.79 -local void make_crc_table OF((void));
34.80 -#ifdef MAKECRCH
34.81 - local void write_table OF((FILE *, const unsigned long FAR *));
34.82 -#endif /* MAKECRCH */
34.83 -/*
34.84 - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
34.85 - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
34.86 -
34.87 - Polynomials over GF(2) are represented in binary, one bit per coefficient,
34.88 - with the lowest powers in the most significant bit. Then adding polynomials
34.89 - is just exclusive-or, and multiplying a polynomial by x is a right shift by
34.90 - one. If we call the above polynomial p, and represent a byte as the
34.91 - polynomial q, also with the lowest power in the most significant bit (so the
34.92 - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
34.93 - where a mod b means the remainder after dividing a by b.
34.94 -
34.95 - This calculation is done using the shift-register method of multiplying and
34.96 - taking the remainder. The register is initialized to zero, and for each
34.97 - incoming bit, x^32 is added mod p to the register if the bit is a one (where
34.98 - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
34.99 - x (which is shifting right by one and adding x^32 mod p if the bit shifted
34.100 - out is a one). We start with the highest power (least significant bit) of
34.101 - q and repeat for all eight bits of q.
34.102 -
34.103 - The first table is simply the CRC of all possible eight bit values. This is
34.104 - all the information needed to generate CRCs on data a byte at a time for all
34.105 - combinations of CRC register values and incoming bytes. The remaining tables
34.106 - allow for word-at-a-time CRC calculation for both big-endian and little-
34.107 - endian machines, where a word is four bytes.
34.108 -*/
34.109 -local void make_crc_table()
34.110 -{
34.111 - unsigned long c;
34.112 - int n, k;
34.113 - unsigned long poly; /* polynomial exclusive-or pattern */
34.114 - /* terms of polynomial defining this crc (except x^32): */
34.115 - static volatile int first = 1; /* flag to limit concurrent making */
34.116 - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
34.117 -
34.118 - /* See if another task is already doing this (not thread-safe, but better
34.119 - than nothing -- significantly reduces duration of vulnerability in
34.120 - case the advice about DYNAMIC_CRC_TABLE is ignored) */
34.121 - if (first) {
34.122 - first = 0;
34.123 -
34.124 - /* make exclusive-or pattern from polynomial (0xedb88320UL) */
34.125 - poly = 0UL;
34.126 - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
34.127 - poly |= 1UL << (31 - p[n]);
34.128 -
34.129 - /* generate a crc for every 8-bit value */
34.130 - for (n = 0; n < 256; n++) {
34.131 - c = (unsigned long)n;
34.132 - for (k = 0; k < 8; k++)
34.133 - c = c & 1 ? poly ^ (c >> 1) : c >> 1;
34.134 - crc_table[0][n] = c;
34.135 - }
34.136 -
34.137 -#ifdef BYFOUR
34.138 - /* generate crc for each value followed by one, two, and three zeros,
34.139 - and then the byte reversal of those as well as the first table */
34.140 - for (n = 0; n < 256; n++) {
34.141 - c = crc_table[0][n];
34.142 - crc_table[4][n] = REV(c);
34.143 - for (k = 1; k < 4; k++) {
34.144 - c = crc_table[0][c & 0xff] ^ (c >> 8);
34.145 - crc_table[k][n] = c;
34.146 - crc_table[k + 4][n] = REV(c);
34.147 - }
34.148 - }
34.149 -#endif /* BYFOUR */
34.150 -
34.151 - crc_table_empty = 0;
34.152 - }
34.153 - else { /* not first */
34.154 - /* wait for the other guy to finish (not efficient, but rare) */
34.155 - while (crc_table_empty)
34.156 - ;
34.157 - }
34.158 -
34.159 -#ifdef MAKECRCH
34.160 - /* write out CRC tables to crc32.h */
34.161 - {
34.162 - FILE *out;
34.163 -
34.164 - out = fopen("crc32.h", "w");
34.165 - if (out == NULL) return;
34.166 - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
34.167 - fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
34.168 - fprintf(out, "local const unsigned long FAR ");
34.169 - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
34.170 - write_table(out, crc_table[0]);
34.171 -# ifdef BYFOUR
34.172 - fprintf(out, "#ifdef BYFOUR\n");
34.173 - for (k = 1; k < 8; k++) {
34.174 - fprintf(out, " },\n {\n");
34.175 - write_table(out, crc_table[k]);
34.176 - }
34.177 - fprintf(out, "#endif\n");
34.178 -# endif /* BYFOUR */
34.179 - fprintf(out, " }\n};\n");
34.180 - fclose(out);
34.181 - }
34.182 -#endif /* MAKECRCH */
34.183 -}
34.184 -
34.185 -#ifdef MAKECRCH
34.186 -local void write_table(out, table)
34.187 - FILE *out;
34.188 - const unsigned long FAR *table;
34.189 -{
34.190 - int n;
34.191 -
34.192 - for (n = 0; n < 256; n++)
34.193 - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
34.194 - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
34.195 -}
34.196 -#endif /* MAKECRCH */
34.197 -
34.198 -#else /* !DYNAMIC_CRC_TABLE */
34.199 -/* ========================================================================
34.200 - * Tables of CRC-32s of all single-byte values, made by make_crc_table().
34.201 - */
34.202 -#include "crc32.h"
34.203 -#endif /* DYNAMIC_CRC_TABLE */
34.204 -
34.205 -/* =========================================================================
34.206 - * This function can be used by asm versions of crc32()
34.207 - */
34.208 -const unsigned long FAR * ZEXPORT get_crc_table()
34.209 -{
34.210 -#ifdef DYNAMIC_CRC_TABLE
34.211 - if (crc_table_empty)
34.212 - make_crc_table();
34.213 -#endif /* DYNAMIC_CRC_TABLE */
34.214 - return (const unsigned long FAR *)crc_table;
34.215 -}
34.216 -
34.217 -/* ========================================================================= */
34.218 -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
34.219 -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
34.220 -
34.221 -/* ========================================================================= */
34.222 -unsigned long ZEXPORT crc32(crc, buf, len)
34.223 - unsigned long crc;
34.224 - const unsigned char FAR *buf;
34.225 - unsigned len;
34.226 -{
34.227 - if (buf == Z_NULL) return 0UL;
34.228 -
34.229 -#ifdef DYNAMIC_CRC_TABLE
34.230 - if (crc_table_empty)
34.231 - make_crc_table();
34.232 -#endif /* DYNAMIC_CRC_TABLE */
34.233 -
34.234 -#ifdef BYFOUR
34.235 - if (sizeof(void *) == sizeof(ptrdiff_t)) {
34.236 - u4 endian;
34.237 -
34.238 - endian = 1;
34.239 - if (*((unsigned char *)(&endian)))
34.240 - return crc32_little(crc, buf, len);
34.241 - else
34.242 - return crc32_big(crc, buf, len);
34.243 - }
34.244 -#endif /* BYFOUR */
34.245 - crc = crc ^ 0xffffffffUL;
34.246 - while (len >= 8) {
34.247 - DO8;
34.248 - len -= 8;
34.249 - }
34.250 - if (len) do {
34.251 - DO1;
34.252 - } while (--len);
34.253 - return crc ^ 0xffffffffUL;
34.254 -}
34.255 -
34.256 -#ifdef BYFOUR
34.257 -
34.258 -/* ========================================================================= */
34.259 -#define DOLIT4 c ^= *buf4++; \
34.260 - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
34.261 - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
34.262 -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
34.263 -
34.264 -/* ========================================================================= */
34.265 -local unsigned long crc32_little(crc, buf, len)
34.266 - unsigned long crc;
34.267 - const unsigned char FAR *buf;
34.268 - unsigned len;
34.269 -{
34.270 - register u4 c;
34.271 - register const u4 FAR *buf4;
34.272 -
34.273 - c = (u4)crc;
34.274 - c = ~c;
34.275 - while (len && ((ptrdiff_t)buf & 3)) {
34.276 - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
34.277 - len--;
34.278 - }
34.279 -
34.280 - buf4 = (const u4 FAR *)(const void FAR *)buf;
34.281 - while (len >= 32) {
34.282 - DOLIT32;
34.283 - len -= 32;
34.284 - }
34.285 - while (len >= 4) {
34.286 - DOLIT4;
34.287 - len -= 4;
34.288 - }
34.289 - buf = (const unsigned char FAR *)buf4;
34.290 -
34.291 - if (len) do {
34.292 - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
34.293 - } while (--len);
34.294 - c = ~c;
34.295 - return (unsigned long)c;
34.296 -}
34.297 -
34.298 -/* ========================================================================= */
34.299 -#define DOBIG4 c ^= *++buf4; \
34.300 - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
34.301 - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
34.302 -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
34.303 -
34.304 -/* ========================================================================= */
34.305 -local unsigned long crc32_big(crc, buf, len)
34.306 - unsigned long crc;
34.307 - const unsigned char FAR *buf;
34.308 - unsigned len;
34.309 -{
34.310 - register u4 c;
34.311 - register const u4 FAR *buf4;
34.312 -
34.313 - c = REV((u4)crc);
34.314 - c = ~c;
34.315 - while (len && ((ptrdiff_t)buf & 3)) {
34.316 - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
34.317 - len--;
34.318 - }
34.319 -
34.320 - buf4 = (const u4 FAR *)(const void FAR *)buf;
34.321 - buf4--;
34.322 - while (len >= 32) {
34.323 - DOBIG32;
34.324 - len -= 32;
34.325 - }
34.326 - while (len >= 4) {
34.327 - DOBIG4;
34.328 - len -= 4;
34.329 - }
34.330 - buf4++;
34.331 - buf = (const unsigned char FAR *)buf4;
34.332 -
34.333 - if (len) do {
34.334 - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
34.335 - } while (--len);
34.336 - c = ~c;
34.337 - return (unsigned long)(REV(c));
34.338 -}
34.339 -
34.340 -#endif /* BYFOUR */
34.341 -
34.342 -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
34.343 -
34.344 -/* ========================================================================= */
34.345 -local unsigned long gf2_matrix_times(mat, vec)
34.346 - unsigned long *mat;
34.347 - unsigned long vec;
34.348 -{
34.349 - unsigned long sum;
34.350 -
34.351 - sum = 0;
34.352 - while (vec) {
34.353 - if (vec & 1)
34.354 - sum ^= *mat;
34.355 - vec >>= 1;
34.356 - mat++;
34.357 - }
34.358 - return sum;
34.359 -}
34.360 -
34.361 -/* ========================================================================= */
34.362 -local void gf2_matrix_square(square, mat)
34.363 - unsigned long *square;
34.364 - unsigned long *mat;
34.365 -{
34.366 - int n;
34.367 -
34.368 - for (n = 0; n < GF2_DIM; n++)
34.369 - square[n] = gf2_matrix_times(mat, mat[n]);
34.370 -}
34.371 -
34.372 -/* ========================================================================= */
34.373 -uLong ZEXPORT crc32_combine(crc1, crc2, len2)
34.374 - uLong crc1;
34.375 - uLong crc2;
34.376 - z_off_t len2;
34.377 -{
34.378 - int n;
34.379 - unsigned long row;
34.380 - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
34.381 - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
34.382 -
34.383 - /* degenerate case */
34.384 - if (len2 == 0)
34.385 - return crc1;
34.386 -
34.387 - /* put operator for one zero bit in odd */
34.388 - odd[0] = 0xedb88320L; /* CRC-32 polynomial */
34.389 - row = 1;
34.390 - for (n = 1; n < GF2_DIM; n++) {
34.391 - odd[n] = row;
34.392 - row <<= 1;
34.393 - }
34.394 -
34.395 - /* put operator for two zero bits in even */
34.396 - gf2_matrix_square(even, odd);
34.397 -
34.398 - /* put operator for four zero bits in odd */
34.399 - gf2_matrix_square(odd, even);
34.400 -
34.401 - /* apply len2 zeros to crc1 (first square will put the operator for one
34.402 - zero byte, eight zero bits, in even) */
34.403 - do {
34.404 - /* apply zeros operator for this bit of len2 */
34.405 - gf2_matrix_square(even, odd);
34.406 - if (len2 & 1)
34.407 - crc1 = gf2_matrix_times(even, crc1);
34.408 - len2 >>= 1;
34.409 -
34.410 - /* if no more bits set, then done */
34.411 - if (len2 == 0)
34.412 - break;
34.413 -
34.414 - /* another iteration of the loop with odd and even swapped */
34.415 - gf2_matrix_square(odd, even);
34.416 - if (len2 & 1)
34.417 - crc1 = gf2_matrix_times(odd, crc1);
34.418 - len2 >>= 1;
34.419 -
34.420 - /* if no more bits set, then done */
34.421 - } while (len2 != 0);
34.422 -
34.423 - /* return combined crc */
34.424 - crc1 ^= crc2;
34.425 - return crc1;
34.426 -}
35.1 --- a/compiler-init/zlib/crc32.h Sat Jul 15 05:02:38 2006 +0000
35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
35.3 @@ -1,441 +0,0 @@
35.4 -/* crc32.h -- tables for rapid CRC calculation
35.5 - * Generated automatically by crc32.c
35.6 - */
35.7 -
35.8 -local const unsigned long FAR crc_table[TBLS][256] =
35.9 -{
35.10 - {
35.11 - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
35.12 - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
35.13 - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
35.14 - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
35.15 - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
35.16 - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
35.17 - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
35.18 - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
35.19 - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
35.20 - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
35.21 - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
35.22 - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
35.23 - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
35.24 - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
35.25 - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
35.26 - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
35.27 - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
35.28 - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
35.29 - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
35.30 - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
35.31 - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
35.32 - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
35.33 - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
35.34 - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
35.35 - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
35.36 - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
35.37 - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
35.38 - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
35.39 - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
35.40 - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
35.41 - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
35.42 - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
35.43 - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
35.44 - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
35.45 - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
35.46 - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
35.47 - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
35.48 - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
35.49 - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
35.50 - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
35.51 - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
35.52 - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
35.53 - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
35.54 - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
35.55 - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
35.56 - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
35.57 - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
35.58 - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
35.59 - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
35.60 - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
35.61 - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
35.62 - 0x2d02ef8dUL
35.63 -#ifdef BYFOUR
35.64 - },
35.65 - {
35.66 - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
35.67 - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
35.68 - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
35.69 - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
35.70 - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
35.71 - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
35.72 - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
35.73 - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
35.74 - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
35.75 - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
35.76 - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
35.77 - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
35.78 - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
35.79 - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
35.80 - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
35.81 - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
35.82 - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
35.83 - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
35.84 - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
35.85 - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
35.86 - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
35.87 - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
35.88 - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
35.89 - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
35.90 - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
35.91 - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
35.92 - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
35.93 - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
35.94 - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
35.95 - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
35.96 - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
35.97 - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
35.98 - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
35.99 - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
35.100 - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
35.101 - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
35.102 - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
35.103 - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
35.104 - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
35.105 - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
35.106 - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
35.107 - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
35.108 - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
35.109 - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
35.110 - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
35.111 - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
35.112 - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
35.113 - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
35.114 - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
35.115 - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
35.116 - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
35.117 - 0x9324fd72UL
35.118 - },
35.119 - {
35.120 - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
35.121 - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
35.122 - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
35.123 - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
35.124 - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
35.125 - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
35.126 - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
35.127 - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
35.128 - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
35.129 - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
35.130 - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
35.131 - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
35.132 - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
35.133 - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
35.134 - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
35.135 - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
35.136 - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
35.137 - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
35.138 - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
35.139 - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
35.140 - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
35.141 - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
35.142 - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
35.143 - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
35.144 - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
35.145 - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
35.146 - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
35.147 - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
35.148 - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
35.149 - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
35.150 - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
35.151 - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
35.152 - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
35.153 - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
35.154 - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
35.155 - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
35.156 - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
35.157 - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
35.158 - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
35.159 - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
35.160 - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
35.161 - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
35.162 - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
35.163 - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
35.164 - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
35.165 - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
35.166 - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
35.167 - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
35.168 - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
35.169 - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
35.170 - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
35.171 - 0xbe9834edUL
35.172 - },
35.173 - {
35.174 - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
35.175 - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
35.176 - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
35.177 - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
35.178 - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
35.179 - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
35.180 - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
35.181 - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
35.182 - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
35.183 - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
35.184 - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
35.185 - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
35.186 - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
35.187 - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
35.188 - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
35.189 - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
35.190 - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
35.191 - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
35.192 - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
35.193 - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
35.194 - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
35.195 - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
35.196 - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
35.197 - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
35.198 - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
35.199 - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
35.200 - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
35.201 - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
35.202 - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
35.203 - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
35.204 - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
35.205 - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
35.206 - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
35.207 - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
35.208 - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
35.209 - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
35.210 - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
35.211 - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
35.212 - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
35.213 - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
35.214 - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
35.215 - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
35.216 - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
35.217 - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
35.218 - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
35.219 - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
35.220 - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
35.221 - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
35.222 - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
35.223 - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
35.224 - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
35.225 - 0xde0506f1UL
35.226 - },
35.227 - {
35.228 - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
35.229 - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
35.230 - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
35.231 - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
35.232 - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
35.233 - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
35.234 - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
35.235 - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
35.236 - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
35.237 - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
35.238 - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
35.239 - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
35.240 - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
35.241 - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
35.242 - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
35.243 - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
35.244 - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
35.245 - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
35.246 - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
35.247 - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
35.248 - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
35.249 - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
35.250 - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
35.251 - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
35.252 - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
35.253 - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
35.254 - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
35.255 - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
35.256 - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
35.257 - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
35.258 - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
35.259 - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
35.260 - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
35.261 - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
35.262 - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
35.263 - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
35.264 - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
35.265 - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
35.266 - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
35.267 - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
35.268 - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
35.269 - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
35.270 - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
35.271 - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
35.272 - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
35.273 - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
35.274 - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
35.275 - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
35.276 - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
35.277 - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
35.278 - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
35.279 - 0x8def022dUL
35.280 - },
35.281 - {
35.282 - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
35.283 - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
35.284 - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
35.285 - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
35.286 - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
35.287 - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
35.288 - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
35.289 - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
35.290 - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
35.291 - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
35.292 - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
35.293 - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
35.294 - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
35.295 - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
35.296 - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
35.297 - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
35.298 - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
35.299 - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
35.300 - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
35.301 - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
35.302 - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
35.303 - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
35.304 - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
35.305 - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
35.306 - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
35.307 - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
35.308 - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
35.309 - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
35.310 - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
35.311 - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
35.312 - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
35.313 - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
35.314 - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
35.315 - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
35.316 - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
35.317 - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
35.318 - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
35.319 - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
35.320 - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
35.321 - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
35.322 - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
35.323 - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
35.324 - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
35.325 - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
35.326 - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
35.327 - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
35.328 - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
35.329 - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
35.330 - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
35.331 - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
35.332 - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
35.333 - 0x72fd2493UL
35.334 - },
35.335 - {
35.336 - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
35.337 - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
35.338 - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
35.339 - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
35.340 - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
35.341 - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
35.342 - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
35.343 - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
35.344 - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
35.345 - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
35.346 - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
35.347 - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
35.348 - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
35.349 - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
35.350 - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
35.351 - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
35.352 - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
35.353 - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
35.354 - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
35.355 - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
35.356 - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
35.357 - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
35.358 - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
35.359 - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
35.360 - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
35.361 - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
35.362 - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
35.363 - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
35.364 - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
35.365 - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
35.366 - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
35.367 - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
35.368 - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
35.369 - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
35.370 - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
35.371 - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
35.372 - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
35.373 - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
35.374 - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
35.375 - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
35.376 - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
35.377 - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
35.378 - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
35.379 - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
35.380 - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
35.381 - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
35.382 - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
35.383 - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
35.384 - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
35.385 - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
35.386 - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
35.387 - 0xed3498beUL
35.388 - },
35.389 - {
35.390 - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
35.391 - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
35.392 - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
35.393 - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
35.394 - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
35.395 - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
35.396 - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
35.397 - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
35.398 - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
35.399 - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
35.400 - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
35.401 - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
35.402 - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
35.403 - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
35.404 - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
35.405 - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
35.406 - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
35.407 - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
35.408 - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
35.409 - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
35.410 - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
35.411 - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
35.412 - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
35.413 - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
35.414 - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
35.415 - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
35.416 - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
35.417 - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
35.418 - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
35.419 - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
35.420 - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
35.421 - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
35.422 - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
35.423 - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
35.424 - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
35.425 - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
35.426 - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
35.427 - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
35.428 - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
35.429 - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
35.430 - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
35.431 - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
35.432 - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
35.433 - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
35.434 - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
35.435 - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
35.436 - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
35.437 - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
35.438 - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
35.439 - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
35.440 - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
35.441 - 0xf10605deUL
35.442 -#endif
35.443 - }
35.444 -};
36.1 --- a/compiler-init/zlib/deflate.c Sat Jul 15 05:02:38 2006 +0000
36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
36.3 @@ -1,1736 +0,0 @@
36.4 -/* deflate.c -- compress data using the deflation algorithm
36.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
36.6 - * For conditions of distribution and use, see copyright notice in zlib.h
36.7 - */
36.8 -
36.9 -/*
36.10 - * ALGORITHM
36.11 - *
36.12 - * The "deflation" process depends on being able to identify portions
36.13 - * of the input text which are identical to earlier input (within a
36.14 - * sliding window trailing behind the input currently being processed).
36.15 - *
36.16 - * The most straightforward technique turns out to be the fastest for
36.17 - * most input files: try all possible matches and select the longest.
36.18 - * The key feature of this algorithm is that insertions into the string
36.19 - * dictionary are very simple and thus fast, and deletions are avoided
36.20 - * completely. Insertions are performed at each input character, whereas
36.21 - * string matches are performed only when the previous match ends. So it
36.22 - * is preferable to spend more time in matches to allow very fast string
36.23 - * insertions and avoid deletions. The matching algorithm for small
36.24 - * strings is inspired from that of Rabin & Karp. A brute force approach
36.25 - * is used to find longer strings when a small match has been found.
36.26 - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
36.27 - * (by Leonid Broukhis).
36.28 - * A previous version of this file used a more sophisticated algorithm
36.29 - * (by Fiala and Greene) which is guaranteed to run in linear amortized
36.30 - * time, but has a larger average cost, uses more memory and is patented.
36.31 - * However the F&G algorithm may be faster for some highly redundant
36.32 - * files if the parameter max_chain_length (described below) is too large.
36.33 - *
36.34 - * ACKNOWLEDGEMENTS
36.35 - *
36.36 - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
36.37 - * I found it in 'freeze' written by Leonid Broukhis.
36.38 - * Thanks to many people for bug reports and testing.
36.39 - *
36.40 - * REFERENCES
36.41 - *
36.42 - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
36.43 - * Available in http://www.ietf.org/rfc/rfc1951.txt
36.44 - *
36.45 - * A description of the Rabin and Karp algorithm is given in the book
36.46 - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
36.47 - *
36.48 - * Fiala,E.R., and Greene,D.H.
36.49 - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
36.50 - *
36.51 - */
36.52 -
36.53 -/* @(#) $Id$ */
36.54 -
36.55 -#include "deflate.h"
36.56 -
36.57 -const char deflate_copyright[] =
36.58 - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
36.59 -/*
36.60 - If you use the zlib library in a product, an acknowledgment is welcome
36.61 - in the documentation of your product. If for some reason you cannot
36.62 - include such an acknowledgment, I would appreciate that you keep this
36.63 - copyright string in the executable of your product.
36.64 - */
36.65 -
36.66 -/* ===========================================================================
36.67 - * Function prototypes.
36.68 - */
36.69 -typedef enum {
36.70 - need_more, /* block not completed, need more input or more output */
36.71 - block_done, /* block flush performed */
36.72 - finish_started, /* finish started, need only more output at next deflate */
36.73 - finish_done /* finish done, accept no more input or output */
36.74 -} block_state;
36.75 -
36.76 -typedef block_state (*compress_func) OF((deflate_state *s, int flush));
36.77 -/* Compression function. Returns the block state after the call. */
36.78 -
36.79 -local void fill_window OF((deflate_state *s));
36.80 -local block_state deflate_stored OF((deflate_state *s, int flush));
36.81 -local block_state deflate_fast OF((deflate_state *s, int flush));
36.82 -#ifndef FASTEST
36.83 -local block_state deflate_slow OF((deflate_state *s, int flush));
36.84 -#endif
36.85 -local void lm_init OF((deflate_state *s));
36.86 -local void putShortMSB OF((deflate_state *s, uInt b));
36.87 -local void flush_pending OF((z_streamp strm));
36.88 -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
36.89 -#ifndef FASTEST
36.90 -#ifdef ASMV
36.91 - void match_init OF((void)); /* asm code initialization */
36.92 - uInt longest_match OF((deflate_state *s, IPos cur_match));
36.93 -#else
36.94 -local uInt longest_match OF((deflate_state *s, IPos cur_match));
36.95 -#endif
36.96 -#endif
36.97 -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
36.98 -
36.99 -#ifdef DEBUG
36.100 -local void check_match OF((deflate_state *s, IPos start, IPos match,
36.101 - int length));
36.102 -#endif
36.103 -
36.104 -/* ===========================================================================
36.105 - * Local data
36.106 - */
36.107 -
36.108 -#define NIL 0
36.109 -/* Tail of hash chains */
36.110 -
36.111 -#ifndef TOO_FAR
36.112 -# define TOO_FAR 4096
36.113 -#endif
36.114 -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
36.115 -
36.116 -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
36.117 -/* Minimum amount of lookahead, except at the end of the input file.
36.118 - * See deflate.c for comments about the MIN_MATCH+1.
36.119 - */
36.120 -
36.121 -/* Values for max_lazy_match, good_match and max_chain_length, depending on
36.122 - * the desired pack level (0..9). The values given below have been tuned to
36.123 - * exclude worst case performance for pathological files. Better values may be
36.124 - * found for specific files.
36.125 - */
36.126 -typedef struct config_s {
36.127 - ush good_length; /* reduce lazy search above this match length */
36.128 - ush max_lazy; /* do not perform lazy search above this match length */
36.129 - ush nice_length; /* quit search above this match length */
36.130 - ush max_chain;
36.131 - compress_func func;
36.132 -} config;
36.133 -
36.134 -#ifdef FASTEST
36.135 -local const config configuration_table[2] = {
36.136 -/* good lazy nice chain */
36.137 -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
36.138 -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
36.139 -#else
36.140 -local const config configuration_table[10] = {
36.141 -/* good lazy nice chain */
36.142 -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
36.143 -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
36.144 -/* 2 */ {4, 5, 16, 8, deflate_fast},
36.145 -/* 3 */ {4, 6, 32, 32, deflate_fast},
36.146 -
36.147 -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
36.148 -/* 5 */ {8, 16, 32, 32, deflate_slow},
36.149 -/* 6 */ {8, 16, 128, 128, deflate_slow},
36.150 -/* 7 */ {8, 32, 128, 256, deflate_slow},
36.151 -/* 8 */ {32, 128, 258, 1024, deflate_slow},
36.152 -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
36.153 -#endif
36.154 -
36.155 -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
36.156 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
36.157 - * meaning.
36.158 - */
36.159 -
36.160 -#define EQUAL 0
36.161 -/* result of memcmp for equal strings */
36.162 -
36.163 -#ifndef NO_DUMMY_DECL
36.164 -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
36.165 -#endif
36.166 -
36.167 -/* ===========================================================================
36.168 - * Update a hash value with the given input byte
36.169 - * IN assertion: all calls to to UPDATE_HASH are made with consecutive
36.170 - * input characters, so that a running hash key can be computed from the
36.171 - * previous key instead of complete recalculation each time.
36.172 - */
36.173 -#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
36.174 -
36.175 -
36.176 -/* ===========================================================================
36.177 - * Insert string str in the dictionary and set match_head to the previous head
36.178 - * of the hash chain (the most recent string with same hash key). Return
36.179 - * the previous length of the hash chain.
36.180 - * If this file is compiled with -DFASTEST, the compression level is forced
36.181 - * to 1, and no hash chains are maintained.
36.182 - * IN assertion: all calls to to INSERT_STRING are made with consecutive
36.183 - * input characters and the first MIN_MATCH bytes of str are valid
36.184 - * (except for the last MIN_MATCH-1 bytes of the input file).
36.185 - */
36.186 -#ifdef FASTEST
36.187 -#define INSERT_STRING(s, str, match_head) \
36.188 - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
36.189 - match_head = s->head[s->ins_h], \
36.190 - s->head[s->ins_h] = (Pos)(str))
36.191 -#else
36.192 -#define INSERT_STRING(s, str, match_head) \
36.193 - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
36.194 - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
36.195 - s->head[s->ins_h] = (Pos)(str))
36.196 -#endif
36.197 -
36.198 -/* ===========================================================================
36.199 - * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
36.200 - * prev[] will be initialized on the fly.
36.201 - */
36.202 -#define CLEAR_HASH(s) \
36.203 - s->head[s->hash_size-1] = NIL; \
36.204 - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
36.205 -
36.206 -/* ========================================================================= */
36.207 -int ZEXPORT deflateInit_(strm, level, version, stream_size)
36.208 - z_streamp strm;
36.209 - int level;
36.210 - const char *version;
36.211 - int stream_size;
36.212 -{
36.213 - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
36.214 - Z_DEFAULT_STRATEGY, version, stream_size);
36.215 - /* To do: ignore strm->next_in if we use it as window */
36.216 -}
36.217 -
36.218 -/* ========================================================================= */
36.219 -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
36.220 - version, stream_size)
36.221 - z_streamp strm;
36.222 - int level;
36.223 - int method;
36.224 - int windowBits;
36.225 - int memLevel;
36.226 - int strategy;
36.227 - const char *version;
36.228 - int stream_size;
36.229 -{
36.230 - deflate_state *s;
36.231 - int wrap = 1;
36.232 - static const char my_version[] = ZLIB_VERSION;
36.233 -
36.234 - ushf *overlay;
36.235 - /* We overlay pending_buf and d_buf+l_buf. This works since the average
36.236 - * output size for (length,distance) codes is <= 24 bits.
36.237 - */
36.238 -
36.239 - if (version == Z_NULL || version[0] != my_version[0] ||
36.240 - stream_size != sizeof(z_stream)) {
36.241 - return Z_VERSION_ERROR;
36.242 - }
36.243 - if (strm == Z_NULL) return Z_STREAM_ERROR;
36.244 -
36.245 - strm->msg = Z_NULL;
36.246 - if (strm->zalloc == (alloc_func)0) {
36.247 - strm->zalloc = zcalloc;
36.248 - strm->opaque = (voidpf)0;
36.249 - }
36.250 - if (strm->zfree == (free_func)0) strm->zfree = zcfree;
36.251 -
36.252 -#ifdef FASTEST
36.253 - if (level != 0) level = 1;
36.254 -#else
36.255 - if (level == Z_DEFAULT_COMPRESSION) level = 6;
36.256 -#endif
36.257 -
36.258 - if (windowBits < 0) { /* suppress zlib wrapper */
36.259 - wrap = 0;
36.260 - windowBits = -windowBits;
36.261 - }
36.262 -#ifdef GZIP
36.263 - else if (windowBits > 15) {
36.264 - wrap = 2; /* write gzip wrapper instead */
36.265 - windowBits -= 16;
36.266 - }
36.267 -#endif
36.268 - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
36.269 - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
36.270 - strategy < 0 || strategy > Z_FIXED) {
36.271 - return Z_STREAM_ERROR;
36.272 - }
36.273 - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
36.274 - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
36.275 - if (s == Z_NULL) return Z_MEM_ERROR;
36.276 - strm->state = (struct internal_state FAR *)s;
36.277 - s->strm = strm;
36.278 -
36.279 - s->wrap = wrap;
36.280 - s->gzhead = Z_NULL;
36.281 - s->w_bits = windowBits;
36.282 - s->w_size = 1 << s->w_bits;
36.283 - s->w_mask = s->w_size - 1;
36.284 -
36.285 - s->hash_bits = memLevel + 7;
36.286 - s->hash_size = 1 << s->hash_bits;
36.287 - s->hash_mask = s->hash_size - 1;
36.288 - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
36.289 -
36.290 - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
36.291 - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
36.292 - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
36.293 -
36.294 - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
36.295 -
36.296 - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
36.297 - s->pending_buf = (uchf *) overlay;
36.298 - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
36.299 -
36.300 - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
36.301 - s->pending_buf == Z_NULL) {
36.302 - s->status = FINISH_STATE;
36.303 - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
36.304 - deflateEnd (strm);
36.305 - return Z_MEM_ERROR;
36.306 - }
36.307 - s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
36.308 - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
36.309 -
36.310 - s->level = level;
36.311 - s->strategy = strategy;
36.312 - s->method = (Byte)method;
36.313 -
36.314 - return deflateReset(strm);
36.315 -}
36.316 -
36.317 -/* ========================================================================= */
36.318 -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
36.319 - z_streamp strm;
36.320 - const Bytef *dictionary;
36.321 - uInt dictLength;
36.322 -{
36.323 - deflate_state *s;
36.324 - uInt length = dictLength;
36.325 - uInt n;
36.326 - IPos hash_head = 0;
36.327 -
36.328 - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
36.329 - strm->state->wrap == 2 ||
36.330 - (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
36.331 - return Z_STREAM_ERROR;
36.332 -
36.333 - s = strm->state;
36.334 - if (s->wrap)
36.335 - strm->adler = adler32(strm->adler, dictionary, dictLength);
36.336 -
36.337 - if (length < MIN_MATCH) return Z_OK;
36.338 - if (length > MAX_DIST(s)) {
36.339 - length = MAX_DIST(s);
36.340 - dictionary += dictLength - length; /* use the tail of the dictionary */
36.341 - }
36.342 - zmemcpy(s->window, dictionary, length);
36.343 - s->strstart = length;
36.344 - s->block_start = (long)length;
36.345 -
36.346 - /* Insert all strings in the hash table (except for the last two bytes).
36.347 - * s->lookahead stays null, so s->ins_h will be recomputed at the next
36.348 - * call of fill_window.
36.349 - */
36.350 - s->ins_h = s->window[0];
36.351 - UPDATE_HASH(s, s->ins_h, s->window[1]);
36.352 - for (n = 0; n <= length - MIN_MATCH; n++) {
36.353 - INSERT_STRING(s, n, hash_head);
36.354 - }
36.355 - if (hash_head) hash_head = 0; /* to make compiler happy */
36.356 - return Z_OK;
36.357 -}
36.358 -
36.359 -/* ========================================================================= */
36.360 -int ZEXPORT deflateReset (strm)
36.361 - z_streamp strm;
36.362 -{
36.363 - deflate_state *s;
36.364 -
36.365 - if (strm == Z_NULL || strm->state == Z_NULL ||
36.366 - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
36.367 - return Z_STREAM_ERROR;
36.368 - }
36.369 -
36.370 - strm->total_in = strm->total_out = 0;
36.371 - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
36.372 - strm->data_type = Z_UNKNOWN;
36.373 -
36.374 - s = (deflate_state *)strm->state;
36.375 - s->pending = 0;
36.376 - s->pending_out = s->pending_buf;
36.377 -
36.378 - if (s->wrap < 0) {
36.379 - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
36.380 - }
36.381 - s->status = s->wrap ? INIT_STATE : BUSY_STATE;
36.382 - strm->adler =
36.383 -#ifdef GZIP
36.384 - s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
36.385 -#endif
36.386 - adler32(0L, Z_NULL, 0);
36.387 - s->last_flush = Z_NO_FLUSH;
36.388 -
36.389 - _tr_init(s);
36.390 - lm_init(s);
36.391 -
36.392 - return Z_OK;
36.393 -}
36.394 -
36.395 -/* ========================================================================= */
36.396 -int ZEXPORT deflateSetHeader (strm, head)
36.397 - z_streamp strm;
36.398 - gz_headerp head;
36.399 -{
36.400 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
36.401 - if (strm->state->wrap != 2) return Z_STREAM_ERROR;
36.402 - strm->state->gzhead = head;
36.403 - return Z_OK;
36.404 -}
36.405 -
36.406 -/* ========================================================================= */
36.407 -int ZEXPORT deflatePrime (strm, bits, value)
36.408 - z_streamp strm;
36.409 - int bits;
36.410 - int value;
36.411 -{
36.412 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
36.413 - strm->state->bi_valid = bits;
36.414 - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
36.415 - return Z_OK;
36.416 -}
36.417 -
36.418 -/* ========================================================================= */
36.419 -int ZEXPORT deflateParams(strm, level, strategy)
36.420 - z_streamp strm;
36.421 - int level;
36.422 - int strategy;
36.423 -{
36.424 - deflate_state *s;
36.425 - compress_func func;
36.426 - int err = Z_OK;
36.427 -
36.428 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
36.429 - s = strm->state;
36.430 -
36.431 -#ifdef FASTEST
36.432 - if (level != 0) level = 1;
36.433 -#else
36.434 - if (level == Z_DEFAULT_COMPRESSION) level = 6;
36.435 -#endif
36.436 - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
36.437 - return Z_STREAM_ERROR;
36.438 - }
36.439 - func = configuration_table[s->level].func;
36.440 -
36.441 - if (func != configuration_table[level].func && strm->total_in != 0) {
36.442 - /* Flush the last buffer: */
36.443 - err = deflate(strm, Z_PARTIAL_FLUSH);
36.444 - }
36.445 - if (s->level != level) {
36.446 - s->level = level;
36.447 - s->max_lazy_match = configuration_table[level].max_lazy;
36.448 - s->good_match = configuration_table[level].good_length;
36.449 - s->nice_match = configuration_table[level].nice_length;
36.450 - s->max_chain_length = configuration_table[level].max_chain;
36.451 - }
36.452 - s->strategy = strategy;
36.453 - return err;
36.454 -}
36.455 -
36.456 -/* ========================================================================= */
36.457 -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
36.458 - z_streamp strm;
36.459 - int good_length;
36.460 - int max_lazy;
36.461 - int nice_length;
36.462 - int max_chain;
36.463 -{
36.464 - deflate_state *s;
36.465 -
36.466 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
36.467 - s = strm->state;
36.468 - s->good_match = good_length;
36.469 - s->max_lazy_match = max_lazy;
36.470 - s->nice_match = nice_length;
36.471 - s->max_chain_length = max_chain;
36.472 - return Z_OK;
36.473 -}
36.474 -
36.475 -/* =========================================================================
36.476 - * For the default windowBits of 15 and memLevel of 8, this function returns
36.477 - * a close to exact, as well as small, upper bound on the compressed size.
36.478 - * They are coded as constants here for a reason--if the #define's are
36.479 - * changed, then this function needs to be changed as well. The return
36.480 - * value for 15 and 8 only works for those exact settings.
36.481 - *
36.482 - * For any setting other than those defaults for windowBits and memLevel,
36.483 - * the value returned is a conservative worst case for the maximum expansion
36.484 - * resulting from using fixed blocks instead of stored blocks, which deflate
36.485 - * can emit on compressed data for some combinations of the parameters.
36.486 - *
36.487 - * This function could be more sophisticated to provide closer upper bounds
36.488 - * for every combination of windowBits and memLevel, as well as wrap.
36.489 - * But even the conservative upper bound of about 14% expansion does not
36.490 - * seem onerous for output buffer allocation.
36.491 - */
36.492 -uLong ZEXPORT deflateBound(strm, sourceLen)
36.493 - z_streamp strm;
36.494 - uLong sourceLen;
36.495 -{
36.496 - deflate_state *s;
36.497 - uLong destLen;
36.498 -
36.499 - /* conservative upper bound */
36.500 - destLen = sourceLen +
36.501 - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
36.502 -
36.503 - /* if can't get parameters, return conservative bound */
36.504 - if (strm == Z_NULL || strm->state == Z_NULL)
36.505 - return destLen;
36.506 -
36.507 - /* if not default parameters, return conservative bound */
36.508 - s = strm->state;
36.509 - if (s->w_bits != 15 || s->hash_bits != 8 + 7)
36.510 - return destLen;
36.511 -
36.512 - /* default settings: return tight bound for that case */
36.513 - return compressBound(sourceLen);
36.514 -}
36.515 -
36.516 -/* =========================================================================
36.517 - * Put a short in the pending buffer. The 16-bit value is put in MSB order.
36.518 - * IN assertion: the stream state is correct and there is enough room in
36.519 - * pending_buf.
36.520 - */
36.521 -local void putShortMSB (s, b)
36.522 - deflate_state *s;
36.523 - uInt b;
36.524 -{
36.525 - put_byte(s, (Byte)(b >> 8));
36.526 - put_byte(s, (Byte)(b & 0xff));
36.527 -}
36.528 -
36.529 -/* =========================================================================
36.530 - * Flush as much pending output as possible. All deflate() output goes
36.531 - * through this function so some applications may wish to modify it
36.532 - * to avoid allocating a large strm->next_out buffer and copying into it.
36.533 - * (See also read_buf()).
36.534 - */
36.535 -local void flush_pending(strm)
36.536 - z_streamp strm;
36.537 -{
36.538 - unsigned len = strm->state->pending;
36.539 -
36.540 - if (len > strm->avail_out) len = strm->avail_out;
36.541 - if (len == 0) return;
36.542 -
36.543 - zmemcpy(strm->next_out, strm->state->pending_out, len);
36.544 - strm->next_out += len;
36.545 - strm->state->pending_out += len;
36.546 - strm->total_out += len;
36.547 - strm->avail_out -= len;
36.548 - strm->state->pending -= len;
36.549 - if (strm->state->pending == 0) {
36.550 - strm->state->pending_out = strm->state->pending_buf;
36.551 - }
36.552 -}
36.553 -
36.554 -/* ========================================================================= */
36.555 -int ZEXPORT deflate (strm, flush)
36.556 - z_streamp strm;
36.557 - int flush;
36.558 -{
36.559 - int old_flush; /* value of flush param for previous deflate call */
36.560 - deflate_state *s;
36.561 -
36.562 - if (strm == Z_NULL || strm->state == Z_NULL ||
36.563 - flush > Z_FINISH || flush < 0) {
36.564 - return Z_STREAM_ERROR;
36.565 - }
36.566 - s = strm->state;
36.567 -
36.568 - if (strm->next_out == Z_NULL ||
36.569 - (strm->next_in == Z_NULL && strm->avail_in != 0) ||
36.570 - (s->status == FINISH_STATE && flush != Z_FINISH)) {
36.571 - ERR_RETURN(strm, Z_STREAM_ERROR);
36.572 - }
36.573 - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
36.574 -
36.575 - s->strm = strm; /* just in case */
36.576 - old_flush = s->last_flush;
36.577 - s->last_flush = flush;
36.578 -
36.579 - /* Write the header */
36.580 - if (s->status == INIT_STATE) {
36.581 -#ifdef GZIP
36.582 - if (s->wrap == 2) {
36.583 - strm->adler = crc32(0L, Z_NULL, 0);
36.584 - put_byte(s, 31);
36.585 - put_byte(s, 139);
36.586 - put_byte(s, 8);
36.587 - if (s->gzhead == NULL) {
36.588 - put_byte(s, 0);
36.589 - put_byte(s, 0);
36.590 - put_byte(s, 0);
36.591 - put_byte(s, 0);
36.592 - put_byte(s, 0);
36.593 - put_byte(s, s->level == 9 ? 2 :
36.594 - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
36.595 - 4 : 0));
36.596 - put_byte(s, OS_CODE);
36.597 - s->status = BUSY_STATE;
36.598 - }
36.599 - else {
36.600 - put_byte(s, (s->gzhead->text ? 1 : 0) +
36.601 - (s->gzhead->hcrc ? 2 : 0) +
36.602 - (s->gzhead->extra == Z_NULL ? 0 : 4) +
36.603 - (s->gzhead->name == Z_NULL ? 0 : 8) +
36.604 - (s->gzhead->comment == Z_NULL ? 0 : 16)
36.605 - );
36.606 - put_byte(s, (Byte)(s->gzhead->time & 0xff));
36.607 - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
36.608 - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
36.609 - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
36.610 - put_byte(s, s->level == 9 ? 2 :
36.611 - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
36.612 - 4 : 0));
36.613 - put_byte(s, s->gzhead->os & 0xff);
36.614 - if (s->gzhead->extra != NULL) {
36.615 - put_byte(s, s->gzhead->extra_len & 0xff);
36.616 - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
36.617 - }
36.618 - if (s->gzhead->hcrc)
36.619 - strm->adler = crc32(strm->adler, s->pending_buf,
36.620 - s->pending);
36.621 - s->gzindex = 0;
36.622 - s->status = EXTRA_STATE;
36.623 - }
36.624 - }
36.625 - else
36.626 -#endif
36.627 - {
36.628 - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
36.629 - uInt level_flags;
36.630 -
36.631 - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
36.632 - level_flags = 0;
36.633 - else if (s->level < 6)
36.634 - level_flags = 1;
36.635 - else if (s->level == 6)
36.636 - level_flags = 2;
36.637 - else
36.638 - level_flags = 3;
36.639 - header |= (level_flags << 6);
36.640 - if (s->strstart != 0) header |= PRESET_DICT;
36.641 - header += 31 - (header % 31);
36.642 -
36.643 - s->status = BUSY_STATE;
36.644 - putShortMSB(s, header);
36.645 -
36.646 - /* Save the adler32 of the preset dictionary: */
36.647 - if (s->strstart != 0) {
36.648 - putShortMSB(s, (uInt)(strm->adler >> 16));
36.649 - putShortMSB(s, (uInt)(strm->adler & 0xffff));
36.650 - }
36.651 - strm->adler = adler32(0L, Z_NULL, 0);
36.652 - }
36.653 - }
36.654 -#ifdef GZIP
36.655 - if (s->status == EXTRA_STATE) {
36.656 - if (s->gzhead->extra != NULL) {
36.657 - uInt beg = s->pending; /* start of bytes to update crc */
36.658 -
36.659 - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
36.660 - if (s->pending == s->pending_buf_size) {
36.661 - if (s->gzhead->hcrc && s->pending > beg)
36.662 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
36.663 - s->pending - beg);
36.664 - flush_pending(strm);
36.665 - beg = s->pending;
36.666 - if (s->pending == s->pending_buf_size)
36.667 - break;
36.668 - }
36.669 - put_byte(s, s->gzhead->extra[s->gzindex]);
36.670 - s->gzindex++;
36.671 - }
36.672 - if (s->gzhead->hcrc && s->pending > beg)
36.673 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
36.674 - s->pending - beg);
36.675 - if (s->gzindex == s->gzhead->extra_len) {
36.676 - s->gzindex = 0;
36.677 - s->status = NAME_STATE;
36.678 - }
36.679 - }
36.680 - else
36.681 - s->status = NAME_STATE;
36.682 - }
36.683 - if (s->status == NAME_STATE) {
36.684 - if (s->gzhead->name != NULL) {
36.685 - uInt beg = s->pending; /* start of bytes to update crc */
36.686 - int val;
36.687 -
36.688 - do {
36.689 - if (s->pending == s->pending_buf_size) {
36.690 - if (s->gzhead->hcrc && s->pending > beg)
36.691 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
36.692 - s->pending - beg);
36.693 - flush_pending(strm);
36.694 - beg = s->pending;
36.695 - if (s->pending == s->pending_buf_size) {
36.696 - val = 1;
36.697 - break;
36.698 - }
36.699 - }
36.700 - val = s->gzhead->name[s->gzindex++];
36.701 - put_byte(s, val);
36.702 - } while (val != 0);
36.703 - if (s->gzhead->hcrc && s->pending > beg)
36.704 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
36.705 - s->pending - beg);
36.706 - if (val == 0) {
36.707 - s->gzindex = 0;
36.708 - s->status = COMMENT_STATE;
36.709 - }
36.710 - }
36.711 - else
36.712 - s->status = COMMENT_STATE;
36.713 - }
36.714 - if (s->status == COMMENT_STATE) {
36.715 - if (s->gzhead->comment != NULL) {
36.716 - uInt beg = s->pending; /* start of bytes to update crc */
36.717 - int val;
36.718 -
36.719 - do {
36.720 - if (s->pending == s->pending_buf_size) {
36.721 - if (s->gzhead->hcrc && s->pending > beg)
36.722 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
36.723 - s->pending - beg);
36.724 - flush_pending(strm);
36.725 - beg = s->pending;
36.726 - if (s->pending == s->pending_buf_size) {
36.727 - val = 1;
36.728 - break;
36.729 - }
36.730 - }
36.731 - val = s->gzhead->comment[s->gzindex++];
36.732 - put_byte(s, val);
36.733 - } while (val != 0);
36.734 - if (s->gzhead->hcrc && s->pending > beg)
36.735 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
36.736 - s->pending - beg);
36.737 - if (val == 0)
36.738 - s->status = HCRC_STATE;
36.739 - }
36.740 - else
36.741 - s->status = HCRC_STATE;
36.742 - }
36.743 - if (s->status == HCRC_STATE) {
36.744 - if (s->gzhead->hcrc) {
36.745 - if (s->pending + 2 > s->pending_buf_size)
36.746 - flush_pending(strm);
36.747 - if (s->pending + 2 <= s->pending_buf_size) {
36.748 - put_byte(s, (Byte)(strm->adler & 0xff));
36.749 - put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
36.750 - strm->adler = crc32(0L, Z_NULL, 0);
36.751 - s->status = BUSY_STATE;
36.752 - }
36.753 - }
36.754 - else
36.755 - s->status = BUSY_STATE;
36.756 - }
36.757 -#endif
36.758 -
36.759 - /* Flush as much pending output as possible */
36.760 - if (s->pending != 0) {
36.761 - flush_pending(strm);
36.762 - if (strm->avail_out == 0) {
36.763 - /* Since avail_out is 0, deflate will be called again with
36.764 - * more output space, but possibly with both pending and
36.765 - * avail_in equal to zero. There won't be anything to do,
36.766 - * but this is not an error situation so make sure we
36.767 - * return OK instead of BUF_ERROR at next call of deflate:
36.768 - */
36.769 - s->last_flush = -1;
36.770 - return Z_OK;
36.771 - }
36.772 -
36.773 - /* Make sure there is something to do and avoid duplicate consecutive
36.774 - * flushes. For repeated and useless calls with Z_FINISH, we keep
36.775 - * returning Z_STREAM_END instead of Z_BUF_ERROR.
36.776 - */
36.777 - } else if (strm->avail_in == 0 && flush <= old_flush &&
36.778 - flush != Z_FINISH) {
36.779 - ERR_RETURN(strm, Z_BUF_ERROR);
36.780 - }
36.781 -
36.782 - /* User must not provide more input after the first FINISH: */
36.783 - if (s->status == FINISH_STATE && strm->avail_in != 0) {
36.784 - ERR_RETURN(strm, Z_BUF_ERROR);
36.785 - }
36.786 -
36.787 - /* Start a new block or continue the current one.
36.788 - */
36.789 - if (strm->avail_in != 0 || s->lookahead != 0 ||
36.790 - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
36.791 - block_state bstate;
36.792 -
36.793 - bstate = (*(configuration_table[s->level].func))(s, flush);
36.794 -
36.795 - if (bstate == finish_started || bstate == finish_done) {
36.796 - s->status = FINISH_STATE;
36.797 - }
36.798 - if (bstate == need_more || bstate == finish_started) {
36.799 - if (strm->avail_out == 0) {
36.800 - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
36.801 - }
36.802 - return Z_OK;
36.803 - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
36.804 - * of deflate should use the same flush parameter to make sure
36.805 - * that the flush is complete. So we don't have to output an
36.806 - * empty block here, this will be done at next call. This also
36.807 - * ensures that for a very small output buffer, we emit at most
36.808 - * one empty block.
36.809 - */
36.810 - }
36.811 - if (bstate == block_done) {
36.812 - if (flush == Z_PARTIAL_FLUSH) {
36.813 - _tr_align(s);
36.814 - } else { /* FULL_FLUSH or SYNC_FLUSH */
36.815 - _tr_stored_block(s, (char*)0, 0L, 0);
36.816 - /* For a full flush, this empty block will be recognized
36.817 - * as a special marker by inflate_sync().
36.818 - */
36.819 - if (flush == Z_FULL_FLUSH) {
36.820 - CLEAR_HASH(s); /* forget history */
36.821 - }
36.822 - }
36.823 - flush_pending(strm);
36.824 - if (strm->avail_out == 0) {
36.825 - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
36.826 - return Z_OK;
36.827 - }
36.828 - }
36.829 - }
36.830 - Assert(strm->avail_out > 0, "bug2");
36.831 -
36.832 - if (flush != Z_FINISH) return Z_OK;
36.833 - if (s->wrap <= 0) return Z_STREAM_END;
36.834 -
36.835 - /* Write the trailer */
36.836 -#ifdef GZIP
36.837 - if (s->wrap == 2) {
36.838 - put_byte(s, (Byte)(strm->adler & 0xff));
36.839 - put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
36.840 - put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
36.841 - put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
36.842 - put_byte(s, (Byte)(strm->total_in & 0xff));
36.843 - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
36.844 - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
36.845 - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
36.846 - }
36.847 - else
36.848 -#endif
36.849 - {
36.850 - putShortMSB(s, (uInt)(strm->adler >> 16));
36.851 - putShortMSB(s, (uInt)(strm->adler & 0xffff));
36.852 - }
36.853 - flush_pending(strm);
36.854 - /* If avail_out is zero, the application will call deflate again
36.855 - * to flush the rest.
36.856 - */
36.857 - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
36.858 - return s->pending != 0 ? Z_OK : Z_STREAM_END;
36.859 -}
36.860 -
36.861 -/* ========================================================================= */
36.862 -int ZEXPORT deflateEnd (strm)
36.863 - z_streamp strm;
36.864 -{
36.865 - int status;
36.866 -
36.867 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
36.868 -
36.869 - status = strm->state->status;
36.870 - if (status != INIT_STATE &&
36.871 - status != EXTRA_STATE &&
36.872 - status != NAME_STATE &&
36.873 - status != COMMENT_STATE &&
36.874 - status != HCRC_STATE &&
36.875 - status != BUSY_STATE &&
36.876 - status != FINISH_STATE) {
36.877 - return Z_STREAM_ERROR;
36.878 - }
36.879 -
36.880 - /* Deallocate in reverse order of allocations: */
36.881 - TRY_FREE(strm, strm->state->pending_buf);
36.882 - TRY_FREE(strm, strm->state->head);
36.883 - TRY_FREE(strm, strm->state->prev);
36.884 - TRY_FREE(strm, strm->state->window);
36.885 -
36.886 - ZFREE(strm, strm->state);
36.887 - strm->state = Z_NULL;
36.888 -
36.889 - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
36.890 -}
36.891 -
36.892 -/* =========================================================================
36.893 - * Copy the source state to the destination state.
36.894 - * To simplify the source, this is not supported for 16-bit MSDOS (which
36.895 - * doesn't have enough memory anyway to duplicate compression states).
36.896 - */
36.897 -int ZEXPORT deflateCopy (dest, source)
36.898 - z_streamp dest;
36.899 - z_streamp source;
36.900 -{
36.901 -#ifdef MAXSEG_64K
36.902 - return Z_STREAM_ERROR;
36.903 -#else
36.904 - deflate_state *ds;
36.905 - deflate_state *ss;
36.906 - ushf *overlay;
36.907 -
36.908 -
36.909 - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
36.910 - return Z_STREAM_ERROR;
36.911 - }
36.912 -
36.913 - ss = source->state;
36.914 -
36.915 - zmemcpy(dest, source, sizeof(z_stream));
36.916 -
36.917 - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
36.918 - if (ds == Z_NULL) return Z_MEM_ERROR;
36.919 - dest->state = (struct internal_state FAR *) ds;
36.920 - zmemcpy(ds, ss, sizeof(deflate_state));
36.921 - ds->strm = dest;
36.922 -
36.923 - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
36.924 - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
36.925 - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
36.926 - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
36.927 - ds->pending_buf = (uchf *) overlay;
36.928 -
36.929 - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
36.930 - ds->pending_buf == Z_NULL) {
36.931 - deflateEnd (dest);
36.932 - return Z_MEM_ERROR;
36.933 - }
36.934 - /* following zmemcpy do not work for 16-bit MSDOS */
36.935 - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
36.936 - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
36.937 - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
36.938 - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
36.939 -
36.940 - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
36.941 - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
36.942 - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
36.943 -
36.944 - ds->l_desc.dyn_tree = ds->dyn_ltree;
36.945 - ds->d_desc.dyn_tree = ds->dyn_dtree;
36.946 - ds->bl_desc.dyn_tree = ds->bl_tree;
36.947 -
36.948 - return Z_OK;
36.949 -#endif /* MAXSEG_64K */
36.950 -}
36.951 -
36.952 -/* ===========================================================================
36.953 - * Read a new buffer from the current input stream, update the adler32
36.954 - * and total number of bytes read. All deflate() input goes through
36.955 - * this function so some applications may wish to modify it to avoid
36.956 - * allocating a large strm->next_in buffer and copying from it.
36.957 - * (See also flush_pending()).
36.958 - */
36.959 -local int read_buf(strm, buf, size)
36.960 - z_streamp strm;
36.961 - Bytef *buf;
36.962 - unsigned size;
36.963 -{
36.964 - unsigned len = strm->avail_in;
36.965 -
36.966 - if (len > size) len = size;
36.967 - if (len == 0) return 0;
36.968 -
36.969 - strm->avail_in -= len;
36.970 -
36.971 - if (strm->state->wrap == 1) {
36.972 - strm->adler = adler32(strm->adler, strm->next_in, len);
36.973 - }
36.974 -#ifdef GZIP
36.975 - else if (strm->state->wrap == 2) {
36.976 - strm->adler = crc32(strm->adler, strm->next_in, len);
36.977 - }
36.978 -#endif
36.979 - zmemcpy(buf, strm->next_in, len);
36.980 - strm->next_in += len;
36.981 - strm->total_in += len;
36.982 -
36.983 - return (int)len;
36.984 -}
36.985 -
36.986 -/* ===========================================================================
36.987 - * Initialize the "longest match" routines for a new zlib stream
36.988 - */
36.989 -local void lm_init (s)
36.990 - deflate_state *s;
36.991 -{
36.992 - s->window_size = (ulg)2L*s->w_size;
36.993 -
36.994 - CLEAR_HASH(s);
36.995 -
36.996 - /* Set the default configuration parameters:
36.997 - */
36.998 - s->max_lazy_match = configuration_table[s->level].max_lazy;
36.999 - s->good_match = configuration_table[s->level].good_length;
36.1000 - s->nice_match = configuration_table[s->level].nice_length;
36.1001 - s->max_chain_length = configuration_table[s->level].max_chain;
36.1002 -
36.1003 - s->strstart = 0;
36.1004 - s->block_start = 0L;
36.1005 - s->lookahead = 0;
36.1006 - s->match_length = s->prev_length = MIN_MATCH-1;
36.1007 - s->match_available = 0;
36.1008 - s->ins_h = 0;
36.1009 -#ifndef FASTEST
36.1010 -#ifdef ASMV
36.1011 - match_init(); /* initialize the asm code */
36.1012 -#endif
36.1013 -#endif
36.1014 -}
36.1015 -
36.1016 -#ifndef FASTEST
36.1017 -/* ===========================================================================
36.1018 - * Set match_start to the longest match starting at the given string and
36.1019 - * return its length. Matches shorter or equal to prev_length are discarded,
36.1020 - * in which case the result is equal to prev_length and match_start is
36.1021 - * garbage.
36.1022 - * IN assertions: cur_match is the head of the hash chain for the current
36.1023 - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
36.1024 - * OUT assertion: the match length is not greater than s->lookahead.
36.1025 - */
36.1026 -#ifndef ASMV
36.1027 -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
36.1028 - * match.S. The code will be functionally equivalent.
36.1029 - */
36.1030 -local uInt longest_match(s, cur_match)
36.1031 - deflate_state *s;
36.1032 - IPos cur_match; /* current match */
36.1033 -{
36.1034 - unsigned chain_length = s->max_chain_length;/* max hash chain length */
36.1035 - register Bytef *scan = s->window + s->strstart; /* current string */
36.1036 - register Bytef *match; /* matched string */
36.1037 - register int len; /* length of current match */
36.1038 - int best_len = s->prev_length; /* best match length so far */
36.1039 - int nice_match = s->nice_match; /* stop if match long enough */
36.1040 - IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
36.1041 - s->strstart - (IPos)MAX_DIST(s) : NIL;
36.1042 - /* Stop when cur_match becomes <= limit. To simplify the code,
36.1043 - * we prevent matches with the string of window index 0.
36.1044 - */
36.1045 - Posf *prev = s->prev;
36.1046 - uInt wmask = s->w_mask;
36.1047 -
36.1048 -#ifdef UNALIGNED_OK
36.1049 - /* Compare two bytes at a time. Note: this is not always beneficial.
36.1050 - * Try with and without -DUNALIGNED_OK to check.
36.1051 - */
36.1052 - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
36.1053 - register ush scan_start = *(ushf*)scan;
36.1054 - register ush scan_end = *(ushf*)(scan+best_len-1);
36.1055 -#else
36.1056 - register Bytef *strend = s->window + s->strstart + MAX_MATCH;
36.1057 - register Byte scan_end1 = scan[best_len-1];
36.1058 - register Byte scan_end = scan[best_len];
36.1059 -#endif
36.1060 -
36.1061 - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
36.1062 - * It is easy to get rid of this optimization if necessary.
36.1063 - */
36.1064 - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
36.1065 -
36.1066 - /* Do not waste too much time if we already have a good match: */
36.1067 - if (s->prev_length >= s->good_match) {
36.1068 - chain_length >>= 2;
36.1069 - }
36.1070 - /* Do not look for matches beyond the end of the input. This is necessary
36.1071 - * to make deflate deterministic.
36.1072 - */
36.1073 - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
36.1074 -
36.1075 - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
36.1076 -
36.1077 - do {
36.1078 - Assert(cur_match < s->strstart, "no future");
36.1079 - match = s->window + cur_match;
36.1080 -
36.1081 - /* Skip to next match if the match length cannot increase
36.1082 - * or if the match length is less than 2. Note that the checks below
36.1083 - * for insufficient lookahead only occur occasionally for performance
36.1084 - * reasons. Therefore uninitialized memory will be accessed, and
36.1085 - * conditional jumps will be made that depend on those values.
36.1086 - * However the length of the match is limited to the lookahead, so
36.1087 - * the output of deflate is not affected by the uninitialized values.
36.1088 - */
36.1089 -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
36.1090 - /* This code assumes sizeof(unsigned short) == 2. Do not use
36.1091 - * UNALIGNED_OK if your compiler uses a different size.
36.1092 - */
36.1093 - if (*(ushf*)(match+best_len-1) != scan_end ||
36.1094 - *(ushf*)match != scan_start) continue;
36.1095 -
36.1096 - /* It is not necessary to compare scan[2] and match[2] since they are
36.1097 - * always equal when the other bytes match, given that the hash keys
36.1098 - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
36.1099 - * strstart+3, +5, ... up to strstart+257. We check for insufficient
36.1100 - * lookahead only every 4th comparison; the 128th check will be made
36.1101 - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
36.1102 - * necessary to put more guard bytes at the end of the window, or
36.1103 - * to check more often for insufficient lookahead.
36.1104 - */
36.1105 - Assert(scan[2] == match[2], "scan[2]?");
36.1106 - scan++, match++;
36.1107 - do {
36.1108 - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
36.1109 - *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
36.1110 - *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
36.1111 - *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
36.1112 - scan < strend);
36.1113 - /* The funny "do {}" generates better code on most compilers */
36.1114 -
36.1115 - /* Here, scan <= window+strstart+257 */
36.1116 - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
36.1117 - if (*scan == *match) scan++;
36.1118 -
36.1119 - len = (MAX_MATCH - 1) - (int)(strend-scan);
36.1120 - scan = strend - (MAX_MATCH-1);
36.1121 -
36.1122 -#else /* UNALIGNED_OK */
36.1123 -
36.1124 - if (match[best_len] != scan_end ||
36.1125 - match[best_len-1] != scan_end1 ||
36.1126 - *match != *scan ||
36.1127 - *++match != scan[1]) continue;
36.1128 -
36.1129 - /* The check at best_len-1 can be removed because it will be made
36.1130 - * again later. (This heuristic is not always a win.)
36.1131 - * It is not necessary to compare scan[2] and match[2] since they
36.1132 - * are always equal when the other bytes match, given that
36.1133 - * the hash keys are equal and that HASH_BITS >= 8.
36.1134 - */
36.1135 - scan += 2, match++;
36.1136 - Assert(*scan == *match, "match[2]?");
36.1137 -
36.1138 - /* We check for insufficient lookahead only every 8th comparison;
36.1139 - * the 256th check will be made at strstart+258.
36.1140 - */
36.1141 - do {
36.1142 - } while (*++scan == *++match && *++scan == *++match &&
36.1143 - *++scan == *++match && *++scan == *++match &&
36.1144 - *++scan == *++match && *++scan == *++match &&
36.1145 - *++scan == *++match && *++scan == *++match &&
36.1146 - scan < strend);
36.1147 -
36.1148 - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
36.1149 -
36.1150 - len = MAX_MATCH - (int)(strend - scan);
36.1151 - scan = strend - MAX_MATCH;
36.1152 -
36.1153 -#endif /* UNALIGNED_OK */
36.1154 -
36.1155 - if (len > best_len) {
36.1156 - s->match_start = cur_match;
36.1157 - best_len = len;
36.1158 - if (len >= nice_match) break;
36.1159 -#ifdef UNALIGNED_OK
36.1160 - scan_end = *(ushf*)(scan+best_len-1);
36.1161 -#else
36.1162 - scan_end1 = scan[best_len-1];
36.1163 - scan_end = scan[best_len];
36.1164 -#endif
36.1165 - }
36.1166 - } while ((cur_match = prev[cur_match & wmask]) > limit
36.1167 - && --chain_length != 0);
36.1168 -
36.1169 - if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
36.1170 - return s->lookahead;
36.1171 -}
36.1172 -#endif /* ASMV */
36.1173 -#endif /* FASTEST */
36.1174 -
36.1175 -/* ---------------------------------------------------------------------------
36.1176 - * Optimized version for level == 1 or strategy == Z_RLE only
36.1177 - */
36.1178 -local uInt longest_match_fast(s, cur_match)
36.1179 - deflate_state *s;
36.1180 - IPos cur_match; /* current match */
36.1181 -{
36.1182 - register Bytef *scan = s->window + s->strstart; /* current string */
36.1183 - register Bytef *match; /* matched string */
36.1184 - register int len; /* length of current match */
36.1185 - register Bytef *strend = s->window + s->strstart + MAX_MATCH;
36.1186 -
36.1187 - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
36.1188 - * It is easy to get rid of this optimization if necessary.
36.1189 - */
36.1190 - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
36.1191 -
36.1192 - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
36.1193 -
36.1194 - Assert(cur_match < s->strstart, "no future");
36.1195 -
36.1196 - match = s->window + cur_match;
36.1197 -
36.1198 - /* Return failure if the match length is less than 2:
36.1199 - */
36.1200 - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
36.1201 -
36.1202 - /* The check at best_len-1 can be removed because it will be made
36.1203 - * again later. (This heuristic is not always a win.)
36.1204 - * It is not necessary to compare scan[2] and match[2] since they
36.1205 - * are always equal when the other bytes match, given that
36.1206 - * the hash keys are equal and that HASH_BITS >= 8.
36.1207 - */
36.1208 - scan += 2, match += 2;
36.1209 - Assert(*scan == *match, "match[2]?");
36.1210 -
36.1211 - /* We check for insufficient lookahead only every 8th comparison;
36.1212 - * the 256th check will be made at strstart+258.
36.1213 - */
36.1214 - do {
36.1215 - } while (*++scan == *++match && *++scan == *++match &&
36.1216 - *++scan == *++match && *++scan == *++match &&
36.1217 - *++scan == *++match && *++scan == *++match &&
36.1218 - *++scan == *++match && *++scan == *++match &&
36.1219 - scan < strend);
36.1220 -
36.1221 - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
36.1222 -
36.1223 - len = MAX_MATCH - (int)(strend - scan);
36.1224 -
36.1225 - if (len < MIN_MATCH) return MIN_MATCH - 1;
36.1226 -
36.1227 - s->match_start = cur_match;
36.1228 - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
36.1229 -}
36.1230 -
36.1231 -#ifdef DEBUG
36.1232 -/* ===========================================================================
36.1233 - * Check that the match at match_start is indeed a match.
36.1234 - */
36.1235 -local void check_match(s, start, match, length)
36.1236 - deflate_state *s;
36.1237 - IPos start, match;
36.1238 - int length;
36.1239 -{
36.1240 - /* check that the match is indeed a match */
36.1241 - if (zmemcmp(s->window + match,
36.1242 - s->window + start, length) != EQUAL) {
36.1243 - fprintf(stderr, " start %u, match %u, length %d\n",
36.1244 - start, match, length);
36.1245 - do {
36.1246 - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
36.1247 - } while (--length != 0);
36.1248 - z_error("invalid match");
36.1249 - }
36.1250 - if (z_verbose > 1) {
36.1251 - fprintf(stderr,"\\[%d,%d]", start-match, length);
36.1252 - do { putc(s->window[start++], stderr); } while (--length != 0);
36.1253 - }
36.1254 -}
36.1255 -#else
36.1256 -# define check_match(s, start, match, length)
36.1257 -#endif /* DEBUG */
36.1258 -
36.1259 -/* ===========================================================================
36.1260 - * Fill the window when the lookahead becomes insufficient.
36.1261 - * Updates strstart and lookahead.
36.1262 - *
36.1263 - * IN assertion: lookahead < MIN_LOOKAHEAD
36.1264 - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
36.1265 - * At least one byte has been read, or avail_in == 0; reads are
36.1266 - * performed for at least two bytes (required for the zip translate_eol
36.1267 - * option -- not supported here).
36.1268 - */
36.1269 -local void fill_window(s)
36.1270 - deflate_state *s;
36.1271 -{
36.1272 - register unsigned n, m;
36.1273 - register Posf *p;
36.1274 - unsigned more; /* Amount of free space at the end of the window. */
36.1275 - uInt wsize = s->w_size;
36.1276 -
36.1277 - do {
36.1278 - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
36.1279 -
36.1280 - /* Deal with !@#$% 64K limit: */
36.1281 - if (sizeof(int) <= 2) {
36.1282 - if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
36.1283 - more = wsize;
36.1284 -
36.1285 - } else if (more == (unsigned)(-1)) {
36.1286 - /* Very unlikely, but possible on 16 bit machine if
36.1287 - * strstart == 0 && lookahead == 1 (input done a byte at time)
36.1288 - */
36.1289 - more--;
36.1290 - }
36.1291 - }
36.1292 -
36.1293 - /* If the window is almost full and there is insufficient lookahead,
36.1294 - * move the upper half to the lower one to make room in the upper half.
36.1295 - */
36.1296 - if (s->strstart >= wsize+MAX_DIST(s)) {
36.1297 -
36.1298 - zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
36.1299 - s->match_start -= wsize;
36.1300 - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
36.1301 - s->block_start -= (long) wsize;
36.1302 -
36.1303 - /* Slide the hash table (could be avoided with 32 bit values
36.1304 - at the expense of memory usage). We slide even when level == 0
36.1305 - to keep the hash table consistent if we switch back to level > 0
36.1306 - later. (Using level 0 permanently is not an optimal usage of
36.1307 - zlib, so we don't care about this pathological case.)
36.1308 - */
36.1309 - /* %%% avoid this when Z_RLE */
36.1310 - n = s->hash_size;
36.1311 - p = &s->head[n];
36.1312 - do {
36.1313 - m = *--p;
36.1314 - *p = (Pos)(m >= wsize ? m-wsize : NIL);
36.1315 - } while (--n);
36.1316 -
36.1317 - n = wsize;
36.1318 -#ifndef FASTEST
36.1319 - p = &s->prev[n];
36.1320 - do {
36.1321 - m = *--p;
36.1322 - *p = (Pos)(m >= wsize ? m-wsize : NIL);
36.1323 - /* If n is not on any hash chain, prev[n] is garbage but
36.1324 - * its value will never be used.
36.1325 - */
36.1326 - } while (--n);
36.1327 -#endif
36.1328 - more += wsize;
36.1329 - }
36.1330 - if (s->strm->avail_in == 0) return;
36.1331 -
36.1332 - /* If there was no sliding:
36.1333 - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
36.1334 - * more == window_size - lookahead - strstart
36.1335 - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
36.1336 - * => more >= window_size - 2*WSIZE + 2
36.1337 - * In the BIG_MEM or MMAP case (not yet supported),
36.1338 - * window_size == input_size + MIN_LOOKAHEAD &&
36.1339 - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
36.1340 - * Otherwise, window_size == 2*WSIZE so more >= 2.
36.1341 - * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
36.1342 - */
36.1343 - Assert(more >= 2, "more < 2");
36.1344 -
36.1345 - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
36.1346 - s->lookahead += n;
36.1347 -
36.1348 - /* Initialize the hash value now that we have some input: */
36.1349 - if (s->lookahead >= MIN_MATCH) {
36.1350 - s->ins_h = s->window[s->strstart];
36.1351 - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
36.1352 -#if MIN_MATCH != 3
36.1353 - Call UPDATE_HASH() MIN_MATCH-3 more times
36.1354 -#endif
36.1355 - }
36.1356 - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
36.1357 - * but this is not important since only literal bytes will be emitted.
36.1358 - */
36.1359 -
36.1360 - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
36.1361 -}
36.1362 -
36.1363 -/* ===========================================================================
36.1364 - * Flush the current block, with given end-of-file flag.
36.1365 - * IN assertion: strstart is set to the end of the current match.
36.1366 - */
36.1367 -#define FLUSH_BLOCK_ONLY(s, eof) { \
36.1368 - _tr_flush_block(s, (s->block_start >= 0L ? \
36.1369 - (charf *)&s->window[(unsigned)s->block_start] : \
36.1370 - (charf *)Z_NULL), \
36.1371 - (ulg)((long)s->strstart - s->block_start), \
36.1372 - (eof)); \
36.1373 - s->block_start = s->strstart; \
36.1374 - flush_pending(s->strm); \
36.1375 - Tracev((stderr,"[FLUSH]")); \
36.1376 -}
36.1377 -
36.1378 -/* Same but force premature exit if necessary. */
36.1379 -#define FLUSH_BLOCK(s, eof) { \
36.1380 - FLUSH_BLOCK_ONLY(s, eof); \
36.1381 - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
36.1382 -}
36.1383 -
36.1384 -/* ===========================================================================
36.1385 - * Copy without compression as much as possible from the input stream, return
36.1386 - * the current block state.
36.1387 - * This function does not insert new strings in the dictionary since
36.1388 - * uncompressible data is probably not useful. This function is used
36.1389 - * only for the level=0 compression option.
36.1390 - * NOTE: this function should be optimized to avoid extra copying from
36.1391 - * window to pending_buf.
36.1392 - */
36.1393 -local block_state deflate_stored(s, flush)
36.1394 - deflate_state *s;
36.1395 - int flush;
36.1396 -{
36.1397 - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
36.1398 - * to pending_buf_size, and each stored block has a 5 byte header:
36.1399 - */
36.1400 - ulg max_block_size = 0xffff;
36.1401 - ulg max_start;
36.1402 -
36.1403 - if (max_block_size > s->pending_buf_size - 5) {
36.1404 - max_block_size = s->pending_buf_size - 5;
36.1405 - }
36.1406 -
36.1407 - /* Copy as much as possible from input to output: */
36.1408 - for (;;) {
36.1409 - /* Fill the window as much as possible: */
36.1410 - if (s->lookahead <= 1) {
36.1411 -
36.1412 - Assert(s->strstart < s->w_size+MAX_DIST(s) ||
36.1413 - s->block_start >= (long)s->w_size, "slide too late");
36.1414 -
36.1415 - fill_window(s);
36.1416 - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
36.1417 -
36.1418 - if (s->lookahead == 0) break; /* flush the current block */
36.1419 - }
36.1420 - Assert(s->block_start >= 0L, "block gone");
36.1421 -
36.1422 - s->strstart += s->lookahead;
36.1423 - s->lookahead = 0;
36.1424 -
36.1425 - /* Emit a stored block if pending_buf will be full: */
36.1426 - max_start = s->block_start + max_block_size;
36.1427 - if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
36.1428 - /* strstart == 0 is possible when wraparound on 16-bit machine */
36.1429 - s->lookahead = (uInt)(s->strstart - max_start);
36.1430 - s->strstart = (uInt)max_start;
36.1431 - FLUSH_BLOCK(s, 0);
36.1432 - }
36.1433 - /* Flush if we may have to slide, otherwise block_start may become
36.1434 - * negative and the data will be gone:
36.1435 - */
36.1436 - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
36.1437 - FLUSH_BLOCK(s, 0);
36.1438 - }
36.1439 - }
36.1440 - FLUSH_BLOCK(s, flush == Z_FINISH);
36.1441 - return flush == Z_FINISH ? finish_done : block_done;
36.1442 -}
36.1443 -
36.1444 -/* ===========================================================================
36.1445 - * Compress as much as possible from the input stream, return the current
36.1446 - * block state.
36.1447 - * This function does not perform lazy evaluation of matches and inserts
36.1448 - * new strings in the dictionary only for unmatched strings or for short
36.1449 - * matches. It is used only for the fast compression options.
36.1450 - */
36.1451 -local block_state deflate_fast(s, flush)
36.1452 - deflate_state *s;
36.1453 - int flush;
36.1454 -{
36.1455 - IPos hash_head = NIL; /* head of the hash chain */
36.1456 - int bflush; /* set if current block must be flushed */
36.1457 -
36.1458 - for (;;) {
36.1459 - /* Make sure that we always have enough lookahead, except
36.1460 - * at the end of the input file. We need MAX_MATCH bytes
36.1461 - * for the next match, plus MIN_MATCH bytes to insert the
36.1462 - * string following the next match.
36.1463 - */
36.1464 - if (s->lookahead < MIN_LOOKAHEAD) {
36.1465 - fill_window(s);
36.1466 - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
36.1467 - return need_more;
36.1468 - }
36.1469 - if (s->lookahead == 0) break; /* flush the current block */
36.1470 - }
36.1471 -
36.1472 - /* Insert the string window[strstart .. strstart+2] in the
36.1473 - * dictionary, and set hash_head to the head of the hash chain:
36.1474 - */
36.1475 - if (s->lookahead >= MIN_MATCH) {
36.1476 - INSERT_STRING(s, s->strstart, hash_head);
36.1477 - }
36.1478 -
36.1479 - /* Find the longest match, discarding those <= prev_length.
36.1480 - * At this point we have always match_length < MIN_MATCH
36.1481 - */
36.1482 - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
36.1483 - /* To simplify the code, we prevent matches with the string
36.1484 - * of window index 0 (in particular we have to avoid a match
36.1485 - * of the string with itself at the start of the input file).
36.1486 - */
36.1487 -#ifdef FASTEST
36.1488 - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
36.1489 - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
36.1490 - s->match_length = longest_match_fast (s, hash_head);
36.1491 - }
36.1492 -#else
36.1493 - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
36.1494 - s->match_length = longest_match (s, hash_head);
36.1495 - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
36.1496 - s->match_length = longest_match_fast (s, hash_head);
36.1497 - }
36.1498 -#endif
36.1499 - /* longest_match() or longest_match_fast() sets match_start */
36.1500 - }
36.1501 - if (s->match_length >= MIN_MATCH) {
36.1502 - check_match(s, s->strstart, s->match_start, s->match_length);
36.1503 -
36.1504 - _tr_tally_dist(s, s->strstart - s->match_start,
36.1505 - s->match_length - MIN_MATCH, bflush);
36.1506 -
36.1507 - s->lookahead -= s->match_length;
36.1508 -
36.1509 - /* Insert new strings in the hash table only if the match length
36.1510 - * is not too large. This saves time but degrades compression.
36.1511 - */
36.1512 -#ifndef FASTEST
36.1513 - if (s->match_length <= s->max_insert_length &&
36.1514 - s->lookahead >= MIN_MATCH) {
36.1515 - s->match_length--; /* string at strstart already in table */
36.1516 - do {
36.1517 - s->strstart++;
36.1518 - INSERT_STRING(s, s->strstart, hash_head);
36.1519 - /* strstart never exceeds WSIZE-MAX_MATCH, so there are
36.1520 - * always MIN_MATCH bytes ahead.
36.1521 - */
36.1522 - } while (--s->match_length != 0);
36.1523 - s->strstart++;
36.1524 - } else
36.1525 -#endif
36.1526 - {
36.1527 - s->strstart += s->match_length;
36.1528 - s->match_length = 0;
36.1529 - s->ins_h = s->window[s->strstart];
36.1530 - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
36.1531 -#if MIN_MATCH != 3
36.1532 - Call UPDATE_HASH() MIN_MATCH-3 more times
36.1533 -#endif
36.1534 - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
36.1535 - * matter since it will be recomputed at next deflate call.
36.1536 - */
36.1537 - }
36.1538 - } else {
36.1539 - /* No match, output a literal byte */
36.1540 - Tracevv((stderr,"%c", s->window[s->strstart]));
36.1541 - _tr_tally_lit (s, s->window[s->strstart], bflush);
36.1542 - s->lookahead--;
36.1543 - s->strstart++;
36.1544 - }
36.1545 - if (bflush) FLUSH_BLOCK(s, 0);
36.1546 - }
36.1547 - FLUSH_BLOCK(s, flush == Z_FINISH);
36.1548 - return flush == Z_FINISH ? finish_done : block_done;
36.1549 -}
36.1550 -
36.1551 -#ifndef FASTEST
36.1552 -/* ===========================================================================
36.1553 - * Same as above, but achieves better compression. We use a lazy
36.1554 - * evaluation for matches: a match is finally adopted only if there is
36.1555 - * no better match at the next window position.
36.1556 - */
36.1557 -local block_state deflate_slow(s, flush)
36.1558 - deflate_state *s;
36.1559 - int flush;
36.1560 -{
36.1561 - IPos hash_head = NIL; /* head of hash chain */
36.1562 - int bflush; /* set if current block must be flushed */
36.1563 -
36.1564 - /* Process the input block. */
36.1565 - for (;;) {
36.1566 - /* Make sure that we always have enough lookahead, except
36.1567 - * at the end of the input file. We need MAX_MATCH bytes
36.1568 - * for the next match, plus MIN_MATCH bytes to insert the
36.1569 - * string following the next match.
36.1570 - */
36.1571 - if (s->lookahead < MIN_LOOKAHEAD) {
36.1572 - fill_window(s);
36.1573 - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
36.1574 - return need_more;
36.1575 - }
36.1576 - if (s->lookahead == 0) break; /* flush the current block */
36.1577 - }
36.1578 -
36.1579 - /* Insert the string window[strstart .. strstart+2] in the
36.1580 - * dictionary, and set hash_head to the head of the hash chain:
36.1581 - */
36.1582 - if (s->lookahead >= MIN_MATCH) {
36.1583 - INSERT_STRING(s, s->strstart, hash_head);
36.1584 - }
36.1585 -
36.1586 - /* Find the longest match, discarding those <= prev_length.
36.1587 - */
36.1588 - s->prev_length = s->match_length, s->prev_match = s->match_start;
36.1589 - s->match_length = MIN_MATCH-1;
36.1590 -
36.1591 - if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
36.1592 - s->strstart - hash_head <= MAX_DIST(s)) {
36.1593 - /* To simplify the code, we prevent matches with the string
36.1594 - * of window index 0 (in particular we have to avoid a match
36.1595 - * of the string with itself at the start of the input file).
36.1596 - */
36.1597 - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
36.1598 - s->match_length = longest_match (s, hash_head);
36.1599 - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
36.1600 - s->match_length = longest_match_fast (s, hash_head);
36.1601 - }
36.1602 - /* longest_match() or longest_match_fast() sets match_start */
36.1603 -
36.1604 - if (s->match_length <= 5 && (s->strategy == Z_FILTERED
36.1605 -#if TOO_FAR <= 32767
36.1606 - || (s->match_length == MIN_MATCH &&
36.1607 - s->strstart - s->match_start > TOO_FAR)
36.1608 -#endif
36.1609 - )) {
36.1610 -
36.1611 - /* If prev_match is also MIN_MATCH, match_start is garbage
36.1612 - * but we will ignore the current match anyway.
36.1613 - */
36.1614 - s->match_length = MIN_MATCH-1;
36.1615 - }
36.1616 - }
36.1617 - /* If there was a match at the previous step and the current
36.1618 - * match is not better, output the previous match:
36.1619 - */
36.1620 - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
36.1621 - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
36.1622 - /* Do not insert strings in hash table beyond this. */
36.1623 -
36.1624 - check_match(s, s->strstart-1, s->prev_match, s->prev_length);
36.1625 -
36.1626 - _tr_tally_dist(s, s->strstart -1 - s->prev_match,
36.1627 - s->prev_length - MIN_MATCH, bflush);
36.1628 -
36.1629 - /* Insert in hash table all strings up to the end of the match.
36.1630 - * strstart-1 and strstart are already inserted. If there is not
36.1631 - * enough lookahead, the last two strings are not inserted in
36.1632 - * the hash table.
36.1633 - */
36.1634 - s->lookahead -= s->prev_length-1;
36.1635 - s->prev_length -= 2;
36.1636 - do {
36.1637 - if (++s->strstart <= max_insert) {
36.1638 - INSERT_STRING(s, s->strstart, hash_head);
36.1639 - }
36.1640 - } while (--s->prev_length != 0);
36.1641 - s->match_available = 0;
36.1642 - s->match_length = MIN_MATCH-1;
36.1643 - s->strstart++;
36.1644 -
36.1645 - if (bflush) FLUSH_BLOCK(s, 0);
36.1646 -
36.1647 - } else if (s->match_available) {
36.1648 - /* If there was no match at the previous position, output a
36.1649 - * single literal. If there was a match but the current match
36.1650 - * is longer, truncate the previous match to a single literal.
36.1651 - */
36.1652 - Tracevv((stderr,"%c", s->window[s->strstart-1]));
36.1653 - _tr_tally_lit(s, s->window[s->strstart-1], bflush);
36.1654 - if (bflush) {
36.1655 - FLUSH_BLOCK_ONLY(s, 0);
36.1656 - }
36.1657 - s->strstart++;
36.1658 - s->lookahead--;
36.1659 - if (s->strm->avail_out == 0) return need_more;
36.1660 - } else {
36.1661 - /* There is no previous match to compare with, wait for
36.1662 - * the next step to decide.
36.1663 - */
36.1664 - s->match_available = 1;
36.1665 - s->strstart++;
36.1666 - s->lookahead--;
36.1667 - }
36.1668 - }
36.1669 - Assert (flush != Z_NO_FLUSH, "no flush?");
36.1670 - if (s->match_available) {
36.1671 - Tracevv((stderr,"%c", s->window[s->strstart-1]));
36.1672 - _tr_tally_lit(s, s->window[s->strstart-1], bflush);
36.1673 - s->match_available = 0;
36.1674 - }
36.1675 - FLUSH_BLOCK(s, flush == Z_FINISH);
36.1676 - return flush == Z_FINISH ? finish_done : block_done;
36.1677 -}
36.1678 -#endif /* FASTEST */
36.1679 -
36.1680 -#if 0
36.1681 -/* ===========================================================================
36.1682 - * For Z_RLE, simply look for runs of bytes, generate matches only of distance
36.1683 - * one. Do not maintain a hash table. (It will be regenerated if this run of
36.1684 - * deflate switches away from Z_RLE.)
36.1685 - */
36.1686 -local block_state deflate_rle(s, flush)
36.1687 - deflate_state *s;
36.1688 - int flush;
36.1689 -{
36.1690 - int bflush; /* set if current block must be flushed */
36.1691 - uInt run; /* length of run */
36.1692 - uInt max; /* maximum length of run */
36.1693 - uInt prev; /* byte at distance one to match */
36.1694 - Bytef *scan; /* scan for end of run */
36.1695 -
36.1696 - for (;;) {
36.1697 - /* Make sure that we always have enough lookahead, except
36.1698 - * at the end of the input file. We need MAX_MATCH bytes
36.1699 - * for the longest encodable run.
36.1700 - */
36.1701 - if (s->lookahead < MAX_MATCH) {
36.1702 - fill_window(s);
36.1703 - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
36.1704 - return need_more;
36.1705 - }
36.1706 - if (s->lookahead == 0) break; /* flush the current block */
36.1707 - }
36.1708 -
36.1709 - /* See how many times the previous byte repeats */
36.1710 - run = 0;
36.1711 - if (s->strstart > 0) { /* if there is a previous byte, that is */
36.1712 - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
36.1713 - scan = s->window + s->strstart - 1;
36.1714 - prev = *scan++;
36.1715 - do {
36.1716 - if (*scan++ != prev)
36.1717 - break;
36.1718 - } while (++run < max);
36.1719 - }
36.1720 -
36.1721 - /* Emit match if have run of MIN_MATCH or longer, else emit literal */
36.1722 - if (run >= MIN_MATCH) {
36.1723 - check_match(s, s->strstart, s->strstart - 1, run);
36.1724 - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
36.1725 - s->lookahead -= run;
36.1726 - s->strstart += run;
36.1727 - } else {
36.1728 - /* No match, output a literal byte */
36.1729 - Tracevv((stderr,"%c", s->window[s->strstart]));
36.1730 - _tr_tally_lit (s, s->window[s->strstart], bflush);
36.1731 - s->lookahead--;
36.1732 - s->strstart++;
36.1733 - }
36.1734 - if (bflush) FLUSH_BLOCK(s, 0);
36.1735 - }
36.1736 - FLUSH_BLOCK(s, flush == Z_FINISH);
36.1737 - return flush == Z_FINISH ? finish_done : block_done;
36.1738 -}
36.1739 -#endif
37.1 --- a/compiler-init/zlib/deflate.h Sat Jul 15 05:02:38 2006 +0000
37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
37.3 @@ -1,331 +0,0 @@
37.4 -/* deflate.h -- internal compression state
37.5 - * Copyright (C) 1995-2004 Jean-loup Gailly
37.6 - * For conditions of distribution and use, see copyright notice in zlib.h
37.7 - */
37.8 -
37.9 -/* WARNING: this file should *not* be used by applications. It is
37.10 - part of the implementation of the compression library and is
37.11 - subject to change. Applications should only use zlib.h.
37.12 - */
37.13 -
37.14 -/* @(#) $Id$ */
37.15 -
37.16 -#ifndef DEFLATE_H
37.17 -#define DEFLATE_H
37.18 -
37.19 -#include "zutil.h"
37.20 -
37.21 -/* define NO_GZIP when compiling if you want to disable gzip header and
37.22 - trailer creation by deflate(). NO_GZIP would be used to avoid linking in
37.23 - the crc code when it is not needed. For shared libraries, gzip encoding
37.24 - should be left enabled. */
37.25 -#ifndef NO_GZIP
37.26 -# define GZIP
37.27 -#endif
37.28 -
37.29 -/* ===========================================================================
37.30 - * Internal compression state.
37.31 - */
37.32 -
37.33 -#define LENGTH_CODES 29
37.34 -/* number of length codes, not counting the special END_BLOCK code */
37.35 -
37.36 -#define LITERALS 256
37.37 -/* number of literal bytes 0..255 */
37.38 -
37.39 -#define L_CODES (LITERALS+1+LENGTH_CODES)
37.40 -/* number of Literal or Length codes, including the END_BLOCK code */
37.41 -
37.42 -#define D_CODES 30
37.43 -/* number of distance codes */
37.44 -
37.45 -#define BL_CODES 19
37.46 -/* number of codes used to transfer the bit lengths */
37.47 -
37.48 -#define HEAP_SIZE (2*L_CODES+1)
37.49 -/* maximum heap size */
37.50 -
37.51 -#define MAX_BITS 15
37.52 -/* All codes must not exceed MAX_BITS bits */
37.53 -
37.54 -#define INIT_STATE 42
37.55 -#define EXTRA_STATE 69
37.56 -#define NAME_STATE 73
37.57 -#define COMMENT_STATE 91
37.58 -#define HCRC_STATE 103
37.59 -#define BUSY_STATE 113
37.60 -#define FINISH_STATE 666
37.61 -/* Stream status */
37.62 -
37.63 -
37.64 -/* Data structure describing a single value and its code string. */
37.65 -typedef struct ct_data_s {
37.66 - union {
37.67 - ush freq; /* frequency count */
37.68 - ush code; /* bit string */
37.69 - } fc;
37.70 - union {
37.71 - ush dad; /* father node in Huffman tree */
37.72 - ush len; /* length of bit string */
37.73 - } dl;
37.74 -} FAR ct_data;
37.75 -
37.76 -#define Freq fc.freq
37.77 -#define Code fc.code
37.78 -#define Dad dl.dad
37.79 -#define Len dl.len
37.80 -
37.81 -typedef struct static_tree_desc_s static_tree_desc;
37.82 -
37.83 -typedef struct tree_desc_s {
37.84 - ct_data *dyn_tree; /* the dynamic tree */
37.85 - int max_code; /* largest code with non zero frequency */
37.86 - static_tree_desc *stat_desc; /* the corresponding static tree */
37.87 -} FAR tree_desc;
37.88 -
37.89 -typedef ush Pos;
37.90 -typedef Pos FAR Posf;
37.91 -typedef unsigned IPos;
37.92 -
37.93 -/* A Pos is an index in the character window. We use short instead of int to
37.94 - * save space in the various tables. IPos is used only for parameter passing.
37.95 - */
37.96 -
37.97 -typedef struct internal_state {
37.98 - z_streamp strm; /* pointer back to this zlib stream */
37.99 - int status; /* as the name implies */
37.100 - Bytef *pending_buf; /* output still pending */
37.101 - ulg pending_buf_size; /* size of pending_buf */
37.102 - Bytef *pending_out; /* next pending byte to output to the stream */
37.103 - uInt pending; /* nb of bytes in the pending buffer */
37.104 - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
37.105 - gz_headerp gzhead; /* gzip header information to write */
37.106 - uInt gzindex; /* where in extra, name, or comment */
37.107 - Byte method; /* STORED (for zip only) or DEFLATED */
37.108 - int last_flush; /* value of flush param for previous deflate call */
37.109 -
37.110 - /* used by deflate.c: */
37.111 -
37.112 - uInt w_size; /* LZ77 window size (32K by default) */
37.113 - uInt w_bits; /* log2(w_size) (8..16) */
37.114 - uInt w_mask; /* w_size - 1 */
37.115 -
37.116 - Bytef *window;
37.117 - /* Sliding window. Input bytes are read into the second half of the window,
37.118 - * and move to the first half later to keep a dictionary of at least wSize
37.119 - * bytes. With this organization, matches are limited to a distance of
37.120 - * wSize-MAX_MATCH bytes, but this ensures that IO is always
37.121 - * performed with a length multiple of the block size. Also, it limits
37.122 - * the window size to 64K, which is quite useful on MSDOS.
37.123 - * To do: use the user input buffer as sliding window.
37.124 - */
37.125 -
37.126 - ulg window_size;
37.127 - /* Actual size of window: 2*wSize, except when the user input buffer
37.128 - * is directly used as sliding window.
37.129 - */
37.130 -
37.131 - Posf *prev;
37.132 - /* Link to older string with same hash index. To limit the size of this
37.133 - * array to 64K, this link is maintained only for the last 32K strings.
37.134 - * An index in this array is thus a window index modulo 32K.
37.135 - */
37.136 -
37.137 - Posf *head; /* Heads of the hash chains or NIL. */
37.138 -
37.139 - uInt ins_h; /* hash index of string to be inserted */
37.140 - uInt hash_size; /* number of elements in hash table */
37.141 - uInt hash_bits; /* log2(hash_size) */
37.142 - uInt hash_mask; /* hash_size-1 */
37.143 -
37.144 - uInt hash_shift;
37.145 - /* Number of bits by which ins_h must be shifted at each input
37.146 - * step. It must be such that after MIN_MATCH steps, the oldest
37.147 - * byte no longer takes part in the hash key, that is:
37.148 - * hash_shift * MIN_MATCH >= hash_bits
37.149 - */
37.150 -
37.151 - long block_start;
37.152 - /* Window position at the beginning of the current output block. Gets
37.153 - * negative when the window is moved backwards.
37.154 - */
37.155 -
37.156 - uInt match_length; /* length of best match */
37.157 - IPos prev_match; /* previous match */
37.158 - int match_available; /* set if previous match exists */
37.159 - uInt strstart; /* start of string to insert */
37.160 - uInt match_start; /* start of matching string */
37.161 - uInt lookahead; /* number of valid bytes ahead in window */
37.162 -
37.163 - uInt prev_length;
37.164 - /* Length of the best match at previous step. Matches not greater than this
37.165 - * are discarded. This is used in the lazy match evaluation.
37.166 - */
37.167 -
37.168 - uInt max_chain_length;
37.169 - /* To speed up deflation, hash chains are never searched beyond this
37.170 - * length. A higher limit improves compression ratio but degrades the
37.171 - * speed.
37.172 - */
37.173 -
37.174 - uInt max_lazy_match;
37.175 - /* Attempt to find a better match only when the current match is strictly
37.176 - * smaller than this value. This mechanism is used only for compression
37.177 - * levels >= 4.
37.178 - */
37.179 -# define max_insert_length max_lazy_match
37.180 - /* Insert new strings in the hash table only if the match length is not
37.181 - * greater than this length. This saves time but degrades compression.
37.182 - * max_insert_length is used only for compression levels <= 3.
37.183 - */
37.184 -
37.185 - int level; /* compression level (1..9) */
37.186 - int strategy; /* favor or force Huffman coding*/
37.187 -
37.188 - uInt good_match;
37.189 - /* Use a faster search when the previous match is longer than this */
37.190 -
37.191 - int nice_match; /* Stop searching when current match exceeds this */
37.192 -
37.193 - /* used by trees.c: */
37.194 - /* Didn't use ct_data typedef below to supress compiler warning */
37.195 - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
37.196 - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
37.197 - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
37.198 -
37.199 - struct tree_desc_s l_desc; /* desc. for literal tree */
37.200 - struct tree_desc_s d_desc; /* desc. for distance tree */
37.201 - struct tree_desc_s bl_desc; /* desc. for bit length tree */
37.202 -
37.203 - ush bl_count[MAX_BITS+1];
37.204 - /* number of codes at each bit length for an optimal tree */
37.205 -
37.206 - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
37.207 - int heap_len; /* number of elements in the heap */
37.208 - int heap_max; /* element of largest frequency */
37.209 - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
37.210 - * The same heap array is used to build all trees.
37.211 - */
37.212 -
37.213 - uch depth[2*L_CODES+1];
37.214 - /* Depth of each subtree used as tie breaker for trees of equal frequency
37.215 - */
37.216 -
37.217 - uchf *l_buf; /* buffer for literals or lengths */
37.218 -
37.219 - uInt lit_bufsize;
37.220 - /* Size of match buffer for literals/lengths. There are 4 reasons for
37.221 - * limiting lit_bufsize to 64K:
37.222 - * - frequencies can be kept in 16 bit counters
37.223 - * - if compression is not successful for the first block, all input
37.224 - * data is still in the window so we can still emit a stored block even
37.225 - * when input comes from standard input. (This can also be done for
37.226 - * all blocks if lit_bufsize is not greater than 32K.)
37.227 - * - if compression is not successful for a file smaller than 64K, we can
37.228 - * even emit a stored file instead of a stored block (saving 5 bytes).
37.229 - * This is applicable only for zip (not gzip or zlib).
37.230 - * - creating new Huffman trees less frequently may not provide fast
37.231 - * adaptation to changes in the input data statistics. (Take for
37.232 - * example a binary file with poorly compressible code followed by
37.233 - * a highly compressible string table.) Smaller buffer sizes give
37.234 - * fast adaptation but have of course the overhead of transmitting
37.235 - * trees more frequently.
37.236 - * - I can't count above 4
37.237 - */
37.238 -
37.239 - uInt last_lit; /* running index in l_buf */
37.240 -
37.241 - ushf *d_buf;
37.242 - /* Buffer for distances. To simplify the code, d_buf and l_buf have
37.243 - * the same number of elements. To use different lengths, an extra flag
37.244 - * array would be necessary.
37.245 - */
37.246 -
37.247 - ulg opt_len; /* bit length of current block with optimal trees */
37.248 - ulg static_len; /* bit length of current block with static trees */
37.249 - uInt matches; /* number of string matches in current block */
37.250 - int last_eob_len; /* bit length of EOB code for last block */
37.251 -
37.252 -#ifdef DEBUG
37.253 - ulg compressed_len; /* total bit length of compressed file mod 2^32 */
37.254 - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
37.255 -#endif
37.256 -
37.257 - ush bi_buf;
37.258 - /* Output buffer. bits are inserted starting at the bottom (least
37.259 - * significant bits).
37.260 - */
37.261 - int bi_valid;
37.262 - /* Number of valid bits in bi_buf. All bits above the last valid bit
37.263 - * are always zero.
37.264 - */
37.265 -
37.266 -} FAR deflate_state;
37.267 -
37.268 -/* Output a byte on the stream.
37.269 - * IN assertion: there is enough room in pending_buf.
37.270 - */
37.271 -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
37.272 -
37.273 -
37.274 -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
37.275 -/* Minimum amount of lookahead, except at the end of the input file.
37.276 - * See deflate.c for comments about the MIN_MATCH+1.
37.277 - */
37.278 -
37.279 -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
37.280 -/* In order to simplify the code, particularly on 16 bit machines, match
37.281 - * distances are limited to MAX_DIST instead of WSIZE.
37.282 - */
37.283 -
37.284 - /* in trees.c */
37.285 -void _tr_init OF((deflate_state *s));
37.286 -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
37.287 -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
37.288 - int eof));
37.289 -void _tr_align OF((deflate_state *s));
37.290 -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
37.291 - int eof));
37.292 -
37.293 -#define d_code(dist) \
37.294 - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
37.295 -/* Mapping from a distance to a distance code. dist is the distance - 1 and
37.296 - * must not have side effects. _dist_code[256] and _dist_code[257] are never
37.297 - * used.
37.298 - */
37.299 -
37.300 -#ifndef DEBUG
37.301 -/* Inline versions of _tr_tally for speed: */
37.302 -
37.303 -#if defined(GEN_TREES_H) || !defined(STDC)
37.304 - extern uch _length_code[];
37.305 - extern uch _dist_code[];
37.306 -#else
37.307 - extern const uch _length_code[];
37.308 - extern const uch _dist_code[];
37.309 -#endif
37.310 -
37.311 -# define _tr_tally_lit(s, c, flush) \
37.312 - { uch cc = (c); \
37.313 - s->d_buf[s->last_lit] = 0; \
37.314 - s->l_buf[s->last_lit++] = cc; \
37.315 - s->dyn_ltree[cc].Freq++; \
37.316 - flush = (s->last_lit == s->lit_bufsize-1); \
37.317 - }
37.318 -# define _tr_tally_dist(s, distance, length, flush) \
37.319 - { uch len = (length); \
37.320 - ush dist = (distance); \
37.321 - s->d_buf[s->last_lit] = dist; \
37.322 - s->l_buf[s->last_lit++] = len; \
37.323 - dist--; \
37.324 - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
37.325 - s->dyn_dtree[d_code(dist)].Freq++; \
37.326 - flush = (s->last_lit == s->lit_bufsize-1); \
37.327 - }
37.328 -#else
37.329 -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
37.330 -# define _tr_tally_dist(s, distance, length, flush) \
37.331 - flush = _tr_tally(s, distance, length)
37.332 -#endif
37.333 -
37.334 -#endif /* DEFLATE_H */
38.1 --- a/compiler-init/zlib/gzio.c Sat Jul 15 05:02:38 2006 +0000
38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
38.3 @@ -1,1026 +0,0 @@
38.4 -/* gzio.c -- IO on .gz files
38.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
38.6 - * For conditions of distribution and use, see copyright notice in zlib.h
38.7 - *
38.8 - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
38.9 - */
38.10 -
38.11 -/* @(#) $Id$ */
38.12 -
38.13 -#include <stdio.h>
38.14 -
38.15 -#include "zutil.h"
38.16 -
38.17 -#ifdef NO_DEFLATE /* for compatibility with old definition */
38.18 -# define NO_GZCOMPRESS
38.19 -#endif
38.20 -
38.21 -#ifndef NO_DUMMY_DECL
38.22 -struct internal_state {int dummy;}; /* for buggy compilers */
38.23 -#endif
38.24 -
38.25 -#ifndef Z_BUFSIZE
38.26 -# ifdef MAXSEG_64K
38.27 -# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
38.28 -# else
38.29 -# define Z_BUFSIZE 16384
38.30 -# endif
38.31 -#endif
38.32 -#ifndef Z_PRINTF_BUFSIZE
38.33 -# define Z_PRINTF_BUFSIZE 4096
38.34 -#endif
38.35 -
38.36 -#ifdef __MVS__
38.37 -# pragma map (fdopen , "\174\174FDOPEN")
38.38 - FILE *fdopen(int, const char *);
38.39 -#endif
38.40 -
38.41 -#ifndef STDC
38.42 -extern voidp malloc OF((uInt size));
38.43 -extern void free OF((voidpf ptr));
38.44 -#endif
38.45 -
38.46 -#define ALLOC(size) malloc(size)
38.47 -#define TRYFREE(p) {if (p) free(p);}
38.48 -
38.49 -static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
38.50 -
38.51 -/* gzip flag byte */
38.52 -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
38.53 -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
38.54 -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
38.55 -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
38.56 -#define COMMENT 0x10 /* bit 4 set: file comment present */
38.57 -#define RESERVED 0xE0 /* bits 5..7: reserved */
38.58 -
38.59 -typedef struct gz_stream {
38.60 - z_stream stream;
38.61 - int z_err; /* error code for last stream operation */
38.62 - int z_eof; /* set if end of input file */
38.63 - FILE *file; /* .gz file */
38.64 - Byte *inbuf; /* input buffer */
38.65 - Byte *outbuf; /* output buffer */
38.66 - uLong crc; /* crc32 of uncompressed data */
38.67 - char *msg; /* error message */
38.68 - char *path; /* path name for debugging only */
38.69 - int transparent; /* 1 if input file is not a .gz file */
38.70 - char mode; /* 'w' or 'r' */
38.71 - z_off_t start; /* start of compressed data in file (header skipped) */
38.72 - z_off_t in; /* bytes into deflate or inflate */
38.73 - z_off_t out; /* bytes out of deflate or inflate */
38.74 - int back; /* one character push-back */
38.75 - int last; /* true if push-back is last character */
38.76 -} gz_stream;
38.77 -
38.78 -
38.79 -local gzFile gz_open OF((const char *path, const char *mode, int fd));
38.80 -local int do_flush OF((gzFile file, int flush));
38.81 -local int get_byte OF((gz_stream *s));
38.82 -local void check_header OF((gz_stream *s));
38.83 -local int destroy OF((gz_stream *s));
38.84 -local void putLong OF((FILE *file, uLong x));
38.85 -local uLong getLong OF((gz_stream *s));
38.86 -
38.87 -/* ===========================================================================
38.88 - Opens a gzip (.gz) file for reading or writing. The mode parameter
38.89 - is as in fopen ("rb" or "wb"). The file is given either by file descriptor
38.90 - or path name (if fd == -1).
38.91 - gz_open returns NULL if the file could not be opened or if there was
38.92 - insufficient memory to allocate the (de)compression state; errno
38.93 - can be checked to distinguish the two cases (if errno is zero, the
38.94 - zlib error is Z_MEM_ERROR).
38.95 -*/
38.96 -local gzFile gz_open (path, mode, fd)
38.97 - const char *path;
38.98 - const char *mode;
38.99 - int fd;
38.100 -{
38.101 - int err;
38.102 - int level = Z_DEFAULT_COMPRESSION; /* compression level */
38.103 - int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
38.104 - char *p = (char*)mode;
38.105 - gz_stream *s;
38.106 - char fmode[80]; /* copy of mode, without the compression level */
38.107 - char *m = fmode;
38.108 -
38.109 - if (!path || !mode) return Z_NULL;
38.110 -
38.111 - s = (gz_stream *)ALLOC(sizeof(gz_stream));
38.112 - if (!s) return Z_NULL;
38.113 -
38.114 - s->stream.zalloc = (alloc_func)0;
38.115 - s->stream.zfree = (free_func)0;
38.116 - s->stream.opaque = (voidpf)0;
38.117 - s->stream.next_in = s->inbuf = Z_NULL;
38.118 - s->stream.next_out = s->outbuf = Z_NULL;
38.119 - s->stream.avail_in = s->stream.avail_out = 0;
38.120 - s->file = NULL;
38.121 - s->z_err = Z_OK;
38.122 - s->z_eof = 0;
38.123 - s->in = 0;
38.124 - s->out = 0;
38.125 - s->back = EOF;
38.126 - s->crc = crc32(0L, Z_NULL, 0);
38.127 - s->msg = NULL;
38.128 - s->transparent = 0;
38.129 -
38.130 - s->path = (char*)ALLOC(strlen(path)+1);
38.131 - if (s->path == NULL) {
38.132 - return destroy(s), (gzFile)Z_NULL;
38.133 - }
38.134 - strcpy(s->path, path); /* do this early for debugging */
38.135 -
38.136 - s->mode = '\0';
38.137 - do {
38.138 - if (*p == 'r') s->mode = 'r';
38.139 - if (*p == 'w' || *p == 'a') s->mode = 'w';
38.140 - if (*p >= '0' && *p <= '9') {
38.141 - level = *p - '0';
38.142 - } else if (*p == 'f') {
38.143 - strategy = Z_FILTERED;
38.144 - } else if (*p == 'h') {
38.145 - strategy = Z_HUFFMAN_ONLY;
38.146 - } else if (*p == 'R') {
38.147 - strategy = Z_RLE;
38.148 - } else {
38.149 - *m++ = *p; /* copy the mode */
38.150 - }
38.151 - } while (*p++ && m != fmode + sizeof(fmode));
38.152 - if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
38.153 -
38.154 - if (s->mode == 'w') {
38.155 -#ifdef NO_GZCOMPRESS
38.156 - err = Z_STREAM_ERROR;
38.157 -#else
38.158 - err = deflateInit2(&(s->stream), level,
38.159 - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
38.160 - /* windowBits is passed < 0 to suppress zlib header */
38.161 -
38.162 - s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
38.163 -#endif
38.164 - if (err != Z_OK || s->outbuf == Z_NULL) {
38.165 - return destroy(s), (gzFile)Z_NULL;
38.166 - }
38.167 - } else {
38.168 - s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
38.169 -
38.170 - err = inflateInit2(&(s->stream), -MAX_WBITS);
38.171 - /* windowBits is passed < 0 to tell that there is no zlib header.
38.172 - * Note that in this case inflate *requires* an extra "dummy" byte
38.173 - * after the compressed stream in order to complete decompression and
38.174 - * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
38.175 - * present after the compressed stream.
38.176 - */
38.177 - if (err != Z_OK || s->inbuf == Z_NULL) {
38.178 - return destroy(s), (gzFile)Z_NULL;
38.179 - }
38.180 - }
38.181 - s->stream.avail_out = Z_BUFSIZE;
38.182 -
38.183 - errno = 0;
38.184 - s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
38.185 -
38.186 - if (s->file == NULL) {
38.187 - return destroy(s), (gzFile)Z_NULL;
38.188 - }
38.189 - if (s->mode == 'w') {
38.190 - /* Write a very simple .gz header:
38.191 - */
38.192 - fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
38.193 - Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
38.194 - s->start = 10L;
38.195 - /* We use 10L instead of ftell(s->file) to because ftell causes an
38.196 - * fflush on some systems. This version of the library doesn't use
38.197 - * start anyway in write mode, so this initialization is not
38.198 - * necessary.
38.199 - */
38.200 - } else {
38.201 - check_header(s); /* skip the .gz header */
38.202 - s->start = ftell(s->file) - s->stream.avail_in;
38.203 - }
38.204 -
38.205 - return (gzFile)s;
38.206 -}
38.207 -
38.208 -/* ===========================================================================
38.209 - Opens a gzip (.gz) file for reading or writing.
38.210 -*/
38.211 -gzFile ZEXPORT gzopen (path, mode)
38.212 - const char *path;
38.213 - const char *mode;
38.214 -{
38.215 - return gz_open (path, mode, -1);
38.216 -}
38.217 -
38.218 -/* ===========================================================================
38.219 - Associate a gzFile with the file descriptor fd. fd is not dup'ed here
38.220 - to mimic the behavio(u)r of fdopen.
38.221 -*/
38.222 -gzFile ZEXPORT gzdopen (fd, mode)
38.223 - int fd;
38.224 - const char *mode;
38.225 -{
38.226 - char name[46]; /* allow for up to 128-bit integers */
38.227 -
38.228 - if (fd < 0) return (gzFile)Z_NULL;
38.229 - sprintf(name, "<fd:%d>", fd); /* for debugging */
38.230 -
38.231 - return gz_open (name, mode, fd);
38.232 -}
38.233 -
38.234 -/* ===========================================================================
38.235 - * Update the compression level and strategy
38.236 - */
38.237 -int ZEXPORT gzsetparams (file, level, strategy)
38.238 - gzFile file;
38.239 - int level;
38.240 - int strategy;
38.241 -{
38.242 - gz_stream *s = (gz_stream*)file;
38.243 -
38.244 - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
38.245 -
38.246 - /* Make room to allow flushing */
38.247 - if (s->stream.avail_out == 0) {
38.248 -
38.249 - s->stream.next_out = s->outbuf;
38.250 - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
38.251 - s->z_err = Z_ERRNO;
38.252 - }
38.253 - s->stream.avail_out = Z_BUFSIZE;
38.254 - }
38.255 -
38.256 - return deflateParams (&(s->stream), level, strategy);
38.257 -}
38.258 -
38.259 -/* ===========================================================================
38.260 - Read a byte from a gz_stream; update next_in and avail_in. Return EOF
38.261 - for end of file.
38.262 - IN assertion: the stream s has been sucessfully opened for reading.
38.263 -*/
38.264 -local int get_byte(s)
38.265 - gz_stream *s;
38.266 -{
38.267 - if (s->z_eof) return EOF;
38.268 - if (s->stream.avail_in == 0) {
38.269 - errno = 0;
38.270 - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
38.271 - if (s->stream.avail_in == 0) {
38.272 - s->z_eof = 1;
38.273 - if (ferror(s->file)) s->z_err = Z_ERRNO;
38.274 - return EOF;
38.275 - }
38.276 - s->stream.next_in = s->inbuf;
38.277 - }
38.278 - s->stream.avail_in--;
38.279 - return *(s->stream.next_in)++;
38.280 -}
38.281 -
38.282 -/* ===========================================================================
38.283 - Check the gzip header of a gz_stream opened for reading. Set the stream
38.284 - mode to transparent if the gzip magic header is not present; set s->err
38.285 - to Z_DATA_ERROR if the magic header is present but the rest of the header
38.286 - is incorrect.
38.287 - IN assertion: the stream s has already been created sucessfully;
38.288 - s->stream.avail_in is zero for the first time, but may be non-zero
38.289 - for concatenated .gz files.
38.290 -*/
38.291 -local void check_header(s)
38.292 - gz_stream *s;
38.293 -{
38.294 - int method; /* method byte */
38.295 - int flags; /* flags byte */
38.296 - uInt len;
38.297 - int c;
38.298 -
38.299 - /* Assure two bytes in the buffer so we can peek ahead -- handle case
38.300 - where first byte of header is at the end of the buffer after the last
38.301 - gzip segment */
38.302 - len = s->stream.avail_in;
38.303 - if (len < 2) {
38.304 - if (len) s->inbuf[0] = s->stream.next_in[0];
38.305 - errno = 0;
38.306 - len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
38.307 - if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
38.308 - s->stream.avail_in += len;
38.309 - s->stream.next_in = s->inbuf;
38.310 - if (s->stream.avail_in < 2) {
38.311 - s->transparent = s->stream.avail_in;
38.312 - return;
38.313 - }
38.314 - }
38.315 -
38.316 - /* Peek ahead to check the gzip magic header */
38.317 - if (s->stream.next_in[0] != gz_magic[0] ||
38.318 - s->stream.next_in[1] != gz_magic[1]) {
38.319 - s->transparent = 1;
38.320 - return;
38.321 - }
38.322 - s->stream.avail_in -= 2;
38.323 - s->stream.next_in += 2;
38.324 -
38.325 - /* Check the rest of the gzip header */
38.326 - method = get_byte(s);
38.327 - flags = get_byte(s);
38.328 - if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
38.329 - s->z_err = Z_DATA_ERROR;
38.330 - return;
38.331 - }
38.332 -
38.333 - /* Discard time, xflags and OS code: */
38.334 - for (len = 0; len < 6; len++) (void)get_byte(s);
38.335 -
38.336 - if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
38.337 - len = (uInt)get_byte(s);
38.338 - len += ((uInt)get_byte(s))<<8;
38.339 - /* len is garbage if EOF but the loop below will quit anyway */
38.340 - while (len-- != 0 && get_byte(s) != EOF) ;
38.341 - }
38.342 - if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
38.343 - while ((c = get_byte(s)) != 0 && c != EOF) ;
38.344 - }
38.345 - if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
38.346 - while ((c = get_byte(s)) != 0 && c != EOF) ;
38.347 - }
38.348 - if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
38.349 - for (len = 0; len < 2; len++) (void)get_byte(s);
38.350 - }
38.351 - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
38.352 -}
38.353 -
38.354 - /* ===========================================================================
38.355 - * Cleanup then free the given gz_stream. Return a zlib error code.
38.356 - Try freeing in the reverse order of allocations.
38.357 - */
38.358 -local int destroy (s)
38.359 - gz_stream *s;
38.360 -{
38.361 - int err = Z_OK;
38.362 -
38.363 - if (!s) return Z_STREAM_ERROR;
38.364 -
38.365 - TRYFREE(s->msg);
38.366 -
38.367 - if (s->stream.state != NULL) {
38.368 - if (s->mode == 'w') {
38.369 -#ifdef NO_GZCOMPRESS
38.370 - err = Z_STREAM_ERROR;
38.371 -#else
38.372 - err = deflateEnd(&(s->stream));
38.373 -#endif
38.374 - } else if (s->mode == 'r') {
38.375 - err = inflateEnd(&(s->stream));
38.376 - }
38.377 - }
38.378 - if (s->file != NULL && fclose(s->file)) {
38.379 -#ifdef ESPIPE
38.380 - if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
38.381 -#endif
38.382 - err = Z_ERRNO;
38.383 - }
38.384 - if (s->z_err < 0) err = s->z_err;
38.385 -
38.386 - TRYFREE(s->inbuf);
38.387 - TRYFREE(s->outbuf);
38.388 - TRYFREE(s->path);
38.389 - TRYFREE(s);
38.390 - return err;
38.391 -}
38.392 -
38.393 -/* ===========================================================================
38.394 - Reads the given number of uncompressed bytes from the compressed file.
38.395 - gzread returns the number of bytes actually read (0 for end of file).
38.396 -*/
38.397 -int ZEXPORT gzread (file, buf, len)
38.398 - gzFile file;
38.399 - voidp buf;
38.400 - unsigned len;
38.401 -{
38.402 - gz_stream *s = (gz_stream*)file;
38.403 - Bytef *start = (Bytef*)buf; /* starting point for crc computation */
38.404 - Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
38.405 -
38.406 - if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
38.407 -
38.408 - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
38.409 - if (s->z_err == Z_STREAM_END) return 0; /* EOF */
38.410 -
38.411 - next_out = (Byte*)buf;
38.412 - s->stream.next_out = (Bytef*)buf;
38.413 - s->stream.avail_out = len;
38.414 -
38.415 - if (s->stream.avail_out && s->back != EOF) {
38.416 - *next_out++ = s->back;
38.417 - s->stream.next_out++;
38.418 - s->stream.avail_out--;
38.419 - s->back = EOF;
38.420 - s->out++;
38.421 - start++;
38.422 - if (s->last) {
38.423 - s->z_err = Z_STREAM_END;
38.424 - return 1;
38.425 - }
38.426 - }
38.427 -
38.428 - while (s->stream.avail_out != 0) {
38.429 -
38.430 - if (s->transparent) {
38.431 - /* Copy first the lookahead bytes: */
38.432 - uInt n = s->stream.avail_in;
38.433 - if (n > s->stream.avail_out) n = s->stream.avail_out;
38.434 - if (n > 0) {
38.435 - zmemcpy(s->stream.next_out, s->stream.next_in, n);
38.436 - next_out += n;
38.437 - s->stream.next_out = next_out;
38.438 - s->stream.next_in += n;
38.439 - s->stream.avail_out -= n;
38.440 - s->stream.avail_in -= n;
38.441 - }
38.442 - if (s->stream.avail_out > 0) {
38.443 - s->stream.avail_out -=
38.444 - (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
38.445 - }
38.446 - len -= s->stream.avail_out;
38.447 - s->in += len;
38.448 - s->out += len;
38.449 - if (len == 0) s->z_eof = 1;
38.450 - return (int)len;
38.451 - }
38.452 - if (s->stream.avail_in == 0 && !s->z_eof) {
38.453 -
38.454 - errno = 0;
38.455 - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
38.456 - if (s->stream.avail_in == 0) {
38.457 - s->z_eof = 1;
38.458 - if (ferror(s->file)) {
38.459 - s->z_err = Z_ERRNO;
38.460 - break;
38.461 - }
38.462 - }
38.463 - s->stream.next_in = s->inbuf;
38.464 - }
38.465 - s->in += s->stream.avail_in;
38.466 - s->out += s->stream.avail_out;
38.467 - s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
38.468 - s->in -= s->stream.avail_in;
38.469 - s->out -= s->stream.avail_out;
38.470 -
38.471 - if (s->z_err == Z_STREAM_END) {
38.472 - /* Check CRC and original size */
38.473 - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
38.474 - start = s->stream.next_out;
38.475 -
38.476 - if (getLong(s) != s->crc) {
38.477 - s->z_err = Z_DATA_ERROR;
38.478 - } else {
38.479 - (void)getLong(s);
38.480 - /* The uncompressed length returned by above getlong() may be
38.481 - * different from s->out in case of concatenated .gz files.
38.482 - * Check for such files:
38.483 - */
38.484 - check_header(s);
38.485 - if (s->z_err == Z_OK) {
38.486 - inflateReset(&(s->stream));
38.487 - s->crc = crc32(0L, Z_NULL, 0);
38.488 - }
38.489 - }
38.490 - }
38.491 - if (s->z_err != Z_OK || s->z_eof) break;
38.492 - }
38.493 - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
38.494 -
38.495 - if (len == s->stream.avail_out &&
38.496 - (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
38.497 - return -1;
38.498 - return (int)(len - s->stream.avail_out);
38.499 -}
38.500 -
38.501 -
38.502 -/* ===========================================================================
38.503 - Reads one byte from the compressed file. gzgetc returns this byte
38.504 - or -1 in case of end of file or error.
38.505 -*/
38.506 -int ZEXPORT gzgetc(file)
38.507 - gzFile file;
38.508 -{
38.509 - unsigned char c;
38.510 -
38.511 - return gzread(file, &c, 1) == 1 ? c : -1;
38.512 -}
38.513 -
38.514 -
38.515 -/* ===========================================================================
38.516 - Push one byte back onto the stream.
38.517 -*/
38.518 -int ZEXPORT gzungetc(c, file)
38.519 - int c;
38.520 - gzFile file;
38.521 -{
38.522 - gz_stream *s = (gz_stream*)file;
38.523 -
38.524 - if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
38.525 - s->back = c;
38.526 - s->out--;
38.527 - s->last = (s->z_err == Z_STREAM_END);
38.528 - if (s->last) s->z_err = Z_OK;
38.529 - s->z_eof = 0;
38.530 - return c;
38.531 -}
38.532 -
38.533 -
38.534 -/* ===========================================================================
38.535 - Reads bytes from the compressed file until len-1 characters are
38.536 - read, or a newline character is read and transferred to buf, or an
38.537 - end-of-file condition is encountered. The string is then terminated
38.538 - with a null character.
38.539 - gzgets returns buf, or Z_NULL in case of error.
38.540 -
38.541 - The current implementation is not optimized at all.
38.542 -*/
38.543 -char * ZEXPORT gzgets(file, buf, len)
38.544 - gzFile file;
38.545 - char *buf;
38.546 - int len;
38.547 -{
38.548 - char *b = buf;
38.549 - if (buf == Z_NULL || len <= 0) return Z_NULL;
38.550 -
38.551 - while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
38.552 - *buf = '\0';
38.553 - return b == buf && len > 0 ? Z_NULL : b;
38.554 -}
38.555 -
38.556 -
38.557 -#ifndef NO_GZCOMPRESS
38.558 -/* ===========================================================================
38.559 - Writes the given number of uncompressed bytes into the compressed file.
38.560 - gzwrite returns the number of bytes actually written (0 in case of error).
38.561 -*/
38.562 -int ZEXPORT gzwrite (file, buf, len)
38.563 - gzFile file;
38.564 - voidpc buf;
38.565 - unsigned len;
38.566 -{
38.567 - gz_stream *s = (gz_stream*)file;
38.568 -
38.569 - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
38.570 -
38.571 - s->stream.next_in = (Bytef*)buf;
38.572 - s->stream.avail_in = len;
38.573 -
38.574 - while (s->stream.avail_in != 0) {
38.575 -
38.576 - if (s->stream.avail_out == 0) {
38.577 -
38.578 - s->stream.next_out = s->outbuf;
38.579 - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
38.580 - s->z_err = Z_ERRNO;
38.581 - break;
38.582 - }
38.583 - s->stream.avail_out = Z_BUFSIZE;
38.584 - }
38.585 - s->in += s->stream.avail_in;
38.586 - s->out += s->stream.avail_out;
38.587 - s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
38.588 - s->in -= s->stream.avail_in;
38.589 - s->out -= s->stream.avail_out;
38.590 - if (s->z_err != Z_OK) break;
38.591 - }
38.592 - s->crc = crc32(s->crc, (const Bytef *)buf, len);
38.593 -
38.594 - return (int)(len - s->stream.avail_in);
38.595 -}
38.596 -
38.597 -
38.598 -/* ===========================================================================
38.599 - Converts, formats, and writes the args to the compressed file under
38.600 - control of the format string, as in fprintf. gzprintf returns the number of
38.601 - uncompressed bytes actually written (0 in case of error).
38.602 -*/
38.603 -#ifdef STDC
38.604 -#include <stdarg.h>
38.605 -
38.606 -int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
38.607 -{
38.608 - char buf[Z_PRINTF_BUFSIZE];
38.609 - va_list va;
38.610 - int len;
38.611 -
38.612 - buf[sizeof(buf) - 1] = 0;
38.613 - va_start(va, format);
38.614 -#ifdef NO_vsnprintf
38.615 -# ifdef HAS_vsprintf_void
38.616 - (void)vsprintf(buf, format, va);
38.617 - va_end(va);
38.618 - for (len = 0; len < sizeof(buf); len++)
38.619 - if (buf[len] == 0) break;
38.620 -# else
38.621 - len = vsprintf(buf, format, va);
38.622 - va_end(va);
38.623 -# endif
38.624 -#else
38.625 -# ifdef HAS_vsnprintf_void
38.626 - (void)vsnprintf(buf, sizeof(buf), format, va);
38.627 - va_end(va);
38.628 - len = strlen(buf);
38.629 -# else
38.630 - len = vsnprintf(buf, sizeof(buf), format, va);
38.631 - va_end(va);
38.632 -# endif
38.633 -#endif
38.634 - if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
38.635 - return 0;
38.636 - return gzwrite(file, buf, (unsigned)len);
38.637 -}
38.638 -#else /* not ANSI C */
38.639 -
38.640 -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
38.641 - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
38.642 - gzFile file;
38.643 - const char *format;
38.644 - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
38.645 - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
38.646 -{
38.647 - char buf[Z_PRINTF_BUFSIZE];
38.648 - int len;
38.649 -
38.650 - buf[sizeof(buf) - 1] = 0;
38.651 -#ifdef NO_snprintf
38.652 -# ifdef HAS_sprintf_void
38.653 - sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
38.654 - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
38.655 - for (len = 0; len < sizeof(buf); len++)
38.656 - if (buf[len] == 0) break;
38.657 -# else
38.658 - len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
38.659 - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
38.660 -# endif
38.661 -#else
38.662 -# ifdef HAS_snprintf_void
38.663 - snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
38.664 - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
38.665 - len = strlen(buf);
38.666 -# else
38.667 - len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
38.668 - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
38.669 -# endif
38.670 -#endif
38.671 - if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
38.672 - return 0;
38.673 - return gzwrite(file, buf, len);
38.674 -}
38.675 -#endif
38.676 -
38.677 -/* ===========================================================================
38.678 - Writes c, converted to an unsigned char, into the compressed file.
38.679 - gzputc returns the value that was written, or -1 in case of error.
38.680 -*/
38.681 -int ZEXPORT gzputc(file, c)
38.682 - gzFile file;
38.683 - int c;
38.684 -{
38.685 - unsigned char cc = (unsigned char) c; /* required for big endian systems */
38.686 -
38.687 - return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
38.688 -}
38.689 -
38.690 -
38.691 -/* ===========================================================================
38.692 - Writes the given null-terminated string to the compressed file, excluding
38.693 - the terminating null character.
38.694 - gzputs returns the number of characters written, or -1 in case of error.
38.695 -*/
38.696 -int ZEXPORT gzputs(file, s)
38.697 - gzFile file;
38.698 - const char *s;
38.699 -{
38.700 - return gzwrite(file, (char*)s, (unsigned)strlen(s));
38.701 -}
38.702 -
38.703 -
38.704 -/* ===========================================================================
38.705 - Flushes all pending output into the compressed file. The parameter
38.706 - flush is as in the deflate() function.
38.707 -*/
38.708 -local int do_flush (file, flush)
38.709 - gzFile file;
38.710 - int flush;
38.711 -{
38.712 - uInt len;
38.713 - int done = 0;
38.714 - gz_stream *s = (gz_stream*)file;
38.715 -
38.716 - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
38.717 -
38.718 - s->stream.avail_in = 0; /* should be zero already anyway */
38.719 -
38.720 - for (;;) {
38.721 - len = Z_BUFSIZE - s->stream.avail_out;
38.722 -
38.723 - if (len != 0) {
38.724 - if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
38.725 - s->z_err = Z_ERRNO;
38.726 - return Z_ERRNO;
38.727 - }
38.728 - s->stream.next_out = s->outbuf;
38.729 - s->stream.avail_out = Z_BUFSIZE;
38.730 - }
38.731 - if (done) break;
38.732 - s->out += s->stream.avail_out;
38.733 - s->z_err = deflate(&(s->stream), flush);
38.734 - s->out -= s->stream.avail_out;
38.735 -
38.736 - /* Ignore the second of two consecutive flushes: */
38.737 - if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
38.738 -
38.739 - /* deflate has finished flushing only when it hasn't used up
38.740 - * all the available space in the output buffer:
38.741 - */
38.742 - done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
38.743 -
38.744 - if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
38.745 - }
38.746 - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
38.747 -}
38.748 -
38.749 -int ZEXPORT gzflush (file, flush)
38.750 - gzFile file;
38.751 - int flush;
38.752 -{
38.753 - gz_stream *s = (gz_stream*)file;
38.754 - int err = do_flush (file, flush);
38.755 -
38.756 - if (err) return err;
38.757 - fflush(s->file);
38.758 - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
38.759 -}
38.760 -#endif /* NO_GZCOMPRESS */
38.761 -
38.762 -/* ===========================================================================
38.763 - Sets the starting position for the next gzread or gzwrite on the given
38.764 - compressed file. The offset represents a number of bytes in the
38.765 - gzseek returns the resulting offset location as measured in bytes from
38.766 - the beginning of the uncompressed stream, or -1 in case of error.
38.767 - SEEK_END is not implemented, returns error.
38.768 - In this version of the library, gzseek can be extremely slow.
38.769 -*/
38.770 -z_off_t ZEXPORT gzseek (file, offset, whence)
38.771 - gzFile file;
38.772 - z_off_t offset;
38.773 - int whence;
38.774 -{
38.775 - gz_stream *s = (gz_stream*)file;
38.776 -
38.777 - if (s == NULL || whence == SEEK_END ||
38.778 - s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
38.779 - return -1L;
38.780 - }
38.781 -
38.782 - if (s->mode == 'w') {
38.783 -#ifdef NO_GZCOMPRESS
38.784 - return -1L;
38.785 -#else
38.786 - if (whence == SEEK_SET) {
38.787 - offset -= s->in;
38.788 - }
38.789 - if (offset < 0) return -1L;
38.790 -
38.791 - /* At this point, offset is the number of zero bytes to write. */
38.792 - if (s->inbuf == Z_NULL) {
38.793 - s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
38.794 - if (s->inbuf == Z_NULL) return -1L;
38.795 - zmemzero(s->inbuf, Z_BUFSIZE);
38.796 - }
38.797 - while (offset > 0) {
38.798 - uInt size = Z_BUFSIZE;
38.799 - if (offset < Z_BUFSIZE) size = (uInt)offset;
38.800 -
38.801 - size = gzwrite(file, s->inbuf, size);
38.802 - if (size == 0) return -1L;
38.803 -
38.804 - offset -= size;
38.805 - }
38.806 - return s->in;
38.807 -#endif
38.808 - }
38.809 - /* Rest of function is for reading only */
38.810 -
38.811 - /* compute absolute position */
38.812 - if (whence == SEEK_CUR) {
38.813 - offset += s->out;
38.814 - }
38.815 - if (offset < 0) return -1L;
38.816 -
38.817 - if (s->transparent) {
38.818 - /* map to fseek */
38.819 - s->back = EOF;
38.820 - s->stream.avail_in = 0;
38.821 - s->stream.next_in = s->inbuf;
38.822 - if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
38.823 -
38.824 - s->in = s->out = offset;
38.825 - return offset;
38.826 - }
38.827 -
38.828 - /* For a negative seek, rewind and use positive seek */
38.829 - if (offset >= s->out) {
38.830 - offset -= s->out;
38.831 - } else if (gzrewind(file) < 0) {
38.832 - return -1L;
38.833 - }
38.834 - /* offset is now the number of bytes to skip. */
38.835 -
38.836 - if (offset != 0 && s->outbuf == Z_NULL) {
38.837 - s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
38.838 - if (s->outbuf == Z_NULL) return -1L;
38.839 - }
38.840 - if (offset && s->back != EOF) {
38.841 - s->back = EOF;
38.842 - s->out++;
38.843 - offset--;
38.844 - if (s->last) s->z_err = Z_STREAM_END;
38.845 - }
38.846 - while (offset > 0) {
38.847 - int size = Z_BUFSIZE;
38.848 - if (offset < Z_BUFSIZE) size = (int)offset;
38.849 -
38.850 - size = gzread(file, s->outbuf, (uInt)size);
38.851 - if (size <= 0) return -1L;
38.852 - offset -= size;
38.853 - }
38.854 - return s->out;
38.855 -}
38.856 -
38.857 -/* ===========================================================================
38.858 - Rewinds input file.
38.859 -*/
38.860 -int ZEXPORT gzrewind (file)
38.861 - gzFile file;
38.862 -{
38.863 - gz_stream *s = (gz_stream*)file;
38.864 -
38.865 - if (s == NULL || s->mode != 'r') return -1;
38.866 -
38.867 - s->z_err = Z_OK;
38.868 - s->z_eof = 0;
38.869 - s->back = EOF;
38.870 - s->stream.avail_in = 0;
38.871 - s->stream.next_in = s->inbuf;
38.872 - s->crc = crc32(0L, Z_NULL, 0);
38.873 - if (!s->transparent) (void)inflateReset(&s->stream);
38.874 - s->in = 0;
38.875 - s->out = 0;
38.876 - return fseek(s->file, s->start, SEEK_SET);
38.877 -}
38.878 -
38.879 -/* ===========================================================================
38.880 - Returns the starting position for the next gzread or gzwrite on the
38.881 - given compressed file. This position represents a number of bytes in the
38.882 - uncompressed data stream.
38.883 -*/
38.884 -z_off_t ZEXPORT gztell (file)
38.885 - gzFile file;
38.886 -{
38.887 - return gzseek(file, 0L, SEEK_CUR);
38.888 -}
38.889 -
38.890 -/* ===========================================================================
38.891 - Returns 1 when EOF has previously been detected reading the given
38.892 - input stream, otherwise zero.
38.893 -*/
38.894 -int ZEXPORT gzeof (file)
38.895 - gzFile file;
38.896 -{
38.897 - gz_stream *s = (gz_stream*)file;
38.898 -
38.899 - /* With concatenated compressed files that can have embedded
38.900 - * crc trailers, z_eof is no longer the only/best indicator of EOF
38.901 - * on a gz_stream. Handle end-of-stream error explicitly here.
38.902 - */
38.903 - if (s == NULL || s->mode != 'r') return 0;
38.904 - if (s->z_eof) return 1;
38.905 - return s->z_err == Z_STREAM_END;
38.906 -}
38.907 -
38.908 -/* ===========================================================================
38.909 - Returns 1 if reading and doing so transparently, otherwise zero.
38.910 -*/
38.911 -int ZEXPORT gzdirect (file)
38.912 - gzFile file;
38.913 -{
38.914 - gz_stream *s = (gz_stream*)file;
38.915 -
38.916 - if (s == NULL || s->mode != 'r') return 0;
38.917 - return s->transparent;
38.918 -}
38.919 -
38.920 -/* ===========================================================================
38.921 - Outputs a long in LSB order to the given file
38.922 -*/
38.923 -local void putLong (file, x)
38.924 - FILE *file;
38.925 - uLong x;
38.926 -{
38.927 - int n;
38.928 - for (n = 0; n < 4; n++) {
38.929 - fputc((int)(x & 0xff), file);
38.930 - x >>= 8;
38.931 - }
38.932 -}
38.933 -
38.934 -/* ===========================================================================
38.935 - Reads a long in LSB order from the given gz_stream. Sets z_err in case
38.936 - of error.
38.937 -*/
38.938 -local uLong getLong (s)
38.939 - gz_stream *s;
38.940 -{
38.941 - uLong x = (uLong)get_byte(s);
38.942 - int c;
38.943 -
38.944 - x += ((uLong)get_byte(s))<<8;
38.945 - x += ((uLong)get_byte(s))<<16;
38.946 - c = get_byte(s);
38.947 - if (c == EOF) s->z_err = Z_DATA_ERROR;
38.948 - x += ((uLong)c)<<24;
38.949 - return x;
38.950 -}
38.951 -
38.952 -/* ===========================================================================
38.953 - Flushes all pending output if necessary, closes the compressed file
38.954 - and deallocates all the (de)compression state.
38.955 -*/
38.956 -int ZEXPORT gzclose (file)
38.957 - gzFile file;
38.958 -{
38.959 - gz_stream *s = (gz_stream*)file;
38.960 -
38.961 - if (s == NULL) return Z_STREAM_ERROR;
38.962 -
38.963 - if (s->mode == 'w') {
38.964 -#ifdef NO_GZCOMPRESS
38.965 - return Z_STREAM_ERROR;
38.966 -#else
38.967 - if (do_flush (file, Z_FINISH) != Z_OK)
38.968 - return destroy((gz_stream*)file);
38.969 -
38.970 - putLong (s->file, s->crc);
38.971 - putLong (s->file, (uLong)(s->in & 0xffffffff));
38.972 -#endif
38.973 - }
38.974 - return destroy((gz_stream*)file);
38.975 -}
38.976 -
38.977 -#ifdef STDC
38.978 -# define zstrerror(errnum) strerror(errnum)
38.979 -#else
38.980 -# define zstrerror(errnum) ""
38.981 -#endif
38.982 -
38.983 -/* ===========================================================================
38.984 - Returns the error message for the last error which occurred on the
38.985 - given compressed file. errnum is set to zlib error number. If an
38.986 - error occurred in the file system and not in the compression library,
38.987 - errnum is set to Z_ERRNO and the application may consult errno
38.988 - to get the exact error code.
38.989 -*/
38.990 -const char * ZEXPORT gzerror (file, errnum)
38.991 - gzFile file;
38.992 - int *errnum;
38.993 -{
38.994 - char *m;
38.995 - gz_stream *s = (gz_stream*)file;
38.996 -
38.997 - if (s == NULL) {
38.998 - *errnum = Z_STREAM_ERROR;
38.999 - return (const char*)ERR_MSG(Z_STREAM_ERROR);
38.1000 - }
38.1001 - *errnum = s->z_err;
38.1002 - if (*errnum == Z_OK) return (const char*)"";
38.1003 -
38.1004 - m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
38.1005 -
38.1006 - if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
38.1007 -
38.1008 - TRYFREE(s->msg);
38.1009 - s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
38.1010 - if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
38.1011 - strcpy(s->msg, s->path);
38.1012 - strcat(s->msg, ": ");
38.1013 - strcat(s->msg, m);
38.1014 - return (const char*)s->msg;
38.1015 -}
38.1016 -
38.1017 -/* ===========================================================================
38.1018 - Clear the error and end-of-file flags, and do the same for the real file.
38.1019 -*/
38.1020 -void ZEXPORT gzclearerr (file)
38.1021 - gzFile file;
38.1022 -{
38.1023 - gz_stream *s = (gz_stream*)file;
38.1024 -
38.1025 - if (s == NULL) return;
38.1026 - if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
38.1027 - s->z_eof = 0;
38.1028 - clearerr(s->file);
38.1029 -}
39.1 --- a/compiler-init/zlib/infback.c Sat Jul 15 05:02:38 2006 +0000
39.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
39.3 @@ -1,623 +0,0 @@
39.4 -/* infback.c -- inflate using a call-back interface
39.5 - * Copyright (C) 1995-2005 Mark Adler
39.6 - * For conditions of distribution and use, see copyright notice in zlib.h
39.7 - */
39.8 -
39.9 -/*
39.10 - This code is largely copied from inflate.c. Normally either infback.o or
39.11 - inflate.o would be linked into an application--not both. The interface
39.12 - with inffast.c is retained so that optimized assembler-coded versions of
39.13 - inflate_fast() can be used with either inflate.c or infback.c.
39.14 - */
39.15 -
39.16 -#include "zutil.h"
39.17 -#include "inftrees.h"
39.18 -#include "inflate.h"
39.19 -#include "inffast.h"
39.20 -
39.21 -/* function prototypes */
39.22 -local void fixedtables OF((struct inflate_state FAR *state));
39.23 -
39.24 -/*
39.25 - strm provides memory allocation functions in zalloc and zfree, or
39.26 - Z_NULL to use the library memory allocation functions.
39.27 -
39.28 - windowBits is in the range 8..15, and window is a user-supplied
39.29 - window and output buffer that is 2**windowBits bytes.
39.30 - */
39.31 -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
39.32 -z_streamp strm;
39.33 -int windowBits;
39.34 -unsigned char FAR *window;
39.35 -const char *version;
39.36 -int stream_size;
39.37 -{
39.38 - struct inflate_state FAR *state;
39.39 -
39.40 - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
39.41 - stream_size != (int)(sizeof(z_stream)))
39.42 - return Z_VERSION_ERROR;
39.43 - if (strm == Z_NULL || window == Z_NULL ||
39.44 - windowBits < 8 || windowBits > 15)
39.45 - return Z_STREAM_ERROR;
39.46 - strm->msg = Z_NULL; /* in case we return an error */
39.47 - if (strm->zalloc == (alloc_func)0) {
39.48 - strm->zalloc = zcalloc;
39.49 - strm->opaque = (voidpf)0;
39.50 - }
39.51 - if (strm->zfree == (free_func)0) strm->zfree = zcfree;
39.52 - state = (struct inflate_state FAR *)ZALLOC(strm, 1,
39.53 - sizeof(struct inflate_state));
39.54 - if (state == Z_NULL) return Z_MEM_ERROR;
39.55 - Tracev((stderr, "inflate: allocated\n"));
39.56 - strm->state = (struct internal_state FAR *)state;
39.57 - state->dmax = 32768U;
39.58 - state->wbits = windowBits;
39.59 - state->wsize = 1U << windowBits;
39.60 - state->window = window;
39.61 - state->write = 0;
39.62 - state->whave = 0;
39.63 - return Z_OK;
39.64 -}
39.65 -
39.66 -/*
39.67 - Return state with length and distance decoding tables and index sizes set to
39.68 - fixed code decoding. Normally this returns fixed tables from inffixed.h.
39.69 - If BUILDFIXED is defined, then instead this routine builds the tables the
39.70 - first time it's called, and returns those tables the first time and
39.71 - thereafter. This reduces the size of the code by about 2K bytes, in
39.72 - exchange for a little execution time. However, BUILDFIXED should not be
39.73 - used for threaded applications, since the rewriting of the tables and virgin
39.74 - may not be thread-safe.
39.75 - */
39.76 -local void fixedtables(state)
39.77 -struct inflate_state FAR *state;
39.78 -{
39.79 -#ifdef BUILDFIXED
39.80 - static int virgin = 1;
39.81 - static code *lenfix, *distfix;
39.82 - static code fixed[544];
39.83 -
39.84 - /* build fixed huffman tables if first call (may not be thread safe) */
39.85 - if (virgin) {
39.86 - unsigned sym, bits;
39.87 - static code *next;
39.88 -
39.89 - /* literal/length table */
39.90 - sym = 0;
39.91 - while (sym < 144) state->lens[sym++] = 8;
39.92 - while (sym < 256) state->lens[sym++] = 9;
39.93 - while (sym < 280) state->lens[sym++] = 7;
39.94 - while (sym < 288) state->lens[sym++] = 8;
39.95 - next = fixed;
39.96 - lenfix = next;
39.97 - bits = 9;
39.98 - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
39.99 -
39.100 - /* distance table */
39.101 - sym = 0;
39.102 - while (sym < 32) state->lens[sym++] = 5;
39.103 - distfix = next;
39.104 - bits = 5;
39.105 - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
39.106 -
39.107 - /* do this just once */
39.108 - virgin = 0;
39.109 - }
39.110 -#else /* !BUILDFIXED */
39.111 -# include "inffixed.h"
39.112 -#endif /* BUILDFIXED */
39.113 - state->lencode = lenfix;
39.114 - state->lenbits = 9;
39.115 - state->distcode = distfix;
39.116 - state->distbits = 5;
39.117 -}
39.118 -
39.119 -/* Macros for inflateBack(): */
39.120 -
39.121 -/* Load returned state from inflate_fast() */
39.122 -#define LOAD() \
39.123 - do { \
39.124 - put = strm->next_out; \
39.125 - left = strm->avail_out; \
39.126 - next = strm->next_in; \
39.127 - have = strm->avail_in; \
39.128 - hold = state->hold; \
39.129 - bits = state->bits; \
39.130 - } while (0)
39.131 -
39.132 -/* Set state from registers for inflate_fast() */
39.133 -#define RESTORE() \
39.134 - do { \
39.135 - strm->next_out = put; \
39.136 - strm->avail_out = left; \
39.137 - strm->next_in = next; \
39.138 - strm->avail_in = have; \
39.139 - state->hold = hold; \
39.140 - state->bits = bits; \
39.141 - } while (0)
39.142 -
39.143 -/* Clear the input bit accumulator */
39.144 -#define INITBITS() \
39.145 - do { \
39.146 - hold = 0; \
39.147 - bits = 0; \
39.148 - } while (0)
39.149 -
39.150 -/* Assure that some input is available. If input is requested, but denied,
39.151 - then return a Z_BUF_ERROR from inflateBack(). */
39.152 -#define PULL() \
39.153 - do { \
39.154 - if (have == 0) { \
39.155 - have = in(in_desc, &next); \
39.156 - if (have == 0) { \
39.157 - next = Z_NULL; \
39.158 - ret = Z_BUF_ERROR; \
39.159 - goto inf_leave; \
39.160 - } \
39.161 - } \
39.162 - } while (0)
39.163 -
39.164 -/* Get a byte of input into the bit accumulator, or return from inflateBack()
39.165 - with an error if there is no input available. */
39.166 -#define PULLBYTE() \
39.167 - do { \
39.168 - PULL(); \
39.169 - have--; \
39.170 - hold += (unsigned long)(*next++) << bits; \
39.171 - bits += 8; \
39.172 - } while (0)
39.173 -
39.174 -/* Assure that there are at least n bits in the bit accumulator. If there is
39.175 - not enough available input to do that, then return from inflateBack() with
39.176 - an error. */
39.177 -#define NEEDBITS(n) \
39.178 - do { \
39.179 - while (bits < (unsigned)(n)) \
39.180 - PULLBYTE(); \
39.181 - } while (0)
39.182 -
39.183 -/* Return the low n bits of the bit accumulator (n < 16) */
39.184 -#define BITS(n) \
39.185 - ((unsigned)hold & ((1U << (n)) - 1))
39.186 -
39.187 -/* Remove n bits from the bit accumulator */
39.188 -#define DROPBITS(n) \
39.189 - do { \
39.190 - hold >>= (n); \
39.191 - bits -= (unsigned)(n); \
39.192 - } while (0)
39.193 -
39.194 -/* Remove zero to seven bits as needed to go to a byte boundary */
39.195 -#define BYTEBITS() \
39.196 - do { \
39.197 - hold >>= bits & 7; \
39.198 - bits -= bits & 7; \
39.199 - } while (0)
39.200 -
39.201 -/* Assure that some output space is available, by writing out the window
39.202 - if it's full. If the write fails, return from inflateBack() with a
39.203 - Z_BUF_ERROR. */
39.204 -#define ROOM() \
39.205 - do { \
39.206 - if (left == 0) { \
39.207 - put = state->window; \
39.208 - left = state->wsize; \
39.209 - state->whave = left; \
39.210 - if (out(out_desc, put, left)) { \
39.211 - ret = Z_BUF_ERROR; \
39.212 - goto inf_leave; \
39.213 - } \
39.214 - } \
39.215 - } while (0)
39.216 -
39.217 -/*
39.218 - strm provides the memory allocation functions and window buffer on input,
39.219 - and provides information on the unused input on return. For Z_DATA_ERROR
39.220 - returns, strm will also provide an error message.
39.221 -
39.222 - in() and out() are the call-back input and output functions. When
39.223 - inflateBack() needs more input, it calls in(). When inflateBack() has
39.224 - filled the window with output, or when it completes with data in the
39.225 - window, it calls out() to write out the data. The application must not
39.226 - change the provided input until in() is called again or inflateBack()
39.227 - returns. The application must not change the window/output buffer until
39.228 - inflateBack() returns.
39.229 -
39.230 - in() and out() are called with a descriptor parameter provided in the
39.231 - inflateBack() call. This parameter can be a structure that provides the
39.232 - information required to do the read or write, as well as accumulated
39.233 - information on the input and output such as totals and check values.
39.234 -
39.235 - in() should return zero on failure. out() should return non-zero on
39.236 - failure. If either in() or out() fails, than inflateBack() returns a
39.237 - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
39.238 - was in() or out() that caused in the error. Otherwise, inflateBack()
39.239 - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
39.240 - error, or Z_MEM_ERROR if it could not allocate memory for the state.
39.241 - inflateBack() can also return Z_STREAM_ERROR if the input parameters
39.242 - are not correct, i.e. strm is Z_NULL or the state was not initialized.
39.243 - */
39.244 -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
39.245 -z_streamp strm;
39.246 -in_func in;
39.247 -void FAR *in_desc;
39.248 -out_func out;
39.249 -void FAR *out_desc;
39.250 -{
39.251 - struct inflate_state FAR *state;
39.252 - unsigned char FAR *next; /* next input */
39.253 - unsigned char FAR *put; /* next output */
39.254 - unsigned have, left; /* available input and output */
39.255 - unsigned long hold; /* bit buffer */
39.256 - unsigned bits; /* bits in bit buffer */
39.257 - unsigned copy; /* number of stored or match bytes to copy */
39.258 - unsigned char FAR *from; /* where to copy match bytes from */
39.259 - code this; /* current decoding table entry */
39.260 - code last; /* parent table entry */
39.261 - unsigned len; /* length to copy for repeats, bits to drop */
39.262 - int ret; /* return code */
39.263 - static const unsigned short order[19] = /* permutation of code lengths */
39.264 - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
39.265 -
39.266 - /* Check that the strm exists and that the state was initialized */
39.267 - if (strm == Z_NULL || strm->state == Z_NULL)
39.268 - return Z_STREAM_ERROR;
39.269 - state = (struct inflate_state FAR *)strm->state;
39.270 -
39.271 - /* Reset the state */
39.272 - strm->msg = Z_NULL;
39.273 - state->mode = TYPE;
39.274 - state->last = 0;
39.275 - state->whave = 0;
39.276 - next = strm->next_in;
39.277 - have = next != Z_NULL ? strm->avail_in : 0;
39.278 - hold = 0;
39.279 - bits = 0;
39.280 - put = state->window;
39.281 - left = state->wsize;
39.282 -
39.283 - /* Inflate until end of block marked as last */
39.284 - for (;;)
39.285 - switch (state->mode) {
39.286 - case TYPE:
39.287 - /* determine and dispatch block type */
39.288 - if (state->last) {
39.289 - BYTEBITS();
39.290 - state->mode = DONE;
39.291 - break;
39.292 - }
39.293 - NEEDBITS(3);
39.294 - state->last = BITS(1);
39.295 - DROPBITS(1);
39.296 - switch (BITS(2)) {
39.297 - case 0: /* stored block */
39.298 - Tracev((stderr, "inflate: stored block%s\n",
39.299 - state->last ? " (last)" : ""));
39.300 - state->mode = STORED;
39.301 - break;
39.302 - case 1: /* fixed block */
39.303 - fixedtables(state);
39.304 - Tracev((stderr, "inflate: fixed codes block%s\n",
39.305 - state->last ? " (last)" : ""));
39.306 - state->mode = LEN; /* decode codes */
39.307 - break;
39.308 - case 2: /* dynamic block */
39.309 - Tracev((stderr, "inflate: dynamic codes block%s\n",
39.310 - state->last ? " (last)" : ""));
39.311 - state->mode = TABLE;
39.312 - break;
39.313 - case 3:
39.314 - strm->msg = (char *)"invalid block type";
39.315 - state->mode = BAD;
39.316 - }
39.317 - DROPBITS(2);
39.318 - break;
39.319 -
39.320 - case STORED:
39.321 - /* get and verify stored block length */
39.322 - BYTEBITS(); /* go to byte boundary */
39.323 - NEEDBITS(32);
39.324 - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
39.325 - strm->msg = (char *)"invalid stored block lengths";
39.326 - state->mode = BAD;
39.327 - break;
39.328 - }
39.329 - state->length = (unsigned)hold & 0xffff;
39.330 - Tracev((stderr, "inflate: stored length %u\n",
39.331 - state->length));
39.332 - INITBITS();
39.333 -
39.334 - /* copy stored block from input to output */
39.335 - while (state->length != 0) {
39.336 - copy = state->length;
39.337 - PULL();
39.338 - ROOM();
39.339 - if (copy > have) copy = have;
39.340 - if (copy > left) copy = left;
39.341 - zmemcpy(put, next, copy);
39.342 - have -= copy;
39.343 - next += copy;
39.344 - left -= copy;
39.345 - put += copy;
39.346 - state->length -= copy;
39.347 - }
39.348 - Tracev((stderr, "inflate: stored end\n"));
39.349 - state->mode = TYPE;
39.350 - break;
39.351 -
39.352 - case TABLE:
39.353 - /* get dynamic table entries descriptor */
39.354 - NEEDBITS(14);
39.355 - state->nlen = BITS(5) + 257;
39.356 - DROPBITS(5);
39.357 - state->ndist = BITS(5) + 1;
39.358 - DROPBITS(5);
39.359 - state->ncode = BITS(4) + 4;
39.360 - DROPBITS(4);
39.361 -#ifndef PKZIP_BUG_WORKAROUND
39.362 - if (state->nlen > 286 || state->ndist > 30) {
39.363 - strm->msg = (char *)"too many length or distance symbols";
39.364 - state->mode = BAD;
39.365 - break;
39.366 - }
39.367 -#endif
39.368 - Tracev((stderr, "inflate: table sizes ok\n"));
39.369 -
39.370 - /* get code length code lengths (not a typo) */
39.371 - state->have = 0;
39.372 - while (state->have < state->ncode) {
39.373 - NEEDBITS(3);
39.374 - state->lens[order[state->have++]] = (unsigned short)BITS(3);
39.375 - DROPBITS(3);
39.376 - }
39.377 - while (state->have < 19)
39.378 - state->lens[order[state->have++]] = 0;
39.379 - state->next = state->codes;
39.380 - state->lencode = (code const FAR *)(state->next);
39.381 - state->lenbits = 7;
39.382 - ret = inflate_table(CODES, state->lens, 19, &(state->next),
39.383 - &(state->lenbits), state->work);
39.384 - if (ret) {
39.385 - strm->msg = (char *)"invalid code lengths set";
39.386 - state->mode = BAD;
39.387 - break;
39.388 - }
39.389 - Tracev((stderr, "inflate: code lengths ok\n"));
39.390 -
39.391 - /* get length and distance code code lengths */
39.392 - state->have = 0;
39.393 - while (state->have < state->nlen + state->ndist) {
39.394 - for (;;) {
39.395 - this = state->lencode[BITS(state->lenbits)];
39.396 - if ((unsigned)(this.bits) <= bits) break;
39.397 - PULLBYTE();
39.398 - }
39.399 - if (this.val < 16) {
39.400 - NEEDBITS(this.bits);
39.401 - DROPBITS(this.bits);
39.402 - state->lens[state->have++] = this.val;
39.403 - }
39.404 - else {
39.405 - if (this.val == 16) {
39.406 - NEEDBITS(this.bits + 2);
39.407 - DROPBITS(this.bits);
39.408 - if (state->have == 0) {
39.409 - strm->msg = (char *)"invalid bit length repeat";
39.410 - state->mode = BAD;
39.411 - break;
39.412 - }
39.413 - len = (unsigned)(state->lens[state->have - 1]);
39.414 - copy = 3 + BITS(2);
39.415 - DROPBITS(2);
39.416 - }
39.417 - else if (this.val == 17) {
39.418 - NEEDBITS(this.bits + 3);
39.419 - DROPBITS(this.bits);
39.420 - len = 0;
39.421 - copy = 3 + BITS(3);
39.422 - DROPBITS(3);
39.423 - }
39.424 - else {
39.425 - NEEDBITS(this.bits + 7);
39.426 - DROPBITS(this.bits);
39.427 - len = 0;
39.428 - copy = 11 + BITS(7);
39.429 - DROPBITS(7);
39.430 - }
39.431 - if (state->have + copy > state->nlen + state->ndist) {
39.432 - strm->msg = (char *)"invalid bit length repeat";
39.433 - state->mode = BAD;
39.434 - break;
39.435 - }
39.436 - while (copy--)
39.437 - state->lens[state->have++] = (unsigned short)len;
39.438 - }
39.439 - }
39.440 -
39.441 - /* handle error breaks in while */
39.442 - if (state->mode == BAD) break;
39.443 -
39.444 - /* build code tables */
39.445 - state->next = state->codes;
39.446 - state->lencode = (code const FAR *)(state->next);
39.447 - state->lenbits = 9;
39.448 - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
39.449 - &(state->lenbits), state->work);
39.450 - if (ret) {
39.451 - strm->msg = (char *)"invalid literal/lengths set";
39.452 - state->mode = BAD;
39.453 - break;
39.454 - }
39.455 - state->distcode = (code const FAR *)(state->next);
39.456 - state->distbits = 6;
39.457 - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
39.458 - &(state->next), &(state->distbits), state->work);
39.459 - if (ret) {
39.460 - strm->msg = (char *)"invalid distances set";
39.461 - state->mode = BAD;
39.462 - break;
39.463 - }
39.464 - Tracev((stderr, "inflate: codes ok\n"));
39.465 - state->mode = LEN;
39.466 -
39.467 - case LEN:
39.468 - /* use inflate_fast() if we have enough input and output */
39.469 - if (have >= 6 && left >= 258) {
39.470 - RESTORE();
39.471 - if (state->whave < state->wsize)
39.472 - state->whave = state->wsize - left;
39.473 - inflate_fast(strm, state->wsize);
39.474 - LOAD();
39.475 - break;
39.476 - }
39.477 -
39.478 - /* get a literal, length, or end-of-block code */
39.479 - for (;;) {
39.480 - this = state->lencode[BITS(state->lenbits)];
39.481 - if ((unsigned)(this.bits) <= bits) break;
39.482 - PULLBYTE();
39.483 - }
39.484 - if (this.op && (this.op & 0xf0) == 0) {
39.485 - last = this;
39.486 - for (;;) {
39.487 - this = state->lencode[last.val +
39.488 - (BITS(last.bits + last.op) >> last.bits)];
39.489 - if ((unsigned)(last.bits + this.bits) <= bits) break;
39.490 - PULLBYTE();
39.491 - }
39.492 - DROPBITS(last.bits);
39.493 - }
39.494 - DROPBITS(this.bits);
39.495 - state->length = (unsigned)this.val;
39.496 -
39.497 - /* process literal */
39.498 - if (this.op == 0) {
39.499 - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
39.500 - "inflate: literal '%c'\n" :
39.501 - "inflate: literal 0x%02x\n", this.val));
39.502 - ROOM();
39.503 - *put++ = (unsigned char)(state->length);
39.504 - left--;
39.505 - state->mode = LEN;
39.506 - break;
39.507 - }
39.508 -
39.509 - /* process end of block */
39.510 - if (this.op & 32) {
39.511 - Tracevv((stderr, "inflate: end of block\n"));
39.512 - state->mode = TYPE;
39.513 - break;
39.514 - }
39.515 -
39.516 - /* invalid code */
39.517 - if (this.op & 64) {
39.518 - strm->msg = (char *)"invalid literal/length code";
39.519 - state->mode = BAD;
39.520 - break;
39.521 - }
39.522 -
39.523 - /* length code -- get extra bits, if any */
39.524 - state->extra = (unsigned)(this.op) & 15;
39.525 - if (state->extra != 0) {
39.526 - NEEDBITS(state->extra);
39.527 - state->length += BITS(state->extra);
39.528 - DROPBITS(state->extra);
39.529 - }
39.530 - Tracevv((stderr, "inflate: length %u\n", state->length));
39.531 -
39.532 - /* get distance code */
39.533 - for (;;) {
39.534 - this = state->distcode[BITS(state->distbits)];
39.535 - if ((unsigned)(this.bits) <= bits) break;
39.536 - PULLBYTE();
39.537 - }
39.538 - if ((this.op & 0xf0) == 0) {
39.539 - last = this;
39.540 - for (;;) {
39.541 - this = state->distcode[last.val +
39.542 - (BITS(last.bits + last.op) >> last.bits)];
39.543 - if ((unsigned)(last.bits + this.bits) <= bits) break;
39.544 - PULLBYTE();
39.545 - }
39.546 - DROPBITS(last.bits);
39.547 - }
39.548 - DROPBITS(this.bits);
39.549 - if (this.op & 64) {
39.550 - strm->msg = (char *)"invalid distance code";
39.551 - state->mode = BAD;
39.552 - break;
39.553 - }
39.554 - state->offset = (unsigned)this.val;
39.555 -
39.556 - /* get distance extra bits, if any */
39.557 - state->extra = (unsigned)(this.op) & 15;
39.558 - if (state->extra != 0) {
39.559 - NEEDBITS(state->extra);
39.560 - state->offset += BITS(state->extra);
39.561 - DROPBITS(state->extra);
39.562 - }
39.563 - if (state->offset > state->wsize - (state->whave < state->wsize ?
39.564 - left : 0)) {
39.565 - strm->msg = (char *)"invalid distance too far back";
39.566 - state->mode = BAD;
39.567 - break;
39.568 - }
39.569 - Tracevv((stderr, "inflate: distance %u\n", state->offset));
39.570 -
39.571 - /* copy match from window to output */
39.572 - do {
39.573 - ROOM();
39.574 - copy = state->wsize - state->offset;
39.575 - if (copy < left) {
39.576 - from = put + copy;
39.577 - copy = left - copy;
39.578 - }
39.579 - else {
39.580 - from = put - state->offset;
39.581 - copy = left;
39.582 - }
39.583 - if (copy > state->length) copy = state->length;
39.584 - state->length -= copy;
39.585 - left -= copy;
39.586 - do {
39.587 - *put++ = *from++;
39.588 - } while (--copy);
39.589 - } while (state->length != 0);
39.590 - break;
39.591 -
39.592 - case DONE:
39.593 - /* inflate stream terminated properly -- write leftover output */
39.594 - ret = Z_STREAM_END;
39.595 - if (left < state->wsize) {
39.596 - if (out(out_desc, state->window, state->wsize - left))
39.597 - ret = Z_BUF_ERROR;
39.598 - }
39.599 - goto inf_leave;
39.600 -
39.601 - case BAD:
39.602 - ret = Z_DATA_ERROR;
39.603 - goto inf_leave;
39.604 -
39.605 - default: /* can't happen, but makes compilers happy */
39.606 - ret = Z_STREAM_ERROR;
39.607 - goto inf_leave;
39.608 - }
39.609 -
39.610 - /* Return unused input */
39.611 - inf_leave:
39.612 - strm->next_in = next;
39.613 - strm->avail_in = have;
39.614 - return ret;
39.615 -}
39.616 -
39.617 -int ZEXPORT inflateBackEnd(strm)
39.618 -z_streamp strm;
39.619 -{
39.620 - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
39.621 - return Z_STREAM_ERROR;
39.622 - ZFREE(strm, strm->state);
39.623 - strm->state = Z_NULL;
39.624 - Tracev((stderr, "inflate: end\n"));
39.625 - return Z_OK;
39.626 -}
40.1 --- a/compiler-init/zlib/inffast.c Sat Jul 15 05:02:38 2006 +0000
40.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
40.3 @@ -1,318 +0,0 @@
40.4 -/* inffast.c -- fast decoding
40.5 - * Copyright (C) 1995-2004 Mark Adler
40.6 - * For conditions of distribution and use, see copyright notice in zlib.h
40.7 - */
40.8 -
40.9 -#include "zutil.h"
40.10 -#include "inftrees.h"
40.11 -#include "inflate.h"
40.12 -#include "inffast.h"
40.13 -
40.14 -#ifndef ASMINF
40.15 -
40.16 -/* Allow machine dependent optimization for post-increment or pre-increment.
40.17 - Based on testing to date,
40.18 - Pre-increment preferred for:
40.19 - - PowerPC G3 (Adler)
40.20 - - MIPS R5000 (Randers-Pehrson)
40.21 - Post-increment preferred for:
40.22 - - none
40.23 - No measurable difference:
40.24 - - Pentium III (Anderson)
40.25 - - M68060 (Nikl)
40.26 - */
40.27 -#ifdef POSTINC
40.28 -# define OFF 0
40.29 -# define PUP(a) *(a)++
40.30 -#else
40.31 -# define OFF 1
40.32 -# define PUP(a) *++(a)
40.33 -#endif
40.34 -
40.35 -/*
40.36 - Decode literal, length, and distance codes and write out the resulting
40.37 - literal and match bytes until either not enough input or output is
40.38 - available, an end-of-block is encountered, or a data error is encountered.
40.39 - When large enough input and output buffers are supplied to inflate(), for
40.40 - example, a 16K input buffer and a 64K output buffer, more than 95% of the
40.41 - inflate execution time is spent in this routine.
40.42 -
40.43 - Entry assumptions:
40.44 -
40.45 - state->mode == LEN
40.46 - strm->avail_in >= 6
40.47 - strm->avail_out >= 258
40.48 - start >= strm->avail_out
40.49 - state->bits < 8
40.50 -
40.51 - On return, state->mode is one of:
40.52 -
40.53 - LEN -- ran out of enough output space or enough available input
40.54 - TYPE -- reached end of block code, inflate() to interpret next block
40.55 - BAD -- error in block data
40.56 -
40.57 - Notes:
40.58 -
40.59 - - The maximum input bits used by a length/distance pair is 15 bits for the
40.60 - length code, 5 bits for the length extra, 15 bits for the distance code,
40.61 - and 13 bits for the distance extra. This totals 48 bits, or six bytes.
40.62 - Therefore if strm->avail_in >= 6, then there is enough input to avoid
40.63 - checking for available input while decoding.
40.64 -
40.65 - - The maximum bytes that a single length/distance pair can output is 258
40.66 - bytes, which is the maximum length that can be coded. inflate_fast()
40.67 - requires strm->avail_out >= 258 for each loop to avoid checking for
40.68 - output space.
40.69 - */
40.70 -void inflate_fast(strm, start)
40.71 -z_streamp strm;
40.72 -unsigned start; /* inflate()'s starting value for strm->avail_out */
40.73 -{
40.74 - struct inflate_state FAR *state;
40.75 - unsigned char FAR *in; /* local strm->next_in */
40.76 - unsigned char FAR *last; /* while in < last, enough input available */
40.77 - unsigned char FAR *out; /* local strm->next_out */
40.78 - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
40.79 - unsigned char FAR *end; /* while out < end, enough space available */
40.80 -#ifdef INFLATE_STRICT
40.81 - unsigned dmax; /* maximum distance from zlib header */
40.82 -#endif
40.83 - unsigned wsize; /* window size or zero if not using window */
40.84 - unsigned whave; /* valid bytes in the window */
40.85 - unsigned write; /* window write index */
40.86 - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
40.87 - unsigned long hold; /* local strm->hold */
40.88 - unsigned bits; /* local strm->bits */
40.89 - code const FAR *lcode; /* local strm->lencode */
40.90 - code const FAR *dcode; /* local strm->distcode */
40.91 - unsigned lmask; /* mask for first level of length codes */
40.92 - unsigned dmask; /* mask for first level of distance codes */
40.93 - code this; /* retrieved table entry */
40.94 - unsigned op; /* code bits, operation, extra bits, or */
40.95 - /* window position, window bytes to copy */
40.96 - unsigned len; /* match length, unused bytes */
40.97 - unsigned dist; /* match distance */
40.98 - unsigned char FAR *from; /* where to copy match from */
40.99 -
40.100 - /* copy state to local variables */
40.101 - state = (struct inflate_state FAR *)strm->state;
40.102 - in = strm->next_in - OFF;
40.103 - last = in + (strm->avail_in - 5);
40.104 - out = strm->next_out - OFF;
40.105 - beg = out - (start - strm->avail_out);
40.106 - end = out + (strm->avail_out - 257);
40.107 -#ifdef INFLATE_STRICT
40.108 - dmax = state->dmax;
40.109 -#endif
40.110 - wsize = state->wsize;
40.111 - whave = state->whave;
40.112 - write = state->write;
40.113 - window = state->window;
40.114 - hold = state->hold;
40.115 - bits = state->bits;
40.116 - lcode = state->lencode;
40.117 - dcode = state->distcode;
40.118 - lmask = (1U << state->lenbits) - 1;
40.119 - dmask = (1U << state->distbits) - 1;
40.120 -
40.121 - /* decode literals and length/distances until end-of-block or not enough
40.122 - input data or output space */
40.123 - do {
40.124 - if (bits < 15) {
40.125 - hold += (unsigned long)(PUP(in)) << bits;
40.126 - bits += 8;
40.127 - hold += (unsigned long)(PUP(in)) << bits;
40.128 - bits += 8;
40.129 - }
40.130 - this = lcode[hold & lmask];
40.131 - dolen:
40.132 - op = (unsigned)(this.bits);
40.133 - hold >>= op;
40.134 - bits -= op;
40.135 - op = (unsigned)(this.op);
40.136 - if (op == 0) { /* literal */
40.137 - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
40.138 - "inflate: literal '%c'\n" :
40.139 - "inflate: literal 0x%02x\n", this.val));
40.140 - PUP(out) = (unsigned char)(this.val);
40.141 - }
40.142 - else if (op & 16) { /* length base */
40.143 - len = (unsigned)(this.val);
40.144 - op &= 15; /* number of extra bits */
40.145 - if (op) {
40.146 - if (bits < op) {
40.147 - hold += (unsigned long)(PUP(in)) << bits;
40.148 - bits += 8;
40.149 - }
40.150 - len += (unsigned)hold & ((1U << op) - 1);
40.151 - hold >>= op;
40.152 - bits -= op;
40.153 - }
40.154 - Tracevv((stderr, "inflate: length %u\n", len));
40.155 - if (bits < 15) {
40.156 - hold += (unsigned long)(PUP(in)) << bits;
40.157 - bits += 8;
40.158 - hold += (unsigned long)(PUP(in)) << bits;
40.159 - bits += 8;
40.160 - }
40.161 - this = dcode[hold & dmask];
40.162 - dodist:
40.163 - op = (unsigned)(this.bits);
40.164 - hold >>= op;
40.165 - bits -= op;
40.166 - op = (unsigned)(this.op);
40.167 - if (op & 16) { /* distance base */
40.168 - dist = (unsigned)(this.val);
40.169 - op &= 15; /* number of extra bits */
40.170 - if (bits < op) {
40.171 - hold += (unsigned long)(PUP(in)) << bits;
40.172 - bits += 8;
40.173 - if (bits < op) {
40.174 - hold += (unsigned long)(PUP(in)) << bits;
40.175 - bits += 8;
40.176 - }
40.177 - }
40.178 - dist += (unsigned)hold & ((1U << op) - 1);
40.179 -#ifdef INFLATE_STRICT
40.180 - if (dist > dmax) {
40.181 - strm->msg = (char *)"invalid distance too far back";
40.182 - state->mode = BAD;
40.183 - break;
40.184 - }
40.185 -#endif
40.186 - hold >>= op;
40.187 - bits -= op;
40.188 - Tracevv((stderr, "inflate: distance %u\n", dist));
40.189 - op = (unsigned)(out - beg); /* max distance in output */
40.190 - if (dist > op) { /* see if copy from window */
40.191 - op = dist - op; /* distance back in window */
40.192 - if (op > whave) {
40.193 - strm->msg = (char *)"invalid distance too far back";
40.194 - state->mode = BAD;
40.195 - break;
40.196 - }
40.197 - from = window - OFF;
40.198 - if (write == 0) { /* very common case */
40.199 - from += wsize - op;
40.200 - if (op < len) { /* some from window */
40.201 - len -= op;
40.202 - do {
40.203 - PUP(out) = PUP(from);
40.204 - } while (--op);
40.205 - from = out - dist; /* rest from output */
40.206 - }
40.207 - }
40.208 - else if (write < op) { /* wrap around window */
40.209 - from += wsize + write - op;
40.210 - op -= write;
40.211 - if (op < len) { /* some from end of window */
40.212 - len -= op;
40.213 - do {
40.214 - PUP(out) = PUP(from);
40.215 - } while (--op);
40.216 - from = window - OFF;
40.217 - if (write < len) { /* some from start of window */
40.218 - op = write;
40.219 - len -= op;
40.220 - do {
40.221 - PUP(out) = PUP(from);
40.222 - } while (--op);
40.223 - from = out - dist; /* rest from output */
40.224 - }
40.225 - }
40.226 - }
40.227 - else { /* contiguous in window */
40.228 - from += write - op;
40.229 - if (op < len) { /* some from window */
40.230 - len -= op;
40.231 - do {
40.232 - PUP(out) = PUP(from);
40.233 - } while (--op);
40.234 - from = out - dist; /* rest from output */
40.235 - }
40.236 - }
40.237 - while (len > 2) {
40.238 - PUP(out) = PUP(from);
40.239 - PUP(out) = PUP(from);
40.240 - PUP(out) = PUP(from);
40.241 - len -= 3;
40.242 - }
40.243 - if (len) {
40.244 - PUP(out) = PUP(from);
40.245 - if (len > 1)
40.246 - PUP(out) = PUP(from);
40.247 - }
40.248 - }
40.249 - else {
40.250 - from = out - dist; /* copy direct from output */
40.251 - do { /* minimum length is three */
40.252 - PUP(out) = PUP(from);
40.253 - PUP(out) = PUP(from);
40.254 - PUP(out) = PUP(from);
40.255 - len -= 3;
40.256 - } while (len > 2);
40.257 - if (len) {
40.258 - PUP(out) = PUP(from);
40.259 - if (len > 1)
40.260 - PUP(out) = PUP(from);
40.261 - }
40.262 - }
40.263 - }
40.264 - else if ((op & 64) == 0) { /* 2nd level distance code */
40.265 - this = dcode[this.val + (hold & ((1U << op) - 1))];
40.266 - goto dodist;
40.267 - }
40.268 - else {
40.269 - strm->msg = (char *)"invalid distance code";
40.270 - state->mode = BAD;
40.271 - break;
40.272 - }
40.273 - }
40.274 - else if ((op & 64) == 0) { /* 2nd level length code */
40.275 - this = lcode[this.val + (hold & ((1U << op) - 1))];
40.276 - goto dolen;
40.277 - }
40.278 - else if (op & 32) { /* end-of-block */
40.279 - Tracevv((stderr, "inflate: end of block\n"));
40.280 - state->mode = TYPE;
40.281 - break;
40.282 - }
40.283 - else {
40.284 - strm->msg = (char *)"invalid literal/length code";
40.285 - state->mode = BAD;
40.286 - break;
40.287 - }
40.288 - } while (in < last && out < end);
40.289 -
40.290 - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
40.291 - len = bits >> 3;
40.292 - in -= len;
40.293 - bits -= len << 3;
40.294 - hold &= (1U << bits) - 1;
40.295 -
40.296 - /* update state and return */
40.297 - strm->next_in = in + OFF;
40.298 - strm->next_out = out + OFF;
40.299 - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
40.300 - strm->avail_out = (unsigned)(out < end ?
40.301 - 257 + (end - out) : 257 - (out - end));
40.302 - state->hold = hold;
40.303 - state->bits = bits;
40.304 - return;
40.305 -}
40.306 -
40.307 -/*
40.308 - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
40.309 - - Using bit fields for code structure
40.310 - - Different op definition to avoid & for extra bits (do & for table bits)
40.311 - - Three separate decoding do-loops for direct, window, and write == 0
40.312 - - Special case for distance > 1 copies to do overlapped load and store copy
40.313 - - Explicit branch predictions (based on measured branch probabilities)
40.314 - - Deferring match copy and interspersed it with decoding subsequent codes
40.315 - - Swapping literal/length else
40.316 - - Swapping window/direct else
40.317 - - Larger unrolled copy loops (three is about right)
40.318 - - Moving len -= 3 statement into middle of loop
40.319 - */
40.320 -
40.321 -#endif /* !ASMINF */
41.1 --- a/compiler-init/zlib/inffast.h Sat Jul 15 05:02:38 2006 +0000
41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
41.3 @@ -1,11 +0,0 @@
41.4 -/* inffast.h -- header to use inffast.c
41.5 - * Copyright (C) 1995-2003 Mark Adler
41.6 - * For conditions of distribution and use, see copyright notice in zlib.h
41.7 - */
41.8 -
41.9 -/* WARNING: this file should *not* be used by applications. It is
41.10 - part of the implementation of the compression library and is
41.11 - subject to change. Applications should only use zlib.h.
41.12 - */
41.13 -
41.14 -void inflate_fast OF((z_streamp strm, unsigned start));
42.1 --- a/compiler-init/zlib/inffixed.h Sat Jul 15 05:02:38 2006 +0000
42.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
42.3 @@ -1,94 +0,0 @@
42.4 - /* inffixed.h -- table for decoding fixed codes
42.5 - * Generated automatically by makefixed().
42.6 - */
42.7 -
42.8 - /* WARNING: this file should *not* be used by applications. It
42.9 - is part of the implementation of the compression library and
42.10 - is subject to change. Applications should only use zlib.h.
42.11 - */
42.12 -
42.13 - static const code lenfix[512] = {
42.14 - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
42.15 - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
42.16 - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
42.17 - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
42.18 - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
42.19 - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
42.20 - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
42.21 - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
42.22 - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
42.23 - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
42.24 - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
42.25 - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
42.26 - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
42.27 - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
42.28 - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
42.29 - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
42.30 - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
42.31 - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
42.32 - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
42.33 - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
42.34 - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
42.35 - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
42.36 - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
42.37 - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
42.38 - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
42.39 - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
42.40 - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
42.41 - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
42.42 - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
42.43 - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
42.44 - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
42.45 - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
42.46 - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
42.47 - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
42.48 - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
42.49 - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
42.50 - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
42.51 - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
42.52 - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
42.53 - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
42.54 - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
42.55 - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
42.56 - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
42.57 - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
42.58 - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
42.59 - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
42.60 - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
42.61 - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
42.62 - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
42.63 - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
42.64 - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
42.65 - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
42.66 - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
42.67 - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
42.68 - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
42.69 - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
42.70 - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
42.71 - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
42.72 - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
42.73 - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
42.74 - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
42.75 - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
42.76 - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
42.77 - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
42.78 - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
42.79 - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
42.80 - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
42.81 - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
42.82 - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
42.83 - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
42.84 - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
42.85 - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
42.86 - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
42.87 - {0,9,255}
42.88 - };
42.89 -
42.90 - static const code distfix[32] = {
42.91 - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
42.92 - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
42.93 - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
42.94 - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
42.95 - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
42.96 - {22,5,193},{64,5,0}
42.97 - };
43.1 --- a/compiler-init/zlib/inflate.c Sat Jul 15 05:02:38 2006 +0000
43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
43.3 @@ -1,1368 +0,0 @@
43.4 -/* inflate.c -- zlib decompression
43.5 - * Copyright (C) 1995-2005 Mark Adler
43.6 - * For conditions of distribution and use, see copyright notice in zlib.h
43.7 - */
43.8 -
43.9 -/*
43.10 - * Change history:
43.11 - *
43.12 - * 1.2.beta0 24 Nov 2002
43.13 - * - First version -- complete rewrite of inflate to simplify code, avoid
43.14 - * creation of window when not needed, minimize use of window when it is
43.15 - * needed, make inffast.c even faster, implement gzip decoding, and to
43.16 - * improve code readability and style over the previous zlib inflate code
43.17 - *
43.18 - * 1.2.beta1 25 Nov 2002
43.19 - * - Use pointers for available input and output checking in inffast.c
43.20 - * - Remove input and output counters in inffast.c
43.21 - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
43.22 - * - Remove unnecessary second byte pull from length extra in inffast.c
43.23 - * - Unroll direct copy to three copies per loop in inffast.c
43.24 - *
43.25 - * 1.2.beta2 4 Dec 2002
43.26 - * - Change external routine names to reduce potential conflicts
43.27 - * - Correct filename to inffixed.h for fixed tables in inflate.c
43.28 - * - Make hbuf[] unsigned char to match parameter type in inflate.c
43.29 - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
43.30 - * to avoid negation problem on Alphas (64 bit) in inflate.c
43.31 - *
43.32 - * 1.2.beta3 22 Dec 2002
43.33 - * - Add comments on state->bits assertion in inffast.c
43.34 - * - Add comments on op field in inftrees.h
43.35 - * - Fix bug in reuse of allocated window after inflateReset()
43.36 - * - Remove bit fields--back to byte structure for speed
43.37 - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
43.38 - * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
43.39 - * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
43.40 - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
43.41 - * - Use local copies of stream next and avail values, as well as local bit
43.42 - * buffer and bit count in inflate()--for speed when inflate_fast() not used
43.43 - *
43.44 - * 1.2.beta4 1 Jan 2003
43.45 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
43.46 - * - Move a comment on output buffer sizes from inffast.c to inflate.c
43.47 - * - Add comments in inffast.c to introduce the inflate_fast() routine
43.48 - * - Rearrange window copies in inflate_fast() for speed and simplification
43.49 - * - Unroll last copy for window match in inflate_fast()
43.50 - * - Use local copies of window variables in inflate_fast() for speed
43.51 - * - Pull out common write == 0 case for speed in inflate_fast()
43.52 - * - Make op and len in inflate_fast() unsigned for consistency
43.53 - * - Add FAR to lcode and dcode declarations in inflate_fast()
43.54 - * - Simplified bad distance check in inflate_fast()
43.55 - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
43.56 - * source file infback.c to provide a call-back interface to inflate for
43.57 - * programs like gzip and unzip -- uses window as output buffer to avoid
43.58 - * window copying
43.59 - *
43.60 - * 1.2.beta5 1 Jan 2003
43.61 - * - Improved inflateBack() interface to allow the caller to provide initial
43.62 - * input in strm.
43.63 - * - Fixed stored blocks bug in inflateBack()
43.64 - *
43.65 - * 1.2.beta6 4 Jan 2003
43.66 - * - Added comments in inffast.c on effectiveness of POSTINC
43.67 - * - Typecasting all around to reduce compiler warnings
43.68 - * - Changed loops from while (1) or do {} while (1) to for (;;), again to
43.69 - * make compilers happy
43.70 - * - Changed type of window in inflateBackInit() to unsigned char *
43.71 - *
43.72 - * 1.2.beta7 27 Jan 2003
43.73 - * - Changed many types to unsigned or unsigned short to avoid warnings
43.74 - * - Added inflateCopy() function
43.75 - *
43.76 - * 1.2.0 9 Mar 2003
43.77 - * - Changed inflateBack() interface to provide separate opaque descriptors
43.78 - * for the in() and out() functions
43.79 - * - Changed inflateBack() argument and in_func typedef to swap the length
43.80 - * and buffer address return values for the input function
43.81 - * - Check next_in and next_out for Z_NULL on entry to inflate()
43.82 - *
43.83 - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
43.84 - */
43.85 -
43.86 -#include "zutil.h"
43.87 -#include "inftrees.h"
43.88 -#include "inflate.h"
43.89 -#include "inffast.h"
43.90 -
43.91 -#ifdef MAKEFIXED
43.92 -# ifndef BUILDFIXED
43.93 -# define BUILDFIXED
43.94 -# endif
43.95 -#endif
43.96 -
43.97 -/* function prototypes */
43.98 -local void fixedtables OF((struct inflate_state FAR *state));
43.99 -local int updatewindow OF((z_streamp strm, unsigned out));
43.100 -#ifdef BUILDFIXED
43.101 - void makefixed OF((void));
43.102 -#endif
43.103 -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
43.104 - unsigned len));
43.105 -
43.106 -int ZEXPORT inflateReset(strm)
43.107 -z_streamp strm;
43.108 -{
43.109 - struct inflate_state FAR *state;
43.110 -
43.111 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
43.112 - state = (struct inflate_state FAR *)strm->state;
43.113 - strm->total_in = strm->total_out = state->total = 0;
43.114 - strm->msg = Z_NULL;
43.115 - strm->adler = 1; /* to support ill-conceived Java test suite */
43.116 - state->mode = HEAD;
43.117 - state->last = 0;
43.118 - state->havedict = 0;
43.119 - state->dmax = 32768U;
43.120 - state->head = Z_NULL;
43.121 - state->wsize = 0;
43.122 - state->whave = 0;
43.123 - state->write = 0;
43.124 - state->hold = 0;
43.125 - state->bits = 0;
43.126 - state->lencode = state->distcode = state->next = state->codes;
43.127 - Tracev((stderr, "inflate: reset\n"));
43.128 - return Z_OK;
43.129 -}
43.130 -
43.131 -int ZEXPORT inflatePrime(strm, bits, value)
43.132 -z_streamp strm;
43.133 -int bits;
43.134 -int value;
43.135 -{
43.136 - struct inflate_state FAR *state;
43.137 -
43.138 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
43.139 - state = (struct inflate_state FAR *)strm->state;
43.140 - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
43.141 - value &= (1L << bits) - 1;
43.142 - state->hold += value << state->bits;
43.143 - state->bits += bits;
43.144 - return Z_OK;
43.145 -}
43.146 -
43.147 -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
43.148 -z_streamp strm;
43.149 -int windowBits;
43.150 -const char *version;
43.151 -int stream_size;
43.152 -{
43.153 - struct inflate_state FAR *state;
43.154 -
43.155 - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
43.156 - stream_size != (int)(sizeof(z_stream)))
43.157 - return Z_VERSION_ERROR;
43.158 - if (strm == Z_NULL) return Z_STREAM_ERROR;
43.159 - strm->msg = Z_NULL; /* in case we return an error */
43.160 - if (strm->zalloc == (alloc_func)0) {
43.161 - strm->zalloc = zcalloc;
43.162 - strm->opaque = (voidpf)0;
43.163 - }
43.164 - if (strm->zfree == (free_func)0) strm->zfree = zcfree;
43.165 - state = (struct inflate_state FAR *)
43.166 - ZALLOC(strm, 1, sizeof(struct inflate_state));
43.167 - if (state == Z_NULL) return Z_MEM_ERROR;
43.168 - Tracev((stderr, "inflate: allocated\n"));
43.169 - strm->state = (struct internal_state FAR *)state;
43.170 - if (windowBits < 0) {
43.171 - state->wrap = 0;
43.172 - windowBits = -windowBits;
43.173 - }
43.174 - else {
43.175 - state->wrap = (windowBits >> 4) + 1;
43.176 -#ifdef GUNZIP
43.177 - if (windowBits < 48) windowBits &= 15;
43.178 -#endif
43.179 - }
43.180 - if (windowBits < 8 || windowBits > 15) {
43.181 - ZFREE(strm, state);
43.182 - strm->state = Z_NULL;
43.183 - return Z_STREAM_ERROR;
43.184 - }
43.185 - state->wbits = (unsigned)windowBits;
43.186 - state->window = Z_NULL;
43.187 - return inflateReset(strm);
43.188 -}
43.189 -
43.190 -int ZEXPORT inflateInit_(strm, version, stream_size)
43.191 -z_streamp strm;
43.192 -const char *version;
43.193 -int stream_size;
43.194 -{
43.195 - return inflateInit2_(strm, DEF_WBITS, version, stream_size);
43.196 -}
43.197 -
43.198 -/*
43.199 - Return state with length and distance decoding tables and index sizes set to
43.200 - fixed code decoding. Normally this returns fixed tables from inffixed.h.
43.201 - If BUILDFIXED is defined, then instead this routine builds the tables the
43.202 - first time it's called, and returns those tables the first time and
43.203 - thereafter. This reduces the size of the code by about 2K bytes, in
43.204 - exchange for a little execution time. However, BUILDFIXED should not be
43.205 - used for threaded applications, since the rewriting of the tables and virgin
43.206 - may not be thread-safe.
43.207 - */
43.208 -local void fixedtables(state)
43.209 -struct inflate_state FAR *state;
43.210 -{
43.211 -#ifdef BUILDFIXED
43.212 - static int virgin = 1;
43.213 - static code *lenfix, *distfix;
43.214 - static code fixed[544];
43.215 -
43.216 - /* build fixed huffman tables if first call (may not be thread safe) */
43.217 - if (virgin) {
43.218 - unsigned sym, bits;
43.219 - static code *next;
43.220 -
43.221 - /* literal/length table */
43.222 - sym = 0;
43.223 - while (sym < 144) state->lens[sym++] = 8;
43.224 - while (sym < 256) state->lens[sym++] = 9;
43.225 - while (sym < 280) state->lens[sym++] = 7;
43.226 - while (sym < 288) state->lens[sym++] = 8;
43.227 - next = fixed;
43.228 - lenfix = next;
43.229 - bits = 9;
43.230 - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
43.231 -
43.232 - /* distance table */
43.233 - sym = 0;
43.234 - while (sym < 32) state->lens[sym++] = 5;
43.235 - distfix = next;
43.236 - bits = 5;
43.237 - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
43.238 -
43.239 - /* do this just once */
43.240 - virgin = 0;
43.241 - }
43.242 -#else /* !BUILDFIXED */
43.243 -# include "inffixed.h"
43.244 -#endif /* BUILDFIXED */
43.245 - state->lencode = lenfix;
43.246 - state->lenbits = 9;
43.247 - state->distcode = distfix;
43.248 - state->distbits = 5;
43.249 -}
43.250 -
43.251 -#ifdef MAKEFIXED
43.252 -#include <stdio.h>
43.253 -
43.254 -/*
43.255 - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
43.256 - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
43.257 - those tables to stdout, which would be piped to inffixed.h. A small program
43.258 - can simply call makefixed to do this:
43.259 -
43.260 - void makefixed(void);
43.261 -
43.262 - int main(void)
43.263 - {
43.264 - makefixed();
43.265 - return 0;
43.266 - }
43.267 -
43.268 - Then that can be linked with zlib built with MAKEFIXED defined and run:
43.269 -
43.270 - a.out > inffixed.h
43.271 - */
43.272 -void makefixed()
43.273 -{
43.274 - unsigned low, size;
43.275 - struct inflate_state state;
43.276 -
43.277 - fixedtables(&state);
43.278 - puts(" /* inffixed.h -- table for decoding fixed codes");
43.279 - puts(" * Generated automatically by makefixed().");
43.280 - puts(" */");
43.281 - puts("");
43.282 - puts(" /* WARNING: this file should *not* be used by applications.");
43.283 - puts(" It is part of the implementation of this library and is");
43.284 - puts(" subject to change. Applications should only use zlib.h.");
43.285 - puts(" */");
43.286 - puts("");
43.287 - size = 1U << 9;
43.288 - printf(" static const code lenfix[%u] = {", size);
43.289 - low = 0;
43.290 - for (;;) {
43.291 - if ((low % 7) == 0) printf("\n ");
43.292 - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
43.293 - state.lencode[low].val);
43.294 - if (++low == size) break;
43.295 - putchar(',');
43.296 - }
43.297 - puts("\n };");
43.298 - size = 1U << 5;
43.299 - printf("\n static const code distfix[%u] = {", size);
43.300 - low = 0;
43.301 - for (;;) {
43.302 - if ((low % 6) == 0) printf("\n ");
43.303 - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
43.304 - state.distcode[low].val);
43.305 - if (++low == size) break;
43.306 - putchar(',');
43.307 - }
43.308 - puts("\n };");
43.309 -}
43.310 -#endif /* MAKEFIXED */
43.311 -
43.312 -/*
43.313 - Update the window with the last wsize (normally 32K) bytes written before
43.314 - returning. If window does not exist yet, create it. This is only called
43.315 - when a window is already in use, or when output has been written during this
43.316 - inflate call, but the end of the deflate stream has not been reached yet.
43.317 - It is also called to create a window for dictionary data when a dictionary
43.318 - is loaded.
43.319 -
43.320 - Providing output buffers larger than 32K to inflate() should provide a speed
43.321 - advantage, since only the last 32K of output is copied to the sliding window
43.322 - upon return from inflate(), and since all distances after the first 32K of
43.323 - output will fall in the output data, making match copies simpler and faster.
43.324 - The advantage may be dependent on the size of the processor's data caches.
43.325 - */
43.326 -local int updatewindow(strm, out)
43.327 -z_streamp strm;
43.328 -unsigned out;
43.329 -{
43.330 - struct inflate_state FAR *state;
43.331 - unsigned copy, dist;
43.332 -
43.333 - state = (struct inflate_state FAR *)strm->state;
43.334 -
43.335 - /* if it hasn't been done already, allocate space for the window */
43.336 - if (state->window == Z_NULL) {
43.337 - state->window = (unsigned char FAR *)
43.338 - ZALLOC(strm, 1U << state->wbits,
43.339 - sizeof(unsigned char));
43.340 - if (state->window == Z_NULL) return 1;
43.341 - }
43.342 -
43.343 - /* if window not in use yet, initialize */
43.344 - if (state->wsize == 0) {
43.345 - state->wsize = 1U << state->wbits;
43.346 - state->write = 0;
43.347 - state->whave = 0;
43.348 - }
43.349 -
43.350 - /* copy state->wsize or less output bytes into the circular window */
43.351 - copy = out - strm->avail_out;
43.352 - if (copy >= state->wsize) {
43.353 - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
43.354 - state->write = 0;
43.355 - state->whave = state->wsize;
43.356 - }
43.357 - else {
43.358 - dist = state->wsize - state->write;
43.359 - if (dist > copy) dist = copy;
43.360 - zmemcpy(state->window + state->write, strm->next_out - copy, dist);
43.361 - copy -= dist;
43.362 - if (copy) {
43.363 - zmemcpy(state->window, strm->next_out - copy, copy);
43.364 - state->write = copy;
43.365 - state->whave = state->wsize;
43.366 - }
43.367 - else {
43.368 - state->write += dist;
43.369 - if (state->write == state->wsize) state->write = 0;
43.370 - if (state->whave < state->wsize) state->whave += dist;
43.371 - }
43.372 - }
43.373 - return 0;
43.374 -}
43.375 -
43.376 -/* Macros for inflate(): */
43.377 -
43.378 -/* check function to use adler32() for zlib or crc32() for gzip */
43.379 -#ifdef GUNZIP
43.380 -# define UPDATE(check, buf, len) \
43.381 - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
43.382 -#else
43.383 -# define UPDATE(check, buf, len) adler32(check, buf, len)
43.384 -#endif
43.385 -
43.386 -/* check macros for header crc */
43.387 -#ifdef GUNZIP
43.388 -# define CRC2(check, word) \
43.389 - do { \
43.390 - hbuf[0] = (unsigned char)(word); \
43.391 - hbuf[1] = (unsigned char)((word) >> 8); \
43.392 - check = crc32(check, hbuf, 2); \
43.393 - } while (0)
43.394 -
43.395 -# define CRC4(check, word) \
43.396 - do { \
43.397 - hbuf[0] = (unsigned char)(word); \
43.398 - hbuf[1] = (unsigned char)((word) >> 8); \
43.399 - hbuf[2] = (unsigned char)((word) >> 16); \
43.400 - hbuf[3] = (unsigned char)((word) >> 24); \
43.401 - check = crc32(check, hbuf, 4); \
43.402 - } while (0)
43.403 -#endif
43.404 -
43.405 -/* Load registers with state in inflate() for speed */
43.406 -#define LOAD() \
43.407 - do { \
43.408 - put = strm->next_out; \
43.409 - left = strm->avail_out; \
43.410 - next = strm->next_in; \
43.411 - have = strm->avail_in; \
43.412 - hold = state->hold; \
43.413 - bits = state->bits; \
43.414 - } while (0)
43.415 -
43.416 -/* Restore state from registers in inflate() */
43.417 -#define RESTORE() \
43.418 - do { \
43.419 - strm->next_out = put; \
43.420 - strm->avail_out = left; \
43.421 - strm->next_in = next; \
43.422 - strm->avail_in = have; \
43.423 - state->hold = hold; \
43.424 - state->bits = bits; \
43.425 - } while (0)
43.426 -
43.427 -/* Clear the input bit accumulator */
43.428 -#define INITBITS() \
43.429 - do { \
43.430 - hold = 0; \
43.431 - bits = 0; \
43.432 - } while (0)
43.433 -
43.434 -/* Get a byte of input into the bit accumulator, or return from inflate()
43.435 - if there is no input available. */
43.436 -#define PULLBYTE() \
43.437 - do { \
43.438 - if (have == 0) goto inf_leave; \
43.439 - have--; \
43.440 - hold += (unsigned long)(*next++) << bits; \
43.441 - bits += 8; \
43.442 - } while (0)
43.443 -
43.444 -/* Assure that there are at least n bits in the bit accumulator. If there is
43.445 - not enough available input to do that, then return from inflate(). */
43.446 -#define NEEDBITS(n) \
43.447 - do { \
43.448 - while (bits < (unsigned)(n)) \
43.449 - PULLBYTE(); \
43.450 - } while (0)
43.451 -
43.452 -/* Return the low n bits of the bit accumulator (n < 16) */
43.453 -#define BITS(n) \
43.454 - ((unsigned)hold & ((1U << (n)) - 1))
43.455 -
43.456 -/* Remove n bits from the bit accumulator */
43.457 -#define DROPBITS(n) \
43.458 - do { \
43.459 - hold >>= (n); \
43.460 - bits -= (unsigned)(n); \
43.461 - } while (0)
43.462 -
43.463 -/* Remove zero to seven bits as needed to go to a byte boundary */
43.464 -#define BYTEBITS() \
43.465 - do { \
43.466 - hold >>= bits & 7; \
43.467 - bits -= bits & 7; \
43.468 - } while (0)
43.469 -
43.470 -/* Reverse the bytes in a 32-bit value */
43.471 -#define REVERSE(q) \
43.472 - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
43.473 - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
43.474 -
43.475 -/*
43.476 - inflate() uses a state machine to process as much input data and generate as
43.477 - much output data as possible before returning. The state machine is
43.478 - structured roughly as follows:
43.479 -
43.480 - for (;;) switch (state) {
43.481 - ...
43.482 - case STATEn:
43.483 - if (not enough input data or output space to make progress)
43.484 - return;
43.485 - ... make progress ...
43.486 - state = STATEm;
43.487 - break;
43.488 - ...
43.489 - }
43.490 -
43.491 - so when inflate() is called again, the same case is attempted again, and
43.492 - if the appropriate resources are provided, the machine proceeds to the
43.493 - next state. The NEEDBITS() macro is usually the way the state evaluates
43.494 - whether it can proceed or should return. NEEDBITS() does the return if
43.495 - the requested bits are not available. The typical use of the BITS macros
43.496 - is:
43.497 -
43.498 - NEEDBITS(n);
43.499 - ... do something with BITS(n) ...
43.500 - DROPBITS(n);
43.501 -
43.502 - where NEEDBITS(n) either returns from inflate() if there isn't enough
43.503 - input left to load n bits into the accumulator, or it continues. BITS(n)
43.504 - gives the low n bits in the accumulator. When done, DROPBITS(n) drops
43.505 - the low n bits off the accumulator. INITBITS() clears the accumulator
43.506 - and sets the number of available bits to zero. BYTEBITS() discards just
43.507 - enough bits to put the accumulator on a byte boundary. After BYTEBITS()
43.508 - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
43.509 -
43.510 - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
43.511 - if there is no input available. The decoding of variable length codes uses
43.512 - PULLBYTE() directly in order to pull just enough bytes to decode the next
43.513 - code, and no more.
43.514 -
43.515 - Some states loop until they get enough input, making sure that enough
43.516 - state information is maintained to continue the loop where it left off
43.517 - if NEEDBITS() returns in the loop. For example, want, need, and keep
43.518 - would all have to actually be part of the saved state in case NEEDBITS()
43.519 - returns:
43.520 -
43.521 - case STATEw:
43.522 - while (want < need) {
43.523 - NEEDBITS(n);
43.524 - keep[want++] = BITS(n);
43.525 - DROPBITS(n);
43.526 - }
43.527 - state = STATEx;
43.528 - case STATEx:
43.529 -
43.530 - As shown above, if the next state is also the next case, then the break
43.531 - is omitted.
43.532 -
43.533 - A state may also return if there is not enough output space available to
43.534 - complete that state. Those states are copying stored data, writing a
43.535 - literal byte, and copying a matching string.
43.536 -
43.537 - When returning, a "goto inf_leave" is used to update the total counters,
43.538 - update the check value, and determine whether any progress has been made
43.539 - during that inflate() call in order to return the proper return code.
43.540 - Progress is defined as a change in either strm->avail_in or strm->avail_out.
43.541 - When there is a window, goto inf_leave will update the window with the last
43.542 - output written. If a goto inf_leave occurs in the middle of decompression
43.543 - and there is no window currently, goto inf_leave will create one and copy
43.544 - output to the window for the next call of inflate().
43.545 -
43.546 - In this implementation, the flush parameter of inflate() only affects the
43.547 - return code (per zlib.h). inflate() always writes as much as possible to
43.548 - strm->next_out, given the space available and the provided input--the effect
43.549 - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
43.550 - the allocation of and copying into a sliding window until necessary, which
43.551 - provides the effect documented in zlib.h for Z_FINISH when the entire input
43.552 - stream available. So the only thing the flush parameter actually does is:
43.553 - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
43.554 - will return Z_BUF_ERROR if it has not reached the end of the stream.
43.555 - */
43.556 -
43.557 -int ZEXPORT inflate(strm, flush)
43.558 -z_streamp strm;
43.559 -int flush;
43.560 -{
43.561 - struct inflate_state FAR *state;
43.562 - unsigned char FAR *next; /* next input */
43.563 - unsigned char FAR *put; /* next output */
43.564 - unsigned have, left; /* available input and output */
43.565 - unsigned long hold; /* bit buffer */
43.566 - unsigned bits; /* bits in bit buffer */
43.567 - unsigned in, out; /* save starting available input and output */
43.568 - unsigned copy; /* number of stored or match bytes to copy */
43.569 - unsigned char FAR *from; /* where to copy match bytes from */
43.570 - code this; /* current decoding table entry */
43.571 - code last; /* parent table entry */
43.572 - unsigned len; /* length to copy for repeats, bits to drop */
43.573 - int ret; /* return code */
43.574 -#ifdef GUNZIP
43.575 - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
43.576 -#endif
43.577 - static const unsigned short order[19] = /* permutation of code lengths */
43.578 - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
43.579 -
43.580 - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
43.581 - (strm->next_in == Z_NULL && strm->avail_in != 0))
43.582 - return Z_STREAM_ERROR;
43.583 -
43.584 - state = (struct inflate_state FAR *)strm->state;
43.585 - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
43.586 - LOAD();
43.587 - in = have;
43.588 - out = left;
43.589 - ret = Z_OK;
43.590 - for (;;)
43.591 - switch (state->mode) {
43.592 - case HEAD:
43.593 - if (state->wrap == 0) {
43.594 - state->mode = TYPEDO;
43.595 - break;
43.596 - }
43.597 - NEEDBITS(16);
43.598 -#ifdef GUNZIP
43.599 - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
43.600 - state->check = crc32(0L, Z_NULL, 0);
43.601 - CRC2(state->check, hold);
43.602 - INITBITS();
43.603 - state->mode = FLAGS;
43.604 - break;
43.605 - }
43.606 - state->flags = 0; /* expect zlib header */
43.607 - if (state->head != Z_NULL)
43.608 - state->head->done = -1;
43.609 - if (!(state->wrap & 1) || /* check if zlib header allowed */
43.610 -#else
43.611 - if (
43.612 -#endif
43.613 - ((BITS(8) << 8) + (hold >> 8)) % 31) {
43.614 - strm->msg = (char *)"incorrect header check";
43.615 - state->mode = BAD;
43.616 - break;
43.617 - }
43.618 - if (BITS(4) != Z_DEFLATED) {
43.619 - strm->msg = (char *)"unknown compression method";
43.620 - state->mode = BAD;
43.621 - break;
43.622 - }
43.623 - DROPBITS(4);
43.624 - len = BITS(4) + 8;
43.625 - if (len > state->wbits) {
43.626 - strm->msg = (char *)"invalid window size";
43.627 - state->mode = BAD;
43.628 - break;
43.629 - }
43.630 - state->dmax = 1U << len;
43.631 - Tracev((stderr, "inflate: zlib header ok\n"));
43.632 - strm->adler = state->check = adler32(0L, Z_NULL, 0);
43.633 - state->mode = hold & 0x200 ? DICTID : TYPE;
43.634 - INITBITS();
43.635 - break;
43.636 -#ifdef GUNZIP
43.637 - case FLAGS:
43.638 - NEEDBITS(16);
43.639 - state->flags = (int)(hold);
43.640 - if ((state->flags & 0xff) != Z_DEFLATED) {
43.641 - strm->msg = (char *)"unknown compression method";
43.642 - state->mode = BAD;
43.643 - break;
43.644 - }
43.645 - if (state->flags & 0xe000) {
43.646 - strm->msg = (char *)"unknown header flags set";
43.647 - state->mode = BAD;
43.648 - break;
43.649 - }
43.650 - if (state->head != Z_NULL)
43.651 - state->head->text = (int)((hold >> 8) & 1);
43.652 - if (state->flags & 0x0200) CRC2(state->check, hold);
43.653 - INITBITS();
43.654 - state->mode = TIME;
43.655 - case TIME:
43.656 - NEEDBITS(32);
43.657 - if (state->head != Z_NULL)
43.658 - state->head->time = hold;
43.659 - if (state->flags & 0x0200) CRC4(state->check, hold);
43.660 - INITBITS();
43.661 - state->mode = OS;
43.662 - case OS:
43.663 - NEEDBITS(16);
43.664 - if (state->head != Z_NULL) {
43.665 - state->head->xflags = (int)(hold & 0xff);
43.666 - state->head->os = (int)(hold >> 8);
43.667 - }
43.668 - if (state->flags & 0x0200) CRC2(state->check, hold);
43.669 - INITBITS();
43.670 - state->mode = EXLEN;
43.671 - case EXLEN:
43.672 - if (state->flags & 0x0400) {
43.673 - NEEDBITS(16);
43.674 - state->length = (unsigned)(hold);
43.675 - if (state->head != Z_NULL)
43.676 - state->head->extra_len = (unsigned)hold;
43.677 - if (state->flags & 0x0200) CRC2(state->check, hold);
43.678 - INITBITS();
43.679 - }
43.680 - else if (state->head != Z_NULL)
43.681 - state->head->extra = Z_NULL;
43.682 - state->mode = EXTRA;
43.683 - case EXTRA:
43.684 - if (state->flags & 0x0400) {
43.685 - copy = state->length;
43.686 - if (copy > have) copy = have;
43.687 - if (copy) {
43.688 - if (state->head != Z_NULL &&
43.689 - state->head->extra != Z_NULL) {
43.690 - len = state->head->extra_len - state->length;
43.691 - zmemcpy(state->head->extra + len, next,
43.692 - len + copy > state->head->extra_max ?
43.693 - state->head->extra_max - len : copy);
43.694 - }
43.695 - if (state->flags & 0x0200)
43.696 - state->check = crc32(state->check, next, copy);
43.697 - have -= copy;
43.698 - next += copy;
43.699 - state->length -= copy;
43.700 - }
43.701 - if (state->length) goto inf_leave;
43.702 - }
43.703 - state->length = 0;
43.704 - state->mode = NAME;
43.705 - case NAME:
43.706 - if (state->flags & 0x0800) {
43.707 - if (have == 0) goto inf_leave;
43.708 - copy = 0;
43.709 - do {
43.710 - len = (unsigned)(next[copy++]);
43.711 - if (state->head != Z_NULL &&
43.712 - state->head->name != Z_NULL &&
43.713 - state->length < state->head->name_max)
43.714 - state->head->name[state->length++] = len;
43.715 - } while (len && copy < have);
43.716 - if (state->flags & 0x0200)
43.717 - state->check = crc32(state->check, next, copy);
43.718 - have -= copy;
43.719 - next += copy;
43.720 - if (len) goto inf_leave;
43.721 - }
43.722 - else if (state->head != Z_NULL)
43.723 - state->head->name = Z_NULL;
43.724 - state->length = 0;
43.725 - state->mode = COMMENT;
43.726 - case COMMENT:
43.727 - if (state->flags & 0x1000) {
43.728 - if (have == 0) goto inf_leave;
43.729 - copy = 0;
43.730 - do {
43.731 - len = (unsigned)(next[copy++]);
43.732 - if (state->head != Z_NULL &&
43.733 - state->head->comment != Z_NULL &&
43.734 - state->length < state->head->comm_max)
43.735 - state->head->comment[state->length++] = len;
43.736 - } while (len && copy < have);
43.737 - if (state->flags & 0x0200)
43.738 - state->check = crc32(state->check, next, copy);
43.739 - have -= copy;
43.740 - next += copy;
43.741 - if (len) goto inf_leave;
43.742 - }
43.743 - else if (state->head != Z_NULL)
43.744 - state->head->comment = Z_NULL;
43.745 - state->mode = HCRC;
43.746 - case HCRC:
43.747 - if (state->flags & 0x0200) {
43.748 - NEEDBITS(16);
43.749 - if (hold != (state->check & 0xffff)) {
43.750 - strm->msg = (char *)"header crc mismatch";
43.751 - state->mode = BAD;
43.752 - break;
43.753 - }
43.754 - INITBITS();
43.755 - }
43.756 - if (state->head != Z_NULL) {
43.757 - state->head->hcrc = (int)((state->flags >> 9) & 1);
43.758 - state->head->done = 1;
43.759 - }
43.760 - strm->adler = state->check = crc32(0L, Z_NULL, 0);
43.761 - state->mode = TYPE;
43.762 - break;
43.763 -#endif
43.764 - case DICTID:
43.765 - NEEDBITS(32);
43.766 - strm->adler = state->check = REVERSE(hold);
43.767 - INITBITS();
43.768 - state->mode = DICT;
43.769 - case DICT:
43.770 - if (state->havedict == 0) {
43.771 - RESTORE();
43.772 - return Z_NEED_DICT;
43.773 - }
43.774 - strm->adler = state->check = adler32(0L, Z_NULL, 0);
43.775 - state->mode = TYPE;
43.776 - case TYPE:
43.777 - if (flush == Z_BLOCK) goto inf_leave;
43.778 - case TYPEDO:
43.779 - if (state->last) {
43.780 - BYTEBITS();
43.781 - state->mode = CHECK;
43.782 - break;
43.783 - }
43.784 - NEEDBITS(3);
43.785 - state->last = BITS(1);
43.786 - DROPBITS(1);
43.787 - switch (BITS(2)) {
43.788 - case 0: /* stored block */
43.789 - Tracev((stderr, "inflate: stored block%s\n",
43.790 - state->last ? " (last)" : ""));
43.791 - state->mode = STORED;
43.792 - break;
43.793 - case 1: /* fixed block */
43.794 - fixedtables(state);
43.795 - Tracev((stderr, "inflate: fixed codes block%s\n",
43.796 - state->last ? " (last)" : ""));
43.797 - state->mode = LEN; /* decode codes */
43.798 - break;
43.799 - case 2: /* dynamic block */
43.800 - Tracev((stderr, "inflate: dynamic codes block%s\n",
43.801 - state->last ? " (last)" : ""));
43.802 - state->mode = TABLE;
43.803 - break;
43.804 - case 3:
43.805 - strm->msg = (char *)"invalid block type";
43.806 - state->mode = BAD;
43.807 - }
43.808 - DROPBITS(2);
43.809 - break;
43.810 - case STORED:
43.811 - BYTEBITS(); /* go to byte boundary */
43.812 - NEEDBITS(32);
43.813 - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
43.814 - strm->msg = (char *)"invalid stored block lengths";
43.815 - state->mode = BAD;
43.816 - break;
43.817 - }
43.818 - state->length = (unsigned)hold & 0xffff;
43.819 - Tracev((stderr, "inflate: stored length %u\n",
43.820 - state->length));
43.821 - INITBITS();
43.822 - state->mode = COPY;
43.823 - case COPY:
43.824 - copy = state->length;
43.825 - if (copy) {
43.826 - if (copy > have) copy = have;
43.827 - if (copy > left) copy = left;
43.828 - if (copy == 0) goto inf_leave;
43.829 - zmemcpy(put, next, copy);
43.830 - have -= copy;
43.831 - next += copy;
43.832 - left -= copy;
43.833 - put += copy;
43.834 - state->length -= copy;
43.835 - break;
43.836 - }
43.837 - Tracev((stderr, "inflate: stored end\n"));
43.838 - state->mode = TYPE;
43.839 - break;
43.840 - case TABLE:
43.841 - NEEDBITS(14);
43.842 - state->nlen = BITS(5) + 257;
43.843 - DROPBITS(5);
43.844 - state->ndist = BITS(5) + 1;
43.845 - DROPBITS(5);
43.846 - state->ncode = BITS(4) + 4;
43.847 - DROPBITS(4);
43.848 -#ifndef PKZIP_BUG_WORKAROUND
43.849 - if (state->nlen > 286 || state->ndist > 30) {
43.850 - strm->msg = (char *)"too many length or distance symbols";
43.851 - state->mode = BAD;
43.852 - break;
43.853 - }
43.854 -#endif
43.855 - Tracev((stderr, "inflate: table sizes ok\n"));
43.856 - state->have = 0;
43.857 - state->mode = LENLENS;
43.858 - case LENLENS:
43.859 - while (state->have < state->ncode) {
43.860 - NEEDBITS(3);
43.861 - state->lens[order[state->have++]] = (unsigned short)BITS(3);
43.862 - DROPBITS(3);
43.863 - }
43.864 - while (state->have < 19)
43.865 - state->lens[order[state->have++]] = 0;
43.866 - state->next = state->codes;
43.867 - state->lencode = (code const FAR *)(state->next);
43.868 - state->lenbits = 7;
43.869 - ret = inflate_table(CODES, state->lens, 19, &(state->next),
43.870 - &(state->lenbits), state->work);
43.871 - if (ret) {
43.872 - strm->msg = (char *)"invalid code lengths set";
43.873 - state->mode = BAD;
43.874 - break;
43.875 - }
43.876 - Tracev((stderr, "inflate: code lengths ok\n"));
43.877 - state->have = 0;
43.878 - state->mode = CODELENS;
43.879 - case CODELENS:
43.880 - while (state->have < state->nlen + state->ndist) {
43.881 - for (;;) {
43.882 - this = state->lencode[BITS(state->lenbits)];
43.883 - if ((unsigned)(this.bits) <= bits) break;
43.884 - PULLBYTE();
43.885 - }
43.886 - if (this.val < 16) {
43.887 - NEEDBITS(this.bits);
43.888 - DROPBITS(this.bits);
43.889 - state->lens[state->have++] = this.val;
43.890 - }
43.891 - else {
43.892 - if (this.val == 16) {
43.893 - NEEDBITS(this.bits + 2);
43.894 - DROPBITS(this.bits);
43.895 - if (state->have == 0) {
43.896 - strm->msg = (char *)"invalid bit length repeat";
43.897 - state->mode = BAD;
43.898 - break;
43.899 - }
43.900 - len = state->lens[state->have - 1];
43.901 - copy = 3 + BITS(2);
43.902 - DROPBITS(2);
43.903 - }
43.904 - else if (this.val == 17) {
43.905 - NEEDBITS(this.bits + 3);
43.906 - DROPBITS(this.bits);
43.907 - len = 0;
43.908 - copy = 3 + BITS(3);
43.909 - DROPBITS(3);
43.910 - }
43.911 - else {
43.912 - NEEDBITS(this.bits + 7);
43.913 - DROPBITS(this.bits);
43.914 - len = 0;
43.915 - copy = 11 + BITS(7);
43.916 - DROPBITS(7);
43.917 - }
43.918 - if (state->have + copy > state->nlen + state->ndist) {
43.919 - strm->msg = (char *)"invalid bit length repeat";
43.920 - state->mode = BAD;
43.921 - break;
43.922 - }
43.923 - while (copy--)
43.924 - state->lens[state->have++] = (unsigned short)len;
43.925 - }
43.926 - }
43.927 -
43.928 - /* handle error breaks in while */
43.929 - if (state->mode == BAD) break;
43.930 -
43.931 - /* build code tables */
43.932 - state->next = state->codes;
43.933 - state->lencode = (code const FAR *)(state->next);
43.934 - state->lenbits = 9;
43.935 - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
43.936 - &(state->lenbits), state->work);
43.937 - if (ret) {
43.938 - strm->msg = (char *)"invalid literal/lengths set";
43.939 - state->mode = BAD;
43.940 - break;
43.941 - }
43.942 - state->distcode = (code const FAR *)(state->next);
43.943 - state->distbits = 6;
43.944 - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
43.945 - &(state->next), &(state->distbits), state->work);
43.946 - if (ret) {
43.947 - strm->msg = (char *)"invalid distances set";
43.948 - state->mode = BAD;
43.949 - break;
43.950 - }
43.951 - Tracev((stderr, "inflate: codes ok\n"));
43.952 - state->mode = LEN;
43.953 - case LEN:
43.954 - if (have >= 6 && left >= 258) {
43.955 - RESTORE();
43.956 - inflate_fast(strm, out);
43.957 - LOAD();
43.958 - break;
43.959 - }
43.960 - for (;;) {
43.961 - this = state->lencode[BITS(state->lenbits)];
43.962 - if ((unsigned)(this.bits) <= bits) break;
43.963 - PULLBYTE();
43.964 - }
43.965 - if (this.op && (this.op & 0xf0) == 0) {
43.966 - last = this;
43.967 - for (;;) {
43.968 - this = state->lencode[last.val +
43.969 - (BITS(last.bits + last.op) >> last.bits)];
43.970 - if ((unsigned)(last.bits + this.bits) <= bits) break;
43.971 - PULLBYTE();
43.972 - }
43.973 - DROPBITS(last.bits);
43.974 - }
43.975 - DROPBITS(this.bits);
43.976 - state->length = (unsigned)this.val;
43.977 - if ((int)(this.op) == 0) {
43.978 - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
43.979 - "inflate: literal '%c'\n" :
43.980 - "inflate: literal 0x%02x\n", this.val));
43.981 - state->mode = LIT;
43.982 - break;
43.983 - }
43.984 - if (this.op & 32) {
43.985 - Tracevv((stderr, "inflate: end of block\n"));
43.986 - state->mode = TYPE;
43.987 - break;
43.988 - }
43.989 - if (this.op & 64) {
43.990 - strm->msg = (char *)"invalid literal/length code";
43.991 - state->mode = BAD;
43.992 - break;
43.993 - }
43.994 - state->extra = (unsigned)(this.op) & 15;
43.995 - state->mode = LENEXT;
43.996 - case LENEXT:
43.997 - if (state->extra) {
43.998 - NEEDBITS(state->extra);
43.999 - state->length += BITS(state->extra);
43.1000 - DROPBITS(state->extra);
43.1001 - }
43.1002 - Tracevv((stderr, "inflate: length %u\n", state->length));
43.1003 - state->mode = DIST;
43.1004 - case DIST:
43.1005 - for (;;) {
43.1006 - this = state->distcode[BITS(state->distbits)];
43.1007 - if ((unsigned)(this.bits) <= bits) break;
43.1008 - PULLBYTE();
43.1009 - }
43.1010 - if ((this.op & 0xf0) == 0) {
43.1011 - last = this;
43.1012 - for (;;) {
43.1013 - this = state->distcode[last.val +
43.1014 - (BITS(last.bits + last.op) >> last.bits)];
43.1015 - if ((unsigned)(last.bits + this.bits) <= bits) break;
43.1016 - PULLBYTE();
43.1017 - }
43.1018 - DROPBITS(last.bits);
43.1019 - }
43.1020 - DROPBITS(this.bits);
43.1021 - if (this.op & 64) {
43.1022 - strm->msg = (char *)"invalid distance code";
43.1023 - state->mode = BAD;
43.1024 - break;
43.1025 - }
43.1026 - state->offset = (unsigned)this.val;
43.1027 - state->extra = (unsigned)(this.op) & 15;
43.1028 - state->mode = DISTEXT;
43.1029 - case DISTEXT:
43.1030 - if (state->extra) {
43.1031 - NEEDBITS(state->extra);
43.1032 - state->offset += BITS(state->extra);
43.1033 - DROPBITS(state->extra);
43.1034 - }
43.1035 -#ifdef INFLATE_STRICT
43.1036 - if (state->offset > state->dmax) {
43.1037 - strm->msg = (char *)"invalid distance too far back";
43.1038 - state->mode = BAD;
43.1039 - break;
43.1040 - }
43.1041 -#endif
43.1042 - if (state->offset > state->whave + out - left) {
43.1043 - strm->msg = (char *)"invalid distance too far back";
43.1044 - state->mode = BAD;
43.1045 - break;
43.1046 - }
43.1047 - Tracevv((stderr, "inflate: distance %u\n", state->offset));
43.1048 - state->mode = MATCH;
43.1049 - case MATCH:
43.1050 - if (left == 0) goto inf_leave;
43.1051 - copy = out - left;
43.1052 - if (state->offset > copy) { /* copy from window */
43.1053 - copy = state->offset - copy;
43.1054 - if (copy > state->write) {
43.1055 - copy -= state->write;
43.1056 - from = state->window + (state->wsize - copy);
43.1057 - }
43.1058 - else
43.1059 - from = state->window + (state->write - copy);
43.1060 - if (copy > state->length) copy = state->length;
43.1061 - }
43.1062 - else { /* copy from output */
43.1063 - from = put - state->offset;
43.1064 - copy = state->length;
43.1065 - }
43.1066 - if (copy > left) copy = left;
43.1067 - left -= copy;
43.1068 - state->length -= copy;
43.1069 - do {
43.1070 - *put++ = *from++;
43.1071 - } while (--copy);
43.1072 - if (state->length == 0) state->mode = LEN;
43.1073 - break;
43.1074 - case LIT:
43.1075 - if (left == 0) goto inf_leave;
43.1076 - *put++ = (unsigned char)(state->length);
43.1077 - left--;
43.1078 - state->mode = LEN;
43.1079 - break;
43.1080 - case CHECK:
43.1081 - if (state->wrap) {
43.1082 - NEEDBITS(32);
43.1083 - out -= left;
43.1084 - strm->total_out += out;
43.1085 - state->total += out;
43.1086 - if (out)
43.1087 - strm->adler = state->check =
43.1088 - UPDATE(state->check, put - out, out);
43.1089 - out = left;
43.1090 - if ((
43.1091 -#ifdef GUNZIP
43.1092 - state->flags ? hold :
43.1093 -#endif
43.1094 - REVERSE(hold)) != state->check) {
43.1095 - strm->msg = (char *)"incorrect data check";
43.1096 - state->mode = BAD;
43.1097 - break;
43.1098 - }
43.1099 - INITBITS();
43.1100 - Tracev((stderr, "inflate: check matches trailer\n"));
43.1101 - }
43.1102 -#ifdef GUNZIP
43.1103 - state->mode = LENGTH;
43.1104 - case LENGTH:
43.1105 - if (state->wrap && state->flags) {
43.1106 - NEEDBITS(32);
43.1107 - if (hold != (state->total & 0xffffffffUL)) {
43.1108 - strm->msg = (char *)"incorrect length check";
43.1109 - state->mode = BAD;
43.1110 - break;
43.1111 - }
43.1112 - INITBITS();
43.1113 - Tracev((stderr, "inflate: length matches trailer\n"));
43.1114 - }
43.1115 -#endif
43.1116 - state->mode = DONE;
43.1117 - case DONE:
43.1118 - ret = Z_STREAM_END;
43.1119 - goto inf_leave;
43.1120 - case BAD:
43.1121 - ret = Z_DATA_ERROR;
43.1122 - goto inf_leave;
43.1123 - case MEM:
43.1124 - return Z_MEM_ERROR;
43.1125 - case SYNC:
43.1126 - default:
43.1127 - return Z_STREAM_ERROR;
43.1128 - }
43.1129 -
43.1130 - /*
43.1131 - Return from inflate(), updating the total counts and the check value.
43.1132 - If there was no progress during the inflate() call, return a buffer
43.1133 - error. Call updatewindow() to create and/or update the window state.
43.1134 - Note: a memory error from inflate() is non-recoverable.
43.1135 - */
43.1136 - inf_leave:
43.1137 - RESTORE();
43.1138 - if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
43.1139 - if (updatewindow(strm, out)) {
43.1140 - state->mode = MEM;
43.1141 - return Z_MEM_ERROR;
43.1142 - }
43.1143 - in -= strm->avail_in;
43.1144 - out -= strm->avail_out;
43.1145 - strm->total_in += in;
43.1146 - strm->total_out += out;
43.1147 - state->total += out;
43.1148 - if (state->wrap && out)
43.1149 - strm->adler = state->check =
43.1150 - UPDATE(state->check, strm->next_out - out, out);
43.1151 - strm->data_type = state->bits + (state->last ? 64 : 0) +
43.1152 - (state->mode == TYPE ? 128 : 0);
43.1153 - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
43.1154 - ret = Z_BUF_ERROR;
43.1155 - return ret;
43.1156 -}
43.1157 -
43.1158 -int ZEXPORT inflateEnd(strm)
43.1159 -z_streamp strm;
43.1160 -{
43.1161 - struct inflate_state FAR *state;
43.1162 - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
43.1163 - return Z_STREAM_ERROR;
43.1164 - state = (struct inflate_state FAR *)strm->state;
43.1165 - if (state->window != Z_NULL) ZFREE(strm, state->window);
43.1166 - ZFREE(strm, strm->state);
43.1167 - strm->state = Z_NULL;
43.1168 - Tracev((stderr, "inflate: end\n"));
43.1169 - return Z_OK;
43.1170 -}
43.1171 -
43.1172 -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
43.1173 -z_streamp strm;
43.1174 -const Bytef *dictionary;
43.1175 -uInt dictLength;
43.1176 -{
43.1177 - struct inflate_state FAR *state;
43.1178 - unsigned long id;
43.1179 -
43.1180 - /* check state */
43.1181 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
43.1182 - state = (struct inflate_state FAR *)strm->state;
43.1183 - if (state->wrap != 0 && state->mode != DICT)
43.1184 - return Z_STREAM_ERROR;
43.1185 -
43.1186 - /* check for correct dictionary id */
43.1187 - if (state->mode == DICT) {
43.1188 - id = adler32(0L, Z_NULL, 0);
43.1189 - id = adler32(id, dictionary, dictLength);
43.1190 - if (id != state->check)
43.1191 - return Z_DATA_ERROR;
43.1192 - }
43.1193 -
43.1194 - /* copy dictionary to window */
43.1195 - if (updatewindow(strm, strm->avail_out)) {
43.1196 - state->mode = MEM;
43.1197 - return Z_MEM_ERROR;
43.1198 - }
43.1199 - if (dictLength > state->wsize) {
43.1200 - zmemcpy(state->window, dictionary + dictLength - state->wsize,
43.1201 - state->wsize);
43.1202 - state->whave = state->wsize;
43.1203 - }
43.1204 - else {
43.1205 - zmemcpy(state->window + state->wsize - dictLength, dictionary,
43.1206 - dictLength);
43.1207 - state->whave = dictLength;
43.1208 - }
43.1209 - state->havedict = 1;
43.1210 - Tracev((stderr, "inflate: dictionary set\n"));
43.1211 - return Z_OK;
43.1212 -}
43.1213 -
43.1214 -int ZEXPORT inflateGetHeader(strm, head)
43.1215 -z_streamp strm;
43.1216 -gz_headerp head;
43.1217 -{
43.1218 - struct inflate_state FAR *state;
43.1219 -
43.1220 - /* check state */
43.1221 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
43.1222 - state = (struct inflate_state FAR *)strm->state;
43.1223 - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
43.1224 -
43.1225 - /* save header structure */
43.1226 - state->head = head;
43.1227 - head->done = 0;
43.1228 - return Z_OK;
43.1229 -}
43.1230 -
43.1231 -/*
43.1232 - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
43.1233 - or when out of input. When called, *have is the number of pattern bytes
43.1234 - found in order so far, in 0..3. On return *have is updated to the new
43.1235 - state. If on return *have equals four, then the pattern was found and the
43.1236 - return value is how many bytes were read including the last byte of the
43.1237 - pattern. If *have is less than four, then the pattern has not been found
43.1238 - yet and the return value is len. In the latter case, syncsearch() can be
43.1239 - called again with more data and the *have state. *have is initialized to
43.1240 - zero for the first call.
43.1241 - */
43.1242 -local unsigned syncsearch(have, buf, len)
43.1243 -unsigned FAR *have;
43.1244 -unsigned char FAR *buf;
43.1245 -unsigned len;
43.1246 -{
43.1247 - unsigned got;
43.1248 - unsigned next;
43.1249 -
43.1250 - got = *have;
43.1251 - next = 0;
43.1252 - while (next < len && got < 4) {
43.1253 - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
43.1254 - got++;
43.1255 - else if (buf[next])
43.1256 - got = 0;
43.1257 - else
43.1258 - got = 4 - got;
43.1259 - next++;
43.1260 - }
43.1261 - *have = got;
43.1262 - return next;
43.1263 -}
43.1264 -
43.1265 -int ZEXPORT inflateSync(strm)
43.1266 -z_streamp strm;
43.1267 -{
43.1268 - unsigned len; /* number of bytes to look at or looked at */
43.1269 - unsigned long in, out; /* temporary to save total_in and total_out */
43.1270 - unsigned char buf[4]; /* to restore bit buffer to byte string */
43.1271 - struct inflate_state FAR *state;
43.1272 -
43.1273 - /* check parameters */
43.1274 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
43.1275 - state = (struct inflate_state FAR *)strm->state;
43.1276 - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
43.1277 -
43.1278 - /* if first time, start search in bit buffer */
43.1279 - if (state->mode != SYNC) {
43.1280 - state->mode = SYNC;
43.1281 - state->hold <<= state->bits & 7;
43.1282 - state->bits -= state->bits & 7;
43.1283 - len = 0;
43.1284 - while (state->bits >= 8) {
43.1285 - buf[len++] = (unsigned char)(state->hold);
43.1286 - state->hold >>= 8;
43.1287 - state->bits -= 8;
43.1288 - }
43.1289 - state->have = 0;
43.1290 - syncsearch(&(state->have), buf, len);
43.1291 - }
43.1292 -
43.1293 - /* search available input */
43.1294 - len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
43.1295 - strm->avail_in -= len;
43.1296 - strm->next_in += len;
43.1297 - strm->total_in += len;
43.1298 -
43.1299 - /* return no joy or set up to restart inflate() on a new block */
43.1300 - if (state->have != 4) return Z_DATA_ERROR;
43.1301 - in = strm->total_in; out = strm->total_out;
43.1302 - inflateReset(strm);
43.1303 - strm->total_in = in; strm->total_out = out;
43.1304 - state->mode = TYPE;
43.1305 - return Z_OK;
43.1306 -}
43.1307 -
43.1308 -/*
43.1309 - Returns true if inflate is currently at the end of a block generated by
43.1310 - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
43.1311 - implementation to provide an additional safety check. PPP uses
43.1312 - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
43.1313 - block. When decompressing, PPP checks that at the end of input packet,
43.1314 - inflate is waiting for these length bytes.
43.1315 - */
43.1316 -int ZEXPORT inflateSyncPoint(strm)
43.1317 -z_streamp strm;
43.1318 -{
43.1319 - struct inflate_state FAR *state;
43.1320 -
43.1321 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
43.1322 - state = (struct inflate_state FAR *)strm->state;
43.1323 - return state->mode == STORED && state->bits == 0;
43.1324 -}
43.1325 -
43.1326 -int ZEXPORT inflateCopy(dest, source)
43.1327 -z_streamp dest;
43.1328 -z_streamp source;
43.1329 -{
43.1330 - struct inflate_state FAR *state;
43.1331 - struct inflate_state FAR *copy;
43.1332 - unsigned char FAR *window;
43.1333 - unsigned wsize;
43.1334 -
43.1335 - /* check input */
43.1336 - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
43.1337 - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
43.1338 - return Z_STREAM_ERROR;
43.1339 - state = (struct inflate_state FAR *)source->state;
43.1340 -
43.1341 - /* allocate space */
43.1342 - copy = (struct inflate_state FAR *)
43.1343 - ZALLOC(source, 1, sizeof(struct inflate_state));
43.1344 - if (copy == Z_NULL) return Z_MEM_ERROR;
43.1345 - window = Z_NULL;
43.1346 - if (state->window != Z_NULL) {
43.1347 - window = (unsigned char FAR *)
43.1348 - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
43.1349 - if (window == Z_NULL) {
43.1350 - ZFREE(source, copy);
43.1351 - return Z_MEM_ERROR;
43.1352 - }
43.1353 - }
43.1354 -
43.1355 - /* copy state */
43.1356 - zmemcpy(dest, source, sizeof(z_stream));
43.1357 - zmemcpy(copy, state, sizeof(struct inflate_state));
43.1358 - if (state->lencode >= state->codes &&
43.1359 - state->lencode <= state->codes + ENOUGH - 1) {
43.1360 - copy->lencode = copy->codes + (state->lencode - state->codes);
43.1361 - copy->distcode = copy->codes + (state->distcode - state->codes);
43.1362 - }
43.1363 - copy->next = copy->codes + (state->next - state->codes);
43.1364 - if (window != Z_NULL) {
43.1365 - wsize = 1U << state->wbits;
43.1366 - zmemcpy(window, state->window, wsize);
43.1367 - }
43.1368 - copy->window = window;
43.1369 - dest->state = (struct internal_state FAR *)copy;
43.1370 - return Z_OK;
43.1371 -}
44.1 --- a/compiler-init/zlib/inflate.h Sat Jul 15 05:02:38 2006 +0000
44.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
44.3 @@ -1,115 +0,0 @@
44.4 -/* inflate.h -- internal inflate state definition
44.5 - * Copyright (C) 1995-2004 Mark Adler
44.6 - * For conditions of distribution and use, see copyright notice in zlib.h
44.7 - */
44.8 -
44.9 -/* WARNING: this file should *not* be used by applications. It is
44.10 - part of the implementation of the compression library and is
44.11 - subject to change. Applications should only use zlib.h.
44.12 - */
44.13 -
44.14 -/* define NO_GZIP when compiling if you want to disable gzip header and
44.15 - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
44.16 - the crc code when it is not needed. For shared libraries, gzip decoding
44.17 - should be left enabled. */
44.18 -#ifndef NO_GZIP
44.19 -# define GUNZIP
44.20 -#endif
44.21 -
44.22 -/* Possible inflate modes between inflate() calls */
44.23 -typedef enum {
44.24 - HEAD, /* i: waiting for magic header */
44.25 - FLAGS, /* i: waiting for method and flags (gzip) */
44.26 - TIME, /* i: waiting for modification time (gzip) */
44.27 - OS, /* i: waiting for extra flags and operating system (gzip) */
44.28 - EXLEN, /* i: waiting for extra length (gzip) */
44.29 - EXTRA, /* i: waiting for extra bytes (gzip) */
44.30 - NAME, /* i: waiting for end of file name (gzip) */
44.31 - COMMENT, /* i: waiting for end of comment (gzip) */
44.32 - HCRC, /* i: waiting for header crc (gzip) */
44.33 - DICTID, /* i: waiting for dictionary check value */
44.34 - DICT, /* waiting for inflateSetDictionary() call */
44.35 - TYPE, /* i: waiting for type bits, including last-flag bit */
44.36 - TYPEDO, /* i: same, but skip check to exit inflate on new block */
44.37 - STORED, /* i: waiting for stored size (length and complement) */
44.38 - COPY, /* i/o: waiting for input or output to copy stored block */
44.39 - TABLE, /* i: waiting for dynamic block table lengths */
44.40 - LENLENS, /* i: waiting for code length code lengths */
44.41 - CODELENS, /* i: waiting for length/lit and distance code lengths */
44.42 - LEN, /* i: waiting for length/lit code */
44.43 - LENEXT, /* i: waiting for length extra bits */
44.44 - DIST, /* i: waiting for distance code */
44.45 - DISTEXT, /* i: waiting for distance extra bits */
44.46 - MATCH, /* o: waiting for output space to copy string */
44.47 - LIT, /* o: waiting for output space to write literal */
44.48 - CHECK, /* i: waiting for 32-bit check value */
44.49 - LENGTH, /* i: waiting for 32-bit length (gzip) */
44.50 - DONE, /* finished check, done -- remain here until reset */
44.51 - BAD, /* got a data error -- remain here until reset */
44.52 - MEM, /* got an inflate() memory error -- remain here until reset */
44.53 - SYNC /* looking for synchronization bytes to restart inflate() */
44.54 -} inflate_mode;
44.55 -
44.56 -/*
44.57 - State transitions between above modes -
44.58 -
44.59 - (most modes can go to the BAD or MEM mode -- not shown for clarity)
44.60 -
44.61 - Process header:
44.62 - HEAD -> (gzip) or (zlib)
44.63 - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
44.64 - NAME -> COMMENT -> HCRC -> TYPE
44.65 - (zlib) -> DICTID or TYPE
44.66 - DICTID -> DICT -> TYPE
44.67 - Read deflate blocks:
44.68 - TYPE -> STORED or TABLE or LEN or CHECK
44.69 - STORED -> COPY -> TYPE
44.70 - TABLE -> LENLENS -> CODELENS -> LEN
44.71 - Read deflate codes:
44.72 - LEN -> LENEXT or LIT or TYPE
44.73 - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
44.74 - LIT -> LEN
44.75 - Process trailer:
44.76 - CHECK -> LENGTH -> DONE
44.77 - */
44.78 -
44.79 -/* state maintained between inflate() calls. Approximately 7K bytes. */
44.80 -struct inflate_state {
44.81 - inflate_mode mode; /* current inflate mode */
44.82 - int last; /* true if processing last block */
44.83 - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
44.84 - int havedict; /* true if dictionary provided */
44.85 - int flags; /* gzip header method and flags (0 if zlib) */
44.86 - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
44.87 - unsigned long check; /* protected copy of check value */
44.88 - unsigned long total; /* protected copy of output count */
44.89 - gz_headerp head; /* where to save gzip header information */
44.90 - /* sliding window */
44.91 - unsigned wbits; /* log base 2 of requested window size */
44.92 - unsigned wsize; /* window size or zero if not using window */
44.93 - unsigned whave; /* valid bytes in the window */
44.94 - unsigned write; /* window write index */
44.95 - unsigned char FAR *window; /* allocated sliding window, if needed */
44.96 - /* bit accumulator */
44.97 - unsigned long hold; /* input bit accumulator */
44.98 - unsigned bits; /* number of bits in "in" */
44.99 - /* for string and stored block copying */
44.100 - unsigned length; /* literal or length of data to copy */
44.101 - unsigned offset; /* distance back to copy string from */
44.102 - /* for table and code decoding */
44.103 - unsigned extra; /* extra bits needed */
44.104 - /* fixed and dynamic code tables */
44.105 - code const FAR *lencode; /* starting table for length/literal codes */
44.106 - code const FAR *distcode; /* starting table for distance codes */
44.107 - unsigned lenbits; /* index bits for lencode */
44.108 - unsigned distbits; /* index bits for distcode */
44.109 - /* dynamic table building */
44.110 - unsigned ncode; /* number of code length code lengths */
44.111 - unsigned nlen; /* number of length code lengths */
44.112 - unsigned ndist; /* number of distance code lengths */
44.113 - unsigned have; /* number of code lengths in lens[] */
44.114 - code FAR *next; /* next available space in codes[] */
44.115 - unsigned short lens[320]; /* temporary storage for code lengths */
44.116 - unsigned short work[288]; /* work area for code table building */
44.117 - code codes[ENOUGH]; /* space for code tables */
44.118 -};
45.1 --- a/compiler-init/zlib/inftrees.c Sat Jul 15 05:02:38 2006 +0000
45.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
45.3 @@ -1,329 +0,0 @@
45.4 -/* inftrees.c -- generate Huffman trees for efficient decoding
45.5 - * Copyright (C) 1995-2005 Mark Adler
45.6 - * For conditions of distribution and use, see copyright notice in zlib.h
45.7 - */
45.8 -
45.9 -#include "zutil.h"
45.10 -#include "inftrees.h"
45.11 -
45.12 -#define MAXBITS 15
45.13 -
45.14 -const char inflate_copyright[] =
45.15 - " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
45.16 -/*
45.17 - If you use the zlib library in a product, an acknowledgment is welcome
45.18 - in the documentation of your product. If for some reason you cannot
45.19 - include such an acknowledgment, I would appreciate that you keep this
45.20 - copyright string in the executable of your product.
45.21 - */
45.22 -
45.23 -/*
45.24 - Build a set of tables to decode the provided canonical Huffman code.
45.25 - The code lengths are lens[0..codes-1]. The result starts at *table,
45.26 - whose indices are 0..2^bits-1. work is a writable array of at least
45.27 - lens shorts, which is used as a work area. type is the type of code
45.28 - to be generated, CODES, LENS, or DISTS. On return, zero is success,
45.29 - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
45.30 - on return points to the next available entry's address. bits is the
45.31 - requested root table index bits, and on return it is the actual root
45.32 - table index bits. It will differ if the request is greater than the
45.33 - longest code or if it is less than the shortest code.
45.34 - */
45.35 -int inflate_table(type, lens, codes, table, bits, work)
45.36 -codetype type;
45.37 -unsigned short FAR *lens;
45.38 -unsigned codes;
45.39 -code FAR * FAR *table;
45.40 -unsigned FAR *bits;
45.41 -unsigned short FAR *work;
45.42 -{
45.43 - unsigned len; /* a code's length in bits */
45.44 - unsigned sym; /* index of code symbols */
45.45 - unsigned min, max; /* minimum and maximum code lengths */
45.46 - unsigned root; /* number of index bits for root table */
45.47 - unsigned curr; /* number of index bits for current table */
45.48 - unsigned drop; /* code bits to drop for sub-table */
45.49 - int left; /* number of prefix codes available */
45.50 - unsigned used; /* code entries in table used */
45.51 - unsigned huff; /* Huffman code */
45.52 - unsigned incr; /* for incrementing code, index */
45.53 - unsigned fill; /* index for replicating entries */
45.54 - unsigned low; /* low bits for current root entry */
45.55 - unsigned mask; /* mask for low root bits */
45.56 - code this; /* table entry for duplication */
45.57 - code FAR *next; /* next available space in table */
45.58 - const unsigned short FAR *base; /* base value table to use */
45.59 - const unsigned short FAR *extra; /* extra bits table to use */
45.60 - int end; /* use base and extra for symbol > end */
45.61 - unsigned short count[MAXBITS+1]; /* number of codes of each length */
45.62 - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
45.63 - static const unsigned short lbase[31] = { /* Length codes 257..285 base */
45.64 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
45.65 - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
45.66 - static const unsigned short lext[31] = { /* Length codes 257..285 extra */
45.67 - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
45.68 - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
45.69 - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
45.70 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
45.71 - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
45.72 - 8193, 12289, 16385, 24577, 0, 0};
45.73 - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
45.74 - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
45.75 - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
45.76 - 28, 28, 29, 29, 64, 64};
45.77 -
45.78 - /*
45.79 - Process a set of code lengths to create a canonical Huffman code. The
45.80 - code lengths are lens[0..codes-1]. Each length corresponds to the
45.81 - symbols 0..codes-1. The Huffman code is generated by first sorting the
45.82 - symbols by length from short to long, and retaining the symbol order
45.83 - for codes with equal lengths. Then the code starts with all zero bits
45.84 - for the first code of the shortest length, and the codes are integer
45.85 - increments for the same length, and zeros are appended as the length
45.86 - increases. For the deflate format, these bits are stored backwards
45.87 - from their more natural integer increment ordering, and so when the
45.88 - decoding tables are built in the large loop below, the integer codes
45.89 - are incremented backwards.
45.90 -
45.91 - This routine assumes, but does not check, that all of the entries in
45.92 - lens[] are in the range 0..MAXBITS. The caller must assure this.
45.93 - 1..MAXBITS is interpreted as that code length. zero means that that
45.94 - symbol does not occur in this code.
45.95 -
45.96 - The codes are sorted by computing a count of codes for each length,
45.97 - creating from that a table of starting indices for each length in the
45.98 - sorted table, and then entering the symbols in order in the sorted
45.99 - table. The sorted table is work[], with that space being provided by
45.100 - the caller.
45.101 -
45.102 - The length counts are used for other purposes as well, i.e. finding
45.103 - the minimum and maximum length codes, determining if there are any
45.104 - codes at all, checking for a valid set of lengths, and looking ahead
45.105 - at length counts to determine sub-table sizes when building the
45.106 - decoding tables.
45.107 - */
45.108 -
45.109 - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
45.110 - for (len = 0; len <= MAXBITS; len++)
45.111 - count[len] = 0;
45.112 - for (sym = 0; sym < codes; sym++)
45.113 - count[lens[sym]]++;
45.114 -
45.115 - /* bound code lengths, force root to be within code lengths */
45.116 - root = *bits;
45.117 - for (max = MAXBITS; max >= 1; max--)
45.118 - if (count[max] != 0) break;
45.119 - if (root > max) root = max;
45.120 - if (max == 0) { /* no symbols to code at all */
45.121 - this.op = (unsigned char)64; /* invalid code marker */
45.122 - this.bits = (unsigned char)1;
45.123 - this.val = (unsigned short)0;
45.124 - *(*table)++ = this; /* make a table to force an error */
45.125 - *(*table)++ = this;
45.126 - *bits = 1;
45.127 - return 0; /* no symbols, but wait for decoding to report error */
45.128 - }
45.129 - for (min = 1; min <= MAXBITS; min++)
45.130 - if (count[min] != 0) break;
45.131 - if (root < min) root = min;
45.132 -
45.133 - /* check for an over-subscribed or incomplete set of lengths */
45.134 - left = 1;
45.135 - for (len = 1; len <= MAXBITS; len++) {
45.136 - left <<= 1;
45.137 - left -= count[len];
45.138 - if (left < 0) return -1; /* over-subscribed */
45.139 - }
45.140 - if (left > 0 && (type == CODES || max != 1))
45.141 - return -1; /* incomplete set */
45.142 -
45.143 - /* generate offsets into symbol table for each length for sorting */
45.144 - offs[1] = 0;
45.145 - for (len = 1; len < MAXBITS; len++)
45.146 - offs[len + 1] = offs[len] + count[len];
45.147 -
45.148 - /* sort symbols by length, by symbol order within each length */
45.149 - for (sym = 0; sym < codes; sym++)
45.150 - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
45.151 -
45.152 - /*
45.153 - Create and fill in decoding tables. In this loop, the table being
45.154 - filled is at next and has curr index bits. The code being used is huff
45.155 - with length len. That code is converted to an index by dropping drop
45.156 - bits off of the bottom. For codes where len is less than drop + curr,
45.157 - those top drop + curr - len bits are incremented through all values to
45.158 - fill the table with replicated entries.
45.159 -
45.160 - root is the number of index bits for the root table. When len exceeds
45.161 - root, sub-tables are created pointed to by the root entry with an index
45.162 - of the low root bits of huff. This is saved in low to check for when a
45.163 - new sub-table should be started. drop is zero when the root table is
45.164 - being filled, and drop is root when sub-tables are being filled.
45.165 -
45.166 - When a new sub-table is needed, it is necessary to look ahead in the
45.167 - code lengths to determine what size sub-table is needed. The length
45.168 - counts are used for this, and so count[] is decremented as codes are
45.169 - entered in the tables.
45.170 -
45.171 - used keeps track of how many table entries have been allocated from the
45.172 - provided *table space. It is checked when a LENS table is being made
45.173 - against the space in *table, ENOUGH, minus the maximum space needed by
45.174 - the worst case distance code, MAXD. This should never happen, but the
45.175 - sufficiency of ENOUGH has not been proven exhaustively, hence the check.
45.176 - This assumes that when type == LENS, bits == 9.
45.177 -
45.178 - sym increments through all symbols, and the loop terminates when
45.179 - all codes of length max, i.e. all codes, have been processed. This
45.180 - routine permits incomplete codes, so another loop after this one fills
45.181 - in the rest of the decoding tables with invalid code markers.
45.182 - */
45.183 -
45.184 - /* set up for code type */
45.185 - switch (type) {
45.186 - case CODES:
45.187 - base = extra = work; /* dummy value--not used */
45.188 - end = 19;
45.189 - break;
45.190 - case LENS:
45.191 - base = lbase;
45.192 - base -= 257;
45.193 - extra = lext;
45.194 - extra -= 257;
45.195 - end = 256;
45.196 - break;
45.197 - default: /* DISTS */
45.198 - base = dbase;
45.199 - extra = dext;
45.200 - end = -1;
45.201 - }
45.202 -
45.203 - /* initialize state for loop */
45.204 - huff = 0; /* starting code */
45.205 - sym = 0; /* starting code symbol */
45.206 - len = min; /* starting code length */
45.207 - next = *table; /* current table to fill in */
45.208 - curr = root; /* current table index bits */
45.209 - drop = 0; /* current bits to drop from code for index */
45.210 - low = (unsigned)(-1); /* trigger new sub-table when len > root */
45.211 - used = 1U << root; /* use root table entries */
45.212 - mask = used - 1; /* mask for comparing low */
45.213 -
45.214 - /* check available table space */
45.215 - if (type == LENS && used >= ENOUGH - MAXD)
45.216 - return 1;
45.217 -
45.218 - /* process all codes and make table entries */
45.219 - for (;;) {
45.220 - /* create table entry */
45.221 - this.bits = (unsigned char)(len - drop);
45.222 - if ((int)(work[sym]) < end) {
45.223 - this.op = (unsigned char)0;
45.224 - this.val = work[sym];
45.225 - }
45.226 - else if ((int)(work[sym]) > end) {
45.227 - this.op = (unsigned char)(extra[work[sym]]);
45.228 - this.val = base[work[sym]];
45.229 - }
45.230 - else {
45.231 - this.op = (unsigned char)(32 + 64); /* end of block */
45.232 - this.val = 0;
45.233 - }
45.234 -
45.235 - /* replicate for those indices with low len bits equal to huff */
45.236 - incr = 1U << (len - drop);
45.237 - fill = 1U << curr;
45.238 - min = fill; /* save offset to next table */
45.239 - do {
45.240 - fill -= incr;
45.241 - next[(huff >> drop) + fill] = this;
45.242 - } while (fill != 0);
45.243 -
45.244 - /* backwards increment the len-bit code huff */
45.245 - incr = 1U << (len - 1);
45.246 - while (huff & incr)
45.247 - incr >>= 1;
45.248 - if (incr != 0) {
45.249 - huff &= incr - 1;
45.250 - huff += incr;
45.251 - }
45.252 - else
45.253 - huff = 0;
45.254 -
45.255 - /* go to next symbol, update count, len */
45.256 - sym++;
45.257 - if (--(count[len]) == 0) {
45.258 - if (len == max) break;
45.259 - len = lens[work[sym]];
45.260 - }
45.261 -
45.262 - /* create new sub-table if needed */
45.263 - if (len > root && (huff & mask) != low) {
45.264 - /* if first time, transition to sub-tables */
45.265 - if (drop == 0)
45.266 - drop = root;
45.267 -
45.268 - /* increment past last table */
45.269 - next += min; /* here min is 1 << curr */
45.270 -
45.271 - /* determine length of next table */
45.272 - curr = len - drop;
45.273 - left = (int)(1 << curr);
45.274 - while (curr + drop < max) {
45.275 - left -= count[curr + drop];
45.276 - if (left <= 0) break;
45.277 - curr++;
45.278 - left <<= 1;
45.279 - }
45.280 -
45.281 - /* check for enough space */
45.282 - used += 1U << curr;
45.283 - if (type == LENS && used >= ENOUGH - MAXD)
45.284 - return 1;
45.285 -
45.286 - /* point entry in root table to sub-table */
45.287 - low = huff & mask;
45.288 - (*table)[low].op = (unsigned char)curr;
45.289 - (*table)[low].bits = (unsigned char)root;
45.290 - (*table)[low].val = (unsigned short)(next - *table);
45.291 - }
45.292 - }
45.293 -
45.294 - /*
45.295 - Fill in rest of table for incomplete codes. This loop is similar to the
45.296 - loop above in incrementing huff for table indices. It is assumed that
45.297 - len is equal to curr + drop, so there is no loop needed to increment
45.298 - through high index bits. When the current sub-table is filled, the loop
45.299 - drops back to the root table to fill in any remaining entries there.
45.300 - */
45.301 - this.op = (unsigned char)64; /* invalid code marker */
45.302 - this.bits = (unsigned char)(len - drop);
45.303 - this.val = (unsigned short)0;
45.304 - while (huff != 0) {
45.305 - /* when done with sub-table, drop back to root table */
45.306 - if (drop != 0 && (huff & mask) != low) {
45.307 - drop = 0;
45.308 - len = root;
45.309 - next = *table;
45.310 - this.bits = (unsigned char)len;
45.311 - }
45.312 -
45.313 - /* put invalid code marker in table */
45.314 - next[huff >> drop] = this;
45.315 -
45.316 - /* backwards increment the len-bit code huff */
45.317 - incr = 1U << (len - 1);
45.318 - while (huff & incr)
45.319 - incr >>= 1;
45.320 - if (incr != 0) {
45.321 - huff &= incr - 1;
45.322 - huff += incr;
45.323 - }
45.324 - else
45.325 - huff = 0;
45.326 - }
45.327 -
45.328 - /* set return parameters */
45.329 - *table += used;
45.330 - *bits = root;
45.331 - return 0;
45.332 -}
46.1 --- a/compiler-init/zlib/inftrees.h Sat Jul 15 05:02:38 2006 +0000
46.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
46.3 @@ -1,55 +0,0 @@
46.4 -/* inftrees.h -- header to use inftrees.c
46.5 - * Copyright (C) 1995-2005 Mark Adler
46.6 - * For conditions of distribution and use, see copyright notice in zlib.h
46.7 - */
46.8 -
46.9 -/* WARNING: this file should *not* be used by applications. It is
46.10 - part of the implementation of the compression library and is
46.11 - subject to change. Applications should only use zlib.h.
46.12 - */
46.13 -
46.14 -/* Structure for decoding tables. Each entry provides either the
46.15 - information needed to do the operation requested by the code that
46.16 - indexed that table entry, or it provides a pointer to another
46.17 - table that indexes more bits of the code. op indicates whether
46.18 - the entry is a pointer to another table, a literal, a length or
46.19 - distance, an end-of-block, or an invalid code. For a table
46.20 - pointer, the low four bits of op is the number of index bits of
46.21 - that table. For a length or distance, the low four bits of op
46.22 - is the number of extra bits to get after the code. bits is
46.23 - the number of bits in this code or part of the code to drop off
46.24 - of the bit buffer. val is the actual byte to output in the case
46.25 - of a literal, the base length or distance, or the offset from
46.26 - the current table to the next table. Each entry is four bytes. */
46.27 -typedef struct {
46.28 - unsigned char op; /* operation, extra bits, table bits */
46.29 - unsigned char bits; /* bits in this part of the code */
46.30 - unsigned short val; /* offset in table or code value */
46.31 -} code;
46.32 -
46.33 -/* op values as set by inflate_table():
46.34 - 00000000 - literal
46.35 - 0000tttt - table link, tttt != 0 is the number of table index bits
46.36 - 0001eeee - length or distance, eeee is the number of extra bits
46.37 - 01100000 - end of block
46.38 - 01000000 - invalid code
46.39 - */
46.40 -
46.41 -/* Maximum size of dynamic tree. The maximum found in a long but non-
46.42 - exhaustive search was 1444 code structures (852 for length/literals
46.43 - and 592 for distances, the latter actually the result of an
46.44 - exhaustive search). The true maximum is not known, but the value
46.45 - below is more than safe. */
46.46 -#define ENOUGH 2048
46.47 -#define MAXD 592
46.48 -
46.49 -/* Type of code to build for inftable() */
46.50 -typedef enum {
46.51 - CODES,
46.52 - LENS,
46.53 - DISTS
46.54 -} codetype;
46.55 -
46.56 -extern int inflate_table OF((codetype type, unsigned short FAR *lens,
46.57 - unsigned codes, code FAR * FAR *table,
46.58 - unsigned FAR *bits, unsigned short FAR *work));
47.1 --- a/compiler-init/zlib/trees.c Sat Jul 15 05:02:38 2006 +0000
47.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
47.3 @@ -1,1219 +0,0 @@
47.4 -/* trees.c -- output deflated data using Huffman coding
47.5 - * Copyright (C) 1995-2005 Jean-loup Gailly
47.6 - * For conditions of distribution and use, see copyright notice in zlib.h
47.7 - */
47.8 -
47.9 -/*
47.10 - * ALGORITHM
47.11 - *
47.12 - * The "deflation" process uses several Huffman trees. The more
47.13 - * common source values are represented by shorter bit sequences.
47.14 - *
47.15 - * Each code tree is stored in a compressed form which is itself
47.16 - * a Huffman encoding of the lengths of all the code strings (in
47.17 - * ascending order by source values). The actual code strings are
47.18 - * reconstructed from the lengths in the inflate process, as described
47.19 - * in the deflate specification.
47.20 - *
47.21 - * REFERENCES
47.22 - *
47.23 - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
47.24 - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
47.25 - *
47.26 - * Storer, James A.
47.27 - * Data Compression: Methods and Theory, pp. 49-50.
47.28 - * Computer Science Press, 1988. ISBN 0-7167-8156-5.
47.29 - *
47.30 - * Sedgewick, R.
47.31 - * Algorithms, p290.
47.32 - * Addison-Wesley, 1983. ISBN 0-201-06672-6.
47.33 - */
47.34 -
47.35 -/* @(#) $Id$ */
47.36 -
47.37 -/* #define GEN_TREES_H */
47.38 -
47.39 -#include "deflate.h"
47.40 -
47.41 -#ifdef DEBUG
47.42 -# include <ctype.h>
47.43 -#endif
47.44 -
47.45 -/* ===========================================================================
47.46 - * Constants
47.47 - */
47.48 -
47.49 -#define MAX_BL_BITS 7
47.50 -/* Bit length codes must not exceed MAX_BL_BITS bits */
47.51 -
47.52 -#define END_BLOCK 256
47.53 -/* end of block literal code */
47.54 -
47.55 -#define REP_3_6 16
47.56 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */
47.57 -
47.58 -#define REPZ_3_10 17
47.59 -/* repeat a zero length 3-10 times (3 bits of repeat count) */
47.60 -
47.61 -#define REPZ_11_138 18
47.62 -/* repeat a zero length 11-138 times (7 bits of repeat count) */
47.63 -
47.64 -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
47.65 - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
47.66 -
47.67 -local const int extra_dbits[D_CODES] /* extra bits for each distance code */
47.68 - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
47.69 -
47.70 -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
47.71 - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
47.72 -
47.73 -local const uch bl_order[BL_CODES]
47.74 - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
47.75 -/* The lengths of the bit length codes are sent in order of decreasing
47.76 - * probability, to avoid transmitting the lengths for unused bit length codes.
47.77 - */
47.78 -
47.79 -#define Buf_size (8 * 2*sizeof(char))
47.80 -/* Number of bits used within bi_buf. (bi_buf might be implemented on
47.81 - * more than 16 bits on some systems.)
47.82 - */
47.83 -
47.84 -/* ===========================================================================
47.85 - * Local data. These are initialized only once.
47.86 - */
47.87 -
47.88 -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
47.89 -
47.90 -#if defined(GEN_TREES_H) || !defined(STDC)
47.91 -/* non ANSI compilers may not accept trees.h */
47.92 -
47.93 -local ct_data static_ltree[L_CODES+2];
47.94 -/* The static literal tree. Since the bit lengths are imposed, there is no
47.95 - * need for the L_CODES extra codes used during heap construction. However
47.96 - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
47.97 - * below).
47.98 - */
47.99 -
47.100 -local ct_data static_dtree[D_CODES];
47.101 -/* The static distance tree. (Actually a trivial tree since all codes use
47.102 - * 5 bits.)
47.103 - */
47.104 -
47.105 -uch _dist_code[DIST_CODE_LEN];
47.106 -/* Distance codes. The first 256 values correspond to the distances
47.107 - * 3 .. 258, the last 256 values correspond to the top 8 bits of
47.108 - * the 15 bit distances.
47.109 - */
47.110 -
47.111 -uch _length_code[MAX_MATCH-MIN_MATCH+1];
47.112 -/* length code for each normalized match length (0 == MIN_MATCH) */
47.113 -
47.114 -local int base_length[LENGTH_CODES];
47.115 -/* First normalized length for each code (0 = MIN_MATCH) */
47.116 -
47.117 -local int base_dist[D_CODES];
47.118 -/* First normalized distance for each code (0 = distance of 1) */
47.119 -
47.120 -#else
47.121 -# include "trees.h"
47.122 -#endif /* GEN_TREES_H */
47.123 -
47.124 -struct static_tree_desc_s {
47.125 - const ct_data *static_tree; /* static tree or NULL */
47.126 - const intf *extra_bits; /* extra bits for each code or NULL */
47.127 - int extra_base; /* base index for extra_bits */
47.128 - int elems; /* max number of elements in the tree */
47.129 - int max_length; /* max bit length for the codes */
47.130 -};
47.131 -
47.132 -local static_tree_desc static_l_desc =
47.133 -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
47.134 -
47.135 -local static_tree_desc static_d_desc =
47.136 -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
47.137 -
47.138 -local static_tree_desc static_bl_desc =
47.139 -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
47.140 -
47.141 -/* ===========================================================================
47.142 - * Local (static) routines in this file.
47.143 - */
47.144 -
47.145 -local void tr_static_init OF((void));
47.146 -local void init_block OF((deflate_state *s));
47.147 -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
47.148 -local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
47.149 -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
47.150 -local void build_tree OF((deflate_state *s, tree_desc *desc));
47.151 -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
47.152 -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
47.153 -local int build_bl_tree OF((deflate_state *s));
47.154 -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
47.155 - int blcodes));
47.156 -local void compress_block OF((deflate_state *s, ct_data *ltree,
47.157 - ct_data *dtree));
47.158 -local void set_data_type OF((deflate_state *s));
47.159 -local unsigned bi_reverse OF((unsigned value, int length));
47.160 -local void bi_windup OF((deflate_state *s));
47.161 -local void bi_flush OF((deflate_state *s));
47.162 -local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
47.163 - int header));
47.164 -
47.165 -#ifdef GEN_TREES_H
47.166 -local void gen_trees_header OF((void));
47.167 -#endif
47.168 -
47.169 -#ifndef DEBUG
47.170 -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
47.171 - /* Send a code of the given tree. c and tree must not have side effects */
47.172 -
47.173 -#else /* DEBUG */
47.174 -# define send_code(s, c, tree) \
47.175 - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
47.176 - send_bits(s, tree[c].Code, tree[c].Len); }
47.177 -#endif
47.178 -
47.179 -/* ===========================================================================
47.180 - * Output a short LSB first on the stream.
47.181 - * IN assertion: there is enough room in pendingBuf.
47.182 - */
47.183 -#define put_short(s, w) { \
47.184 - put_byte(s, (uch)((w) & 0xff)); \
47.185 - put_byte(s, (uch)((ush)(w) >> 8)); \
47.186 -}
47.187 -
47.188 -/* ===========================================================================
47.189 - * Send a value on a given number of bits.
47.190 - * IN assertion: length <= 16 and value fits in length bits.
47.191 - */
47.192 -#ifdef DEBUG
47.193 -local void send_bits OF((deflate_state *s, int value, int length));
47.194 -
47.195 -local void send_bits(s, value, length)
47.196 - deflate_state *s;
47.197 - int value; /* value to send */
47.198 - int length; /* number of bits */
47.199 -{
47.200 - Tracevv((stderr," l %2d v %4x ", length, value));
47.201 - Assert(length > 0 && length <= 15, "invalid length");
47.202 - s->bits_sent += (ulg)length;
47.203 -
47.204 - /* If not enough room in bi_buf, use (valid) bits from bi_buf and
47.205 - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
47.206 - * unused bits in value.
47.207 - */
47.208 - if (s->bi_valid > (int)Buf_size - length) {
47.209 - s->bi_buf |= (value << s->bi_valid);
47.210 - put_short(s, s->bi_buf);
47.211 - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
47.212 - s->bi_valid += length - Buf_size;
47.213 - } else {
47.214 - s->bi_buf |= value << s->bi_valid;
47.215 - s->bi_valid += length;
47.216 - }
47.217 -}
47.218 -#else /* !DEBUG */
47.219 -
47.220 -#define send_bits(s, value, length) \
47.221 -{ int len = length;\
47.222 - if (s->bi_valid > (int)Buf_size - len) {\
47.223 - int val = value;\
47.224 - s->bi_buf |= (val << s->bi_valid);\
47.225 - put_short(s, s->bi_buf);\
47.226 - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
47.227 - s->bi_valid += len - Buf_size;\
47.228 - } else {\
47.229 - s->bi_buf |= (value) << s->bi_valid;\
47.230 - s->bi_valid += len;\
47.231 - }\
47.232 -}
47.233 -#endif /* DEBUG */
47.234 -
47.235 -
47.236 -/* the arguments must not have side effects */
47.237 -
47.238 -/* ===========================================================================
47.239 - * Initialize the various 'constant' tables.
47.240 - */
47.241 -local void tr_static_init()
47.242 -{
47.243 -#if defined(GEN_TREES_H) || !defined(STDC)
47.244 - static int static_init_done = 0;
47.245 - int n; /* iterates over tree elements */
47.246 - int bits; /* bit counter */
47.247 - int length; /* length value */
47.248 - int code; /* code value */
47.249 - int dist; /* distance index */
47.250 - ush bl_count[MAX_BITS+1];
47.251 - /* number of codes at each bit length for an optimal tree */
47.252 -
47.253 - if (static_init_done) return;
47.254 -
47.255 - /* For some embedded targets, global variables are not initialized: */
47.256 - static_l_desc.static_tree = static_ltree;
47.257 - static_l_desc.extra_bits = extra_lbits;
47.258 - static_d_desc.static_tree = static_dtree;
47.259 - static_d_desc.extra_bits = extra_dbits;
47.260 - static_bl_desc.extra_bits = extra_blbits;
47.261 -
47.262 - /* Initialize the mapping length (0..255) -> length code (0..28) */
47.263 - length = 0;
47.264 - for (code = 0; code < LENGTH_CODES-1; code++) {
47.265 - base_length[code] = length;
47.266 - for (n = 0; n < (1<<extra_lbits[code]); n++) {
47.267 - _length_code[length++] = (uch)code;
47.268 - }
47.269 - }
47.270 - Assert (length == 256, "tr_static_init: length != 256");
47.271 - /* Note that the length 255 (match length 258) can be represented
47.272 - * in two different ways: code 284 + 5 bits or code 285, so we
47.273 - * overwrite length_code[255] to use the best encoding:
47.274 - */
47.275 - _length_code[length-1] = (uch)code;
47.276 -
47.277 - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
47.278 - dist = 0;
47.279 - for (code = 0 ; code < 16; code++) {
47.280 - base_dist[code] = dist;
47.281 - for (n = 0; n < (1<<extra_dbits[code]); n++) {
47.282 - _dist_code[dist++] = (uch)code;
47.283 - }
47.284 - }
47.285 - Assert (dist == 256, "tr_static_init: dist != 256");
47.286 - dist >>= 7; /* from now on, all distances are divided by 128 */
47.287 - for ( ; code < D_CODES; code++) {
47.288 - base_dist[code] = dist << 7;
47.289 - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
47.290 - _dist_code[256 + dist++] = (uch)code;
47.291 - }
47.292 - }
47.293 - Assert (dist == 256, "tr_static_init: 256+dist != 512");
47.294 -
47.295 - /* Construct the codes of the static literal tree */
47.296 - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
47.297 - n = 0;
47.298 - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
47.299 - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
47.300 - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
47.301 - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
47.302 - /* Codes 286 and 287 do not exist, but we must include them in the
47.303 - * tree construction to get a canonical Huffman tree (longest code
47.304 - * all ones)
47.305 - */
47.306 - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
47.307 -
47.308 - /* The static distance tree is trivial: */
47.309 - for (n = 0; n < D_CODES; n++) {
47.310 - static_dtree[n].Len = 5;
47.311 - static_dtree[n].Code = bi_reverse((unsigned)n, 5);
47.312 - }
47.313 - static_init_done = 1;
47.314 -
47.315 -# ifdef GEN_TREES_H
47.316 - gen_trees_header();
47.317 -# endif
47.318 -#endif /* defined(GEN_TREES_H) || !defined(STDC) */
47.319 -}
47.320 -
47.321 -/* ===========================================================================
47.322 - * Genererate the file trees.h describing the static trees.
47.323 - */
47.324 -#ifdef GEN_TREES_H
47.325 -# ifndef DEBUG
47.326 -# include <stdio.h>
47.327 -# endif
47.328 -
47.329 -# define SEPARATOR(i, last, width) \
47.330 - ((i) == (last)? "\n};\n\n" : \
47.331 - ((i) % (width) == (width)-1 ? ",\n" : ", "))
47.332 -
47.333 -void gen_trees_header()
47.334 -{
47.335 - FILE *header = fopen("trees.h", "w");
47.336 - int i;
47.337 -
47.338 - Assert (header != NULL, "Can't open trees.h");
47.339 - fprintf(header,
47.340 - "/* header created automatically with -DGEN_TREES_H */\n\n");
47.341 -
47.342 - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
47.343 - for (i = 0; i < L_CODES+2; i++) {
47.344 - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
47.345 - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
47.346 - }
47.347 -
47.348 - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
47.349 - for (i = 0; i < D_CODES; i++) {
47.350 - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
47.351 - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
47.352 - }
47.353 -
47.354 - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
47.355 - for (i = 0; i < DIST_CODE_LEN; i++) {
47.356 - fprintf(header, "%2u%s", _dist_code[i],
47.357 - SEPARATOR(i, DIST_CODE_LEN-1, 20));
47.358 - }
47.359 -
47.360 - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
47.361 - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
47.362 - fprintf(header, "%2u%s", _length_code[i],
47.363 - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
47.364 - }
47.365 -
47.366 - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
47.367 - for (i = 0; i < LENGTH_CODES; i++) {
47.368 - fprintf(header, "%1u%s", base_length[i],
47.369 - SEPARATOR(i, LENGTH_CODES-1, 20));
47.370 - }
47.371 -
47.372 - fprintf(header, "local const int base_dist[D_CODES] = {\n");
47.373 - for (i = 0; i < D_CODES; i++) {
47.374 - fprintf(header, "%5u%s", base_dist[i],
47.375 - SEPARATOR(i, D_CODES-1, 10));
47.376 - }
47.377 -
47.378 - fclose(header);
47.379 -}
47.380 -#endif /* GEN_TREES_H */
47.381 -
47.382 -/* ===========================================================================
47.383 - * Initialize the tree data structures for a new zlib stream.
47.384 - */
47.385 -void _tr_init(s)
47.386 - deflate_state *s;
47.387 -{
47.388 - tr_static_init();
47.389 -
47.390 - s->l_desc.dyn_tree = s->dyn_ltree;
47.391 - s->l_desc.stat_desc = &static_l_desc;
47.392 -
47.393 - s->d_desc.dyn_tree = s->dyn_dtree;
47.394 - s->d_desc.stat_desc = &static_d_desc;
47.395 -
47.396 - s->bl_desc.dyn_tree = s->bl_tree;
47.397 - s->bl_desc.stat_desc = &static_bl_desc;
47.398 -
47.399 - s->bi_buf = 0;
47.400 - s->bi_valid = 0;
47.401 - s->last_eob_len = 8; /* enough lookahead for inflate */
47.402 -#ifdef DEBUG
47.403 - s->compressed_len = 0L;
47.404 - s->bits_sent = 0L;
47.405 -#endif
47.406 -
47.407 - /* Initialize the first block of the first file: */
47.408 - init_block(s);
47.409 -}
47.410 -
47.411 -/* ===========================================================================
47.412 - * Initialize a new block.
47.413 - */
47.414 -local void init_block(s)
47.415 - deflate_state *s;
47.416 -{
47.417 - int n; /* iterates over tree elements */
47.418 -
47.419 - /* Initialize the trees. */
47.420 - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
47.421 - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
47.422 - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
47.423 -
47.424 - s->dyn_ltree[END_BLOCK].Freq = 1;
47.425 - s->opt_len = s->static_len = 0L;
47.426 - s->last_lit = s->matches = 0;
47.427 -}
47.428 -
47.429 -#define SMALLEST 1
47.430 -/* Index within the heap array of least frequent node in the Huffman tree */
47.431 -
47.432 -
47.433 -/* ===========================================================================
47.434 - * Remove the smallest element from the heap and recreate the heap with
47.435 - * one less element. Updates heap and heap_len.
47.436 - */
47.437 -#define pqremove(s, tree, top) \
47.438 -{\
47.439 - top = s->heap[SMALLEST]; \
47.440 - s->heap[SMALLEST] = s->heap[s->heap_len--]; \
47.441 - pqdownheap(s, tree, SMALLEST); \
47.442 -}
47.443 -
47.444 -/* ===========================================================================
47.445 - * Compares to subtrees, using the tree depth as tie breaker when
47.446 - * the subtrees have equal frequency. This minimizes the worst case length.
47.447 - */
47.448 -#define smaller(tree, n, m, depth) \
47.449 - (tree[n].Freq < tree[m].Freq || \
47.450 - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
47.451 -
47.452 -/* ===========================================================================
47.453 - * Restore the heap property by moving down the tree starting at node k,
47.454 - * exchanging a node with the smallest of its two sons if necessary, stopping
47.455 - * when the heap property is re-established (each father smaller than its
47.456 - * two sons).
47.457 - */
47.458 -local void pqdownheap(s, tree, k)
47.459 - deflate_state *s;
47.460 - ct_data *tree; /* the tree to restore */
47.461 - int k; /* node to move down */
47.462 -{
47.463 - int v = s->heap[k];
47.464 - int j = k << 1; /* left son of k */
47.465 - while (j <= s->heap_len) {
47.466 - /* Set j to the smallest of the two sons: */
47.467 - if (j < s->heap_len &&
47.468 - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
47.469 - j++;
47.470 - }
47.471 - /* Exit if v is smaller than both sons */
47.472 - if (smaller(tree, v, s->heap[j], s->depth)) break;
47.473 -
47.474 - /* Exchange v with the smallest son */
47.475 - s->heap[k] = s->heap[j]; k = j;
47.476 -
47.477 - /* And continue down the tree, setting j to the left son of k */
47.478 - j <<= 1;
47.479 - }
47.480 - s->heap[k] = v;
47.481 -}
47.482 -
47.483 -/* ===========================================================================
47.484 - * Compute the optimal bit lengths for a tree and update the total bit length
47.485 - * for the current block.
47.486 - * IN assertion: the fields freq and dad are set, heap[heap_max] and
47.487 - * above are the tree nodes sorted by increasing frequency.
47.488 - * OUT assertions: the field len is set to the optimal bit length, the
47.489 - * array bl_count contains the frequencies for each bit length.
47.490 - * The length opt_len is updated; static_len is also updated if stree is
47.491 - * not null.
47.492 - */
47.493 -local void gen_bitlen(s, desc)
47.494 - deflate_state *s;
47.495 - tree_desc *desc; /* the tree descriptor */
47.496 -{
47.497 - ct_data *tree = desc->dyn_tree;
47.498 - int max_code = desc->max_code;
47.499 - const ct_data *stree = desc->stat_desc->static_tree;
47.500 - const intf *extra = desc->stat_desc->extra_bits;
47.501 - int base = desc->stat_desc->extra_base;
47.502 - int max_length = desc->stat_desc->max_length;
47.503 - int h; /* heap index */
47.504 - int n, m; /* iterate over the tree elements */
47.505 - int bits; /* bit length */
47.506 - int xbits; /* extra bits */
47.507 - ush f; /* frequency */
47.508 - int overflow = 0; /* number of elements with bit length too large */
47.509 -
47.510 - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
47.511 -
47.512 - /* In a first pass, compute the optimal bit lengths (which may
47.513 - * overflow in the case of the bit length tree).
47.514 - */
47.515 - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
47.516 -
47.517 - for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
47.518 - n = s->heap[h];
47.519 - bits = tree[tree[n].Dad].Len + 1;
47.520 - if (bits > max_length) bits = max_length, overflow++;
47.521 - tree[n].Len = (ush)bits;
47.522 - /* We overwrite tree[n].Dad which is no longer needed */
47.523 -
47.524 - if (n > max_code) continue; /* not a leaf node */
47.525 -
47.526 - s->bl_count[bits]++;
47.527 - xbits = 0;
47.528 - if (n >= base) xbits = extra[n-base];
47.529 - f = tree[n].Freq;
47.530 - s->opt_len += (ulg)f * (bits + xbits);
47.531 - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
47.532 - }
47.533 - if (overflow == 0) return;
47.534 -
47.535 - Trace((stderr,"\nbit length overflow\n"));
47.536 - /* This happens for example on obj2 and pic of the Calgary corpus */
47.537 -
47.538 - /* Find the first bit length which could increase: */
47.539 - do {
47.540 - bits = max_length-1;
47.541 - while (s->bl_count[bits] == 0) bits--;
47.542 - s->bl_count[bits]--; /* move one leaf down the tree */
47.543 - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
47.544 - s->bl_count[max_length]--;
47.545 - /* The brother of the overflow item also moves one step up,
47.546 - * but this does not affect bl_count[max_length]
47.547 - */
47.548 - overflow -= 2;
47.549 - } while (overflow > 0);
47.550 -
47.551 - /* Now recompute all bit lengths, scanning in increasing frequency.
47.552 - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
47.553 - * lengths instead of fixing only the wrong ones. This idea is taken
47.554 - * from 'ar' written by Haruhiko Okumura.)
47.555 - */
47.556 - for (bits = max_length; bits != 0; bits--) {
47.557 - n = s->bl_count[bits];
47.558 - while (n != 0) {
47.559 - m = s->heap[--h];
47.560 - if (m > max_code) continue;
47.561 - if ((unsigned) tree[m].Len != (unsigned) bits) {
47.562 - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
47.563 - s->opt_len += ((long)bits - (long)tree[m].Len)
47.564 - *(long)tree[m].Freq;
47.565 - tree[m].Len = (ush)bits;
47.566 - }
47.567 - n--;
47.568 - }
47.569 - }
47.570 -}
47.571 -
47.572 -/* ===========================================================================
47.573 - * Generate the codes for a given tree and bit counts (which need not be
47.574 - * optimal).
47.575 - * IN assertion: the array bl_count contains the bit length statistics for
47.576 - * the given tree and the field len is set for all tree elements.
47.577 - * OUT assertion: the field code is set for all tree elements of non
47.578 - * zero code length.
47.579 - */
47.580 -local void gen_codes (tree, max_code, bl_count)
47.581 - ct_data *tree; /* the tree to decorate */
47.582 - int max_code; /* largest code with non zero frequency */
47.583 - ushf *bl_count; /* number of codes at each bit length */
47.584 -{
47.585 - ush next_code[MAX_BITS+1]; /* next code value for each bit length */
47.586 - ush code = 0; /* running code value */
47.587 - int bits; /* bit index */
47.588 - int n; /* code index */
47.589 -
47.590 - /* The distribution counts are first used to generate the code values
47.591 - * without bit reversal.
47.592 - */
47.593 - for (bits = 1; bits <= MAX_BITS; bits++) {
47.594 - next_code[bits] = code = (code + bl_count[bits-1]) << 1;
47.595 - }
47.596 - /* Check that the bit counts in bl_count are consistent. The last code
47.597 - * must be all ones.
47.598 - */
47.599 - Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
47.600 - "inconsistent bit counts");
47.601 - Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
47.602 -
47.603 - for (n = 0; n <= max_code; n++) {
47.604 - int len = tree[n].Len;
47.605 - if (len == 0) continue;
47.606 - /* Now reverse the bits */
47.607 - tree[n].Code = bi_reverse(next_code[len]++, len);
47.608 -
47.609 - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
47.610 - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
47.611 - }
47.612 -}
47.613 -
47.614 -/* ===========================================================================
47.615 - * Construct one Huffman tree and assigns the code bit strings and lengths.
47.616 - * Update the total bit length for the current block.
47.617 - * IN assertion: the field freq is set for all tree elements.
47.618 - * OUT assertions: the fields len and code are set to the optimal bit length
47.619 - * and corresponding code. The length opt_len is updated; static_len is
47.620 - * also updated if stree is not null. The field max_code is set.
47.621 - */
47.622 -local void build_tree(s, desc)
47.623 - deflate_state *s;
47.624 - tree_desc *desc; /* the tree descriptor */
47.625 -{
47.626 - ct_data *tree = desc->dyn_tree;
47.627 - const ct_data *stree = desc->stat_desc->static_tree;
47.628 - int elems = desc->stat_desc->elems;
47.629 - int n, m; /* iterate over heap elements */
47.630 - int max_code = -1; /* largest code with non zero frequency */
47.631 - int node; /* new node being created */
47.632 -
47.633 - /* Construct the initial heap, with least frequent element in
47.634 - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
47.635 - * heap[0] is not used.
47.636 - */
47.637 - s->heap_len = 0, s->heap_max = HEAP_SIZE;
47.638 -
47.639 - for (n = 0; n < elems; n++) {
47.640 - if (tree[n].Freq != 0) {
47.641 - s->heap[++(s->heap_len)] = max_code = n;
47.642 - s->depth[n] = 0;
47.643 - } else {
47.644 - tree[n].Len = 0;
47.645 - }
47.646 - }
47.647 -
47.648 - /* The pkzip format requires that at least one distance code exists,
47.649 - * and that at least one bit should be sent even if there is only one
47.650 - * possible code. So to avoid special checks later on we force at least
47.651 - * two codes of non zero frequency.
47.652 - */
47.653 - while (s->heap_len < 2) {
47.654 - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
47.655 - tree[node].Freq = 1;
47.656 - s->depth[node] = 0;
47.657 - s->opt_len--; if (stree) s->static_len -= stree[node].Len;
47.658 - /* node is 0 or 1 so it does not have extra bits */
47.659 - }
47.660 - desc->max_code = max_code;
47.661 -
47.662 - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
47.663 - * establish sub-heaps of increasing lengths:
47.664 - */
47.665 - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
47.666 -
47.667 - /* Construct the Huffman tree by repeatedly combining the least two
47.668 - * frequent nodes.
47.669 - */
47.670 - node = elems; /* next internal node of the tree */
47.671 - do {
47.672 - pqremove(s, tree, n); /* n = node of least frequency */
47.673 - m = s->heap[SMALLEST]; /* m = node of next least frequency */
47.674 -
47.675 - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
47.676 - s->heap[--(s->heap_max)] = m;
47.677 -
47.678 - /* Create a new node father of n and m */
47.679 - tree[node].Freq = tree[n].Freq + tree[m].Freq;
47.680 - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
47.681 - s->depth[n] : s->depth[m]) + 1);
47.682 - tree[n].Dad = tree[m].Dad = (ush)node;
47.683 -#ifdef DUMP_BL_TREE
47.684 - if (tree == s->bl_tree) {
47.685 - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
47.686 - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
47.687 - }
47.688 -#endif
47.689 - /* and insert the new node in the heap */
47.690 - s->heap[SMALLEST] = node++;
47.691 - pqdownheap(s, tree, SMALLEST);
47.692 -
47.693 - } while (s->heap_len >= 2);
47.694 -
47.695 - s->heap[--(s->heap_max)] = s->heap[SMALLEST];
47.696 -
47.697 - /* At this point, the fields freq and dad are set. We can now
47.698 - * generate the bit lengths.
47.699 - */
47.700 - gen_bitlen(s, (tree_desc *)desc);
47.701 -
47.702 - /* The field len is now set, we can generate the bit codes */
47.703 - gen_codes ((ct_data *)tree, max_code, s->bl_count);
47.704 -}
47.705 -
47.706 -/* ===========================================================================
47.707 - * Scan a literal or distance tree to determine the frequencies of the codes
47.708 - * in the bit length tree.
47.709 - */
47.710 -local void scan_tree (s, tree, max_code)
47.711 - deflate_state *s;
47.712 - ct_data *tree; /* the tree to be scanned */
47.713 - int max_code; /* and its largest code of non zero frequency */
47.714 -{
47.715 - int n; /* iterates over all tree elements */
47.716 - int prevlen = -1; /* last emitted length */
47.717 - int curlen; /* length of current code */
47.718 - int nextlen = tree[0].Len; /* length of next code */
47.719 - int count = 0; /* repeat count of the current code */
47.720 - int max_count = 7; /* max repeat count */
47.721 - int min_count = 4; /* min repeat count */
47.722 -
47.723 - if (nextlen == 0) max_count = 138, min_count = 3;
47.724 - tree[max_code+1].Len = (ush)0xffff; /* guard */
47.725 -
47.726 - for (n = 0; n <= max_code; n++) {
47.727 - curlen = nextlen; nextlen = tree[n+1].Len;
47.728 - if (++count < max_count && curlen == nextlen) {
47.729 - continue;
47.730 - } else if (count < min_count) {
47.731 - s->bl_tree[curlen].Freq += count;
47.732 - } else if (curlen != 0) {
47.733 - if (curlen != prevlen) s->bl_tree[curlen].Freq++;
47.734 - s->bl_tree[REP_3_6].Freq++;
47.735 - } else if (count <= 10) {
47.736 - s->bl_tree[REPZ_3_10].Freq++;
47.737 - } else {
47.738 - s->bl_tree[REPZ_11_138].Freq++;
47.739 - }
47.740 - count = 0; prevlen = curlen;
47.741 - if (nextlen == 0) {
47.742 - max_count = 138, min_count = 3;
47.743 - } else if (curlen == nextlen) {
47.744 - max_count = 6, min_count = 3;
47.745 - } else {
47.746 - max_count = 7, min_count = 4;
47.747 - }
47.748 - }
47.749 -}
47.750 -
47.751 -/* ===========================================================================
47.752 - * Send a literal or distance tree in compressed form, using the codes in
47.753 - * bl_tree.
47.754 - */
47.755 -local void send_tree (s, tree, max_code)
47.756 - deflate_state *s;
47.757 - ct_data *tree; /* the tree to be scanned */
47.758 - int max_code; /* and its largest code of non zero frequency */
47.759 -{
47.760 - int n; /* iterates over all tree elements */
47.761 - int prevlen = -1; /* last emitted length */
47.762 - int curlen; /* length of current code */
47.763 - int nextlen = tree[0].Len; /* length of next code */
47.764 - int count = 0; /* repeat count of the current code */
47.765 - int max_count = 7; /* max repeat count */
47.766 - int min_count = 4; /* min repeat count */
47.767 -
47.768 - /* tree[max_code+1].Len = -1; */ /* guard already set */
47.769 - if (nextlen == 0) max_count = 138, min_count = 3;
47.770 -
47.771 - for (n = 0; n <= max_code; n++) {
47.772 - curlen = nextlen; nextlen = tree[n+1].Len;
47.773 - if (++count < max_count && curlen == nextlen) {
47.774 - continue;
47.775 - } else if (count < min_count) {
47.776 - do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
47.777 -
47.778 - } else if (curlen != 0) {
47.779 - if (curlen != prevlen) {
47.780 - send_code(s, curlen, s->bl_tree); count--;
47.781 - }
47.782 - Assert(count >= 3 && count <= 6, " 3_6?");
47.783 - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
47.784 -
47.785 - } else if (count <= 10) {
47.786 - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
47.787 -
47.788 - } else {
47.789 - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
47.790 - }
47.791 - count = 0; prevlen = curlen;
47.792 - if (nextlen == 0) {
47.793 - max_count = 138, min_count = 3;
47.794 - } else if (curlen == nextlen) {
47.795 - max_count = 6, min_count = 3;
47.796 - } else {
47.797 - max_count = 7, min_count = 4;
47.798 - }
47.799 - }
47.800 -}
47.801 -
47.802 -/* ===========================================================================
47.803 - * Construct the Huffman tree for the bit lengths and return the index in
47.804 - * bl_order of the last bit length code to send.
47.805 - */
47.806 -local int build_bl_tree(s)
47.807 - deflate_state *s;
47.808 -{
47.809 - int max_blindex; /* index of last bit length code of non zero freq */
47.810 -
47.811 - /* Determine the bit length frequencies for literal and distance trees */
47.812 - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
47.813 - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
47.814 -
47.815 - /* Build the bit length tree: */
47.816 - build_tree(s, (tree_desc *)(&(s->bl_desc)));
47.817 - /* opt_len now includes the length of the tree representations, except
47.818 - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
47.819 - */
47.820 -
47.821 - /* Determine the number of bit length codes to send. The pkzip format
47.822 - * requires that at least 4 bit length codes be sent. (appnote.txt says
47.823 - * 3 but the actual value used is 4.)
47.824 - */
47.825 - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
47.826 - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
47.827 - }
47.828 - /* Update opt_len to include the bit length tree and counts */
47.829 - s->opt_len += 3*(max_blindex+1) + 5+5+4;
47.830 - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
47.831 - s->opt_len, s->static_len));
47.832 -
47.833 - return max_blindex;
47.834 -}
47.835 -
47.836 -/* ===========================================================================
47.837 - * Send the header for a block using dynamic Huffman trees: the counts, the
47.838 - * lengths of the bit length codes, the literal tree and the distance tree.
47.839 - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
47.840 - */
47.841 -local void send_all_trees(s, lcodes, dcodes, blcodes)
47.842 - deflate_state *s;
47.843 - int lcodes, dcodes, blcodes; /* number of codes for each tree */
47.844 -{
47.845 - int rank; /* index in bl_order */
47.846 -
47.847 - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
47.848 - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
47.849 - "too many codes");
47.850 - Tracev((stderr, "\nbl counts: "));
47.851 - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
47.852 - send_bits(s, dcodes-1, 5);
47.853 - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
47.854 - for (rank = 0; rank < blcodes; rank++) {
47.855 - Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
47.856 - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
47.857 - }
47.858 - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
47.859 -
47.860 - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
47.861 - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
47.862 -
47.863 - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
47.864 - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
47.865 -}
47.866 -
47.867 -/* ===========================================================================
47.868 - * Send a stored block
47.869 - */
47.870 -void _tr_stored_block(s, buf, stored_len, eof)
47.871 - deflate_state *s;
47.872 - charf *buf; /* input block */
47.873 - ulg stored_len; /* length of input block */
47.874 - int eof; /* true if this is the last block for a file */
47.875 -{
47.876 - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
47.877 -#ifdef DEBUG
47.878 - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
47.879 - s->compressed_len += (stored_len + 4) << 3;
47.880 -#endif
47.881 - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
47.882 -}
47.883 -
47.884 -/* ===========================================================================
47.885 - * Send one empty static block to give enough lookahead for inflate.
47.886 - * This takes 10 bits, of which 7 may remain in the bit buffer.
47.887 - * The current inflate code requires 9 bits of lookahead. If the
47.888 - * last two codes for the previous block (real code plus EOB) were coded
47.889 - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
47.890 - * the last real code. In this case we send two empty static blocks instead
47.891 - * of one. (There are no problems if the previous block is stored or fixed.)
47.892 - * To simplify the code, we assume the worst case of last real code encoded
47.893 - * on one bit only.
47.894 - */
47.895 -void _tr_align(s)
47.896 - deflate_state *s;
47.897 -{
47.898 - send_bits(s, STATIC_TREES<<1, 3);
47.899 - send_code(s, END_BLOCK, static_ltree);
47.900 -#ifdef DEBUG
47.901 - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
47.902 -#endif
47.903 - bi_flush(s);
47.904 - /* Of the 10 bits for the empty block, we have already sent
47.905 - * (10 - bi_valid) bits. The lookahead for the last real code (before
47.906 - * the EOB of the previous block) was thus at least one plus the length
47.907 - * of the EOB plus what we have just sent of the empty static block.
47.908 - */
47.909 - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
47.910 - send_bits(s, STATIC_TREES<<1, 3);
47.911 - send_code(s, END_BLOCK, static_ltree);
47.912 -#ifdef DEBUG
47.913 - s->compressed_len += 10L;
47.914 -#endif
47.915 - bi_flush(s);
47.916 - }
47.917 - s->last_eob_len = 7;
47.918 -}
47.919 -
47.920 -/* ===========================================================================
47.921 - * Determine the best encoding for the current block: dynamic trees, static
47.922 - * trees or store, and output the encoded block to the zip file.
47.923 - */
47.924 -void _tr_flush_block(s, buf, stored_len, eof)
47.925 - deflate_state *s;
47.926 - charf *buf; /* input block, or NULL if too old */
47.927 - ulg stored_len; /* length of input block */
47.928 - int eof; /* true if this is the last block for a file */
47.929 -{
47.930 - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
47.931 - int max_blindex = 0; /* index of last bit length code of non zero freq */
47.932 -
47.933 - /* Build the Huffman trees unless a stored block is forced */
47.934 - if (s->level > 0) {
47.935 -
47.936 - /* Check if the file is binary or text */
47.937 - if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
47.938 - set_data_type(s);
47.939 -
47.940 - /* Construct the literal and distance trees */
47.941 - build_tree(s, (tree_desc *)(&(s->l_desc)));
47.942 - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
47.943 - s->static_len));
47.944 -
47.945 - build_tree(s, (tree_desc *)(&(s->d_desc)));
47.946 - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
47.947 - s->static_len));
47.948 - /* At this point, opt_len and static_len are the total bit lengths of
47.949 - * the compressed block data, excluding the tree representations.
47.950 - */
47.951 -
47.952 - /* Build the bit length tree for the above two trees, and get the index
47.953 - * in bl_order of the last bit length code to send.
47.954 - */
47.955 - max_blindex = build_bl_tree(s);
47.956 -
47.957 - /* Determine the best encoding. Compute the block lengths in bytes. */
47.958 - opt_lenb = (s->opt_len+3+7)>>3;
47.959 - static_lenb = (s->static_len+3+7)>>3;
47.960 -
47.961 - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
47.962 - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
47.963 - s->last_lit));
47.964 -
47.965 - if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
47.966 -
47.967 - } else {
47.968 - Assert(buf != (char*)0, "lost buf");
47.969 - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
47.970 - }
47.971 -
47.972 -#ifdef FORCE_STORED
47.973 - if (buf != (char*)0) { /* force stored block */
47.974 -#else
47.975 - if (stored_len+4 <= opt_lenb && buf != (char*)0) {
47.976 - /* 4: two words for the lengths */
47.977 -#endif
47.978 - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
47.979 - * Otherwise we can't have processed more than WSIZE input bytes since
47.980 - * the last block flush, because compression would have been
47.981 - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
47.982 - * transform a block into a stored block.
47.983 - */
47.984 - _tr_stored_block(s, buf, stored_len, eof);
47.985 -
47.986 -#ifdef FORCE_STATIC
47.987 - } else if (static_lenb >= 0) { /* force static trees */
47.988 -#else
47.989 - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
47.990 -#endif
47.991 - send_bits(s, (STATIC_TREES<<1)+eof, 3);
47.992 - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
47.993 -#ifdef DEBUG
47.994 - s->compressed_len += 3 + s->static_len;
47.995 -#endif
47.996 - } else {
47.997 - send_bits(s, (DYN_TREES<<1)+eof, 3);
47.998 - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
47.999 - max_blindex+1);
47.1000 - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
47.1001 -#ifdef DEBUG
47.1002 - s->compressed_len += 3 + s->opt_len;
47.1003 -#endif
47.1004 - }
47.1005 - Assert (s->compressed_len == s->bits_sent, "bad compressed size");
47.1006 - /* The above check is made mod 2^32, for files larger than 512 MB
47.1007 - * and uLong implemented on 32 bits.
47.1008 - */
47.1009 - init_block(s);
47.1010 -
47.1011 - if (eof) {
47.1012 - bi_windup(s);
47.1013 -#ifdef DEBUG
47.1014 - s->compressed_len += 7; /* align on byte boundary */
47.1015 -#endif
47.1016 - }
47.1017 - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
47.1018 - s->compressed_len-7*eof));
47.1019 -}
47.1020 -
47.1021 -/* ===========================================================================
47.1022 - * Save the match info and tally the frequency counts. Return true if
47.1023 - * the current block must be flushed.
47.1024 - */
47.1025 -int _tr_tally (s, dist, lc)
47.1026 - deflate_state *s;
47.1027 - unsigned dist; /* distance of matched string */
47.1028 - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
47.1029 -{
47.1030 - s->d_buf[s->last_lit] = (ush)dist;
47.1031 - s->l_buf[s->last_lit++] = (uch)lc;
47.1032 - if (dist == 0) {
47.1033 - /* lc is the unmatched char */
47.1034 - s->dyn_ltree[lc].Freq++;
47.1035 - } else {
47.1036 - s->matches++;
47.1037 - /* Here, lc is the match length - MIN_MATCH */
47.1038 - dist--; /* dist = match distance - 1 */
47.1039 - Assert((ush)dist < (ush)MAX_DIST(s) &&
47.1040 - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
47.1041 - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
47.1042 -
47.1043 - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
47.1044 - s->dyn_dtree[d_code(dist)].Freq++;
47.1045 - }
47.1046 -
47.1047 -#ifdef TRUNCATE_BLOCK
47.1048 - /* Try to guess if it is profitable to stop the current block here */
47.1049 - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
47.1050 - /* Compute an upper bound for the compressed length */
47.1051 - ulg out_length = (ulg)s->last_lit*8L;
47.1052 - ulg in_length = (ulg)((long)s->strstart - s->block_start);
47.1053 - int dcode;
47.1054 - for (dcode = 0; dcode < D_CODES; dcode++) {
47.1055 - out_length += (ulg)s->dyn_dtree[dcode].Freq *
47.1056 - (5L+extra_dbits[dcode]);
47.1057 - }
47.1058 - out_length >>= 3;
47.1059 - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
47.1060 - s->last_lit, in_length, out_length,
47.1061 - 100L - out_length*100L/in_length));
47.1062 - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
47.1063 - }
47.1064 -#endif
47.1065 - return (s->last_lit == s->lit_bufsize-1);
47.1066 - /* We avoid equality with lit_bufsize because of wraparound at 64K
47.1067 - * on 16 bit machines and because stored blocks are restricted to
47.1068 - * 64K-1 bytes.
47.1069 - */
47.1070 -}
47.1071 -
47.1072 -/* ===========================================================================
47.1073 - * Send the block data compressed using the given Huffman trees
47.1074 - */
47.1075 -local void compress_block(s, ltree, dtree)
47.1076 - deflate_state *s;
47.1077 - ct_data *ltree; /* literal tree */
47.1078 - ct_data *dtree; /* distance tree */
47.1079 -{
47.1080 - unsigned dist; /* distance of matched string */
47.1081 - int lc; /* match length or unmatched char (if dist == 0) */
47.1082 - unsigned lx = 0; /* running index in l_buf */
47.1083 - unsigned code; /* the code to send */
47.1084 - int extra; /* number of extra bits to send */
47.1085 -
47.1086 - if (s->last_lit != 0) do {
47.1087 - dist = s->d_buf[lx];
47.1088 - lc = s->l_buf[lx++];
47.1089 - if (dist == 0) {
47.1090 - send_code(s, lc, ltree); /* send a literal byte */
47.1091 - Tracecv(isgraph(lc), (stderr," '%c' ", lc));
47.1092 - } else {
47.1093 - /* Here, lc is the match length - MIN_MATCH */
47.1094 - code = _length_code[lc];
47.1095 - send_code(s, code+LITERALS+1, ltree); /* send the length code */
47.1096 - extra = extra_lbits[code];
47.1097 - if (extra != 0) {
47.1098 - lc -= base_length[code];
47.1099 - send_bits(s, lc, extra); /* send the extra length bits */
47.1100 - }
47.1101 - dist--; /* dist is now the match distance - 1 */
47.1102 - code = d_code(dist);
47.1103 - Assert (code < D_CODES, "bad d_code");
47.1104 -
47.1105 - send_code(s, code, dtree); /* send the distance code */
47.1106 - extra = extra_dbits[code];
47.1107 - if (extra != 0) {
47.1108 - dist -= base_dist[code];
47.1109 - send_bits(s, dist, extra); /* send the extra distance bits */
47.1110 - }
47.1111 - } /* literal or match pair ? */
47.1112 -
47.1113 - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
47.1114 - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
47.1115 - "pendingBuf overflow");
47.1116 -
47.1117 - } while (lx < s->last_lit);
47.1118 -
47.1119 - send_code(s, END_BLOCK, ltree);
47.1120 - s->last_eob_len = ltree[END_BLOCK].Len;
47.1121 -}
47.1122 -
47.1123 -/* ===========================================================================
47.1124 - * Set the data type to BINARY or TEXT, using a crude approximation:
47.1125 - * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
47.1126 - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
47.1127 - * IN assertion: the fields Freq of dyn_ltree are set.
47.1128 - */
47.1129 -local void set_data_type(s)
47.1130 - deflate_state *s;
47.1131 -{
47.1132 - int n;
47.1133 -
47.1134 - for (n = 0; n < 9; n++)
47.1135 - if (s->dyn_ltree[n].Freq != 0)
47.1136 - break;
47.1137 - if (n == 9)
47.1138 - for (n = 14; n < 32; n++)
47.1139 - if (s->dyn_ltree[n].Freq != 0)
47.1140 - break;
47.1141 - s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
47.1142 -}
47.1143 -
47.1144 -/* ===========================================================================
47.1145 - * Reverse the first len bits of a code, using straightforward code (a faster
47.1146 - * method would use a table)
47.1147 - * IN assertion: 1 <= len <= 15
47.1148 - */
47.1149 -local unsigned bi_reverse(code, len)
47.1150 - unsigned code; /* the value to invert */
47.1151 - int len; /* its bit length */
47.1152 -{
47.1153 - register unsigned res = 0;
47.1154 - do {
47.1155 - res |= code & 1;
47.1156 - code >>= 1, res <<= 1;
47.1157 - } while (--len > 0);
47.1158 - return res >> 1;
47.1159 -}
47.1160 -
47.1161 -/* ===========================================================================
47.1162 - * Flush the bit buffer, keeping at most 7 bits in it.
47.1163 - */
47.1164 -local void bi_flush(s)
47.1165 - deflate_state *s;
47.1166 -{
47.1167 - if (s->bi_valid == 16) {
47.1168 - put_short(s, s->bi_buf);
47.1169 - s->bi_buf = 0;
47.1170 - s->bi_valid = 0;
47.1171 - } else if (s->bi_valid >= 8) {
47.1172 - put_byte(s, (Byte)s->bi_buf);
47.1173 - s->bi_buf >>= 8;
47.1174 - s->bi_valid -= 8;
47.1175 - }
47.1176 -}
47.1177 -
47.1178 -/* ===========================================================================
47.1179 - * Flush the bit buffer and align the output on a byte boundary
47.1180 - */
47.1181 -local void bi_windup(s)
47.1182 - deflate_state *s;
47.1183 -{
47.1184 - if (s->bi_valid > 8) {
47.1185 - put_short(s, s->bi_buf);
47.1186 - } else if (s->bi_valid > 0) {
47.1187 - put_byte(s, (Byte)s->bi_buf);
47.1188 - }
47.1189 - s->bi_buf = 0;
47.1190 - s->bi_valid = 0;
47.1191 -#ifdef DEBUG
47.1192 - s->bits_sent = (s->bits_sent+7) & ~7;
47.1193 -#endif
47.1194 -}
47.1195 -
47.1196 -/* ===========================================================================
47.1197 - * Copy a stored block, storing first the length and its
47.1198 - * one's complement if requested.
47.1199 - */
47.1200 -local void copy_block(s, buf, len, header)
47.1201 - deflate_state *s;
47.1202 - charf *buf; /* the input data */
47.1203 - unsigned len; /* its length */
47.1204 - int header; /* true if block header must be written */
47.1205 -{
47.1206 - bi_windup(s); /* align on byte boundary */
47.1207 - s->last_eob_len = 8; /* enough lookahead for inflate */
47.1208 -
47.1209 - if (header) {
47.1210 - put_short(s, (ush)len);
47.1211 - put_short(s, (ush)~len);
47.1212 -#ifdef DEBUG
47.1213 - s->bits_sent += 2*16;
47.1214 -#endif
47.1215 - }
47.1216 -#ifdef DEBUG
47.1217 - s->bits_sent += (ulg)len<<3;
47.1218 -#endif
47.1219 - while (len--) {
47.1220 - put_byte(s, *buf++);
47.1221 - }
47.1222 -}
48.1 --- a/compiler-init/zlib/trees.h Sat Jul 15 05:02:38 2006 +0000
48.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
48.3 @@ -1,128 +0,0 @@
48.4 -/* header created automatically with -DGEN_TREES_H */
48.5 -
48.6 -local const ct_data static_ltree[L_CODES+2] = {
48.7 -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
48.8 -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
48.9 -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
48.10 -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
48.11 -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
48.12 -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
48.13 -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
48.14 -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
48.15 -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
48.16 -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
48.17 -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
48.18 -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
48.19 -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
48.20 -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
48.21 -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
48.22 -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
48.23 -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
48.24 -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
48.25 -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
48.26 -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
48.27 -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
48.28 -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
48.29 -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
48.30 -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
48.31 -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
48.32 -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
48.33 -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
48.34 -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
48.35 -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
48.36 -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
48.37 -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
48.38 -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
48.39 -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
48.40 -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
48.41 -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
48.42 -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
48.43 -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
48.44 -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
48.45 -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
48.46 -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
48.47 -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
48.48 -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
48.49 -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
48.50 -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
48.51 -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
48.52 -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
48.53 -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
48.54 -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
48.55 -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
48.56 -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
48.57 -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
48.58 -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
48.59 -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
48.60 -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
48.61 -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
48.62 -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
48.63 -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
48.64 -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
48.65 -};
48.66 -
48.67 -local const ct_data static_dtree[D_CODES] = {
48.68 -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
48.69 -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
48.70 -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
48.71 -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
48.72 -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
48.73 -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
48.74 -};
48.75 -
48.76 -const uch _dist_code[DIST_CODE_LEN] = {
48.77 - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
48.78 - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
48.79 -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
48.80 -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
48.81 -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
48.82 -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
48.83 -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
48.84 -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
48.85 -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
48.86 -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
48.87 -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
48.88 -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
48.89 -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
48.90 -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
48.91 -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
48.92 -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
48.93 -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
48.94 -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
48.95 -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
48.96 -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
48.97 -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
48.98 -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
48.99 -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
48.100 -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
48.101 -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
48.102 -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
48.103 -};
48.104 -
48.105 -const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
48.106 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
48.107 -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
48.108 -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
48.109 -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
48.110 -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
48.111 -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
48.112 -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
48.113 -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
48.114 -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
48.115 -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
48.116 -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
48.117 -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
48.118 -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
48.119 -};
48.120 -
48.121 -local const int base_length[LENGTH_CODES] = {
48.122 -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
48.123 -64, 80, 96, 112, 128, 160, 192, 224, 0
48.124 -};
48.125 -
48.126 -local const int base_dist[D_CODES] = {
48.127 - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
48.128 - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
48.129 - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
48.130 -};
48.131 -
49.1 --- a/compiler-init/zlib/uncompr.c Sat Jul 15 05:02:38 2006 +0000
49.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
49.3 @@ -1,61 +0,0 @@
49.4 -/* uncompr.c -- decompress a memory buffer
49.5 - * Copyright (C) 1995-2003 Jean-loup Gailly.
49.6 - * For conditions of distribution and use, see copyright notice in zlib.h
49.7 - */
49.8 -
49.9 -/* @(#) $Id$ */
49.10 -
49.11 -#define ZLIB_INTERNAL
49.12 -#include "zlib.h"
49.13 -
49.14 -/* ===========================================================================
49.15 - Decompresses the source buffer into the destination buffer. sourceLen is
49.16 - the byte length of the source buffer. Upon entry, destLen is the total
49.17 - size of the destination buffer, which must be large enough to hold the
49.18 - entire uncompressed data. (The size of the uncompressed data must have
49.19 - been saved previously by the compressor and transmitted to the decompressor
49.20 - by some mechanism outside the scope of this compression library.)
49.21 - Upon exit, destLen is the actual size of the compressed buffer.
49.22 - This function can be used to decompress a whole file at once if the
49.23 - input file is mmap'ed.
49.24 -
49.25 - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
49.26 - enough memory, Z_BUF_ERROR if there was not enough room in the output
49.27 - buffer, or Z_DATA_ERROR if the input data was corrupted.
49.28 -*/
49.29 -int ZEXPORT uncompress (dest, destLen, source, sourceLen)
49.30 - Bytef *dest;
49.31 - uLongf *destLen;
49.32 - const Bytef *source;
49.33 - uLong sourceLen;
49.34 -{
49.35 - z_stream stream;
49.36 - int err;
49.37 -
49.38 - stream.next_in = (Bytef*)source;
49.39 - stream.avail_in = (uInt)sourceLen;
49.40 - /* Check for source > 64K on 16-bit machine: */
49.41 - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
49.42 -
49.43 - stream.next_out = dest;
49.44 - stream.avail_out = (uInt)*destLen;
49.45 - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
49.46 -
49.47 - stream.zalloc = (alloc_func)0;
49.48 - stream.zfree = (free_func)0;
49.49 -
49.50 - err = inflateInit(&stream);
49.51 - if (err != Z_OK) return err;
49.52 -
49.53 - err = inflate(&stream, Z_FINISH);
49.54 - if (err != Z_STREAM_END) {
49.55 - inflateEnd(&stream);
49.56 - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
49.57 - return Z_DATA_ERROR;
49.58 - return err;
49.59 - }
49.60 - *destLen = stream.total_out;
49.61 -
49.62 - err = inflateEnd(&stream);
49.63 - return err;
49.64 -}
50.1 --- a/compiler-init/zlib/zconf.h Sat Jul 15 05:02:38 2006 +0000
50.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
50.3 @@ -1,281 +0,0 @@
50.4 -/* zconf.h -- configuration of the zlib compression library
50.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
50.6 - * For conditions of distribution and use, see copyright notice in zlib.h
50.7 - */
50.8 -
50.9 -/* @(#) $Id$ */
50.10 -
50.11 -#ifndef ZCONF_H
50.12 -#define ZCONF_H
50.13 -
50.14 -#if defined(__MSDOS__) && !defined(MSDOS)
50.15 -# define MSDOS
50.16 -#endif
50.17 -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
50.18 -# define OS2
50.19 -#endif
50.20 -#if defined(_WINDOWS) && !defined(WINDOWS)
50.21 -# define WINDOWS
50.22 -#endif
50.23 -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
50.24 -# ifndef WIN32
50.25 -# define WIN32
50.26 -# endif
50.27 -#endif
50.28 -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
50.29 -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
50.30 -# ifndef SYS16BIT
50.31 -# define SYS16BIT
50.32 -# endif
50.33 -# endif
50.34 -#endif
50.35 -
50.36 -/*
50.37 - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
50.38 - * than 64k bytes at a time (needed on systems with 16-bit int).
50.39 - */
50.40 -#ifdef SYS16BIT
50.41 -# define MAXSEG_64K
50.42 -#endif
50.43 -#ifdef MSDOS
50.44 -# define UNALIGNED_OK
50.45 -#endif
50.46 -
50.47 -#ifdef __STDC_VERSION__
50.48 -# ifndef STDC
50.49 -# define STDC
50.50 -# endif
50.51 -# if __STDC_VERSION__ >= 199901L
50.52 -# ifndef STDC99
50.53 -# define STDC99
50.54 -# endif
50.55 -# endif
50.56 -#endif
50.57 -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
50.58 -# define STDC
50.59 -#endif
50.60 -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
50.61 -# define STDC
50.62 -#endif
50.63 -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
50.64 -# define STDC
50.65 -#endif
50.66 -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
50.67 -# define STDC
50.68 -#endif
50.69 -
50.70 -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
50.71 -# define STDC
50.72 -#endif
50.73 -
50.74 -#ifndef STDC
50.75 -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
50.76 -# define const /* note: need a more gentle solution here */
50.77 -# endif
50.78 -#endif
50.79 -
50.80 -/* Some Mac compilers merge all .h files incorrectly: */
50.81 -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
50.82 -# define NO_DUMMY_DECL
50.83 -#endif
50.84 -
50.85 -/* Maximum value for memLevel in deflateInit2 */
50.86 -#ifndef MAX_MEM_LEVEL
50.87 -# ifdef MAXSEG_64K
50.88 -# define MAX_MEM_LEVEL 8
50.89 -# else
50.90 -# define MAX_MEM_LEVEL 9
50.91 -# endif
50.92 -#endif
50.93 -
50.94 -/* Maximum value for windowBits in deflateInit2 and inflateInit2.
50.95 - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
50.96 - * created by gzip. (Files created by minigzip can still be extracted by
50.97 - * gzip.)
50.98 - */
50.99 -#ifndef MAX_WBITS
50.100 -# define MAX_WBITS 15 /* 32K LZ77 window */
50.101 -#endif
50.102 -
50.103 -/* The memory requirements for deflate are (in bytes):
50.104 - (1 << (windowBits+2)) + (1 << (memLevel+9))
50.105 - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
50.106 - plus a few kilobytes for small objects. For example, if you want to reduce
50.107 - the default memory requirements from 256K to 128K, compile with
50.108 - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
50.109 - Of course this will generally degrade compression (there's no free lunch).
50.110 -
50.111 - The memory requirements for inflate are (in bytes) 1 << windowBits
50.112 - that is, 32K for windowBits=15 (default value) plus a few kilobytes
50.113 - for small objects.
50.114 -*/
50.115 -
50.116 - /* Type declarations */
50.117 -
50.118 -#ifndef OF /* function prototypes */
50.119 -# ifdef STDC
50.120 -# define OF(args) args
50.121 -# else
50.122 -# define OF(args) ()
50.123 -# endif
50.124 -#endif
50.125 -
50.126 -/* The following definitions for FAR are needed only for MSDOS mixed
50.127 - * model programming (small or medium model with some far allocations).
50.128 - * This was tested only with MSC; for other MSDOS compilers you may have
50.129 - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
50.130 - * just define FAR to be empty.
50.131 - */
50.132 -#ifdef SYS16BIT
50.133 -# if defined(M_I86SM) || defined(M_I86MM)
50.134 - /* MSC small or medium model */
50.135 -# define SMALL_MEDIUM
50.136 -# ifdef _MSC_VER
50.137 -# define FAR _far
50.138 -# else
50.139 -# define FAR far
50.140 -# endif
50.141 -# endif
50.142 -# if (defined(__SMALL__) || defined(__MEDIUM__))
50.143 - /* Turbo C small or medium model */
50.144 -# define SMALL_MEDIUM
50.145 -# ifdef __BORLANDC__
50.146 -# define FAR _far
50.147 -# else
50.148 -# define FAR far
50.149 -# endif
50.150 -# endif
50.151 -#endif
50.152 -
50.153 -#if defined(WINDOWS) || defined(WIN32)
50.154 - /* If building or using zlib as a DLL, define ZLIB_DLL.
50.155 - * This is not mandatory, but it offers a little performance increase.
50.156 - */
50.157 -# ifdef ZLIB_DLL
50.158 -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
50.159 -# ifdef ZLIB_INTERNAL
50.160 -# define ZEXTERN extern __declspec(dllexport)
50.161 -# else
50.162 -# define ZEXTERN extern __declspec(dllimport)
50.163 -# endif
50.164 -# endif
50.165 -# endif /* ZLIB_DLL */
50.166 - /* If building or using zlib with the WINAPI/WINAPIV calling convention,
50.167 - * define ZLIB_WINAPI.
50.168 - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
50.169 - */
50.170 -# ifdef ZLIB_WINAPI
50.171 -# ifdef FAR
50.172 -# undef FAR
50.173 -# endif
50.174 -# include <windows.h>
50.175 - /* No need for _export, use ZLIB.DEF instead. */
50.176 - /* For complete Windows compatibility, use WINAPI, not __stdcall. */
50.177 -# define ZEXPORT WINAPI
50.178 -# ifdef WIN32
50.179 -# define ZEXPORTVA WINAPIV
50.180 -# else
50.181 -# define ZEXPORTVA FAR CDECL
50.182 -# endif
50.183 -# endif
50.184 -#endif
50.185 -
50.186 -#if defined (__BEOS__)
50.187 -# ifdef ZLIB_DLL
50.188 -# ifdef ZLIB_INTERNAL
50.189 -# define ZEXPORT __declspec(dllexport)
50.190 -# define ZEXPORTVA __declspec(dllexport)
50.191 -# else
50.192 -# define ZEXPORT __declspec(dllimport)
50.193 -# define ZEXPORTVA __declspec(dllimport)
50.194 -# endif
50.195 -# endif
50.196 -#endif
50.197 -
50.198 -#ifndef ZEXTERN
50.199 -# define ZEXTERN extern
50.200 -#endif
50.201 -#ifndef ZEXPORT
50.202 -# define ZEXPORT
50.203 -#endif
50.204 -#ifndef ZEXPORTVA
50.205 -# define ZEXPORTVA
50.206 -#endif
50.207 -
50.208 -#ifndef FAR
50.209 -# define FAR
50.210 -#endif
50.211 -
50.212 -#if !defined(__MACTYPES__)
50.213 -typedef unsigned char Byte; /* 8 bits */
50.214 -#endif
50.215 -typedef unsigned int uInt; /* 16 bits or more */
50.216 -typedef unsigned long uLong; /* 32 bits or more */
50.217 -
50.218 -#ifdef SMALL_MEDIUM
50.219 - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
50.220 -# define Bytef Byte FAR
50.221 -#else
50.222 - typedef Byte FAR Bytef;
50.223 -#endif
50.224 -typedef char FAR charf;
50.225 -typedef int FAR intf;
50.226 -typedef uInt FAR uIntf;
50.227 -typedef uLong FAR uLongf;
50.228 -
50.229 -#ifdef STDC
50.230 - typedef void const *voidpc;
50.231 - typedef void FAR *voidpf;
50.232 - typedef void *voidp;
50.233 -#else
50.234 - typedef Byte const *voidpc;
50.235 - typedef Byte FAR *voidpf;
50.236 - typedef Byte *voidp;
50.237 -#endif
50.238 -
50.239 -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
50.240 -# include <sys/types.h> /* for off_t */
50.241 -# include <unistd.h> /* for SEEK_* and off_t */
50.242 -# ifdef VMS
50.243 -# include <unixio.h> /* for off_t */
50.244 -# endif
50.245 -# define z_off_t off_t
50.246 -#endif
50.247 -#ifndef SEEK_SET
50.248 -# define SEEK_SET 0 /* Seek from beginning of file. */
50.249 -# define SEEK_CUR 1 /* Seek from current position. */
50.250 -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
50.251 -#endif
50.252 -#ifndef z_off_t
50.253 -# define z_off_t long
50.254 -#endif
50.255 -
50.256 -#if defined(__OS400__)
50.257 -# define NO_vsnprintf
50.258 -#endif
50.259 -
50.260 -#if defined(__MVS__)
50.261 -# define NO_vsnprintf
50.262 -# ifdef FAR
50.263 -# undef FAR
50.264 -# endif
50.265 -#endif
50.266 -
50.267 -/* MVS linker does not support external names larger than 8 bytes */
50.268 -#if defined(__MVS__)
50.269 -# pragma map(deflateInit_,"DEIN")
50.270 -# pragma map(deflateInit2_,"DEIN2")
50.271 -# pragma map(deflateEnd,"DEEND")
50.272 -# pragma map(deflateBound,"DEBND")
50.273 -# pragma map(inflateInit_,"ININ")
50.274 -# pragma map(inflateInit2_,"ININ2")
50.275 -# pragma map(inflateEnd,"INEND")
50.276 -# pragma map(inflateSync,"INSY")
50.277 -# pragma map(inflateSetDictionary,"INSEDI")
50.278 -# pragma map(compressBound,"CMBND")
50.279 -# pragma map(inflate_table,"INTABL")
50.280 -# pragma map(inflate_fast,"INFA")
50.281 -# pragma map(inflate_copyright,"INCOPY")
50.282 -#endif
50.283 -
50.284 -#endif /* ZCONF_H */
51.1 --- a/compiler-init/zlib/zlib.h Sat Jul 15 05:02:38 2006 +0000
51.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
51.3 @@ -1,1357 +0,0 @@
51.4 -/* zlib.h -- interface of the 'zlib' general purpose compression library
51.5 - version 1.2.3, July 18th, 2005
51.6 -
51.7 - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
51.8 -
51.9 - This software is provided 'as-is', without any express or implied
51.10 - warranty. In no event will the authors be held liable for any damages
51.11 - arising from the use of this software.
51.12 -
51.13 - Permission is granted to anyone to use this software for any purpose,
51.14 - including commercial applications, and to alter it and redistribute it
51.15 - freely, subject to the following restrictions:
51.16 -
51.17 - 1. The origin of this software must not be misrepresented; you must not
51.18 - claim that you wrote the original software. If you use this software
51.19 - in a product, an acknowledgment in the product documentation would be
51.20 - appreciated but is not required.
51.21 - 2. Altered source versions must be plainly marked as such, and must not be
51.22 - misrepresented as being the original software.
51.23 - 3. This notice may not be removed or altered from any source distribution.
51.24 -
51.25 - Jean-loup Gailly Mark Adler
51.26 - [email protected] [email protected]
51.27 -
51.28 -
51.29 - The data format used by the zlib library is described by RFCs (Request for
51.30 - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
51.31 - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
51.32 -*/
51.33 -
51.34 -#ifndef ZLIB_H
51.35 -#define ZLIB_H
51.36 -
51.37 -#include "zconf.h"
51.38 -
51.39 -#ifdef __cplusplus
51.40 -extern "C" {
51.41 -#endif
51.42 -
51.43 -#define ZLIB_VERSION "1.2.3"
51.44 -#define ZLIB_VERNUM 0x1230
51.45 -
51.46 -/*
51.47 - The 'zlib' compression library provides in-memory compression and
51.48 - decompression functions, including integrity checks of the uncompressed
51.49 - data. This version of the library supports only one compression method
51.50 - (deflation) but other algorithms will be added later and will have the same
51.51 - stream interface.
51.52 -
51.53 - Compression can be done in a single step if the buffers are large
51.54 - enough (for example if an input file is mmap'ed), or can be done by
51.55 - repeated calls of the compression function. In the latter case, the
51.56 - application must provide more input and/or consume the output
51.57 - (providing more output space) before each call.
51.58 -
51.59 - The compressed data format used by default by the in-memory functions is
51.60 - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
51.61 - around a deflate stream, which is itself documented in RFC 1951.
51.62 -
51.63 - The library also supports reading and writing files in gzip (.gz) format
51.64 - with an interface similar to that of stdio using the functions that start
51.65 - with "gz". The gzip format is different from the zlib format. gzip is a
51.66 - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
51.67 -
51.68 - This library can optionally read and write gzip streams in memory as well.
51.69 -
51.70 - The zlib format was designed to be compact and fast for use in memory
51.71 - and on communications channels. The gzip format was designed for single-
51.72 - file compression on file systems, has a larger header than zlib to maintain
51.73 - directory information, and uses a different, slower check method than zlib.
51.74 -
51.75 - The library does not install any signal handler. The decoder checks
51.76 - the consistency of the compressed data, so the library should never
51.77 - crash even in case of corrupted input.
51.78 -*/
51.79 -
51.80 -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
51.81 -typedef void (*free_func) OF((voidpf opaque, voidpf address));
51.82 -
51.83 -struct internal_state;
51.84 -
51.85 -typedef struct z_stream_s {
51.86 - Bytef *next_in; /* next input byte */
51.87 - uInt avail_in; /* number of bytes available at next_in */
51.88 - uLong total_in; /* total nb of input bytes read so far */
51.89 -
51.90 - Bytef *next_out; /* next output byte should be put there */
51.91 - uInt avail_out; /* remaining free space at next_out */
51.92 - uLong total_out; /* total nb of bytes output so far */
51.93 -
51.94 - char *msg; /* last error message, NULL if no error */
51.95 - struct internal_state FAR *state; /* not visible by applications */
51.96 -
51.97 - alloc_func zalloc; /* used to allocate the internal state */
51.98 - free_func zfree; /* used to free the internal state */
51.99 - voidpf opaque; /* private data object passed to zalloc and zfree */
51.100 -
51.101 - int data_type; /* best guess about the data type: binary or text */
51.102 - uLong adler; /* adler32 value of the uncompressed data */
51.103 - uLong reserved; /* reserved for future use */
51.104 -} z_stream;
51.105 -
51.106 -typedef z_stream FAR *z_streamp;
51.107 -
51.108 -/*
51.109 - gzip header information passed to and from zlib routines. See RFC 1952
51.110 - for more details on the meanings of these fields.
51.111 -*/
51.112 -typedef struct gz_header_s {
51.113 - int text; /* true if compressed data believed to be text */
51.114 - uLong time; /* modification time */
51.115 - int xflags; /* extra flags (not used when writing a gzip file) */
51.116 - int os; /* operating system */
51.117 - Bytef *extra; /* pointer to extra field or Z_NULL if none */
51.118 - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
51.119 - uInt extra_max; /* space at extra (only when reading header) */
51.120 - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
51.121 - uInt name_max; /* space at name (only when reading header) */
51.122 - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
51.123 - uInt comm_max; /* space at comment (only when reading header) */
51.124 - int hcrc; /* true if there was or will be a header crc */
51.125 - int done; /* true when done reading gzip header (not used
51.126 - when writing a gzip file) */
51.127 -} gz_header;
51.128 -
51.129 -typedef gz_header FAR *gz_headerp;
51.130 -
51.131 -/*
51.132 - The application must update next_in and avail_in when avail_in has
51.133 - dropped to zero. It must update next_out and avail_out when avail_out
51.134 - has dropped to zero. The application must initialize zalloc, zfree and
51.135 - opaque before calling the init function. All other fields are set by the
51.136 - compression library and must not be updated by the application.
51.137 -
51.138 - The opaque value provided by the application will be passed as the first
51.139 - parameter for calls of zalloc and zfree. This can be useful for custom
51.140 - memory management. The compression library attaches no meaning to the
51.141 - opaque value.
51.142 -
51.143 - zalloc must return Z_NULL if there is not enough memory for the object.
51.144 - If zlib is used in a multi-threaded application, zalloc and zfree must be
51.145 - thread safe.
51.146 -
51.147 - On 16-bit systems, the functions zalloc and zfree must be able to allocate
51.148 - exactly 65536 bytes, but will not be required to allocate more than this
51.149 - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
51.150 - pointers returned by zalloc for objects of exactly 65536 bytes *must*
51.151 - have their offset normalized to zero. The default allocation function
51.152 - provided by this library ensures this (see zutil.c). To reduce memory
51.153 - requirements and avoid any allocation of 64K objects, at the expense of
51.154 - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
51.155 -
51.156 - The fields total_in and total_out can be used for statistics or
51.157 - progress reports. After compression, total_in holds the total size of
51.158 - the uncompressed data and may be saved for use in the decompressor
51.159 - (particularly if the decompressor wants to decompress everything in
51.160 - a single step).
51.161 -*/
51.162 -
51.163 - /* constants */
51.164 -
51.165 -#define Z_NO_FLUSH 0
51.166 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
51.167 -#define Z_SYNC_FLUSH 2
51.168 -#define Z_FULL_FLUSH 3
51.169 -#define Z_FINISH 4
51.170 -#define Z_BLOCK 5
51.171 -/* Allowed flush values; see deflate() and inflate() below for details */
51.172 -
51.173 -#define Z_OK 0
51.174 -#define Z_STREAM_END 1
51.175 -#define Z_NEED_DICT 2
51.176 -#define Z_ERRNO (-1)
51.177 -#define Z_STREAM_ERROR (-2)
51.178 -#define Z_DATA_ERROR (-3)
51.179 -#define Z_MEM_ERROR (-4)
51.180 -#define Z_BUF_ERROR (-5)
51.181 -#define Z_VERSION_ERROR (-6)
51.182 -/* Return codes for the compression/decompression functions. Negative
51.183 - * values are errors, positive values are used for special but normal events.
51.184 - */
51.185 -
51.186 -#define Z_NO_COMPRESSION 0
51.187 -#define Z_BEST_SPEED 1
51.188 -#define Z_BEST_COMPRESSION 9
51.189 -#define Z_DEFAULT_COMPRESSION (-1)
51.190 -/* compression levels */
51.191 -
51.192 -#define Z_FILTERED 1
51.193 -#define Z_HUFFMAN_ONLY 2
51.194 -#define Z_RLE 3
51.195 -#define Z_FIXED 4
51.196 -#define Z_DEFAULT_STRATEGY 0
51.197 -/* compression strategy; see deflateInit2() below for details */
51.198 -
51.199 -#define Z_BINARY 0
51.200 -#define Z_TEXT 1
51.201 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
51.202 -#define Z_UNKNOWN 2
51.203 -/* Possible values of the data_type field (though see inflate()) */
51.204 -
51.205 -#define Z_DEFLATED 8
51.206 -/* The deflate compression method (the only one supported in this version) */
51.207 -
51.208 -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
51.209 -
51.210 -#define zlib_version zlibVersion()
51.211 -/* for compatibility with versions < 1.0.2 */
51.212 -
51.213 - /* basic functions */
51.214 -
51.215 -ZEXTERN const char * ZEXPORT zlibVersion OF((void));
51.216 -/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
51.217 - If the first character differs, the library code actually used is
51.218 - not compatible with the zlib.h header file used by the application.
51.219 - This check is automatically made by deflateInit and inflateInit.
51.220 - */
51.221 -
51.222 -/*
51.223 -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
51.224 -
51.225 - Initializes the internal stream state for compression. The fields
51.226 - zalloc, zfree and opaque must be initialized before by the caller.
51.227 - If zalloc and zfree are set to Z_NULL, deflateInit updates them to
51.228 - use default allocation functions.
51.229 -
51.230 - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
51.231 - 1 gives best speed, 9 gives best compression, 0 gives no compression at
51.232 - all (the input data is simply copied a block at a time).
51.233 - Z_DEFAULT_COMPRESSION requests a default compromise between speed and
51.234 - compression (currently equivalent to level 6).
51.235 -
51.236 - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
51.237 - enough memory, Z_STREAM_ERROR if level is not a valid compression level,
51.238 - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
51.239 - with the version assumed by the caller (ZLIB_VERSION).
51.240 - msg is set to null if there is no error message. deflateInit does not
51.241 - perform any compression: this will be done by deflate().
51.242 -*/
51.243 -
51.244 -
51.245 -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
51.246 -/*
51.247 - deflate compresses as much data as possible, and stops when the input
51.248 - buffer becomes empty or the output buffer becomes full. It may introduce some
51.249 - output latency (reading input without producing any output) except when
51.250 - forced to flush.
51.251 -
51.252 - The detailed semantics are as follows. deflate performs one or both of the
51.253 - following actions:
51.254 -
51.255 - - Compress more input starting at next_in and update next_in and avail_in
51.256 - accordingly. If not all input can be processed (because there is not
51.257 - enough room in the output buffer), next_in and avail_in are updated and
51.258 - processing will resume at this point for the next call of deflate().
51.259 -
51.260 - - Provide more output starting at next_out and update next_out and avail_out
51.261 - accordingly. This action is forced if the parameter flush is non zero.
51.262 - Forcing flush frequently degrades the compression ratio, so this parameter
51.263 - should be set only when necessary (in interactive applications).
51.264 - Some output may be provided even if flush is not set.
51.265 -
51.266 - Before the call of deflate(), the application should ensure that at least
51.267 - one of the actions is possible, by providing more input and/or consuming
51.268 - more output, and updating avail_in or avail_out accordingly; avail_out
51.269 - should never be zero before the call. The application can consume the
51.270 - compressed output when it wants, for example when the output buffer is full
51.271 - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
51.272 - and with zero avail_out, it must be called again after making room in the
51.273 - output buffer because there might be more output pending.
51.274 -
51.275 - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
51.276 - decide how much data to accumualte before producing output, in order to
51.277 - maximize compression.
51.278 -
51.279 - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
51.280 - flushed to the output buffer and the output is aligned on a byte boundary, so
51.281 - that the decompressor can get all input data available so far. (In particular
51.282 - avail_in is zero after the call if enough output space has been provided
51.283 - before the call.) Flushing may degrade compression for some compression
51.284 - algorithms and so it should be used only when necessary.
51.285 -
51.286 - If flush is set to Z_FULL_FLUSH, all output is flushed as with
51.287 - Z_SYNC_FLUSH, and the compression state is reset so that decompression can
51.288 - restart from this point if previous compressed data has been damaged or if
51.289 - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
51.290 - compression.
51.291 -
51.292 - If deflate returns with avail_out == 0, this function must be called again
51.293 - with the same value of the flush parameter and more output space (updated
51.294 - avail_out), until the flush is complete (deflate returns with non-zero
51.295 - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
51.296 - avail_out is greater than six to avoid repeated flush markers due to
51.297 - avail_out == 0 on return.
51.298 -
51.299 - If the parameter flush is set to Z_FINISH, pending input is processed,
51.300 - pending output is flushed and deflate returns with Z_STREAM_END if there
51.301 - was enough output space; if deflate returns with Z_OK, this function must be
51.302 - called again with Z_FINISH and more output space (updated avail_out) but no
51.303 - more input data, until it returns with Z_STREAM_END or an error. After
51.304 - deflate has returned Z_STREAM_END, the only possible operations on the
51.305 - stream are deflateReset or deflateEnd.
51.306 -
51.307 - Z_FINISH can be used immediately after deflateInit if all the compression
51.308 - is to be done in a single step. In this case, avail_out must be at least
51.309 - the value returned by deflateBound (see below). If deflate does not return
51.310 - Z_STREAM_END, then it must be called again as described above.
51.311 -
51.312 - deflate() sets strm->adler to the adler32 checksum of all input read
51.313 - so far (that is, total_in bytes).
51.314 -
51.315 - deflate() may update strm->data_type if it can make a good guess about
51.316 - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
51.317 - binary. This field is only for information purposes and does not affect
51.318 - the compression algorithm in any manner.
51.319 -
51.320 - deflate() returns Z_OK if some progress has been made (more input
51.321 - processed or more output produced), Z_STREAM_END if all input has been
51.322 - consumed and all output has been produced (only when flush is set to
51.323 - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
51.324 - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
51.325 - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
51.326 - fatal, and deflate() can be called again with more input and more output
51.327 - space to continue compressing.
51.328 -*/
51.329 -
51.330 -
51.331 -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
51.332 -/*
51.333 - All dynamically allocated data structures for this stream are freed.
51.334 - This function discards any unprocessed input and does not flush any
51.335 - pending output.
51.336 -
51.337 - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
51.338 - stream state was inconsistent, Z_DATA_ERROR if the stream was freed
51.339 - prematurely (some input or output was discarded). In the error case,
51.340 - msg may be set but then points to a static string (which must not be
51.341 - deallocated).
51.342 -*/
51.343 -
51.344 -
51.345 -/*
51.346 -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
51.347 -
51.348 - Initializes the internal stream state for decompression. The fields
51.349 - next_in, avail_in, zalloc, zfree and opaque must be initialized before by
51.350 - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
51.351 - value depends on the compression method), inflateInit determines the
51.352 - compression method from the zlib header and allocates all data structures
51.353 - accordingly; otherwise the allocation will be deferred to the first call of
51.354 - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
51.355 - use default allocation functions.
51.356 -
51.357 - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
51.358 - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
51.359 - version assumed by the caller. msg is set to null if there is no error
51.360 - message. inflateInit does not perform any decompression apart from reading
51.361 - the zlib header if present: this will be done by inflate(). (So next_in and
51.362 - avail_in may be modified, but next_out and avail_out are unchanged.)
51.363 -*/
51.364 -
51.365 -
51.366 -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
51.367 -/*
51.368 - inflate decompresses as much data as possible, and stops when the input
51.369 - buffer becomes empty or the output buffer becomes full. It may introduce
51.370 - some output latency (reading input without producing any output) except when
51.371 - forced to flush.
51.372 -
51.373 - The detailed semantics are as follows. inflate performs one or both of the
51.374 - following actions:
51.375 -
51.376 - - Decompress more input starting at next_in and update next_in and avail_in
51.377 - accordingly. If not all input can be processed (because there is not
51.378 - enough room in the output buffer), next_in is updated and processing
51.379 - will resume at this point for the next call of inflate().
51.380 -
51.381 - - Provide more output starting at next_out and update next_out and avail_out
51.382 - accordingly. inflate() provides as much output as possible, until there
51.383 - is no more input data or no more space in the output buffer (see below
51.384 - about the flush parameter).
51.385 -
51.386 - Before the call of inflate(), the application should ensure that at least
51.387 - one of the actions is possible, by providing more input and/or consuming
51.388 - more output, and updating the next_* and avail_* values accordingly.
51.389 - The application can consume the uncompressed output when it wants, for
51.390 - example when the output buffer is full (avail_out == 0), or after each
51.391 - call of inflate(). If inflate returns Z_OK and with zero avail_out, it
51.392 - must be called again after making room in the output buffer because there
51.393 - might be more output pending.
51.394 -
51.395 - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
51.396 - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
51.397 - output as possible to the output buffer. Z_BLOCK requests that inflate() stop
51.398 - if and when it gets to the next deflate block boundary. When decoding the
51.399 - zlib or gzip format, this will cause inflate() to return immediately after
51.400 - the header and before the first block. When doing a raw inflate, inflate()
51.401 - will go ahead and process the first block, and will return when it gets to
51.402 - the end of that block, or when it runs out of data.
51.403 -
51.404 - The Z_BLOCK option assists in appending to or combining deflate streams.
51.405 - Also to assist in this, on return inflate() will set strm->data_type to the
51.406 - number of unused bits in the last byte taken from strm->next_in, plus 64
51.407 - if inflate() is currently decoding the last block in the deflate stream,
51.408 - plus 128 if inflate() returned immediately after decoding an end-of-block
51.409 - code or decoding the complete header up to just before the first byte of the
51.410 - deflate stream. The end-of-block will not be indicated until all of the
51.411 - uncompressed data from that block has been written to strm->next_out. The
51.412 - number of unused bits may in general be greater than seven, except when
51.413 - bit 7 of data_type is set, in which case the number of unused bits will be
51.414 - less than eight.
51.415 -
51.416 - inflate() should normally be called until it returns Z_STREAM_END or an
51.417 - error. However if all decompression is to be performed in a single step
51.418 - (a single call of inflate), the parameter flush should be set to
51.419 - Z_FINISH. In this case all pending input is processed and all pending
51.420 - output is flushed; avail_out must be large enough to hold all the
51.421 - uncompressed data. (The size of the uncompressed data may have been saved
51.422 - by the compressor for this purpose.) The next operation on this stream must
51.423 - be inflateEnd to deallocate the decompression state. The use of Z_FINISH
51.424 - is never required, but can be used to inform inflate that a faster approach
51.425 - may be used for the single inflate() call.
51.426 -
51.427 - In this implementation, inflate() always flushes as much output as
51.428 - possible to the output buffer, and always uses the faster approach on the
51.429 - first call. So the only effect of the flush parameter in this implementation
51.430 - is on the return value of inflate(), as noted below, or when it returns early
51.431 - because Z_BLOCK is used.
51.432 -
51.433 - If a preset dictionary is needed after this call (see inflateSetDictionary
51.434 - below), inflate sets strm->adler to the adler32 checksum of the dictionary
51.435 - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
51.436 - strm->adler to the adler32 checksum of all output produced so far (that is,
51.437 - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
51.438 - below. At the end of the stream, inflate() checks that its computed adler32
51.439 - checksum is equal to that saved by the compressor and returns Z_STREAM_END
51.440 - only if the checksum is correct.
51.441 -
51.442 - inflate() will decompress and check either zlib-wrapped or gzip-wrapped
51.443 - deflate data. The header type is detected automatically. Any information
51.444 - contained in the gzip header is not retained, so applications that need that
51.445 - information should instead use raw inflate, see inflateInit2() below, or
51.446 - inflateBack() and perform their own processing of the gzip header and
51.447 - trailer.
51.448 -
51.449 - inflate() returns Z_OK if some progress has been made (more input processed
51.450 - or more output produced), Z_STREAM_END if the end of the compressed data has
51.451 - been reached and all uncompressed output has been produced, Z_NEED_DICT if a
51.452 - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
51.453 - corrupted (input stream not conforming to the zlib format or incorrect check
51.454 - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
51.455 - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
51.456 - Z_BUF_ERROR if no progress is possible or if there was not enough room in the
51.457 - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
51.458 - inflate() can be called again with more input and more output space to
51.459 - continue decompressing. If Z_DATA_ERROR is returned, the application may then
51.460 - call inflateSync() to look for a good compression block if a partial recovery
51.461 - of the data is desired.
51.462 -*/
51.463 -
51.464 -
51.465 -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
51.466 -/*
51.467 - All dynamically allocated data structures for this stream are freed.
51.468 - This function discards any unprocessed input and does not flush any
51.469 - pending output.
51.470 -
51.471 - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
51.472 - was inconsistent. In the error case, msg may be set but then points to a
51.473 - static string (which must not be deallocated).
51.474 -*/
51.475 -
51.476 - /* Advanced functions */
51.477 -
51.478 -/*
51.479 - The following functions are needed only in some special applications.
51.480 -*/
51.481 -
51.482 -/*
51.483 -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
51.484 - int level,
51.485 - int method,
51.486 - int windowBits,
51.487 - int memLevel,
51.488 - int strategy));
51.489 -
51.490 - This is another version of deflateInit with more compression options. The
51.491 - fields next_in, zalloc, zfree and opaque must be initialized before by
51.492 - the caller.
51.493 -
51.494 - The method parameter is the compression method. It must be Z_DEFLATED in
51.495 - this version of the library.
51.496 -
51.497 - The windowBits parameter is the base two logarithm of the window size
51.498 - (the size of the history buffer). It should be in the range 8..15 for this
51.499 - version of the library. Larger values of this parameter result in better
51.500 - compression at the expense of memory usage. The default value is 15 if
51.501 - deflateInit is used instead.
51.502 -
51.503 - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
51.504 - determines the window size. deflate() will then generate raw deflate data
51.505 - with no zlib header or trailer, and will not compute an adler32 check value.
51.506 -
51.507 - windowBits can also be greater than 15 for optional gzip encoding. Add
51.508 - 16 to windowBits to write a simple gzip header and trailer around the
51.509 - compressed data instead of a zlib wrapper. The gzip header will have no
51.510 - file name, no extra data, no comment, no modification time (set to zero),
51.511 - no header crc, and the operating system will be set to 255 (unknown). If a
51.512 - gzip stream is being written, strm->adler is a crc32 instead of an adler32.
51.513 -
51.514 - The memLevel parameter specifies how much memory should be allocated
51.515 - for the internal compression state. memLevel=1 uses minimum memory but
51.516 - is slow and reduces compression ratio; memLevel=9 uses maximum memory
51.517 - for optimal speed. The default value is 8. See zconf.h for total memory
51.518 - usage as a function of windowBits and memLevel.
51.519 -
51.520 - The strategy parameter is used to tune the compression algorithm. Use the
51.521 - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
51.522 - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
51.523 - string match), or Z_RLE to limit match distances to one (run-length
51.524 - encoding). Filtered data consists mostly of small values with a somewhat
51.525 - random distribution. In this case, the compression algorithm is tuned to
51.526 - compress them better. The effect of Z_FILTERED is to force more Huffman
51.527 - coding and less string matching; it is somewhat intermediate between
51.528 - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
51.529 - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
51.530 - parameter only affects the compression ratio but not the correctness of the
51.531 - compressed output even if it is not set appropriately. Z_FIXED prevents the
51.532 - use of dynamic Huffman codes, allowing for a simpler decoder for special
51.533 - applications.
51.534 -
51.535 - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
51.536 - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
51.537 - method). msg is set to null if there is no error message. deflateInit2 does
51.538 - not perform any compression: this will be done by deflate().
51.539 -*/
51.540 -
51.541 -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
51.542 - const Bytef *dictionary,
51.543 - uInt dictLength));
51.544 -/*
51.545 - Initializes the compression dictionary from the given byte sequence
51.546 - without producing any compressed output. This function must be called
51.547 - immediately after deflateInit, deflateInit2 or deflateReset, before any
51.548 - call of deflate. The compressor and decompressor must use exactly the same
51.549 - dictionary (see inflateSetDictionary).
51.550 -
51.551 - The dictionary should consist of strings (byte sequences) that are likely
51.552 - to be encountered later in the data to be compressed, with the most commonly
51.553 - used strings preferably put towards the end of the dictionary. Using a
51.554 - dictionary is most useful when the data to be compressed is short and can be
51.555 - predicted with good accuracy; the data can then be compressed better than
51.556 - with the default empty dictionary.
51.557 -
51.558 - Depending on the size of the compression data structures selected by
51.559 - deflateInit or deflateInit2, a part of the dictionary may in effect be
51.560 - discarded, for example if the dictionary is larger than the window size in
51.561 - deflate or deflate2. Thus the strings most likely to be useful should be
51.562 - put at the end of the dictionary, not at the front. In addition, the
51.563 - current implementation of deflate will use at most the window size minus
51.564 - 262 bytes of the provided dictionary.
51.565 -
51.566 - Upon return of this function, strm->adler is set to the adler32 value
51.567 - of the dictionary; the decompressor may later use this value to determine
51.568 - which dictionary has been used by the compressor. (The adler32 value
51.569 - applies to the whole dictionary even if only a subset of the dictionary is
51.570 - actually used by the compressor.) If a raw deflate was requested, then the
51.571 - adler32 value is not computed and strm->adler is not set.
51.572 -
51.573 - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
51.574 - parameter is invalid (such as NULL dictionary) or the stream state is
51.575 - inconsistent (for example if deflate has already been called for this stream
51.576 - or if the compression method is bsort). deflateSetDictionary does not
51.577 - perform any compression: this will be done by deflate().
51.578 -*/
51.579 -
51.580 -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
51.581 - z_streamp source));
51.582 -/*
51.583 - Sets the destination stream as a complete copy of the source stream.
51.584 -
51.585 - This function can be useful when several compression strategies will be
51.586 - tried, for example when there are several ways of pre-processing the input
51.587 - data with a filter. The streams that will be discarded should then be freed
51.588 - by calling deflateEnd. Note that deflateCopy duplicates the internal
51.589 - compression state which can be quite large, so this strategy is slow and
51.590 - can consume lots of memory.
51.591 -
51.592 - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
51.593 - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
51.594 - (such as zalloc being NULL). msg is left unchanged in both source and
51.595 - destination.
51.596 -*/
51.597 -
51.598 -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
51.599 -/*
51.600 - This function is equivalent to deflateEnd followed by deflateInit,
51.601 - but does not free and reallocate all the internal compression state.
51.602 - The stream will keep the same compression level and any other attributes
51.603 - that may have been set by deflateInit2.
51.604 -
51.605 - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
51.606 - stream state was inconsistent (such as zalloc or state being NULL).
51.607 -*/
51.608 -
51.609 -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
51.610 - int level,
51.611 - int strategy));
51.612 -/*
51.613 - Dynamically update the compression level and compression strategy. The
51.614 - interpretation of level and strategy is as in deflateInit2. This can be
51.615 - used to switch between compression and straight copy of the input data, or
51.616 - to switch to a different kind of input data requiring a different
51.617 - strategy. If the compression level is changed, the input available so far
51.618 - is compressed with the old level (and may be flushed); the new level will
51.619 - take effect only at the next call of deflate().
51.620 -
51.621 - Before the call of deflateParams, the stream state must be set as for
51.622 - a call of deflate(), since the currently available input may have to
51.623 - be compressed and flushed. In particular, strm->avail_out must be non-zero.
51.624 -
51.625 - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
51.626 - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
51.627 - if strm->avail_out was zero.
51.628 -*/
51.629 -
51.630 -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
51.631 - int good_length,
51.632 - int max_lazy,
51.633 - int nice_length,
51.634 - int max_chain));
51.635 -/*
51.636 - Fine tune deflate's internal compression parameters. This should only be
51.637 - used by someone who understands the algorithm used by zlib's deflate for
51.638 - searching for the best matching string, and even then only by the most
51.639 - fanatic optimizer trying to squeeze out the last compressed bit for their
51.640 - specific input data. Read the deflate.c source code for the meaning of the
51.641 - max_lazy, good_length, nice_length, and max_chain parameters.
51.642 -
51.643 - deflateTune() can be called after deflateInit() or deflateInit2(), and
51.644 - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
51.645 - */
51.646 -
51.647 -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
51.648 - uLong sourceLen));
51.649 -/*
51.650 - deflateBound() returns an upper bound on the compressed size after
51.651 - deflation of sourceLen bytes. It must be called after deflateInit()
51.652 - or deflateInit2(). This would be used to allocate an output buffer
51.653 - for deflation in a single pass, and so would be called before deflate().
51.654 -*/
51.655 -
51.656 -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
51.657 - int bits,
51.658 - int value));
51.659 -/*
51.660 - deflatePrime() inserts bits in the deflate output stream. The intent
51.661 - is that this function is used to start off the deflate output with the
51.662 - bits leftover from a previous deflate stream when appending to it. As such,
51.663 - this function can only be used for raw deflate, and must be used before the
51.664 - first deflate() call after a deflateInit2() or deflateReset(). bits must be
51.665 - less than or equal to 16, and that many of the least significant bits of
51.666 - value will be inserted in the output.
51.667 -
51.668 - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
51.669 - stream state was inconsistent.
51.670 -*/
51.671 -
51.672 -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
51.673 - gz_headerp head));
51.674 -/*
51.675 - deflateSetHeader() provides gzip header information for when a gzip
51.676 - stream is requested by deflateInit2(). deflateSetHeader() may be called
51.677 - after deflateInit2() or deflateReset() and before the first call of
51.678 - deflate(). The text, time, os, extra field, name, and comment information
51.679 - in the provided gz_header structure are written to the gzip header (xflag is
51.680 - ignored -- the extra flags are set according to the compression level). The
51.681 - caller must assure that, if not Z_NULL, name and comment are terminated with
51.682 - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
51.683 - available there. If hcrc is true, a gzip header crc is included. Note that
51.684 - the current versions of the command-line version of gzip (up through version
51.685 - 1.3.x) do not support header crc's, and will report that it is a "multi-part
51.686 - gzip file" and give up.
51.687 -
51.688 - If deflateSetHeader is not used, the default gzip header has text false,
51.689 - the time set to zero, and os set to 255, with no extra, name, or comment
51.690 - fields. The gzip header is returned to the default state by deflateReset().
51.691 -
51.692 - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
51.693 - stream state was inconsistent.
51.694 -*/
51.695 -
51.696 -/*
51.697 -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
51.698 - int windowBits));
51.699 -
51.700 - This is another version of inflateInit with an extra parameter. The
51.701 - fields next_in, avail_in, zalloc, zfree and opaque must be initialized
51.702 - before by the caller.
51.703 -
51.704 - The windowBits parameter is the base two logarithm of the maximum window
51.705 - size (the size of the history buffer). It should be in the range 8..15 for
51.706 - this version of the library. The default value is 15 if inflateInit is used
51.707 - instead. windowBits must be greater than or equal to the windowBits value
51.708 - provided to deflateInit2() while compressing, or it must be equal to 15 if
51.709 - deflateInit2() was not used. If a compressed stream with a larger window
51.710 - size is given as input, inflate() will return with the error code
51.711 - Z_DATA_ERROR instead of trying to allocate a larger window.
51.712 -
51.713 - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
51.714 - determines the window size. inflate() will then process raw deflate data,
51.715 - not looking for a zlib or gzip header, not generating a check value, and not
51.716 - looking for any check values for comparison at the end of the stream. This
51.717 - is for use with other formats that use the deflate compressed data format
51.718 - such as zip. Those formats provide their own check values. If a custom
51.719 - format is developed using the raw deflate format for compressed data, it is
51.720 - recommended that a check value such as an adler32 or a crc32 be applied to
51.721 - the uncompressed data as is done in the zlib, gzip, and zip formats. For
51.722 - most applications, the zlib format should be used as is. Note that comments
51.723 - above on the use in deflateInit2() applies to the magnitude of windowBits.
51.724 -
51.725 - windowBits can also be greater than 15 for optional gzip decoding. Add
51.726 - 32 to windowBits to enable zlib and gzip decoding with automatic header
51.727 - detection, or add 16 to decode only the gzip format (the zlib format will
51.728 - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
51.729 - a crc32 instead of an adler32.
51.730 -
51.731 - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
51.732 - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
51.733 - is set to null if there is no error message. inflateInit2 does not perform
51.734 - any decompression apart from reading the zlib header if present: this will
51.735 - be done by inflate(). (So next_in and avail_in may be modified, but next_out
51.736 - and avail_out are unchanged.)
51.737 -*/
51.738 -
51.739 -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
51.740 - const Bytef *dictionary,
51.741 - uInt dictLength));
51.742 -/*
51.743 - Initializes the decompression dictionary from the given uncompressed byte
51.744 - sequence. This function must be called immediately after a call of inflate,
51.745 - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
51.746 - can be determined from the adler32 value returned by that call of inflate.
51.747 - The compressor and decompressor must use exactly the same dictionary (see
51.748 - deflateSetDictionary). For raw inflate, this function can be called
51.749 - immediately after inflateInit2() or inflateReset() and before any call of
51.750 - inflate() to set the dictionary. The application must insure that the
51.751 - dictionary that was used for compression is provided.
51.752 -
51.753 - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
51.754 - parameter is invalid (such as NULL dictionary) or the stream state is
51.755 - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
51.756 - expected one (incorrect adler32 value). inflateSetDictionary does not
51.757 - perform any decompression: this will be done by subsequent calls of
51.758 - inflate().
51.759 -*/
51.760 -
51.761 -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
51.762 -/*
51.763 - Skips invalid compressed data until a full flush point (see above the
51.764 - description of deflate with Z_FULL_FLUSH) can be found, or until all
51.765 - available input is skipped. No output is provided.
51.766 -
51.767 - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
51.768 - if no more input was provided, Z_DATA_ERROR if no flush point has been found,
51.769 - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
51.770 - case, the application may save the current current value of total_in which
51.771 - indicates where valid compressed data was found. In the error case, the
51.772 - application may repeatedly call inflateSync, providing more input each time,
51.773 - until success or end of the input data.
51.774 -*/
51.775 -
51.776 -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
51.777 - z_streamp source));
51.778 -/*
51.779 - Sets the destination stream as a complete copy of the source stream.
51.780 -
51.781 - This function can be useful when randomly accessing a large stream. The
51.782 - first pass through the stream can periodically record the inflate state,
51.783 - allowing restarting inflate at those points when randomly accessing the
51.784 - stream.
51.785 -
51.786 - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
51.787 - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
51.788 - (such as zalloc being NULL). msg is left unchanged in both source and
51.789 - destination.
51.790 -*/
51.791 -
51.792 -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
51.793 -/*
51.794 - This function is equivalent to inflateEnd followed by inflateInit,
51.795 - but does not free and reallocate all the internal decompression state.
51.796 - The stream will keep attributes that may have been set by inflateInit2.
51.797 -
51.798 - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
51.799 - stream state was inconsistent (such as zalloc or state being NULL).
51.800 -*/
51.801 -
51.802 -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
51.803 - int bits,
51.804 - int value));
51.805 -/*
51.806 - This function inserts bits in the inflate input stream. The intent is
51.807 - that this function is used to start inflating at a bit position in the
51.808 - middle of a byte. The provided bits will be used before any bytes are used
51.809 - from next_in. This function should only be used with raw inflate, and
51.810 - should be used before the first inflate() call after inflateInit2() or
51.811 - inflateReset(). bits must be less than or equal to 16, and that many of the
51.812 - least significant bits of value will be inserted in the input.
51.813 -
51.814 - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
51.815 - stream state was inconsistent.
51.816 -*/
51.817 -
51.818 -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
51.819 - gz_headerp head));
51.820 -/*
51.821 - inflateGetHeader() requests that gzip header information be stored in the
51.822 - provided gz_header structure. inflateGetHeader() may be called after
51.823 - inflateInit2() or inflateReset(), and before the first call of inflate().
51.824 - As inflate() processes the gzip stream, head->done is zero until the header
51.825 - is completed, at which time head->done is set to one. If a zlib stream is
51.826 - being decoded, then head->done is set to -1 to indicate that there will be
51.827 - no gzip header information forthcoming. Note that Z_BLOCK can be used to
51.828 - force inflate() to return immediately after header processing is complete
51.829 - and before any actual data is decompressed.
51.830 -
51.831 - The text, time, xflags, and os fields are filled in with the gzip header
51.832 - contents. hcrc is set to true if there is a header CRC. (The header CRC
51.833 - was valid if done is set to one.) If extra is not Z_NULL, then extra_max
51.834 - contains the maximum number of bytes to write to extra. Once done is true,
51.835 - extra_len contains the actual extra field length, and extra contains the
51.836 - extra field, or that field truncated if extra_max is less than extra_len.
51.837 - If name is not Z_NULL, then up to name_max characters are written there,
51.838 - terminated with a zero unless the length is greater than name_max. If
51.839 - comment is not Z_NULL, then up to comm_max characters are written there,
51.840 - terminated with a zero unless the length is greater than comm_max. When
51.841 - any of extra, name, or comment are not Z_NULL and the respective field is
51.842 - not present in the header, then that field is set to Z_NULL to signal its
51.843 - absence. This allows the use of deflateSetHeader() with the returned
51.844 - structure to duplicate the header. However if those fields are set to
51.845 - allocated memory, then the application will need to save those pointers
51.846 - elsewhere so that they can be eventually freed.
51.847 -
51.848 - If inflateGetHeader is not used, then the header information is simply
51.849 - discarded. The header is always checked for validity, including the header
51.850 - CRC if present. inflateReset() will reset the process to discard the header
51.851 - information. The application would need to call inflateGetHeader() again to
51.852 - retrieve the header from the next gzip stream.
51.853 -
51.854 - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
51.855 - stream state was inconsistent.
51.856 -*/
51.857 -
51.858 -/*
51.859 -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
51.860 - unsigned char FAR *window));
51.861 -
51.862 - Initialize the internal stream state for decompression using inflateBack()
51.863 - calls. The fields zalloc, zfree and opaque in strm must be initialized
51.864 - before the call. If zalloc and zfree are Z_NULL, then the default library-
51.865 - derived memory allocation routines are used. windowBits is the base two
51.866 - logarithm of the window size, in the range 8..15. window is a caller
51.867 - supplied buffer of that size. Except for special applications where it is
51.868 - assured that deflate was used with small window sizes, windowBits must be 15
51.869 - and a 32K byte window must be supplied to be able to decompress general
51.870 - deflate streams.
51.871 -
51.872 - See inflateBack() for the usage of these routines.
51.873 -
51.874 - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
51.875 - the paramaters are invalid, Z_MEM_ERROR if the internal state could not
51.876 - be allocated, or Z_VERSION_ERROR if the version of the library does not
51.877 - match the version of the header file.
51.878 -*/
51.879 -
51.880 -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
51.881 -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
51.882 -
51.883 -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
51.884 - in_func in, void FAR *in_desc,
51.885 - out_func out, void FAR *out_desc));
51.886 -/*
51.887 - inflateBack() does a raw inflate with a single call using a call-back
51.888 - interface for input and output. This is more efficient than inflate() for
51.889 - file i/o applications in that it avoids copying between the output and the
51.890 - sliding window by simply making the window itself the output buffer. This
51.891 - function trusts the application to not change the output buffer passed by
51.892 - the output function, at least until inflateBack() returns.
51.893 -
51.894 - inflateBackInit() must be called first to allocate the internal state
51.895 - and to initialize the state with the user-provided window buffer.
51.896 - inflateBack() may then be used multiple times to inflate a complete, raw
51.897 - deflate stream with each call. inflateBackEnd() is then called to free
51.898 - the allocated state.
51.899 -
51.900 - A raw deflate stream is one with no zlib or gzip header or trailer.
51.901 - This routine would normally be used in a utility that reads zip or gzip
51.902 - files and writes out uncompressed files. The utility would decode the
51.903 - header and process the trailer on its own, hence this routine expects
51.904 - only the raw deflate stream to decompress. This is different from the
51.905 - normal behavior of inflate(), which expects either a zlib or gzip header and
51.906 - trailer around the deflate stream.
51.907 -
51.908 - inflateBack() uses two subroutines supplied by the caller that are then
51.909 - called by inflateBack() for input and output. inflateBack() calls those
51.910 - routines until it reads a complete deflate stream and writes out all of the
51.911 - uncompressed data, or until it encounters an error. The function's
51.912 - parameters and return types are defined above in the in_func and out_func
51.913 - typedefs. inflateBack() will call in(in_desc, &buf) which should return the
51.914 - number of bytes of provided input, and a pointer to that input in buf. If
51.915 - there is no input available, in() must return zero--buf is ignored in that
51.916 - case--and inflateBack() will return a buffer error. inflateBack() will call
51.917 - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
51.918 - should return zero on success, or non-zero on failure. If out() returns
51.919 - non-zero, inflateBack() will return with an error. Neither in() nor out()
51.920 - are permitted to change the contents of the window provided to
51.921 - inflateBackInit(), which is also the buffer that out() uses to write from.
51.922 - The length written by out() will be at most the window size. Any non-zero
51.923 - amount of input may be provided by in().
51.924 -
51.925 - For convenience, inflateBack() can be provided input on the first call by
51.926 - setting strm->next_in and strm->avail_in. If that input is exhausted, then
51.927 - in() will be called. Therefore strm->next_in must be initialized before
51.928 - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
51.929 - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
51.930 - must also be initialized, and then if strm->avail_in is not zero, input will
51.931 - initially be taken from strm->next_in[0 .. strm->avail_in - 1].
51.932 -
51.933 - The in_desc and out_desc parameters of inflateBack() is passed as the
51.934 - first parameter of in() and out() respectively when they are called. These
51.935 - descriptors can be optionally used to pass any information that the caller-
51.936 - supplied in() and out() functions need to do their job.
51.937 -
51.938 - On return, inflateBack() will set strm->next_in and strm->avail_in to
51.939 - pass back any unused input that was provided by the last in() call. The
51.940 - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
51.941 - if in() or out() returned an error, Z_DATA_ERROR if there was a format
51.942 - error in the deflate stream (in which case strm->msg is set to indicate the
51.943 - nature of the error), or Z_STREAM_ERROR if the stream was not properly
51.944 - initialized. In the case of Z_BUF_ERROR, an input or output error can be
51.945 - distinguished using strm->next_in which will be Z_NULL only if in() returned
51.946 - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
51.947 - out() returning non-zero. (in() will always be called before out(), so
51.948 - strm->next_in is assured to be defined if out() returns non-zero.) Note
51.949 - that inflateBack() cannot return Z_OK.
51.950 -*/
51.951 -
51.952 -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
51.953 -/*
51.954 - All memory allocated by inflateBackInit() is freed.
51.955 -
51.956 - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
51.957 - state was inconsistent.
51.958 -*/
51.959 -
51.960 -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
51.961 -/* Return flags indicating compile-time options.
51.962 -
51.963 - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
51.964 - 1.0: size of uInt
51.965 - 3.2: size of uLong
51.966 - 5.4: size of voidpf (pointer)
51.967 - 7.6: size of z_off_t
51.968 -
51.969 - Compiler, assembler, and debug options:
51.970 - 8: DEBUG
51.971 - 9: ASMV or ASMINF -- use ASM code
51.972 - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
51.973 - 11: 0 (reserved)
51.974 -
51.975 - One-time table building (smaller code, but not thread-safe if true):
51.976 - 12: BUILDFIXED -- build static block decoding tables when needed
51.977 - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
51.978 - 14,15: 0 (reserved)
51.979 -
51.980 - Library content (indicates missing functionality):
51.981 - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
51.982 - deflate code when not needed)
51.983 - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
51.984 - and decode gzip streams (to avoid linking crc code)
51.985 - 18-19: 0 (reserved)
51.986 -
51.987 - Operation variations (changes in library functionality):
51.988 - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
51.989 - 21: FASTEST -- deflate algorithm with only one, lowest compression level
51.990 - 22,23: 0 (reserved)
51.991 -
51.992 - The sprintf variant used by gzprintf (zero is best):
51.993 - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
51.994 - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
51.995 - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
51.996 -
51.997 - Remainder:
51.998 - 27-31: 0 (reserved)
51.999 - */
51.1000 -
51.1001 -
51.1002 - /* utility functions */
51.1003 -
51.1004 -/*
51.1005 - The following utility functions are implemented on top of the
51.1006 - basic stream-oriented functions. To simplify the interface, some
51.1007 - default options are assumed (compression level and memory usage,
51.1008 - standard memory allocation functions). The source code of these
51.1009 - utility functions can easily be modified if you need special options.
51.1010 -*/
51.1011 -
51.1012 -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
51.1013 - const Bytef *source, uLong sourceLen));
51.1014 -/*
51.1015 - Compresses the source buffer into the destination buffer. sourceLen is
51.1016 - the byte length of the source buffer. Upon entry, destLen is the total
51.1017 - size of the destination buffer, which must be at least the value returned
51.1018 - by compressBound(sourceLen). Upon exit, destLen is the actual size of the
51.1019 - compressed buffer.
51.1020 - This function can be used to compress a whole file at once if the
51.1021 - input file is mmap'ed.
51.1022 - compress returns Z_OK if success, Z_MEM_ERROR if there was not
51.1023 - enough memory, Z_BUF_ERROR if there was not enough room in the output
51.1024 - buffer.
51.1025 -*/
51.1026 -
51.1027 -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
51.1028 - const Bytef *source, uLong sourceLen,
51.1029 - int level));
51.1030 -/*
51.1031 - Compresses the source buffer into the destination buffer. The level
51.1032 - parameter has the same meaning as in deflateInit. sourceLen is the byte
51.1033 - length of the source buffer. Upon entry, destLen is the total size of the
51.1034 - destination buffer, which must be at least the value returned by
51.1035 - compressBound(sourceLen). Upon exit, destLen is the actual size of the
51.1036 - compressed buffer.
51.1037 -
51.1038 - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
51.1039 - memory, Z_BUF_ERROR if there was not enough room in the output buffer,
51.1040 - Z_STREAM_ERROR if the level parameter is invalid.
51.1041 -*/
51.1042 -
51.1043 -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
51.1044 -/*
51.1045 - compressBound() returns an upper bound on the compressed size after
51.1046 - compress() or compress2() on sourceLen bytes. It would be used before
51.1047 - a compress() or compress2() call to allocate the destination buffer.
51.1048 -*/
51.1049 -
51.1050 -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
51.1051 - const Bytef *source, uLong sourceLen));
51.1052 -/*
51.1053 - Decompresses the source buffer into the destination buffer. sourceLen is
51.1054 - the byte length of the source buffer. Upon entry, destLen is the total
51.1055 - size of the destination buffer, which must be large enough to hold the
51.1056 - entire uncompressed data. (The size of the uncompressed data must have
51.1057 - been saved previously by the compressor and transmitted to the decompressor
51.1058 - by some mechanism outside the scope of this compression library.)
51.1059 - Upon exit, destLen is the actual size of the compressed buffer.
51.1060 - This function can be used to decompress a whole file at once if the
51.1061 - input file is mmap'ed.
51.1062 -
51.1063 - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
51.1064 - enough memory, Z_BUF_ERROR if there was not enough room in the output
51.1065 - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
51.1066 -*/
51.1067 -
51.1068 -
51.1069 -typedef voidp gzFile;
51.1070 -
51.1071 -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
51.1072 -/*
51.1073 - Opens a gzip (.gz) file for reading or writing. The mode parameter
51.1074 - is as in fopen ("rb" or "wb") but can also include a compression level
51.1075 - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
51.1076 - Huffman only compression as in "wb1h", or 'R' for run-length encoding
51.1077 - as in "wb1R". (See the description of deflateInit2 for more information
51.1078 - about the strategy parameter.)
51.1079 -
51.1080 - gzopen can be used to read a file which is not in gzip format; in this
51.1081 - case gzread will directly read from the file without decompression.
51.1082 -
51.1083 - gzopen returns NULL if the file could not be opened or if there was
51.1084 - insufficient memory to allocate the (de)compression state; errno
51.1085 - can be checked to distinguish the two cases (if errno is zero, the
51.1086 - zlib error is Z_MEM_ERROR). */
51.1087 -
51.1088 -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
51.1089 -/*
51.1090 - gzdopen() associates a gzFile with the file descriptor fd. File
51.1091 - descriptors are obtained from calls like open, dup, creat, pipe or
51.1092 - fileno (in the file has been previously opened with fopen).
51.1093 - The mode parameter is as in gzopen.
51.1094 - The next call of gzclose on the returned gzFile will also close the
51.1095 - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
51.1096 - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
51.1097 - gzdopen returns NULL if there was insufficient memory to allocate
51.1098 - the (de)compression state.
51.1099 -*/
51.1100 -
51.1101 -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
51.1102 -/*
51.1103 - Dynamically update the compression level or strategy. See the description
51.1104 - of deflateInit2 for the meaning of these parameters.
51.1105 - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
51.1106 - opened for writing.
51.1107 -*/
51.1108 -
51.1109 -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
51.1110 -/*
51.1111 - Reads the given number of uncompressed bytes from the compressed file.
51.1112 - If the input file was not in gzip format, gzread copies the given number
51.1113 - of bytes into the buffer.
51.1114 - gzread returns the number of uncompressed bytes actually read (0 for
51.1115 - end of file, -1 for error). */
51.1116 -
51.1117 -ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
51.1118 - voidpc buf, unsigned len));
51.1119 -/*
51.1120 - Writes the given number of uncompressed bytes into the compressed file.
51.1121 - gzwrite returns the number of uncompressed bytes actually written
51.1122 - (0 in case of error).
51.1123 -*/
51.1124 -
51.1125 -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
51.1126 -/*
51.1127 - Converts, formats, and writes the args to the compressed file under
51.1128 - control of the format string, as in fprintf. gzprintf returns the number of
51.1129 - uncompressed bytes actually written (0 in case of error). The number of
51.1130 - uncompressed bytes written is limited to 4095. The caller should assure that
51.1131 - this limit is not exceeded. If it is exceeded, then gzprintf() will return
51.1132 - return an error (0) with nothing written. In this case, there may also be a
51.1133 - buffer overflow with unpredictable consequences, which is possible only if
51.1134 - zlib was compiled with the insecure functions sprintf() or vsprintf()
51.1135 - because the secure snprintf() or vsnprintf() functions were not available.
51.1136 -*/
51.1137 -
51.1138 -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
51.1139 -/*
51.1140 - Writes the given null-terminated string to the compressed file, excluding
51.1141 - the terminating null character.
51.1142 - gzputs returns the number of characters written, or -1 in case of error.
51.1143 -*/
51.1144 -
51.1145 -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
51.1146 -/*
51.1147 - Reads bytes from the compressed file until len-1 characters are read, or
51.1148 - a newline character is read and transferred to buf, or an end-of-file
51.1149 - condition is encountered. The string is then terminated with a null
51.1150 - character.
51.1151 - gzgets returns buf, or Z_NULL in case of error.
51.1152 -*/
51.1153 -
51.1154 -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
51.1155 -/*
51.1156 - Writes c, converted to an unsigned char, into the compressed file.
51.1157 - gzputc returns the value that was written, or -1 in case of error.
51.1158 -*/
51.1159 -
51.1160 -ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
51.1161 -/*
51.1162 - Reads one byte from the compressed file. gzgetc returns this byte
51.1163 - or -1 in case of end of file or error.
51.1164 -*/
51.1165 -
51.1166 -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
51.1167 -/*
51.1168 - Push one character back onto the stream to be read again later.
51.1169 - Only one character of push-back is allowed. gzungetc() returns the
51.1170 - character pushed, or -1 on failure. gzungetc() will fail if a
51.1171 - character has been pushed but not read yet, or if c is -1. The pushed
51.1172 - character will be discarded if the stream is repositioned with gzseek()
51.1173 - or gzrewind().
51.1174 -*/
51.1175 -
51.1176 -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
51.1177 -/*
51.1178 - Flushes all pending output into the compressed file. The parameter
51.1179 - flush is as in the deflate() function. The return value is the zlib
51.1180 - error number (see function gzerror below). gzflush returns Z_OK if
51.1181 - the flush parameter is Z_FINISH and all output could be flushed.
51.1182 - gzflush should be called only when strictly necessary because it can
51.1183 - degrade compression.
51.1184 -*/
51.1185 -
51.1186 -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
51.1187 - z_off_t offset, int whence));
51.1188 -/*
51.1189 - Sets the starting position for the next gzread or gzwrite on the
51.1190 - given compressed file. The offset represents a number of bytes in the
51.1191 - uncompressed data stream. The whence parameter is defined as in lseek(2);
51.1192 - the value SEEK_END is not supported.
51.1193 - If the file is opened for reading, this function is emulated but can be
51.1194 - extremely slow. If the file is opened for writing, only forward seeks are
51.1195 - supported; gzseek then compresses a sequence of zeroes up to the new
51.1196 - starting position.
51.1197 -
51.1198 - gzseek returns the resulting offset location as measured in bytes from
51.1199 - the beginning of the uncompressed stream, or -1 in case of error, in
51.1200 - particular if the file is opened for writing and the new starting position
51.1201 - would be before the current position.
51.1202 -*/
51.1203 -
51.1204 -ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
51.1205 -/*
51.1206 - Rewinds the given file. This function is supported only for reading.
51.1207 -
51.1208 - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
51.1209 -*/
51.1210 -
51.1211 -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
51.1212 -/*
51.1213 - Returns the starting position for the next gzread or gzwrite on the
51.1214 - given compressed file. This position represents a number of bytes in the
51.1215 - uncompressed data stream.
51.1216 -
51.1217 - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
51.1218 -*/
51.1219 -
51.1220 -ZEXTERN int ZEXPORT gzeof OF((gzFile file));
51.1221 -/*
51.1222 - Returns 1 when EOF has previously been detected reading the given
51.1223 - input stream, otherwise zero.
51.1224 -*/
51.1225 -
51.1226 -ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
51.1227 -/*
51.1228 - Returns 1 if file is being read directly without decompression, otherwise
51.1229 - zero.
51.1230 -*/
51.1231 -
51.1232 -ZEXTERN int ZEXPORT gzclose OF((gzFile file));
51.1233 -/*
51.1234 - Flushes all pending output if necessary, closes the compressed file
51.1235 - and deallocates all the (de)compression state. The return value is the zlib
51.1236 - error number (see function gzerror below).
51.1237 -*/
51.1238 -
51.1239 -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
51.1240 -/*
51.1241 - Returns the error message for the last error which occurred on the
51.1242 - given compressed file. errnum is set to zlib error number. If an
51.1243 - error occurred in the file system and not in the compression library,
51.1244 - errnum is set to Z_ERRNO and the application may consult errno
51.1245 - to get the exact error code.
51.1246 -*/
51.1247 -
51.1248 -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
51.1249 -/*
51.1250 - Clears the error and end-of-file flags for file. This is analogous to the
51.1251 - clearerr() function in stdio. This is useful for continuing to read a gzip
51.1252 - file that is being written concurrently.
51.1253 -*/
51.1254 -
51.1255 - /* checksum functions */
51.1256 -
51.1257 -/*
51.1258 - These functions are not related to compression but are exported
51.1259 - anyway because they might be useful in applications using the
51.1260 - compression library.
51.1261 -*/
51.1262 -
51.1263 -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
51.1264 -/*
51.1265 - Update a running Adler-32 checksum with the bytes buf[0..len-1] and
51.1266 - return the updated checksum. If buf is NULL, this function returns
51.1267 - the required initial value for the checksum.
51.1268 - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
51.1269 - much faster. Usage example:
51.1270 -
51.1271 - uLong adler = adler32(0L, Z_NULL, 0);
51.1272 -
51.1273 - while (read_buffer(buffer, length) != EOF) {
51.1274 - adler = adler32(adler, buffer, length);
51.1275 - }
51.1276 - if (adler != original_adler) error();
51.1277 -*/
51.1278 -
51.1279 -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
51.1280 - z_off_t len2));
51.1281 -/*
51.1282 - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
51.1283 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
51.1284 - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
51.1285 - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
51.1286 -*/
51.1287 -
51.1288 -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
51.1289 -/*
51.1290 - Update a running CRC-32 with the bytes buf[0..len-1] and return the
51.1291 - updated CRC-32. If buf is NULL, this function returns the required initial
51.1292 - value for the for the crc. Pre- and post-conditioning (one's complement) is
51.1293 - performed within this function so it shouldn't be done by the application.
51.1294 - Usage example:
51.1295 -
51.1296 - uLong crc = crc32(0L, Z_NULL, 0);
51.1297 -
51.1298 - while (read_buffer(buffer, length) != EOF) {
51.1299 - crc = crc32(crc, buffer, length);
51.1300 - }
51.1301 - if (crc != original_crc) error();
51.1302 -*/
51.1303 -
51.1304 -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
51.1305 -
51.1306 -/*
51.1307 - Combine two CRC-32 check values into one. For two sequences of bytes,
51.1308 - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
51.1309 - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
51.1310 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
51.1311 - len2.
51.1312 -*/
51.1313 -
51.1314 -
51.1315 - /* various hacks, don't look :) */
51.1316 -
51.1317 -/* deflateInit and inflateInit are macros to allow checking the zlib version
51.1318 - * and the compiler's view of z_stream:
51.1319 - */
51.1320 -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
51.1321 - const char *version, int stream_size));
51.1322 -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
51.1323 - const char *version, int stream_size));
51.1324 -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
51.1325 - int windowBits, int memLevel,
51.1326 - int strategy, const char *version,
51.1327 - int stream_size));
51.1328 -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
51.1329 - const char *version, int stream_size));
51.1330 -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
51.1331 - unsigned char FAR *window,
51.1332 - const char *version,
51.1333 - int stream_size));
51.1334 -#define deflateInit(strm, level) \
51.1335 - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
51.1336 -#define inflateInit(strm) \
51.1337 - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
51.1338 -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
51.1339 - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
51.1340 - (strategy), ZLIB_VERSION, sizeof(z_stream))
51.1341 -#define inflateInit2(strm, windowBits) \
51.1342 - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
51.1343 -#define inflateBackInit(strm, windowBits, window) \
51.1344 - inflateBackInit_((strm), (windowBits), (window), \
51.1345 - ZLIB_VERSION, sizeof(z_stream))
51.1346 -
51.1347 -
51.1348 -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
51.1349 - struct internal_state {int dummy;}; /* hack for buggy compilers */
51.1350 -#endif
51.1351 -
51.1352 -ZEXTERN const char * ZEXPORT zError OF((int));
51.1353 -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
51.1354 -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
51.1355 -
51.1356 -#ifdef __cplusplus
51.1357 -}
51.1358 -#endif
51.1359 -
51.1360 -#endif /* ZLIB_H */
52.1 --- a/compiler-init/zlib/zutil.c Sat Jul 15 05:02:38 2006 +0000
52.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
52.3 @@ -1,318 +0,0 @@
52.4 -/* zutil.c -- target dependent utility functions for the compression library
52.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
52.6 - * For conditions of distribution and use, see copyright notice in zlib.h
52.7 - */
52.8 -
52.9 -/* @(#) $Id$ */
52.10 -
52.11 -#include "zutil.h"
52.12 -
52.13 -#ifndef NO_DUMMY_DECL
52.14 -struct internal_state {int dummy;}; /* for buggy compilers */
52.15 -#endif
52.16 -
52.17 -const char * const z_errmsg[10] = {
52.18 -"need dictionary", /* Z_NEED_DICT 2 */
52.19 -"stream end", /* Z_STREAM_END 1 */
52.20 -"", /* Z_OK 0 */
52.21 -"file error", /* Z_ERRNO (-1) */
52.22 -"stream error", /* Z_STREAM_ERROR (-2) */
52.23 -"data error", /* Z_DATA_ERROR (-3) */
52.24 -"insufficient memory", /* Z_MEM_ERROR (-4) */
52.25 -"buffer error", /* Z_BUF_ERROR (-5) */
52.26 -"incompatible version",/* Z_VERSION_ERROR (-6) */
52.27 -""};
52.28 -
52.29 -
52.30 -const char * ZEXPORT zlibVersion()
52.31 -{
52.32 - return ZLIB_VERSION;
52.33 -}
52.34 -
52.35 -uLong ZEXPORT zlibCompileFlags()
52.36 -{
52.37 - uLong flags;
52.38 -
52.39 - flags = 0;
52.40 - switch (sizeof(uInt)) {
52.41 - case 2: break;
52.42 - case 4: flags += 1; break;
52.43 - case 8: flags += 2; break;
52.44 - default: flags += 3;
52.45 - }
52.46 - switch (sizeof(uLong)) {
52.47 - case 2: break;
52.48 - case 4: flags += 1 << 2; break;
52.49 - case 8: flags += 2 << 2; break;
52.50 - default: flags += 3 << 2;
52.51 - }
52.52 - switch (sizeof(voidpf)) {
52.53 - case 2: break;
52.54 - case 4: flags += 1 << 4; break;
52.55 - case 8: flags += 2 << 4; break;
52.56 - default: flags += 3 << 4;
52.57 - }
52.58 - switch (sizeof(z_off_t)) {
52.59 - case 2: break;
52.60 - case 4: flags += 1 << 6; break;
52.61 - case 8: flags += 2 << 6; break;
52.62 - default: flags += 3 << 6;
52.63 - }
52.64 -#ifdef DEBUG
52.65 - flags += 1 << 8;
52.66 -#endif
52.67 -#if defined(ASMV) || defined(ASMINF)
52.68 - flags += 1 << 9;
52.69 -#endif
52.70 -#ifdef ZLIB_WINAPI
52.71 - flags += 1 << 10;
52.72 -#endif
52.73 -#ifdef BUILDFIXED
52.74 - flags += 1 << 12;
52.75 -#endif
52.76 -#ifdef DYNAMIC_CRC_TABLE
52.77 - flags += 1 << 13;
52.78 -#endif
52.79 -#ifdef NO_GZCOMPRESS
52.80 - flags += 1L << 16;
52.81 -#endif
52.82 -#ifdef NO_GZIP
52.83 - flags += 1L << 17;
52.84 -#endif
52.85 -#ifdef PKZIP_BUG_WORKAROUND
52.86 - flags += 1L << 20;
52.87 -#endif
52.88 -#ifdef FASTEST
52.89 - flags += 1L << 21;
52.90 -#endif
52.91 -#ifdef STDC
52.92 -# ifdef NO_vsnprintf
52.93 - flags += 1L << 25;
52.94 -# ifdef HAS_vsprintf_void
52.95 - flags += 1L << 26;
52.96 -# endif
52.97 -# else
52.98 -# ifdef HAS_vsnprintf_void
52.99 - flags += 1L << 26;
52.100 -# endif
52.101 -# endif
52.102 -#else
52.103 - flags += 1L << 24;
52.104 -# ifdef NO_snprintf
52.105 - flags += 1L << 25;
52.106 -# ifdef HAS_sprintf_void
52.107 - flags += 1L << 26;
52.108 -# endif
52.109 -# else
52.110 -# ifdef HAS_snprintf_void
52.111 - flags += 1L << 26;
52.112 -# endif
52.113 -# endif
52.114 -#endif
52.115 - return flags;
52.116 -}
52.117 -
52.118 -#ifdef DEBUG
52.119 -
52.120 -# ifndef verbose
52.121 -# define verbose 0
52.122 -# endif
52.123 -int z_verbose = verbose;
52.124 -
52.125 -void z_error (m)
52.126 - char *m;
52.127 -{
52.128 - fprintf(stderr, "%s\n", m);
52.129 - exit(1);
52.130 -}
52.131 -#endif
52.132 -
52.133 -/* exported to allow conversion of error code to string for compress() and
52.134 - * uncompress()
52.135 - */
52.136 -const char * ZEXPORT zError(err)
52.137 - int err;
52.138 -{
52.139 - return ERR_MSG(err);
52.140 -}
52.141 -
52.142 -#if defined(_WIN32_WCE)
52.143 - /* The Microsoft C Run-Time Library for Windows CE doesn't have
52.144 - * errno. We define it as a global variable to simplify porting.
52.145 - * Its value is always 0 and should not be used.
52.146 - */
52.147 - int errno = 0;
52.148 -#endif
52.149 -
52.150 -#ifndef HAVE_MEMCPY
52.151 -
52.152 -void zmemcpy(dest, source, len)
52.153 - Bytef* dest;
52.154 - const Bytef* source;
52.155 - uInt len;
52.156 -{
52.157 - if (len == 0) return;
52.158 - do {
52.159 - *dest++ = *source++; /* ??? to be unrolled */
52.160 - } while (--len != 0);
52.161 -}
52.162 -
52.163 -int zmemcmp(s1, s2, len)
52.164 - const Bytef* s1;
52.165 - const Bytef* s2;
52.166 - uInt len;
52.167 -{
52.168 - uInt j;
52.169 -
52.170 - for (j = 0; j < len; j++) {
52.171 - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
52.172 - }
52.173 - return 0;
52.174 -}
52.175 -
52.176 -void zmemzero(dest, len)
52.177 - Bytef* dest;
52.178 - uInt len;
52.179 -{
52.180 - if (len == 0) return;
52.181 - do {
52.182 - *dest++ = 0; /* ??? to be unrolled */
52.183 - } while (--len != 0);
52.184 -}
52.185 -#endif
52.186 -
52.187 -
52.188 -#ifdef SYS16BIT
52.189 -
52.190 -#ifdef __TURBOC__
52.191 -/* Turbo C in 16-bit mode */
52.192 -
52.193 -# define MY_ZCALLOC
52.194 -
52.195 -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
52.196 - * and farmalloc(64K) returns a pointer with an offset of 8, so we
52.197 - * must fix the pointer. Warning: the pointer must be put back to its
52.198 - * original form in order to free it, use zcfree().
52.199 - */
52.200 -
52.201 -#define MAX_PTR 10
52.202 -/* 10*64K = 640K */
52.203 -
52.204 -local int next_ptr = 0;
52.205 -
52.206 -typedef struct ptr_table_s {
52.207 - voidpf org_ptr;
52.208 - voidpf new_ptr;
52.209 -} ptr_table;
52.210 -
52.211 -local ptr_table table[MAX_PTR];
52.212 -/* This table is used to remember the original form of pointers
52.213 - * to large buffers (64K). Such pointers are normalized with a zero offset.
52.214 - * Since MSDOS is not a preemptive multitasking OS, this table is not
52.215 - * protected from concurrent access. This hack doesn't work anyway on
52.216 - * a protected system like OS/2. Use Microsoft C instead.
52.217 - */
52.218 -
52.219 -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
52.220 -{
52.221 - voidpf buf = opaque; /* just to make some compilers happy */
52.222 - ulg bsize = (ulg)items*size;
52.223 -
52.224 - /* If we allocate less than 65520 bytes, we assume that farmalloc
52.225 - * will return a usable pointer which doesn't have to be normalized.
52.226 - */
52.227 - if (bsize < 65520L) {
52.228 - buf = farmalloc(bsize);
52.229 - if (*(ush*)&buf != 0) return buf;
52.230 - } else {
52.231 - buf = farmalloc(bsize + 16L);
52.232 - }
52.233 - if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
52.234 - table[next_ptr].org_ptr = buf;
52.235 -
52.236 - /* Normalize the pointer to seg:0 */
52.237 - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
52.238 - *(ush*)&buf = 0;
52.239 - table[next_ptr++].new_ptr = buf;
52.240 - return buf;
52.241 -}
52.242 -
52.243 -void zcfree (voidpf opaque, voidpf ptr)
52.244 -{
52.245 - int n;
52.246 - if (*(ush*)&ptr != 0) { /* object < 64K */
52.247 - farfree(ptr);
52.248 - return;
52.249 - }
52.250 - /* Find the original pointer */
52.251 - for (n = 0; n < next_ptr; n++) {
52.252 - if (ptr != table[n].new_ptr) continue;
52.253 -
52.254 - farfree(table[n].org_ptr);
52.255 - while (++n < next_ptr) {
52.256 - table[n-1] = table[n];
52.257 - }
52.258 - next_ptr--;
52.259 - return;
52.260 - }
52.261 - ptr = opaque; /* just to make some compilers happy */
52.262 - Assert(0, "zcfree: ptr not found");
52.263 -}
52.264 -
52.265 -#endif /* __TURBOC__ */
52.266 -
52.267 -
52.268 -#ifdef M_I86
52.269 -/* Microsoft C in 16-bit mode */
52.270 -
52.271 -# define MY_ZCALLOC
52.272 -
52.273 -#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
52.274 -# define _halloc halloc
52.275 -# define _hfree hfree
52.276 -#endif
52.277 -
52.278 -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
52.279 -{
52.280 - if (opaque) opaque = 0; /* to make compiler happy */
52.281 - return _halloc((long)items, size);
52.282 -}
52.283 -
52.284 -void zcfree (voidpf opaque, voidpf ptr)
52.285 -{
52.286 - if (opaque) opaque = 0; /* to make compiler happy */
52.287 - _hfree(ptr);
52.288 -}
52.289 -
52.290 -#endif /* M_I86 */
52.291 -
52.292 -#endif /* SYS16BIT */
52.293 -
52.294 -
52.295 -#ifndef MY_ZCALLOC /* Any system without a special alloc function */
52.296 -
52.297 -#ifndef STDC
52.298 -extern voidp malloc OF((uInt size));
52.299 -extern voidp calloc OF((uInt items, uInt size));
52.300 -extern void free OF((voidpf ptr));
52.301 -#endif
52.302 -
52.303 -voidpf zcalloc (opaque, items, size)
52.304 - voidpf opaque;
52.305 - unsigned items;
52.306 - unsigned size;
52.307 -{
52.308 - if (opaque) items += size - size; /* make compiler happy */
52.309 - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
52.310 - (voidpf)calloc(items, size);
52.311 -}
52.312 -
52.313 -void zcfree (opaque, ptr)
52.314 - voidpf opaque;
52.315 - voidpf ptr;
52.316 -{
52.317 - free(ptr);
52.318 - if (opaque) return; /* make compiler happy */
52.319 -}
52.320 -
52.321 -#endif /* MY_ZCALLOC */
53.1 --- a/compiler-init/zlib/zutil.h Sat Jul 15 05:02:38 2006 +0000
53.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
53.3 @@ -1,269 +0,0 @@
53.4 -/* zutil.h -- internal interface and configuration of the compression library
53.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
53.6 - * For conditions of distribution and use, see copyright notice in zlib.h
53.7 - */
53.8 -
53.9 -/* WARNING: this file should *not* be used by applications. It is
53.10 - part of the implementation of the compression library and is
53.11 - subject to change. Applications should only use zlib.h.
53.12 - */
53.13 -
53.14 -/* @(#) $Id$ */
53.15 -
53.16 -#ifndef ZUTIL_H
53.17 -#define ZUTIL_H
53.18 -
53.19 -#define ZLIB_INTERNAL
53.20 -#include "zlib.h"
53.21 -
53.22 -#ifdef STDC
53.23 -# ifndef _WIN32_WCE
53.24 -# include <stddef.h>
53.25 -# endif
53.26 -# include <string.h>
53.27 -# include <stdlib.h>
53.28 -#endif
53.29 -#ifdef NO_ERRNO_H
53.30 -# ifdef _WIN32_WCE
53.31 - /* The Microsoft C Run-Time Library for Windows CE doesn't have
53.32 - * errno. We define it as a global variable to simplify porting.
53.33 - * Its value is always 0 and should not be used. We rename it to
53.34 - * avoid conflict with other libraries that use the same workaround.
53.35 - */
53.36 -# define errno z_errno
53.37 -# endif
53.38 - extern int errno;
53.39 -#else
53.40 -# ifndef _WIN32_WCE
53.41 -# include <errno.h>
53.42 -# endif
53.43 -#endif
53.44 -
53.45 -#ifndef local
53.46 -# define local static
53.47 -#endif
53.48 -/* compile with -Dlocal if your debugger can't find static symbols */
53.49 -
53.50 -typedef unsigned char uch;
53.51 -typedef uch FAR uchf;
53.52 -typedef unsigned short ush;
53.53 -typedef ush FAR ushf;
53.54 -typedef unsigned long ulg;
53.55 -
53.56 -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
53.57 -/* (size given to avoid silly warnings with Visual C++) */
53.58 -
53.59 -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
53.60 -
53.61 -#define ERR_RETURN(strm,err) \
53.62 - return (strm->msg = (char*)ERR_MSG(err), (err))
53.63 -/* To be used only when the state is known to be valid */
53.64 -
53.65 - /* common constants */
53.66 -
53.67 -#ifndef DEF_WBITS
53.68 -# define DEF_WBITS MAX_WBITS
53.69 -#endif
53.70 -/* default windowBits for decompression. MAX_WBITS is for compression only */
53.71 -
53.72 -#if MAX_MEM_LEVEL >= 8
53.73 -# define DEF_MEM_LEVEL 8
53.74 -#else
53.75 -# define DEF_MEM_LEVEL MAX_MEM_LEVEL
53.76 -#endif
53.77 -/* default memLevel */
53.78 -
53.79 -#define STORED_BLOCK 0
53.80 -#define STATIC_TREES 1
53.81 -#define DYN_TREES 2
53.82 -/* The three kinds of block type */
53.83 -
53.84 -#define MIN_MATCH 3
53.85 -#define MAX_MATCH 258
53.86 -/* The minimum and maximum match lengths */
53.87 -
53.88 -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
53.89 -
53.90 - /* target dependencies */
53.91 -
53.92 -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
53.93 -# define OS_CODE 0x00
53.94 -# if defined(__TURBOC__) || defined(__BORLANDC__)
53.95 -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
53.96 - /* Allow compilation with ANSI keywords only enabled */
53.97 - void _Cdecl farfree( void *block );
53.98 - void *_Cdecl farmalloc( unsigned long nbytes );
53.99 -# else
53.100 -# include <alloc.h>
53.101 -# endif
53.102 -# else /* MSC or DJGPP */
53.103 -# include <malloc.h>
53.104 -# endif
53.105 -#endif
53.106 -
53.107 -#ifdef AMIGA
53.108 -# define OS_CODE 0x01
53.109 -#endif
53.110 -
53.111 -#if defined(VAXC) || defined(VMS)
53.112 -# define OS_CODE 0x02
53.113 -# define F_OPEN(name, mode) \
53.114 - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
53.115 -#endif
53.116 -
53.117 -#if defined(ATARI) || defined(atarist)
53.118 -# define OS_CODE 0x05
53.119 -#endif
53.120 -
53.121 -#ifdef OS2
53.122 -# define OS_CODE 0x06
53.123 -# ifdef M_I86
53.124 - #include <malloc.h>
53.125 -# endif
53.126 -#endif
53.127 -
53.128 -#if defined(MACOS) || defined(TARGET_OS_MAC)
53.129 -# define OS_CODE 0x07
53.130 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
53.131 -# include <unix.h> /* for fdopen */
53.132 -# else
53.133 -# ifndef fdopen
53.134 -# define fdopen(fd,mode) NULL /* No fdopen() */
53.135 -# endif
53.136 -# endif
53.137 -#endif
53.138 -
53.139 -#ifdef TOPS20
53.140 -# define OS_CODE 0x0a
53.141 -#endif
53.142 -
53.143 -#ifdef WIN32
53.144 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
53.145 -# define OS_CODE 0x0b
53.146 -# endif
53.147 -#endif
53.148 -
53.149 -#ifdef __50SERIES /* Prime/PRIMOS */
53.150 -# define OS_CODE 0x0f
53.151 -#endif
53.152 -
53.153 -#if defined(_BEOS_) || defined(RISCOS)
53.154 -# define fdopen(fd,mode) NULL /* No fdopen() */
53.155 -#endif
53.156 -
53.157 -#if (defined(_MSC_VER) && (_MSC_VER > 600))
53.158 -# if defined(_WIN32_WCE)
53.159 -# define fdopen(fd,mode) NULL /* No fdopen() */
53.160 -# ifndef _PTRDIFF_T_DEFINED
53.161 - typedef int ptrdiff_t;
53.162 -# define _PTRDIFF_T_DEFINED
53.163 -# endif
53.164 -# else
53.165 -# define fdopen(fd,type) _fdopen(fd,type)
53.166 -# endif
53.167 -#endif
53.168 -
53.169 - /* common defaults */
53.170 -
53.171 -#ifndef OS_CODE
53.172 -# define OS_CODE 0x03 /* assume Unix */
53.173 -#endif
53.174 -
53.175 -#ifndef F_OPEN
53.176 -# define F_OPEN(name, mode) fopen((name), (mode))
53.177 -#endif
53.178 -
53.179 - /* functions */
53.180 -
53.181 -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
53.182 -# ifndef HAVE_VSNPRINTF
53.183 -# define HAVE_VSNPRINTF
53.184 -# endif
53.185 -#endif
53.186 -#if defined(__CYGWIN__)
53.187 -# ifndef HAVE_VSNPRINTF
53.188 -# define HAVE_VSNPRINTF
53.189 -# endif
53.190 -#endif
53.191 -#ifndef HAVE_VSNPRINTF
53.192 -# ifdef MSDOS
53.193 - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
53.194 - but for now we just assume it doesn't. */
53.195 -# define NO_vsnprintf
53.196 -# endif
53.197 -# ifdef __TURBOC__
53.198 -# define NO_vsnprintf
53.199 -# endif
53.200 -# ifdef WIN32
53.201 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
53.202 -# if !defined(vsnprintf) && !defined(NO_vsnprintf)
53.203 -# define vsnprintf _vsnprintf
53.204 -# endif
53.205 -# endif
53.206 -# ifdef __SASC
53.207 -# define NO_vsnprintf
53.208 -# endif
53.209 -#endif
53.210 -#ifdef VMS
53.211 -# define NO_vsnprintf
53.212 -#endif
53.213 -
53.214 -#if defined(pyr)
53.215 -# define NO_MEMCPY
53.216 -#endif
53.217 -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
53.218 - /* Use our own functions for small and medium model with MSC <= 5.0.
53.219 - * You may have to use the same strategy for Borland C (untested).
53.220 - * The __SC__ check is for Symantec.
53.221 - */
53.222 -# define NO_MEMCPY
53.223 -#endif
53.224 -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
53.225 -# define HAVE_MEMCPY
53.226 -#endif
53.227 -#ifdef HAVE_MEMCPY
53.228 -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
53.229 -# define zmemcpy _fmemcpy
53.230 -# define zmemcmp _fmemcmp
53.231 -# define zmemzero(dest, len) _fmemset(dest, 0, len)
53.232 -# else
53.233 -# define zmemcpy memcpy
53.234 -# define zmemcmp memcmp
53.235 -# define zmemzero(dest, len) memset(dest, 0, len)
53.236 -# endif
53.237 -#else
53.238 - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
53.239 - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
53.240 - extern void zmemzero OF((Bytef* dest, uInt len));
53.241 -#endif
53.242 -
53.243 -/* Diagnostic functions */
53.244 -#ifdef DEBUG
53.245 -# include <stdio.h>
53.246 - extern int z_verbose;
53.247 - extern void z_error OF((char *m));
53.248 -# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
53.249 -# define Trace(x) {if (z_verbose>=0) fprintf x ;}
53.250 -# define Tracev(x) {if (z_verbose>0) fprintf x ;}
53.251 -# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
53.252 -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
53.253 -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
53.254 -#else
53.255 -# define Assert(cond,msg)
53.256 -# define Trace(x)
53.257 -# define Tracev(x)
53.258 -# define Tracevv(x)
53.259 -# define Tracec(c,x)
53.260 -# define Tracecv(c,x)
53.261 -#endif
53.262 -
53.263 -
53.264 -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
53.265 -void zcfree OF((voidpf opaque, voidpf ptr));
53.266 -
53.267 -#define ZALLOC(strm, items, size) \
53.268 - (*((strm)->zalloc))((strm)->opaque, (items), (size))
53.269 -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
53.270 -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
53.271 -
53.272 -#endif /* ZUTIL_H */