added binary writer stuff
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4033
This commit is contained in:
parent
b712d61b47
commit
66f7568ce7
@ -206,9 +206,9 @@ typedef int (AMXAPI *AMX_IDLE)(struct tagAMX *amx, int AMXAPI Exec(struct tagAMX
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined __GNUC__
|
#if defined __GNUC__
|
||||||
#define PACKED __attribute__((packed))
|
#define PACKEDENTRY __attribute__((packed))
|
||||||
#else
|
#else
|
||||||
#define PACKED
|
#define PACKEDENTRY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined AMX_NO_ALIGN
|
#if !defined AMX_NO_ALIGN
|
||||||
@ -226,8 +226,8 @@ typedef int (AMXAPI *AMX_IDLE)(struct tagAMX *amx, int AMXAPI Exec(struct tagAMX
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct tagAMX_NATIVE_INFO {
|
typedef struct tagAMX_NATIVE_INFO {
|
||||||
const char _FAR *name PACKED;
|
const char _FAR *name PACKEDENTRY;
|
||||||
AMX_NATIVE func PACKED;
|
AMX_NATIVE func PACKEDENTRY;
|
||||||
} AMX_NATIVE_INFO;
|
} AMX_NATIVE_INFO;
|
||||||
|
|
||||||
#define AMX_USERNUM 4
|
#define AMX_USERNUM 4
|
||||||
@ -235,48 +235,48 @@ typedef struct tagAMX_NATIVE_INFO {
|
|||||||
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
||||||
|
|
||||||
typedef struct tagAMX_FUNCSTUB {
|
typedef struct tagAMX_FUNCSTUB {
|
||||||
ucell address PACKED;
|
ucell address PACKEDENTRY;
|
||||||
char name[sEXPMAX+1] PACKED;
|
char name[sEXPMAX+1] PACKEDENTRY;
|
||||||
} AMX_FUNCSTUB;
|
} AMX_FUNCSTUB;
|
||||||
|
|
||||||
typedef struct tagFUNCSTUBNT {
|
typedef struct tagFUNCSTUBNT {
|
||||||
ucell address PACKED;
|
ucell address PACKEDENTRY;
|
||||||
uint32_t nameofs PACKED;
|
uint32_t nameofs PACKEDENTRY;
|
||||||
} AMX_FUNCSTUBNT;
|
} AMX_FUNCSTUBNT;
|
||||||
|
|
||||||
/* The AMX structure is the internal structure for many functions. Not all
|
/* The AMX structure is the internal structure for many functions. Not all
|
||||||
* fields are valid at all times; many fields are cached in local variables.
|
* fields are valid at all times; many fields are cached in local variables.
|
||||||
*/
|
*/
|
||||||
typedef struct tagAMX {
|
typedef struct tagAMX {
|
||||||
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
unsigned char _FAR *base PACKEDENTRY; /* points to the AMX header plus the code, optionally also the data */
|
||||||
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
unsigned char _FAR *data PACKEDENTRY; /* points to separate data+stack+heap, may be NULL */
|
||||||
AMX_CALLBACK callback PACKED;
|
AMX_CALLBACK callback PACKEDENTRY;
|
||||||
AMX_DEBUG debug PACKED; /* debug callback */
|
AMX_DEBUG debug PACKEDENTRY; /* debug callback */
|
||||||
/* for external functions a few registers must be accessible from the outside */
|
/* for external functions a few registers must be accessible from the outside */
|
||||||
cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */
|
cell cip PACKEDENTRY; /* instruction pointer: relative to base + amxhdr->cod */
|
||||||
cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */
|
cell frm PACKEDENTRY; /* stack frame base: relative to base + amxhdr->dat */
|
||||||
cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */
|
cell hea PACKEDENTRY; /* top of the heap: relative to base + amxhdr->dat */
|
||||||
cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */
|
cell hlw PACKEDENTRY; /* bottom of the heap: relative to base + amxhdr->dat */
|
||||||
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
cell stk PACKEDENTRY; /* stack pointer: relative to base + amxhdr->dat */
|
||||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
cell stp PACKEDENTRY; /* top of the stack: relative to base + amxhdr->dat */
|
||||||
int flags PACKED; /* current status, see amx_Flags() */
|
int flags PACKEDENTRY; /* current status, see amx_Flags() */
|
||||||
/* user data */
|
/* user data */
|
||||||
long usertags[AMX_USERNUM] PACKED;
|
long usertags[AMX_USERNUM] PACKEDENTRY;
|
||||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
void _FAR *userdata[AMX_USERNUM] PACKEDENTRY;
|
||||||
/* native functions can raise an error */
|
/* native functions can raise an error */
|
||||||
int error PACKED;
|
int error PACKEDENTRY;
|
||||||
/* passing parameters requires a "count" field */
|
/* passing parameters requires a "count" field */
|
||||||
int paramcount;
|
int paramcount;
|
||||||
/* the sleep opcode needs to store the full AMX status */
|
/* the sleep opcode needs to store the full AMX status */
|
||||||
cell pri PACKED;
|
cell pri PACKEDENTRY;
|
||||||
cell alt PACKED;
|
cell alt PACKEDENTRY;
|
||||||
cell reset_stk PACKED;
|
cell reset_stk PACKEDENTRY;
|
||||||
cell reset_hea PACKED;
|
cell reset_hea PACKEDENTRY;
|
||||||
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
cell sysreq_d PACKEDENTRY; /* relocated address/value for the SYSREQ.D opcode */
|
||||||
#if defined JIT
|
#if defined JIT
|
||||||
/* support variables for the JIT */
|
/* support variables for the JIT */
|
||||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
int reloc_size PACKEDENTRY; /* required temporary buffer for relocations */
|
||||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
long code_size PACKEDENTRY; /* estimated memory footprint of the native code */
|
||||||
#endif
|
#endif
|
||||||
} AMX;
|
} AMX;
|
||||||
|
|
||||||
@ -284,23 +284,23 @@ typedef struct tagAMX {
|
|||||||
* structure is used internaly.
|
* structure is used internaly.
|
||||||
*/
|
*/
|
||||||
typedef struct tagAMX_HEADER {
|
typedef struct tagAMX_HEADER {
|
||||||
int32_t size PACKED; /* size of the "file" */
|
int32_t size PACKEDENTRY; /* size of the "file" */
|
||||||
uint16_t magic PACKED; /* signature */
|
uint16_t magic PACKEDENTRY; /* signature */
|
||||||
char file_version PACKED; /* file format version */
|
char file_version PACKEDENTRY; /* file format version */
|
||||||
char amx_version PACKED; /* required version of the AMX */
|
char amx_version PACKEDENTRY; /* required version of the AMX */
|
||||||
int16_t flags PACKED;
|
int16_t flags PACKEDENTRY;
|
||||||
int16_t defsize PACKED; /* size of a definition record */
|
int16_t defsize PACKEDENTRY; /* size of a definition record */
|
||||||
int32_t cod PACKED; /* initial value of COD - code block */
|
int32_t cod PACKEDENTRY; /* initial value of COD - code block */
|
||||||
int32_t dat PACKED; /* initial value of DAT - data block */
|
int32_t dat PACKEDENTRY; /* initial value of DAT - data block */
|
||||||
int32_t hea PACKED; /* initial value of HEA - start of the heap */
|
int32_t hea PACKEDENTRY; /* initial value of HEA - start of the heap */
|
||||||
int32_t stp PACKED; /* initial value of STP - stack top */
|
int32_t stp PACKEDENTRY; /* initial value of STP - stack top */
|
||||||
int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
|
int32_t cip PACKEDENTRY; /* initial value of CIP - the instruction pointer */
|
||||||
int32_t publics PACKED; /* offset to the "public functions" table */
|
int32_t publics PACKEDENTRY; /* offset to the "public functions" table */
|
||||||
int32_t natives PACKED; /* offset to the "native functions" table */
|
int32_t natives PACKEDENTRY; /* offset to the "native functions" table */
|
||||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
int32_t libraries PACKEDENTRY; /* offset to the table of libraries */
|
||||||
int32_t pubvars PACKED; /* the "public variables" table */
|
int32_t pubvars PACKEDENTRY; /* the "public variables" table */
|
||||||
int32_t tags PACKED; /* the "public tagnames" table */
|
int32_t tags PACKEDENTRY; /* the "public tagnames" table */
|
||||||
int32_t nametable PACKED; /* name table */
|
int32_t nametable PACKEDENTRY; /* name table */
|
||||||
} AMX_HEADER;
|
} AMX_HEADER;
|
||||||
|
|
||||||
#if PAWN_CELL_SIZE==16
|
#if PAWN_CELL_SIZE==16
|
||||||
|
@ -8,11 +8,27 @@
|
|||||||
#include "osdefs.h"
|
#include "osdefs.h"
|
||||||
#include "zlib/zlib.h"
|
#include "zlib/zlib.h"
|
||||||
|
|
||||||
#define NUM_SECTIONS 6
|
enum FileSections
|
||||||
|
{
|
||||||
|
FS_Code, /* required */
|
||||||
|
FS_Data, /* required */
|
||||||
|
FS_Publics,
|
||||||
|
FS_Pubvars,
|
||||||
|
FS_Natives,
|
||||||
|
FS_Nametable, /* required */
|
||||||
|
FS_DbgFile,
|
||||||
|
FS_DbgSymbol,
|
||||||
|
FS_DbgLine,
|
||||||
|
FS_DbgTags,
|
||||||
|
FS_DbgAutomaton,
|
||||||
|
FS_DbgState,
|
||||||
|
/* --- */
|
||||||
|
FS_Number,
|
||||||
|
};
|
||||||
|
|
||||||
int pc_printf(const char *message,...);
|
int pc_printf(const char *message,...);
|
||||||
int pc_compile(int argc, char **argv);
|
int pc_compile(int argc, char **argv);
|
||||||
void sfwrite(const void *buf, size_t size, size_t count, FILE *fp);
|
void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf);
|
||||||
|
|
||||||
memfile_t *bin_file = NULL;
|
memfile_t *bin_file = NULL;
|
||||||
jmp_buf brkout;
|
jmp_buf brkout;
|
||||||
@ -21,17 +37,11 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
if (pc_compile(argc,argv) == 0)
|
if (pc_compile(argc,argv) == 0)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
|
||||||
AMX_HEADER *hdr;
|
AMX_HEADER *hdr;
|
||||||
sp_file_hdr_t shdr;
|
|
||||||
uint32_t curoffs = 0;
|
|
||||||
uint32_t lastsection = 0;
|
|
||||||
int err;
|
int err;
|
||||||
uint8_t i8;
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
const char *tables[NUM_SECTIONS] = {".code", ".data", ".publics", ".pubvars", ".natives", ".names"};
|
sp_file_t *spf;
|
||||||
uint32_t offsets[NUM_SECTIONS] = {0,0,0,0,0,0};
|
uint32_t sections[FS_Number] = {1,1,0,0,0,1,0,0,0,0,0,0};
|
||||||
sp_file_section_t sh;
|
|
||||||
|
|
||||||
if (bin_file == NULL)
|
if (bin_file == NULL)
|
||||||
{
|
{
|
||||||
@ -39,13 +49,12 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
hdr = (AMX_HEADER *)bin_file->base;
|
hdr = (AMX_HEADER *)bin_file->base;
|
||||||
shdr.version = SPFILE_VERSION;
|
|
||||||
shdr.magic = SPFILE_MAGIC;
|
|
||||||
|
|
||||||
if ((fp=fopen(bin_file->name, "wb")) == NULL)
|
if ((spf=spfw_create(bin_file->name, NULL)) == NULL)
|
||||||
{
|
{
|
||||||
pc_printf("Error writing to file: %s", bin_file->name);
|
pc_printf("Error creating binary file!\n");
|
||||||
return 1;
|
memfile_destroy(bin_file);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err=setjmp(brkout))!=0)
|
if ((err=setjmp(brkout))!=0)
|
||||||
@ -53,48 +62,34 @@ int main(int argc, char *argv[])
|
|||||||
goto write_error;
|
goto write_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
shdr.sections = NUM_SECTIONS;
|
spfw_add_section(spf, ".code");
|
||||||
shdr.stringtab = sizeof(shdr) + (sizeof(sp_file_section_t) * shdr.sections);
|
spfw_add_section(spf, ".data");
|
||||||
|
|
||||||
/**
|
sections[FS_Publics] = (hdr->natives - hdr->publics) / hdr->defsize;
|
||||||
* write the header
|
if (sections[FS_Publics])
|
||||||
* unwritten values:
|
|
||||||
* imagesize
|
|
||||||
*/
|
|
||||||
sfwrite(&shdr, sizeof(shdr), 1, fp);
|
|
||||||
|
|
||||||
curoffs = shdr.stringtab;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* write the sections
|
|
||||||
* unwritten values:
|
|
||||||
* dataoffs
|
|
||||||
* size
|
|
||||||
*/
|
|
||||||
for (i8=0; i8<shdr.sections; i8++)
|
|
||||||
{
|
{
|
||||||
/* set name offset to next in string table */
|
spfw_add_section(spf, ".publics");
|
||||||
sh.nameoffs = curoffs - shdr.stringtab;
|
}
|
||||||
/* save offset to this section */
|
sections[FS_Pubvars] = (hdr->tags - hdr->pubvars) / hdr->defsize;
|
||||||
offsets[i8] = (uint32_t)ftell(fp) + sizeof(sh.nameoffs);
|
if (sections[FS_Pubvars])
|
||||||
/* update `end of file` offset */
|
{
|
||||||
curoffs += strlen(tables[i8]) + 1;
|
spfw_add_section(spf, ".pubvars");
|
||||||
sfwrite(&sh, sizeof(sh), 1, fp);
|
}
|
||||||
|
sections[FS_Natives] = (hdr->libraries - hdr->natives) / hdr->defsize;
|
||||||
|
if (sections[FS_Natives])
|
||||||
|
{
|
||||||
|
spfw_add_section(spf, ".natives");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** write the string table */
|
spfw_add_section(spf, ".names");
|
||||||
for (i8=0; i8<shdr.sections; i8++)
|
|
||||||
{
|
|
||||||
sfwrite(tables[i8], 1, strlen(tables[i8])+1, fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastsection = curoffs;
|
spfw_finalize_header(spf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin writing each of our known tables out
|
* Begin writing each of our known tables out
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (strcmp(tables[0], ".code") == 0)
|
if (sections[FS_Code])
|
||||||
{
|
{
|
||||||
sp_file_code_t cod;
|
sp_file_code_t cod;
|
||||||
cell cip;
|
cell cip;
|
||||||
@ -331,21 +326,14 @@ int main(int argc, char *argv[])
|
|||||||
cod.codesize = (uint32_t)(tptr - tbase);
|
cod.codesize = (uint32_t)(tptr - tbase);
|
||||||
cod.disksize = cod.codesize;
|
cod.disksize = cod.codesize;
|
||||||
cod.compression = SPFILE_COMPRESSION_NONE;
|
cod.compression = SPFILE_COMPRESSION_NONE;
|
||||||
sfwrite(&cod, sizeof(cod), 1, fp);
|
sfwrite(&cod, sizeof(cod), 1, spf);
|
||||||
sfwrite(tbase, cod.codesize, 1, fp);
|
sfwrite(tbase, cod.codesize, 1, spf);
|
||||||
free(tbase);
|
free(tbase);
|
||||||
|
|
||||||
/* backtrack and write this section's header info */
|
spfw_next_section(spf);
|
||||||
curoffs = (uint32_t)ftell(fp);
|
|
||||||
fseek(fp, offsets[0], SEEK_SET);
|
|
||||||
sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
|
|
||||||
cod.codesize += sizeof(cod);
|
|
||||||
sfwrite(&cod.codesize, sizeof(uint32_t), 1, fp);
|
|
||||||
fseek(fp, curoffs, SEEK_SET);
|
|
||||||
lastsection = curoffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tables[1], ".data") == 0)
|
if (sections[FS_Data])
|
||||||
{
|
{
|
||||||
sp_file_data_t dat;
|
sp_file_data_t dat;
|
||||||
unsigned char *dbase;
|
unsigned char *dbase;
|
||||||
@ -366,7 +354,7 @@ int main(int argc, char *argv[])
|
|||||||
cmp_dbase = (Bytef *)malloc(dat.disksize);
|
cmp_dbase = (Bytef *)malloc(dat.disksize);
|
||||||
|
|
||||||
/* compress */
|
/* compress */
|
||||||
err = compress2(cmp_dbase, &disksize, (Bytef *)dbase, dat.datasize, Z_BEST_COMPRESSION);
|
err = compress2(cmp_dbase, &disksize, (Bytef *)dbase, (uLong)dat.datasize, Z_BEST_COMPRESSION);
|
||||||
|
|
||||||
if (err != Z_OK)
|
if (err != Z_OK)
|
||||||
{
|
{
|
||||||
@ -376,40 +364,33 @@ int main(int argc, char *argv[])
|
|||||||
dat.disksize = dat.datasize;
|
dat.disksize = dat.datasize;
|
||||||
|
|
||||||
/* write header */
|
/* write header */
|
||||||
sfwrite(&dat, sizeof(dat), 1, fp);
|
sfwrite(&dat, sizeof(dat), 1, spf);
|
||||||
/* write data */
|
/* write data */
|
||||||
sfwrite(&dbase, dat.datasize, 1, fp);
|
sfwrite(&dbase, dat.datasize, 1, spf);
|
||||||
} else {
|
} else {
|
||||||
dat.disksize = (uint32_t)disksize;
|
dat.disksize = (uint32_t)disksize;
|
||||||
|
|
||||||
/* write header */
|
/* write header */
|
||||||
sfwrite(&dat, sizeof(dat), 1, fp);
|
sfwrite(&dat, sizeof(dat), 1, spf);
|
||||||
/* write data */
|
/* write data */
|
||||||
sfwrite(&cmp_dbase, dat.disksize, 1, fp);
|
sfwrite(cmp_dbase, dat.disksize, 1, spf);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(cmp_dbase);
|
free(cmp_dbase);
|
||||||
} else {
|
} else {
|
||||||
/* should be 0 */
|
/* should be 0 */
|
||||||
dat.disksize = dat.datasize;
|
dat.disksize = dat.datasize;
|
||||||
sfwrite(&dat, sizeof(dat), 1, fp);
|
sfwrite(&dat, sizeof(dat), 1, spf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* backtrack and write this section's header info */
|
spfw_next_section(spf);
|
||||||
curoffs = ftell(fp);
|
|
||||||
fseek(fp, offsets[1], SEEK_SET);
|
|
||||||
sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
|
|
||||||
disksize += sizeof(dat);
|
|
||||||
sfwrite(&disksize, sizeof(uint32_t),1, fp);
|
|
||||||
fseek(fp, curoffs, SEEK_SET);
|
|
||||||
lastsection = curoffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tables[2], ".publics") == 0)
|
if (sections[FS_Publics])
|
||||||
{
|
{
|
||||||
sp_file_publics_t *pbtbl;
|
sp_file_publics_t *pbtbl;
|
||||||
AMX_FUNCSTUBNT *stub;
|
AMX_FUNCSTUBNT *stub;
|
||||||
uint32_t publics = (hdr->natives - hdr->publics) / hdr->defsize;
|
uint32_t publics = sections[FS_Publics];
|
||||||
|
|
||||||
pbtbl = (sp_file_publics_t *)malloc(sizeof(sp_file_publics_t) * publics);
|
pbtbl = (sp_file_publics_t *)malloc(sizeof(sp_file_publics_t) * publics);
|
||||||
stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->publics);
|
stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->publics);
|
||||||
@ -423,25 +404,18 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (publics)
|
if (publics)
|
||||||
{
|
{
|
||||||
sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, fp);
|
sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, spf);
|
||||||
}
|
}
|
||||||
free(pbtbl);
|
free(pbtbl);
|
||||||
|
|
||||||
/* backtrack and write section's header info */
|
spfw_next_section(spf);
|
||||||
curoffs = ftell(fp);
|
|
||||||
fseek(fp, offsets[2], SEEK_SET);
|
|
||||||
sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
|
|
||||||
publics *= sizeof(sp_file_publics_t);
|
|
||||||
sfwrite(&publics, sizeof(uint32_t), 1, fp);
|
|
||||||
fseek(fp, curoffs, SEEK_SET);
|
|
||||||
lastsection = curoffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tables[3], ".pubvars") == 0)
|
if (sections[FS_Pubvars])
|
||||||
{
|
{
|
||||||
sp_file_pubvars_t *pbvars;
|
sp_file_pubvars_t *pbvars;
|
||||||
AMX_FUNCSTUBNT *stub;
|
AMX_FUNCSTUBNT *stub;
|
||||||
uint32_t pubvars = (hdr->tags - hdr->pubvars) / hdr->defsize;
|
uint32_t pubvars = sections[FS_Pubvars];
|
||||||
|
|
||||||
pbvars = (sp_file_pubvars_t *)malloc(sizeof(sp_file_pubvars_t) * pubvars);
|
pbvars = (sp_file_pubvars_t *)malloc(sizeof(sp_file_pubvars_t) * pubvars);
|
||||||
stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->pubvars);
|
stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->pubvars);
|
||||||
@ -455,21 +429,13 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (pubvars)
|
if (pubvars)
|
||||||
{
|
{
|
||||||
sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, fp);
|
sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, spf);
|
||||||
}
|
}
|
||||||
free(pbvars);
|
free(pbvars);
|
||||||
|
spfw_next_section(spf);
|
||||||
/* backtrack and write section's header info */
|
|
||||||
curoffs = ftell(fp);
|
|
||||||
fseek(fp, offsets[3], SEEK_SET);
|
|
||||||
sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
|
|
||||||
pubvars *= sizeof(sp_file_pubvars_t);
|
|
||||||
sfwrite(&pubvars, sizeof(uint32_t), 1, fp);
|
|
||||||
fseek(fp, curoffs, SEEK_SET);
|
|
||||||
lastsection = curoffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tables[4], ".natives") == 0)
|
if (sections[FS_Natives])
|
||||||
{
|
{
|
||||||
sp_file_natives_t *nvtbl;
|
sp_file_natives_t *nvtbl;
|
||||||
AMX_FUNCSTUBNT *stub;
|
AMX_FUNCSTUBNT *stub;
|
||||||
@ -486,21 +452,13 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (natives)
|
if (natives)
|
||||||
{
|
{
|
||||||
sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, fp);
|
sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, spf);
|
||||||
}
|
}
|
||||||
free(nvtbl);
|
free(nvtbl);
|
||||||
|
spfw_next_section(spf);
|
||||||
/* backtrack and write header */
|
|
||||||
curoffs = ftell(fp);
|
|
||||||
fseek(fp, offsets[4], SEEK_SET);
|
|
||||||
sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
|
|
||||||
natives *= sizeof(sp_file_natives_t);
|
|
||||||
sfwrite(&natives, sizeof(uint32_t), 1, fp);
|
|
||||||
fseek(fp, curoffs, SEEK_SET);
|
|
||||||
lastsection = curoffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tables[5], ".names") == 0)
|
if (sections[FS_Nametable])
|
||||||
{
|
{
|
||||||
unsigned char *base;
|
unsigned char *base;
|
||||||
uint32_t namelen;
|
uint32_t namelen;
|
||||||
@ -512,25 +470,18 @@ int main(int argc, char *argv[])
|
|||||||
* this may clip at most an extra three bytes in!
|
* this may clip at most an extra three bytes in!
|
||||||
*/
|
*/
|
||||||
namelen = hdr->cod - hdr->nametable;
|
namelen = hdr->cod - hdr->nametable;
|
||||||
sfwrite(base, namelen, 1, fp);
|
sfwrite(base, namelen, 1, spf);
|
||||||
|
spfw_next_section(spf);
|
||||||
/* backtrack and write header */
|
|
||||||
curoffs = ftell(fp);
|
|
||||||
fseek(fp, offsets[5], SEEK_SET);
|
|
||||||
sfwrite(&lastsection, sizeof(uint32_t), 1, fp);
|
|
||||||
sfwrite(&namelen, sizeof(uint32_t), 1, fp);
|
|
||||||
fseek(fp, curoffs, SEEK_SET);
|
|
||||||
lastsection = curoffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
spfw_finalize_all(spf);
|
||||||
|
spfw_destroy(spf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
write_error:
|
write_error:
|
||||||
pc_printf("Error writing to file: %s", bin_file->name);
|
pc_printf("Error writing to file: %s", bin_file->name);
|
||||||
unlink(bin_file->name);
|
unlink(bin_file->name);
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
memfile_destroy(bin_file);
|
memfile_destroy(bin_file);
|
||||||
bin_file = NULL;
|
bin_file = NULL;
|
||||||
@ -541,9 +492,9 @@ write_error:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfwrite(const void *buf, size_t size, size_t count, FILE *fp)
|
void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf)
|
||||||
{
|
{
|
||||||
if (fwrite(buf, size, count, fp) != count)
|
if (spf->funcs.fnWrite(buf, size, count, spf->handle) != count)
|
||||||
{
|
{
|
||||||
longjmp(brkout, 1);
|
longjmp(brkout, 1);
|
||||||
}
|
}
|
||||||
|
@ -31,26 +31,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "memfile.h"
|
#include "memfile.h"
|
||||||
|
|
||||||
#if defined FORTIFY
|
|
||||||
#include <alloc/fortify.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define BUFFERSIZE 512u
|
|
||||||
|
|
||||||
/* For every block, except the first:
|
|
||||||
* buffer points to a block that is BUFFERSIZE long that holds the data
|
|
||||||
* bufpos is the "used size" of the block
|
|
||||||
* For the first block:
|
|
||||||
* buffer points to the "file name"
|
|
||||||
* bufpos is the current "file pointer"
|
|
||||||
*/
|
|
||||||
typedef memfile_t MEMFILE;
|
typedef memfile_t MEMFILE;
|
||||||
#define tMEMFILE 1
|
#define tMEMFILE 1
|
||||||
|
|
||||||
#include "sc.h"
|
#include "sc.h"
|
||||||
|
|
||||||
|
|
||||||
MEMFILE *mfcreate(char *filename)
|
MEMFILE *mfcreate(char *filename)
|
||||||
{
|
{
|
||||||
return memfile_creat(filename, 4096);
|
return memfile_creat(filename, 4096);
|
||||||
|
224
sourcepawn/compiler/sp_file.c
Normal file
224
sourcepawn/compiler/sp_file.c
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "sp_file.h"
|
||||||
|
|
||||||
|
void *fp_open(const char *name);
|
||||||
|
void fp_close(void *handle);
|
||||||
|
size_t fp_write(const void *buf, size_t size, size_t count, void *handle);
|
||||||
|
size_t fp_read(void *buf, size_t size, size_t count, void *handle);
|
||||||
|
size_t fp_getpos(void *handle);
|
||||||
|
int fp_setpos(void *handle, size_t pos);
|
||||||
|
|
||||||
|
sp_writefuncs_t cstd_funcs =
|
||||||
|
{
|
||||||
|
fp_open,
|
||||||
|
fp_close,
|
||||||
|
fp_write,
|
||||||
|
fp_read,
|
||||||
|
fp_getpos,
|
||||||
|
fp_setpos
|
||||||
|
};
|
||||||
|
|
||||||
|
sp_file_t *spfw_create(const char *name, sp_writefuncs_t *optfuncs)
|
||||||
|
{
|
||||||
|
sp_file_t file;
|
||||||
|
sp_file_t *pFile;
|
||||||
|
|
||||||
|
if (!optfuncs)
|
||||||
|
{
|
||||||
|
optfuncs = &cstd_funcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.handle = optfuncs->fnOpen(name);
|
||||||
|
if (!file.handle)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFile = (sp_file_t *)malloc(sizeof(sp_file_t));
|
||||||
|
|
||||||
|
pFile->handle = file.handle;
|
||||||
|
memcpy(&pFile->funcs, optfuncs, sizeof(sp_writefuncs_t));
|
||||||
|
pFile->curoffs = 0;
|
||||||
|
pFile->header.magic = SPFILE_MAGIC;
|
||||||
|
pFile->header.sections = 0;
|
||||||
|
pFile->header.stringtab = 0;
|
||||||
|
pFile->header.version = SPFILE_VERSION;
|
||||||
|
pFile->header.imagesize = 0;
|
||||||
|
pFile->lastsection = 0;
|
||||||
|
pFile->offsets = NULL;
|
||||||
|
pFile->sections = NULL;
|
||||||
|
pFile->state = -1;
|
||||||
|
pFile->nametab = NULL;
|
||||||
|
pFile->nametab_idx = 0;
|
||||||
|
|
||||||
|
return pFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spfw_destroy(sp_file_t *spf)
|
||||||
|
{
|
||||||
|
free(spf->sections);
|
||||||
|
free(spf->nametab);
|
||||||
|
free(spf->offsets);
|
||||||
|
spf->funcs.fnClose(spf->handle);
|
||||||
|
free(spf);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t spfw_add_section(sp_file_t *spf, const char *name)
|
||||||
|
{
|
||||||
|
size_t namelen;
|
||||||
|
uint8_t s;
|
||||||
|
if (spf->state != -1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
namelen = strlen(name) + 1;
|
||||||
|
|
||||||
|
if (spf->header.sections == 0)
|
||||||
|
{
|
||||||
|
/** allocate for first section */
|
||||||
|
spf->sections = (sp_file_section_t *)malloc(sizeof(sp_file_section_t));
|
||||||
|
spf->offsets = (size_t *)malloc(sizeof(size_t));
|
||||||
|
spf->nametab = (char *)malloc(namelen);
|
||||||
|
} else {
|
||||||
|
uint16_t num = spf->header.sections + 1;
|
||||||
|
spf->sections = (sp_file_section_t *)realloc(spf->sections, sizeof(sp_file_section_t) * num);
|
||||||
|
spf->offsets = (size_t *)realloc(spf->offsets, sizeof(size_t) * num);
|
||||||
|
spf->nametab = (char *)realloc(spf->nametab, spf->nametab_idx + namelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = spf->header.sections;
|
||||||
|
|
||||||
|
spf->sections[s].nameoffs = spf->nametab_idx;
|
||||||
|
/**
|
||||||
|
* "fix" offset will be the second uint2 slot, which is after the previous sections after the header.
|
||||||
|
*/
|
||||||
|
spf->offsets[s] = sizeof(spf->header) + (sizeof(sp_file_section_t) * spf->header.sections) + sizeof(uint32_t);
|
||||||
|
strcpy(&spf->nametab[spf->nametab_idx], name);
|
||||||
|
spf->nametab_idx += namelen;
|
||||||
|
|
||||||
|
return ++spf->header.sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spfw_finalize_header(sp_file_t *spf)
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
if (spf->state != -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = sizeof(sp_file_section_t) * spf->header.sections;
|
||||||
|
|
||||||
|
spf->header.stringtab = sizeof(spf->header) + size;
|
||||||
|
if (spf->funcs.fnWrite(&spf->header, sizeof(spf->header), 1, spf->handle) != 1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (spf->funcs.fnWrite(spf->sections, sizeof(sp_file_section_t), spf->header.sections, spf->handle) !=
|
||||||
|
spf->header.sections)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (spf->funcs.fnWrite(spf->nametab, sizeof(char), spf->nametab_idx, spf->handle) != spf->nametab_idx)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
spf->curoffs = spf->funcs.fnGetPos(spf->handle);
|
||||||
|
spf->lastsection = spf->curoffs;
|
||||||
|
spf->state++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spfw_next_section(sp_file_t *spf)
|
||||||
|
{
|
||||||
|
uint8_t s;
|
||||||
|
uint32_t rest[2];
|
||||||
|
|
||||||
|
if (spf->state < 0 || spf->state > spf->header.sections)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spf->state == (int)spf->header.sections)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = (uint8_t)spf->state;
|
||||||
|
|
||||||
|
spf->curoffs = spf->funcs.fnGetPos(spf->handle);
|
||||||
|
spf->funcs.fnSetPos(spf->handle, spf->offsets[s]);
|
||||||
|
|
||||||
|
rest[0] = spf->lastsection;
|
||||||
|
rest[1] = spf->curoffs - spf->lastsection;
|
||||||
|
if (spf->funcs.fnWrite(rest, sizeof(uint32_t), 2, spf->handle) != 2)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
spf->funcs.fnSetPos(spf->handle, spf->curoffs);
|
||||||
|
spf->lastsection = spf->curoffs;
|
||||||
|
|
||||||
|
spf->state++;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spfw_finalize_all(sp_file_t *spf)
|
||||||
|
{
|
||||||
|
uint8_t offs;
|
||||||
|
|
||||||
|
if (spf->state < spf->header.sections)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
offs = offsetof(sp_file_hdr_t, imagesize);
|
||||||
|
spf->header.imagesize = spf->funcs.fnGetPos(spf->handle);
|
||||||
|
spf->funcs.fnSetPos(spf->handle, offs);
|
||||||
|
spf->funcs.fnWrite(&spf->header.imagesize, sizeof(uint32_t), 1, spf->handle);
|
||||||
|
spf->funcs.fnSetPos(spf->handle, spf->header.imagesize);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default file operations...
|
||||||
|
* Based on C standard library calls.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *fp_open(const char *name)
|
||||||
|
{
|
||||||
|
return fopen(name, "wb");
|
||||||
|
}
|
||||||
|
|
||||||
|
void fp_close(void *handle)
|
||||||
|
{
|
||||||
|
fclose((FILE *)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fp_write(const void *buf, size_t size, size_t count, void *handle)
|
||||||
|
{
|
||||||
|
return fwrite(buf, size, count, (FILE *)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fp_read(void *buf, size_t size, size_t count, void *handle)
|
||||||
|
{
|
||||||
|
return fread(buf, size, count, (FILE *)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fp_getpos(void *handle)
|
||||||
|
{
|
||||||
|
return (size_t)ftell((FILE *)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fp_setpos(void *handle, size_t pos)
|
||||||
|
{
|
||||||
|
return fseek((FILE *)handle, (long)pos, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,110 +1,80 @@
|
|||||||
#ifndef _INCLUDE_SPFILE_H
|
#ifndef _INCLUDE_SPFILE_H
|
||||||
#define _INCLUDE_SPFILE_H
|
#define _INCLUDE_SPFILE_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include "sp_file_headers.h"
|
||||||
#if defined __GNUC__ || defined HAVE_STDINT_
|
|
||||||
#include <stdint.h>
|
|
||||||
#else
|
|
||||||
#if !defined HAVE_STDINT_H
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
typedef __int64 int64_t;
|
|
||||||
typedef unsigned __int32 uint32_t;
|
|
||||||
typedef __int32 int32_t;
|
|
||||||
typedef unsigned __int16 uint16_t;
|
|
||||||
typedef __int16 int16_t;
|
|
||||||
typedef unsigned __int8 uint8_t;
|
|
||||||
typedef __int8 int8_t;
|
|
||||||
#define HAVE_STDINT_H
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SPFILE_MAGIC 0xDEADC0D3
|
/**
|
||||||
#define SPFILE_VERSION 0x0100
|
* Used for overwriting writing routines.
|
||||||
|
*/
|
||||||
//:TODO: better compiler/nix support
|
typedef struct sp_writefuncs_s
|
||||||
#if defined __linux__
|
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
|
||||||
#else
|
|
||||||
#pragma pack(push)
|
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct sp_file_section_s
|
|
||||||
{
|
{
|
||||||
uint32_t nameoffs; /* rel offset into global string table */
|
void *(*fnOpen)(const char *); /* filename, returns handle */
|
||||||
uint32_t dataoffs;
|
void (*fnClose)(void *); /* handle */
|
||||||
uint32_t size;
|
/* buffer, size, count, handle, returns count written */
|
||||||
} sp_file_section_t;
|
size_t (*fnWrite)(const void *, size_t, size_t, void *);
|
||||||
|
/* buffer, size, count, handle, returns count read */
|
||||||
|
size_t (*fnRead)(void *, size_t, size_t, void *);
|
||||||
|
/* returns current position from start */
|
||||||
|
size_t (*fnGetPos)(void *);
|
||||||
|
/* sets current position from start, return 0 for success, nonzero for error */
|
||||||
|
int (*fnSetPos)(void *, size_t);
|
||||||
|
} sp_writefuncs_t;
|
||||||
|
|
||||||
typedef struct sp_file_hdr_s
|
typedef struct sp_file_s
|
||||||
{
|
{
|
||||||
uint32_t magic;
|
sp_file_hdr_t header;
|
||||||
uint16_t version;
|
sp_file_section_t *sections;
|
||||||
uint32_t imagesize;
|
size_t *offsets;
|
||||||
uint8_t sections;
|
sp_writefuncs_t funcs;
|
||||||
uint32_t stringtab;
|
size_t lastsection;
|
||||||
} sp_file_hdr_t;
|
size_t curoffs;
|
||||||
|
void *handle;
|
||||||
|
int state;
|
||||||
|
char *nametab;
|
||||||
|
size_t nametab_idx;
|
||||||
|
} sp_file_t;
|
||||||
|
|
||||||
typedef enum
|
/**
|
||||||
{
|
* Creates a new SourcePawn binary file.
|
||||||
SP_FILE_NONE = 0,
|
* You may optionally specify alternative writing functions.
|
||||||
SP_FILE_DEBUG = 1,
|
*/
|
||||||
} sp_file_flags_t;
|
sp_file_t *spfw_create(const char *name, sp_writefuncs_t *optfuncs);
|
||||||
|
|
||||||
/* section is ".code" */
|
/**
|
||||||
typedef struct sp_file_code_s
|
* Closes file handle and frees memory.
|
||||||
{
|
*/
|
||||||
uint32_t codesize; /* codesize in bytes */
|
void spfw_destroy(sp_file_t *spf);
|
||||||
uint8_t cellsize; /* cellsize in bytes */
|
|
||||||
uint8_t codeversion; /* version of opcodes supported */
|
|
||||||
uint16_t flags; /* flags */
|
|
||||||
uint32_t main; /* address to "main" if any */
|
|
||||||
uint32_t disksize; /* disksize in bytes */
|
|
||||||
uint32_t compression; /* compression */
|
|
||||||
uint32_t code; /* rel offset to code */
|
|
||||||
} sp_file_code_t;
|
|
||||||
|
|
||||||
#define SPFILE_COMPRESSION_NONE 0
|
/**
|
||||||
#define SPFILE_COMPRESSION_GZ 1
|
* Adds a section name to the header.
|
||||||
|
* Only valid BEFORE finalization.
|
||||||
|
* Returns the number of sections, or 0 on failure.
|
||||||
|
*/
|
||||||
|
uint8_t spfw_add_section(sp_file_t *spf, const char *name);
|
||||||
|
|
||||||
/* section is .data */
|
/**
|
||||||
typedef struct sp_file_data_s
|
* Finalizes the section header.
|
||||||
{
|
* This means no more sections can be added after this call.
|
||||||
uint32_t datasize; /* size of data section in memory */
|
* Also, aligns the writer to the first section.
|
||||||
uint32_t memsize; /* total mem required (includes data) */
|
* Returns 0 on success, nonzero on error.
|
||||||
uint32_t disksize; /* size of data on disk (compressed) */
|
*/
|
||||||
uint8_t compression; /* compression */
|
int spfw_finalize_header(sp_file_t *spf);
|
||||||
uint32_t data; /* file offset to data (helper) */
|
|
||||||
} sp_file_data_t;
|
|
||||||
|
|
||||||
/* section is .publics */
|
/**
|
||||||
typedef struct sp_file_publics_s
|
* Finalizes the current section and advances to the next.
|
||||||
{
|
* In order for this to be accurate, the file pointer must
|
||||||
uint32_t address; /* address rel to code section */
|
* reside at the end before calling this, because the size
|
||||||
uint32_t name; /* index into nametable */
|
* is calculated by differencing with the last known offset.
|
||||||
} sp_file_publics_t;
|
* Returns 1 if there are more sections left, 0 otherwise.
|
||||||
|
* Returns -1 if the file state is wrong.
|
||||||
|
*/
|
||||||
|
int spfw_next_section(sp_file_t *spf);
|
||||||
|
|
||||||
/* section is .natives */
|
/**
|
||||||
typedef struct sp_file_natives_s
|
* Finalizes all sections.
|
||||||
{
|
* Cannot be called until all sections are used.
|
||||||
uint32_t name; /* name of native at index */
|
* Must be called with the file pointer at the end.
|
||||||
} sp_file_natives_t;
|
*/
|
||||||
|
int spfw_finalize_all(sp_file_t *spf);
|
||||||
/* section is .pubvars */
|
|
||||||
typedef struct sp_file_pubvars_s
|
|
||||||
{
|
|
||||||
uint32_t address; /* address rel to dat section */
|
|
||||||
uint32_t name; /* index into nametable */
|
|
||||||
} sp_file_pubvars_t;
|
|
||||||
|
|
||||||
#if defined __linux__
|
|
||||||
#pragma pack() /* reset default packing */
|
|
||||||
#else
|
|
||||||
#pragma pack(pop) /* reset previous packing */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* section is .names */
|
|
||||||
typedef char * sp_file_nametab_t;
|
|
||||||
|
|
||||||
#endif //_INCLUDE_SPFILE_H
|
#endif //_INCLUDE_SPFILE_H
|
||||||
|
@ -250,6 +250,10 @@
|
|||||||
RelativePath=".\scvars.c"
|
RelativePath=".\scvars.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sp_file.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
@ -260,6 +264,10 @@
|
|||||||
RelativePath=".\amx.h"
|
RelativePath=".\amx.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\amxdbg.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\lstring.h"
|
RelativePath=".\lstring.h"
|
||||||
>
|
>
|
||||||
@ -280,6 +288,10 @@
|
|||||||
RelativePath=".\sp_file.h"
|
RelativePath=".\sp_file.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\sp_file_headers.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\svnrev.h"
|
RelativePath=".\svnrev.h"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user