removed local branch dvander
authorDavid Anderson <dvander@alliedmods.net>
Sat Jul 15 05:11:30 2006 +0000 (2006-07-15)
branchdvander
changeset 26cddce0804b2a
parent 23 040a84cd0eee
child 2286 34e6e8ca7db2
removed local branch
compiler-init/amx.h
compiler-init/amxdbg.h
compiler-init/libpawnc.c
compiler-init/libpawnc.rc
compiler-init/lstring.c
compiler-init/lstring.h
compiler-init/memfile.c
compiler-init/memfile.h
compiler-init/osdefs.h
compiler-init/pawn.ico
compiler-init/pawncc.c
compiler-init/sc.h
compiler-init/sc1.c
compiler-init/sc2.c
compiler-init/sc3.c
compiler-init/sc4.c
compiler-init/sc5.c
compiler-init/sc5.scp
compiler-init/sc6.c
compiler-init/sc7.c
compiler-init/sc7.scp
compiler-init/scexpand.c
compiler-init/sci18n.c
compiler-init/sclist.c
compiler-init/scmemfil.c
compiler-init/scstate.c
compiler-init/scvars.c
compiler-init/sp_file.h
compiler-init/spcomp.sln
compiler-init/spcomp.vcproj
compiler-init/svnrev.h
compiler-init/zlib/adler32.c
compiler-init/zlib/compress.c
compiler-init/zlib/crc32.c
compiler-init/zlib/crc32.h
compiler-init/zlib/deflate.c
compiler-init/zlib/deflate.h
compiler-init/zlib/gzio.c
compiler-init/zlib/infback.c
compiler-init/zlib/inffast.c
compiler-init/zlib/inffast.h
compiler-init/zlib/inffixed.h
compiler-init/zlib/inflate.c
compiler-init/zlib/inflate.h
compiler-init/zlib/inftrees.c
compiler-init/zlib/inftrees.h
compiler-init/zlib/trees.c
compiler-init/zlib/trees.h
compiler-init/zlib/uncompr.c
compiler-init/zlib/zconf.h
compiler-init/zlib/zlib.h
compiler-init/zlib/zutil.c
compiler-init/zlib/zutil.h
     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 &lt; 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,"&lt;");
 13.3855 -      ptr+=4;
 13.3856 -      break;
 13.3857 -    case '>':
 13.3858 -      strcpy(ptr,"&gt;");
 13.3859 -      ptr+=4;
 13.3860 -      break;
 13.3861 -    case '&':
 13.3862 -      strcpy(ptr,"&amp;");
 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,"&amp;%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," &amp;");
 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,&params);
  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,&params);
  19.301 -  ucell p2=getparam(params,&params);
  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,&params);
  19.315 -  ucell p2=getparam(params,&params);
  19.316 -  ucell p3=getparam(params,&params);
  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,&params);
  19.331 -  ucell p2=getparam(params,&params);
  19.332 -  ucell p3=getparam(params,&params);
  19.333 -  ucell p4=getparam(params,&params);
  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,&params);
  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,&params);
  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 */