1.1 --- a/sourcepawn/compiler/amx.h Sat Jul 15 19:23:07 2006 +0000
1.2 +++ b/sourcepawn/compiler/amx.h Wed Jul 19 00:53:26 2006 +0000
1.3 @@ -206,9 +206,9 @@
1.4 #endif
1.5
1.6 #if defined __GNUC__
1.7 - #define PACKED __attribute__((packed))
1.8 + #define PACKEDENTRY __attribute__((packed))
1.9 #else
1.10 - #define PACKED
1.11 + #define PACKEDENTRY
1.12 #endif
1.13
1.14 #if !defined AMX_NO_ALIGN
1.15 @@ -226,8 +226,8 @@
1.16 #endif
1.17
1.18 typedef struct tagAMX_NATIVE_INFO {
1.19 - const char _FAR *name PACKED;
1.20 - AMX_NATIVE func PACKED;
1.21 + const char _FAR *name PACKEDENTRY;
1.22 + AMX_NATIVE func PACKEDENTRY;
1.23 } AMX_NATIVE_INFO;
1.24
1.25 #define AMX_USERNUM 4
1.26 @@ -235,48 +235,48 @@
1.27 #define sNAMEMAX 31 /* maximum name length of symbol name */
1.28
1.29 typedef struct tagAMX_FUNCSTUB {
1.30 - ucell address PACKED;
1.31 - char name[sEXPMAX+1] PACKED;
1.32 + ucell address PACKEDENTRY;
1.33 + char name[sEXPMAX+1] PACKEDENTRY;
1.34 } AMX_FUNCSTUB;
1.35
1.36 typedef struct tagFUNCSTUBNT {
1.37 - ucell address PACKED;
1.38 - uint32_t nameofs PACKED;
1.39 + ucell address PACKEDENTRY;
1.40 + uint32_t nameofs PACKEDENTRY;
1.41 } AMX_FUNCSTUBNT;
1.42
1.43 /* The AMX structure is the internal structure for many functions. Not all
1.44 * fields are valid at all times; many fields are cached in local variables.
1.45 */
1.46 typedef struct tagAMX {
1.47 - unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
1.48 - unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
1.49 - AMX_CALLBACK callback PACKED;
1.50 - AMX_DEBUG debug PACKED; /* debug callback */
1.51 + unsigned char _FAR *base PACKEDENTRY; /* points to the AMX header plus the code, optionally also the data */
1.52 + unsigned char _FAR *data PACKEDENTRY; /* points to separate data+stack+heap, may be NULL */
1.53 + AMX_CALLBACK callback PACKEDENTRY;
1.54 + AMX_DEBUG debug PACKEDENTRY; /* debug callback */
1.55 /* for external functions a few registers must be accessible from the outside */
1.56 - cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */
1.57 - cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */
1.58 - cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */
1.59 - cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */
1.60 - cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
1.61 - cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
1.62 - int flags PACKED; /* current status, see amx_Flags() */
1.63 + cell cip PACKEDENTRY; /* instruction pointer: relative to base + amxhdr->cod */
1.64 + cell frm PACKEDENTRY; /* stack frame base: relative to base + amxhdr->dat */
1.65 + cell hea PACKEDENTRY; /* top of the heap: relative to base + amxhdr->dat */
1.66 + cell hlw PACKEDENTRY; /* bottom of the heap: relative to base + amxhdr->dat */
1.67 + cell stk PACKEDENTRY; /* stack pointer: relative to base + amxhdr->dat */
1.68 + cell stp PACKEDENTRY; /* top of the stack: relative to base + amxhdr->dat */
1.69 + int flags PACKEDENTRY; /* current status, see amx_Flags() */
1.70 /* user data */
1.71 - long usertags[AMX_USERNUM] PACKED;
1.72 - void _FAR *userdata[AMX_USERNUM] PACKED;
1.73 + long usertags[AMX_USERNUM] PACKEDENTRY;
1.74 + void _FAR *userdata[AMX_USERNUM] PACKEDENTRY;
1.75 /* native functions can raise an error */
1.76 - int error PACKED;
1.77 + int error PACKEDENTRY;
1.78 /* passing parameters requires a "count" field */
1.79 int paramcount;
1.80 /* the sleep opcode needs to store the full AMX status */
1.81 - cell pri PACKED;
1.82 - cell alt PACKED;
1.83 - cell reset_stk PACKED;
1.84 - cell reset_hea PACKED;
1.85 - cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
1.86 + cell pri PACKEDENTRY;
1.87 + cell alt PACKEDENTRY;
1.88 + cell reset_stk PACKEDENTRY;
1.89 + cell reset_hea PACKEDENTRY;
1.90 + cell sysreq_d PACKEDENTRY; /* relocated address/value for the SYSREQ.D opcode */
1.91 #if defined JIT
1.92 /* support variables for the JIT */
1.93 - int reloc_size PACKED; /* required temporary buffer for relocations */
1.94 - long code_size PACKED; /* estimated memory footprint of the native code */
1.95 + int reloc_size PACKEDENTRY; /* required temporary buffer for relocations */
1.96 + long code_size PACKEDENTRY; /* estimated memory footprint of the native code */
1.97 #endif
1.98 } AMX;
1.99
1.100 @@ -284,23 +284,23 @@
1.101 * structure is used internaly.
1.102 */
1.103 typedef struct tagAMX_HEADER {
1.104 - int32_t size PACKED; /* size of the "file" */
1.105 - uint16_t magic PACKED; /* signature */
1.106 - char file_version PACKED; /* file format version */
1.107 - char amx_version PACKED; /* required version of the AMX */
1.108 - int16_t flags PACKED;
1.109 - int16_t defsize PACKED; /* size of a definition record */
1.110 - int32_t cod PACKED; /* initial value of COD - code block */
1.111 - int32_t dat PACKED; /* initial value of DAT - data block */
1.112 - int32_t hea PACKED; /* initial value of HEA - start of the heap */
1.113 - int32_t stp PACKED; /* initial value of STP - stack top */
1.114 - int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
1.115 - int32_t publics PACKED; /* offset to the "public functions" table */
1.116 - int32_t natives PACKED; /* offset to the "native functions" table */
1.117 - int32_t libraries PACKED; /* offset to the table of libraries */
1.118 - int32_t pubvars PACKED; /* the "public variables" table */
1.119 - int32_t tags PACKED; /* the "public tagnames" table */
1.120 - int32_t nametable PACKED; /* name table */
1.121 + int32_t size PACKEDENTRY; /* size of the "file" */
1.122 + uint16_t magic PACKEDENTRY; /* signature */
1.123 + char file_version PACKEDENTRY; /* file format version */
1.124 + char amx_version PACKEDENTRY; /* required version of the AMX */
1.125 + int16_t flags PACKEDENTRY;
1.126 + int16_t defsize PACKEDENTRY; /* size of a definition record */
1.127 + int32_t cod PACKEDENTRY; /* initial value of COD - code block */
1.128 + int32_t dat PACKEDENTRY; /* initial value of DAT - data block */
1.129 + int32_t hea PACKEDENTRY; /* initial value of HEA - start of the heap */
1.130 + int32_t stp PACKEDENTRY; /* initial value of STP - stack top */
1.131 + int32_t cip PACKEDENTRY; /* initial value of CIP - the instruction pointer */
1.132 + int32_t publics PACKEDENTRY; /* offset to the "public functions" table */
1.133 + int32_t natives PACKEDENTRY; /* offset to the "native functions" table */
1.134 + int32_t libraries PACKEDENTRY; /* offset to the table of libraries */
1.135 + int32_t pubvars PACKEDENTRY; /* the "public variables" table */
1.136 + int32_t tags PACKEDENTRY; /* the "public tagnames" table */
1.137 + int32_t nametable PACKEDENTRY; /* name table */
1.138 } AMX_HEADER;
1.139
1.140 #if PAWN_CELL_SIZE==16
2.1 --- a/sourcepawn/compiler/pawncc.c Sat Jul 15 19:23:07 2006 +0000
2.2 +++ b/sourcepawn/compiler/pawncc.c Wed Jul 19 00:53:26 2006 +0000
2.3 @@ -8,11 +8,27 @@
2.4 #include "osdefs.h"
2.5 #include "zlib/zlib.h"
2.6
2.7 -#define NUM_SECTIONS 6
2.8 +enum FileSections
2.9 +{
2.10 + FS_Code, /* required */
2.11 + FS_Data, /* required */
2.12 + FS_Publics,
2.13 + FS_Pubvars,
2.14 + FS_Natives,
2.15 + FS_Nametable, /* required */
2.16 + FS_DbgFile,
2.17 + FS_DbgSymbol,
2.18 + FS_DbgLine,
2.19 + FS_DbgTags,
2.20 + FS_DbgAutomaton,
2.21 + FS_DbgState,
2.22 + /* --- */
2.23 + FS_Number,
2.24 +};
2.25
2.26 int pc_printf(const char *message,...);
2.27 int pc_compile(int argc, char **argv);
2.28 -void sfwrite(const void *buf, size_t size, size_t count, FILE *fp);
2.29 +void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf);
2.30
2.31 memfile_t *bin_file = NULL;
2.32 jmp_buf brkout;
2.33 @@ -21,17 +37,11 @@
2.34 {
2.35 if (pc_compile(argc,argv) == 0)
2.36 {
2.37 - FILE *fp;
2.38 AMX_HEADER *hdr;
2.39 - sp_file_hdr_t shdr;
2.40 - uint32_t curoffs = 0;
2.41 - uint32_t lastsection = 0;
2.42 int err;
2.43 - uint8_t i8;
2.44 uint32_t i;
2.45 - const char *tables[NUM_SECTIONS] = {".code", ".data", ".publics", ".pubvars", ".natives", ".names"};
2.46 - uint32_t offsets[NUM_SECTIONS] = {0,0,0,0,0,0};
2.47 - sp_file_section_t sh;
2.48 + sp_file_t *spf;
2.49 + uint32_t sections[FS_Number] = {1,1,0,0,0,1,0,0,0,0,0,0};
2.50
2.51 if (bin_file == NULL)
2.52 {
2.53 @@ -39,13 +49,12 @@
2.54 }
2.55
2.56 hdr = (AMX_HEADER *)bin_file->base;
2.57 - shdr.version = SPFILE_VERSION;
2.58 - shdr.magic = SPFILE_MAGIC;
2.59
2.60 - if ((fp=fopen(bin_file->name, "wb")) == NULL)
2.61 + if ((spf=spfw_create(bin_file->name, NULL)) == NULL)
2.62 {
2.63 - pc_printf("Error writing to file: %s", bin_file->name);
2.64 - return 1;
2.65 + pc_printf("Error creating binary file!\n");
2.66 + memfile_destroy(bin_file);
2.67 + return 0;
2.68 }
2.69
2.70 if ((err=setjmp(brkout))!=0)
2.71 @@ -53,48 +62,34 @@
2.72 goto write_error;
2.73 }
2.74
2.75 - shdr.sections = NUM_SECTIONS;
2.76 - shdr.stringtab = sizeof(shdr) + (sizeof(sp_file_section_t) * shdr.sections);
2.77 -
2.78 - /**
2.79 - * write the header
2.80 - * unwritten values:
2.81 - * imagesize
2.82 - */
2.83 - sfwrite(&shdr, sizeof(shdr), 1, fp);
2.84 -
2.85 - curoffs = shdr.stringtab;
2.86 + spfw_add_section(spf, ".code");
2.87 + spfw_add_section(spf, ".data");
2.88
2.89 - /**
2.90 - * write the sections
2.91 - * unwritten values:
2.92 - * dataoffs
2.93 - * size
2.94 - */
2.95 - for (i8=0; i8<shdr.sections; i8++)
2.96 + sections[FS_Publics] = (hdr->natives - hdr->publics) / hdr->defsize;
2.97 + if (sections[FS_Publics])
2.98 {
2.99 - /* set name offset to next in string table */
2.100 - sh.nameoffs = curoffs - shdr.stringtab;
2.101 - /* save offset to this section */
2.102 - offsets[i8] = (uint32_t)ftell(fp) + sizeof(sh.nameoffs);
2.103 - /* update `end of file` offset */
2.104 - curoffs += strlen(tables[i8]) + 1;
2.105 - sfwrite(&sh, sizeof(sh), 1, fp);
2.106 + spfw_add_section(spf, ".publics");
2.107 + }
2.108 + sections[FS_Pubvars] = (hdr->tags - hdr->pubvars) / hdr->defsize;
2.109 + if (sections[FS_Pubvars])
2.110 + {
2.111 + spfw_add_section(spf, ".pubvars");
2.112 + }
2.113 + sections[FS_Natives] = (hdr->libraries - hdr->natives) / hdr->defsize;
2.114 + if (sections[FS_Natives])
2.115 + {
2.116 + spfw_add_section(spf, ".natives");
2.117 }
2.118
2.119 - /** write the string table */
2.120 - for (i8=0; i8<shdr.sections; i8++)
2.121 - {
2.122 - sfwrite(tables[i8], 1, strlen(tables[i8])+1, fp);
2.123 - }
2.124 + spfw_add_section(spf, ".names");
2.125
2.126 - lastsection = curoffs;
2.127 -
2.128 + spfw_finalize_header(spf);
2.129 +
2.130 /**
2.131 * Begin writing each of our known tables out
2.132 */
2.133
2.134 - if (strcmp(tables[0], ".code") == 0)
2.135 + if (sections[FS_Code])
2.136 {
2.137 sp_file_code_t cod;
2.138 cell cip;
2.139 @@ -331,21 +326,14 @@
2.140 cod.codesize = (uint32_t)(tptr - tbase);
2.141 cod.disksize = cod.codesize;
2.142 cod.compression = SPFILE_COMPRESSION_NONE;
2.143 - sfwrite(&cod, sizeof(cod), 1, fp);
2.144 - sfwrite(tbase, cod.codesize, 1, fp);
2.145 + sfwrite(&cod, sizeof(cod), 1, spf);
2.146 + sfwrite(tbase, cod.codesize, 1, spf);
2.147 free(tbase);
2.148
2.149 - /* backtrack and write this section's header info */
2.150 - curoffs = (uint32_t)ftell(fp);
2.151 - fseek(fp, offsets[0], SEEK_SET);
2.152 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
2.153 - cod.codesize += sizeof(cod);
2.154 - sfwrite(&cod.codesize, sizeof(uint32_t), 1, fp);
2.155 - fseek(fp, curoffs, SEEK_SET);
2.156 - lastsection = curoffs;
2.157 + spfw_next_section(spf);
2.158 }
2.159
2.160 - if (strcmp(tables[1], ".data") == 0)
2.161 + if (sections[FS_Data])
2.162 {
2.163 sp_file_data_t dat;
2.164 unsigned char *dbase;
2.165 @@ -366,7 +354,7 @@
2.166 cmp_dbase = (Bytef *)malloc(dat.disksize);
2.167
2.168 /* compress */
2.169 - err = compress2(cmp_dbase, &disksize, (Bytef *)dbase, dat.datasize, Z_BEST_COMPRESSION);
2.170 + err = compress2(cmp_dbase, &disksize, (Bytef *)dbase, (uLong)dat.datasize, Z_BEST_COMPRESSION);
2.171
2.172 if (err != Z_OK)
2.173 {
2.174 @@ -376,40 +364,33 @@
2.175 dat.disksize = dat.datasize;
2.176
2.177 /* write header */
2.178 - sfwrite(&dat, sizeof(dat), 1, fp);
2.179 + sfwrite(&dat, sizeof(dat), 1, spf);
2.180 /* write data */
2.181 - sfwrite(&dbase, dat.datasize, 1, fp);
2.182 + sfwrite(&dbase, dat.datasize, 1, spf);
2.183 } else {
2.184 dat.disksize = (uint32_t)disksize;
2.185
2.186 /* write header */
2.187 - sfwrite(&dat, sizeof(dat), 1, fp);
2.188 + sfwrite(&dat, sizeof(dat), 1, spf);
2.189 /* write data */
2.190 - sfwrite(&cmp_dbase, dat.disksize, 1, fp);
2.191 + sfwrite(cmp_dbase, dat.disksize, 1, spf);
2.192 }
2.193
2.194 free(cmp_dbase);
2.195 } else {
2.196 /* should be 0 */
2.197 dat.disksize = dat.datasize;
2.198 - sfwrite(&dat, sizeof(dat), 1, fp);
2.199 + sfwrite(&dat, sizeof(dat), 1, spf);
2.200 }
2.201
2.202 - /* backtrack and write this section's header info */
2.203 - curoffs = ftell(fp);
2.204 - fseek(fp, offsets[1], SEEK_SET);
2.205 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
2.206 - disksize += sizeof(dat);
2.207 - sfwrite(&disksize, sizeof(uint32_t),1, fp);
2.208 - fseek(fp, curoffs, SEEK_SET);
2.209 - lastsection = curoffs;
2.210 + spfw_next_section(spf);
2.211 }
2.212
2.213 - if (strcmp(tables[2], ".publics") == 0)
2.214 + if (sections[FS_Publics])
2.215 {
2.216 sp_file_publics_t *pbtbl;
2.217 AMX_FUNCSTUBNT *stub;
2.218 - uint32_t publics = (hdr->natives - hdr->publics) / hdr->defsize;
2.219 + uint32_t publics = sections[FS_Publics];
2.220
2.221 pbtbl = (sp_file_publics_t *)malloc(sizeof(sp_file_publics_t) * publics);
2.222 stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->publics);
2.223 @@ -423,25 +404,18 @@
2.224 }
2.225 if (publics)
2.226 {
2.227 - sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, fp);
2.228 + sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, spf);
2.229 }
2.230 free(pbtbl);
2.231
2.232 - /* backtrack and write section's header info */
2.233 - curoffs = ftell(fp);
2.234 - fseek(fp, offsets[2], SEEK_SET);
2.235 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
2.236 - publics *= sizeof(sp_file_publics_t);
2.237 - sfwrite(&publics, sizeof(uint32_t), 1, fp);
2.238 - fseek(fp, curoffs, SEEK_SET);
2.239 - lastsection = curoffs;
2.240 + spfw_next_section(spf);
2.241 }
2.242
2.243 - if (strcmp(tables[3], ".pubvars") == 0)
2.244 + if (sections[FS_Pubvars])
2.245 {
2.246 sp_file_pubvars_t *pbvars;
2.247 AMX_FUNCSTUBNT *stub;
2.248 - uint32_t pubvars = (hdr->tags - hdr->pubvars) / hdr->defsize;
2.249 + uint32_t pubvars = sections[FS_Pubvars];
2.250
2.251 pbvars = (sp_file_pubvars_t *)malloc(sizeof(sp_file_pubvars_t) * pubvars);
2.252 stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->pubvars);
2.253 @@ -455,21 +429,13 @@
2.254 }
2.255 if (pubvars)
2.256 {
2.257 - sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, fp);
2.258 + sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, spf);
2.259 }
2.260 free(pbvars);
2.261 -
2.262 - /* backtrack and write section's header info */
2.263 - curoffs = ftell(fp);
2.264 - fseek(fp, offsets[3], SEEK_SET);
2.265 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
2.266 - pubvars *= sizeof(sp_file_pubvars_t);
2.267 - sfwrite(&pubvars, sizeof(uint32_t), 1, fp);
2.268 - fseek(fp, curoffs, SEEK_SET);
2.269 - lastsection = curoffs;
2.270 + spfw_next_section(spf);
2.271 }
2.272
2.273 - if (strcmp(tables[4], ".natives") == 0)
2.274 + if (sections[FS_Natives])
2.275 {
2.276 sp_file_natives_t *nvtbl;
2.277 AMX_FUNCSTUBNT *stub;
2.278 @@ -486,21 +452,13 @@
2.279 }
2.280 if (natives)
2.281 {
2.282 - sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, fp);
2.283 + sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, spf);
2.284 }
2.285 free(nvtbl);
2.286 -
2.287 - /* backtrack and write header */
2.288 - curoffs = ftell(fp);
2.289 - fseek(fp, offsets[4], SEEK_SET);
2.290 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
2.291 - natives *= sizeof(sp_file_natives_t);
2.292 - sfwrite(&natives, sizeof(uint32_t), 1, fp);
2.293 - fseek(fp, curoffs, SEEK_SET);
2.294 - lastsection = curoffs;
2.295 + spfw_next_section(spf);
2.296 }
2.297
2.298 - if (strcmp(tables[5], ".names") == 0)
2.299 + if (sections[FS_Nametable])
2.300 {
2.301 unsigned char *base;
2.302 uint32_t namelen;
2.303 @@ -512,25 +470,18 @@
2.304 * this may clip at most an extra three bytes in!
2.305 */
2.306 namelen = hdr->cod - hdr->nametable;
2.307 - sfwrite(base, namelen, 1, fp);
2.308 -
2.309 - /* backtrack and write header */
2.310 - curoffs = ftell(fp);
2.311 - fseek(fp, offsets[5], SEEK_SET);
2.312 - sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
2.313 - sfwrite(&namelen, sizeof(uint32_t), 1, fp);
2.314 - fseek(fp, curoffs, SEEK_SET);
2.315 - lastsection = curoffs;
2.316 + sfwrite(base, namelen, 1, spf);
2.317 + spfw_next_section(spf);
2.318 }
2.319
2.320 - fclose(fp);
2.321 + spfw_finalize_all(spf);
2.322 + spfw_destroy(spf);
2.323
2.324 return 0;
2.325
2.326 write_error:
2.327 pc_printf("Error writing to file: %s", bin_file->name);
2.328 unlink(bin_file->name);
2.329 - fclose(fp);
2.330
2.331 memfile_destroy(bin_file);
2.332 bin_file = NULL;
2.333 @@ -541,9 +492,9 @@
2.334 return 1;
2.335 }
2.336
2.337 -void sfwrite(const void *buf, size_t size, size_t count, FILE *fp)
2.338 +void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf)
2.339 {
2.340 - if (fwrite(buf, size, count, fp) != count)
2.341 + if (spf->funcs.fnWrite(buf, size, count, spf->handle) != count)
2.342 {
2.343 longjmp(brkout, 1);
2.344 }
3.1 --- a/sourcepawn/compiler/scmemfil.c Sat Jul 15 19:23:07 2006 +0000
3.2 +++ b/sourcepawn/compiler/scmemfil.c Wed Jul 19 00:53:26 2006 +0000
3.3 @@ -31,26 +31,11 @@
3.4 #include <string.h>
3.5 #include "memfile.h"
3.6
3.7 -#if defined FORTIFY
3.8 - #include <alloc/fortify.h>
3.9 -#endif
3.10 -
3.11 -
3.12 -#define BUFFERSIZE 512u
3.13 -
3.14 -/* For every block, except the first:
3.15 - * buffer points to a block that is BUFFERSIZE long that holds the data
3.16 - * bufpos is the "used size" of the block
3.17 - * For the first block:
3.18 - * buffer points to the "file name"
3.19 - * bufpos is the current "file pointer"
3.20 - */
3.21 typedef memfile_t MEMFILE;
3.22 #define tMEMFILE 1
3.23
3.24 #include "sc.h"
3.25
3.26 -
3.27 MEMFILE *mfcreate(char *filename)
3.28 {
3.29 return memfile_creat(filename, 4096);
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/sourcepawn/compiler/sp_file.c Wed Jul 19 00:53:26 2006 +0000
4.3 @@ -0,0 +1,224 @@
4.4 +#include <stdio.h>
4.5 +#include <string.h>
4.6 +#include <malloc.h>
4.7 +#include "sp_file.h"
4.8 +
4.9 +void *fp_open(const char *name);
4.10 +void fp_close(void *handle);
4.11 +size_t fp_write(const void *buf, size_t size, size_t count, void *handle);
4.12 +size_t fp_read(void *buf, size_t size, size_t count, void *handle);
4.13 +size_t fp_getpos(void *handle);
4.14 +int fp_setpos(void *handle, size_t pos);
4.15 +
4.16 +sp_writefuncs_t cstd_funcs =
4.17 +{
4.18 + fp_open,
4.19 + fp_close,
4.20 + fp_write,
4.21 + fp_read,
4.22 + fp_getpos,
4.23 + fp_setpos
4.24 +};
4.25 +
4.26 +sp_file_t *spfw_create(const char *name, sp_writefuncs_t *optfuncs)
4.27 +{
4.28 + sp_file_t file;
4.29 + sp_file_t *pFile;
4.30 +
4.31 + if (!optfuncs)
4.32 + {
4.33 + optfuncs = &cstd_funcs;
4.34 + }
4.35 +
4.36 + file.handle = optfuncs->fnOpen(name);
4.37 + if (!file.handle)
4.38 + {
4.39 + return NULL;
4.40 + }
4.41 +
4.42 + pFile = (sp_file_t *)malloc(sizeof(sp_file_t));
4.43 +
4.44 + pFile->handle = file.handle;
4.45 + memcpy(&pFile->funcs, optfuncs, sizeof(sp_writefuncs_t));
4.46 + pFile->curoffs = 0;
4.47 + pFile->header.magic = SPFILE_MAGIC;
4.48 + pFile->header.sections = 0;
4.49 + pFile->header.stringtab = 0;
4.50 + pFile->header.version = SPFILE_VERSION;
4.51 + pFile->header.imagesize = 0;
4.52 + pFile->lastsection = 0;
4.53 + pFile->offsets = NULL;
4.54 + pFile->sections = NULL;
4.55 + pFile->state = -1;
4.56 + pFile->nametab = NULL;
4.57 + pFile->nametab_idx = 0;
4.58 +
4.59 + return pFile;
4.60 +}
4.61 +
4.62 +void spfw_destroy(sp_file_t *spf)
4.63 +{
4.64 + free(spf->sections);
4.65 + free(spf->nametab);
4.66 + free(spf->offsets);
4.67 + spf->funcs.fnClose(spf->handle);
4.68 + free(spf);
4.69 +}
4.70 +
4.71 +uint8_t spfw_add_section(sp_file_t *spf, const char *name)
4.72 +{
4.73 + size_t namelen;
4.74 + uint8_t s;
4.75 + if (spf->state != -1)
4.76 + {
4.77 + return 0;
4.78 + }
4.79 +
4.80 + namelen = strlen(name) + 1;
4.81 +
4.82 + if (spf->header.sections == 0)
4.83 + {
4.84 + /** allocate for first section */
4.85 + spf->sections = (sp_file_section_t *)malloc(sizeof(sp_file_section_t));
4.86 + spf->offsets = (size_t *)malloc(sizeof(size_t));
4.87 + spf->nametab = (char *)malloc(namelen);
4.88 + } else {
4.89 + uint16_t num = spf->header.sections + 1;
4.90 + spf->sections = (sp_file_section_t *)realloc(spf->sections, sizeof(sp_file_section_t) * num);
4.91 + spf->offsets = (size_t *)realloc(spf->offsets, sizeof(size_t) * num);
4.92 + spf->nametab = (char *)realloc(spf->nametab, spf->nametab_idx + namelen);
4.93 + }
4.94 +
4.95 + s = spf->header.sections;
4.96 +
4.97 + spf->sections[s].nameoffs = spf->nametab_idx;
4.98 + /**
4.99 + * "fix" offset will be the second uint2 slot, which is after the previous sections after the header.
4.100 + */
4.101 + spf->offsets[s] = sizeof(spf->header) + (sizeof(sp_file_section_t) * spf->header.sections) + sizeof(uint32_t);
4.102 + strcpy(&spf->nametab[spf->nametab_idx], name);
4.103 + spf->nametab_idx += namelen;
4.104 +
4.105 + return ++spf->header.sections;
4.106 +}
4.107 +
4.108 +int spfw_finalize_header(sp_file_t *spf)
4.109 +{
4.110 + uint32_t size;
4.111 + if (spf->state != -1)
4.112 + {
4.113 + return -1;
4.114 + }
4.115 +
4.116 + size = sizeof(sp_file_section_t) * spf->header.sections;
4.117 +
4.118 + spf->header.stringtab = sizeof(spf->header) + size;
4.119 + if (spf->funcs.fnWrite(&spf->header, sizeof(spf->header), 1, spf->handle) != 1)
4.120 + {
4.121 + return -1;
4.122 + }
4.123 + if (spf->funcs.fnWrite(spf->sections, sizeof(sp_file_section_t), spf->header.sections, spf->handle) !=
4.124 + spf->header.sections)
4.125 + {
4.126 + return -1;
4.127 + }
4.128 + if (spf->funcs.fnWrite(spf->nametab, sizeof(char), spf->nametab_idx, spf->handle) != spf->nametab_idx)
4.129 + {
4.130 + return -1;
4.131 + }
4.132 + spf->curoffs = spf->funcs.fnGetPos(spf->handle);
4.133 + spf->lastsection = spf->curoffs;
4.134 + spf->state++;
4.135 +
4.136 + return 0;
4.137 +}
4.138 +
4.139 +int spfw_next_section(sp_file_t *spf)
4.140 +{
4.141 + uint8_t s;
4.142 + uint32_t rest[2];
4.143 +
4.144 + if (spf->state < 0 || spf->state > spf->header.sections)
4.145 + {
4.146 + return -1;
4.147 + }
4.148 +
4.149 + if (spf->state == (int)spf->header.sections)
4.150 + {
4.151 + return 0;
4.152 + }
4.153 +
4.154 + s = (uint8_t)spf->state;
4.155 +
4.156 + spf->curoffs = spf->funcs.fnGetPos(spf->handle);
4.157 + spf->funcs.fnSetPos(spf->handle, spf->offsets[s]);
4.158 +
4.159 + rest[0] = spf->lastsection;
4.160 + rest[1] = spf->curoffs - spf->lastsection;
4.161 + if (spf->funcs.fnWrite(rest, sizeof(uint32_t), 2, spf->handle) != 2)
4.162 + {
4.163 + return -1;
4.164 + }
4.165 +
4.166 + spf->funcs.fnSetPos(spf->handle, spf->curoffs);
4.167 + spf->lastsection = spf->curoffs;
4.168 +
4.169 + spf->state++;
4.170 +
4.171 + return 1;
4.172 +}
4.173 +
4.174 +int spfw_finalize_all(sp_file_t *spf)
4.175 +{
4.176 + uint8_t offs;
4.177 +
4.178 + if (spf->state < spf->header.sections)
4.179 + {
4.180 + return -1;
4.181 + }
4.182 +
4.183 + offs = offsetof(sp_file_hdr_t, imagesize);
4.184 + spf->header.imagesize = spf->funcs.fnGetPos(spf->handle);
4.185 + spf->funcs.fnSetPos(spf->handle, offs);
4.186 + spf->funcs.fnWrite(&spf->header.imagesize, sizeof(uint32_t), 1, spf->handle);
4.187 + spf->funcs.fnSetPos(spf->handle, spf->header.imagesize);
4.188 +
4.189 + return 1;
4.190 +}
4.191 +
4.192 +/**
4.193 + * Default file operations...
4.194 + * Based on C standard library calls.
4.195 + */
4.196 +
4.197 +void *fp_open(const char *name)
4.198 +{
4.199 + return fopen(name, "wb");
4.200 +}
4.201 +
4.202 +void fp_close(void *handle)
4.203 +{
4.204 + fclose((FILE *)handle);
4.205 +}
4.206 +
4.207 +size_t fp_write(const void *buf, size_t size, size_t count, void *handle)
4.208 +{
4.209 + return fwrite(buf, size, count, (FILE *)handle);
4.210 +}
4.211 +
4.212 +size_t fp_read(void *buf, size_t size, size_t count, void *handle)
4.213 +{
4.214 + return fread(buf, size, count, (FILE *)handle);
4.215 +}
4.216 +
4.217 +size_t fp_getpos(void *handle)
4.218 +{
4.219 + return (size_t)ftell((FILE *)handle);
4.220 +}
4.221 +
4.222 +int fp_setpos(void *handle, size_t pos)
4.223 +{
4.224 + return fseek((FILE *)handle, (long)pos, SEEK_SET);
4.225 +}
4.226 +
4.227 +
5.1 --- a/sourcepawn/compiler/sp_file.h Sat Jul 15 19:23:07 2006 +0000
5.2 +++ b/sourcepawn/compiler/sp_file.h Wed Jul 19 00:53:26 2006 +0000
5.3 @@ -1,110 +1,80 @@
5.4 #ifndef _INCLUDE_SPFILE_H
5.5 #define _INCLUDE_SPFILE_H
5.6
5.7 -#include <stddef.h>
5.8 -#if defined __GNUC__ || defined HAVE_STDINT_
5.9 -#include <stdint.h>
5.10 -#else
5.11 - #if !defined HAVE_STDINT_H
5.12 - typedef unsigned __int64 uint64_t;
5.13 - typedef __int64 int64_t;
5.14 - typedef unsigned __int32 uint32_t;
5.15 - typedef __int32 int32_t;
5.16 - typedef unsigned __int16 uint16_t;
5.17 - typedef __int16 int16_t;
5.18 - typedef unsigned __int8 uint8_t;
5.19 - typedef __int8 int8_t;
5.20 - #define HAVE_STDINT_H
5.21 - #endif
5.22 -#endif
5.23 -
5.24 -#define SPFILE_MAGIC 0xDEADC0D3
5.25 -#define SPFILE_VERSION 0x0100
5.26 +#include "sp_file_headers.h"
5.27
5.28 -//:TODO: better compiler/nix support
5.29 -#if defined __linux__
5.30 - #pragma pack(1) /* structures must be packed (byte-aligned) */
5.31 -#else
5.32 - #pragma pack(push)
5.33 - #pragma pack(1) /* structures must be packed (byte-aligned) */
5.34 -#endif
5.35 -
5.36 -typedef struct sp_file_section_s
5.37 +/**
5.38 + * Used for overwriting writing routines.
5.39 + */
5.40 +typedef struct sp_writefuncs_s
5.41 {
5.42 - uint32_t nameoffs; /* rel offset into global string table */
5.43 - uint32_t dataoffs;
5.44 - uint32_t size;
5.45 -} sp_file_section_t;
5.46 + void *(*fnOpen)(const char *); /* filename, returns handle */
5.47 + void (*fnClose)(void *); /* handle */
5.48 + /* buffer, size, count, handle, returns count written */
5.49 + size_t (*fnWrite)(const void *, size_t, size_t, void *);
5.50 + /* buffer, size, count, handle, returns count read */
5.51 + size_t (*fnRead)(void *, size_t, size_t, void *);
5.52 + /* returns current position from start */
5.53 + size_t (*fnGetPos)(void *);
5.54 + /* sets current position from start, return 0 for success, nonzero for error */
5.55 + int (*fnSetPos)(void *, size_t);
5.56 +} sp_writefuncs_t;
5.57
5.58 -typedef struct sp_file_hdr_s
5.59 -{
5.60 - uint32_t magic;
5.61 - uint16_t version;
5.62 - uint32_t imagesize;
5.63 - uint8_t sections;
5.64 - uint32_t stringtab;
5.65 -} sp_file_hdr_t;
5.66 -
5.67 -typedef enum
5.68 -{
5.69 - SP_FILE_NONE = 0,
5.70 - SP_FILE_DEBUG = 1,
5.71 -} sp_file_flags_t;
5.72 -
5.73 -/* section is ".code" */
5.74 -typedef struct sp_file_code_s
5.75 +typedef struct sp_file_s
5.76 {
5.77 - uint32_t codesize; /* codesize in bytes */
5.78 - uint8_t cellsize; /* cellsize in bytes */
5.79 - uint8_t codeversion; /* version of opcodes supported */
5.80 - uint16_t flags; /* flags */
5.81 - uint32_t main; /* address to "main" if any */
5.82 - uint32_t disksize; /* disksize in bytes */
5.83 - uint32_t compression; /* compression */
5.84 - uint32_t code; /* rel offset to code */
5.85 -} sp_file_code_t;
5.86 + sp_file_hdr_t header;
5.87 + sp_file_section_t *sections;
5.88 + size_t *offsets;
5.89 + sp_writefuncs_t funcs;
5.90 + size_t lastsection;
5.91 + size_t curoffs;
5.92 + void *handle;
5.93 + int state;
5.94 + char *nametab;
5.95 + size_t nametab_idx;
5.96 +} sp_file_t;
5.97
5.98 -#define SPFILE_COMPRESSION_NONE 0
5.99 -#define SPFILE_COMPRESSION_GZ 1
5.100 +/**
5.101 + * Creates a new SourcePawn binary file.
5.102 + * You may optionally specify alternative writing functions.
5.103 + */
5.104 +sp_file_t *spfw_create(const char *name, sp_writefuncs_t *optfuncs);
5.105
5.106 -/* section is .data */
5.107 -typedef struct sp_file_data_s
5.108 -{
5.109 - uint32_t datasize; /* size of data section in memory */
5.110 - uint32_t memsize; /* total mem required (includes data) */
5.111 - uint32_t disksize; /* size of data on disk (compressed) */
5.112 - uint8_t compression; /* compression */
5.113 - uint32_t data; /* file offset to data (helper) */
5.114 -} sp_file_data_t;
5.115 +/**
5.116 + * Closes file handle and frees memory.
5.117 + */
5.118 +void spfw_destroy(sp_file_t *spf);
5.119
5.120 -/* section is .publics */
5.121 -typedef struct sp_file_publics_s
5.122 -{
5.123 - uint32_t address; /* address rel to code section */
5.124 - uint32_t name; /* index into nametable */
5.125 -} sp_file_publics_t;
5.126 +/**
5.127 + * Adds a section name to the header.
5.128 + * Only valid BEFORE finalization.
5.129 + * Returns the number of sections, or 0 on failure.
5.130 + */
5.131 +uint8_t spfw_add_section(sp_file_t *spf, const char *name);
5.132
5.133 -/* section is .natives */
5.134 -typedef struct sp_file_natives_s
5.135 -{
5.136 - uint32_t name; /* name of native at index */
5.137 -} sp_file_natives_t;
5.138 +/**
5.139 + * Finalizes the section header.
5.140 + * This means no more sections can be added after this call.
5.141 + * Also, aligns the writer to the first section.
5.142 + * Returns 0 on success, nonzero on error.
5.143 + */
5.144 +int spfw_finalize_header(sp_file_t *spf);
5.145
5.146 -/* section is .pubvars */
5.147 -typedef struct sp_file_pubvars_s
5.148 -{
5.149 - uint32_t address; /* address rel to dat section */
5.150 - uint32_t name; /* index into nametable */
5.151 -} sp_file_pubvars_t;
5.152 +/**
5.153 + * Finalizes the current section and advances to the next.
5.154 + * In order for this to be accurate, the file pointer must
5.155 + * reside at the end before calling this, because the size
5.156 + * is calculated by differencing with the last known offset.
5.157 + * Returns 1 if there are more sections left, 0 otherwise.
5.158 + * Returns -1 if the file state is wrong.
5.159 + */
5.160 +int spfw_next_section(sp_file_t *spf);
5.161
5.162 -#if defined __linux__
5.163 - #pragma pack() /* reset default packing */
5.164 -#else
5.165 - #pragma pack(pop) /* reset previous packing */
5.166 -#endif
5.167 -
5.168 -
5.169 -/* section is .names */
5.170 -typedef char * sp_file_nametab_t;
5.171 +/**
5.172 + * Finalizes all sections.
5.173 + * Cannot be called until all sections are used.
5.174 + * Must be called with the file pointer at the end.
5.175 + */
5.176 +int spfw_finalize_all(sp_file_t *spf);
5.177
5.178 #endif //_INCLUDE_SPFILE_H
6.1 --- a/sourcepawn/compiler/spcomp.vcproj Sat Jul 15 19:23:07 2006 +0000
6.2 +++ b/sourcepawn/compiler/spcomp.vcproj Wed Jul 19 00:53:26 2006 +0000
6.3 @@ -250,6 +250,10 @@
6.4 RelativePath=".\scvars.c"
6.5 >
6.6 </File>
6.7 + <File
6.8 + RelativePath=".\sp_file.c"
6.9 + >
6.10 + </File>
6.11 </Filter>
6.12 <Filter
6.13 Name="Header Files"
6.14 @@ -261,6 +265,10 @@
6.15 >
6.16 </File>
6.17 <File
6.18 + RelativePath=".\amxdbg.h"
6.19 + >
6.20 + </File>
6.21 + <File
6.22 RelativePath=".\lstring.h"
6.23 >
6.24 </File>
6.25 @@ -281,6 +289,10 @@
6.26 >
6.27 </File>
6.28 <File
6.29 + RelativePath=".\sp_file_headers.h"
6.30 + >
6.31 + </File>
6.32 + <File
6.33 RelativePath=".\svnrev.h"
6.34 >
6.35 </File>