sourcepawn/compiler/pawncc.c
author David Anderson <dvander@alliedmods.net>
Thu Jan 25 20:08:00 2007 +0000 (2007-01-25)
changeset 353 492a8d0d5f59
parent 343 9f6532016ce1
child 386 f095e8dbb569
permissions -rw-r--r--
added linux support
dvander@27
     1
#include <stdio.h>
dvander@27
     2
#include <setjmp.h>
dvander@27
     3
#include <assert.h>
dvander@27
     4
#include <string.h>
dvander@27
     5
#include "memfile.h"
dvander@27
     6
#include "sp_file.h"
dvander@27
     7
#include "amx.h"
dvander@31
     8
#include "amxdbg.h"
dvander@27
     9
#include "osdefs.h"
dvander@27
    10
#include "zlib/zlib.h"
dvander@27
    11
dvander@29
    12
enum FileSections
dvander@29
    13
{
dvander@29
    14
	FS_Code,			/* required */
dvander@29
    15
	FS_Data,			/* required */
dvander@29
    16
	FS_Publics,
dvander@29
    17
	FS_Pubvars,
dvander@29
    18
	FS_Natives,
faluco@144
    19
	FS_Libraries,
dvander@29
    20
	FS_Nametable,		/* required */
dvander@29
    21
	FS_DbgFile,
dvander@29
    22
	FS_DbgSymbol,
dvander@29
    23
	FS_DbgLine,
dvander@29
    24
	FS_DbgTags,
dvander@29
    25
	FS_DbgAutomaton,
dvander@29
    26
	FS_DbgState,
dvander@31
    27
	FS_DbgStrings,
dvander@46
    28
	FS_DbgInfo,
dvander@29
    29
	/* --- */
dvander@29
    30
	FS_Number,
dvander@29
    31
};
dvander@27
    32
dvander@27
    33
int pc_printf(const char *message,...);
dvander@27
    34
int pc_compile(int argc, char **argv);
dvander@29
    35
void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf);
dvander@27
    36
dvander@27
    37
memfile_t *bin_file = NULL;
dvander@27
    38
jmp_buf brkout;
dvander@27
    39
dvander@27
    40
int main(int argc, char *argv[])
dvander@27
    41
{
dvander@343
    42
#if defined _DEBUG
dvander@343
    43
	getchar();
dvander@343
    44
#endif
dvander@27
    45
	if (pc_compile(argc,argv) == 0)
dvander@27
    46
	{
dvander@27
    47
		AMX_HEADER *hdr;
dvander@31
    48
		AMX_DBG_HDR *dbg = NULL;
dvander@27
    49
		int err;
dvander@27
    50
		uint32_t i;
dvander@29
    51
		sp_file_t *spf;
dvander@132
    52
		memfile_t *dbgtab = NULL;		//dbgcrab
dvander@31
    53
		unsigned char *dbgptr = NULL;
faluco@144
    54
		uint32_t sections[FS_Number] = {1,1,0,0,0,0,1,0,0,0,0,0,0};
dvander@31
    55
		FILE *fp;
dvander@27
    56
dvander@27
    57
		if (bin_file == NULL)
dvander@27
    58
		{
dvander@27
    59
			return 0;
dvander@27
    60
		}
dvander@27
    61
dvander@27
    62
		hdr = (AMX_HEADER *)bin_file->base;
dvander@27
    63
dvander@29
    64
		if ((spf=spfw_create(bin_file->name, NULL)) == NULL)
dvander@27
    65
		{
dvander@29
    66
			pc_printf("Error creating binary file!\n");
dvander@29
    67
			memfile_destroy(bin_file);
dvander@29
    68
			return 0;
dvander@27
    69
		}
dvander@27
    70
dvander@27
    71
		if ((err=setjmp(brkout))!=0)
dvander@27
    72
		{
dvander@27
    73
			goto write_error;
dvander@27
    74
		}
dvander@27
    75
dvander@29
    76
		spfw_add_section(spf, ".code");
dvander@29
    77
		spfw_add_section(spf, ".data");
dvander@27
    78
dvander@29
    79
		sections[FS_Publics] = (hdr->natives - hdr->publics) / hdr->defsize;
dvander@29
    80
		if (sections[FS_Publics])
dvander@27
    81
		{
dvander@29
    82
			spfw_add_section(spf, ".publics");
dvander@29
    83
		}
dvander@29
    84
		sections[FS_Pubvars] = (hdr->tags - hdr->pubvars) / hdr->defsize;
dvander@29
    85
		if (sections[FS_Pubvars])
dvander@29
    86
		{
dvander@29
    87
			spfw_add_section(spf, ".pubvars");
dvander@29
    88
		}
dvander@29
    89
		sections[FS_Natives] = (hdr->libraries - hdr->natives) / hdr->defsize;
dvander@29
    90
		if (sections[FS_Natives])
dvander@29
    91
		{
dvander@29
    92
			spfw_add_section(spf, ".natives");
dvander@27
    93
		}
faluco@144
    94
		sections[FS_Libraries] = (hdr->pubvars - hdr->libraries) / hdr->defsize;
faluco@144
    95
		if (sections[FS_Libraries])
faluco@144
    96
		{
faluco@144
    97
			spfw_add_section(spf, ".libraries");
faluco@144
    98
		}
dvander@27
    99
dvander@29
   100
		spfw_add_section(spf, ".names");
dvander@27
   101
dvander@31
   102
		if (hdr->flags & AMX_FLAG_DEBUG)
dvander@31
   103
		{
dvander@31
   104
			dbg = (AMX_DBG_HDR *)((unsigned char *)hdr + hdr->size);
dvander@31
   105
			if (dbg->magic != AMX_DBG_MAGIC)
dvander@31
   106
			{
dvander@31
   107
				pc_printf("Error reading AMX_DBG_HDR, debug data will not be written.");
dvander@31
   108
			} else {
dvander@31
   109
				dbgtab = memfile_creat("", 512);
dvander@31
   110
				dbgptr = (unsigned char *)dbg + sizeof(AMX_DBG_HDR);
dvander@31
   111
				if (dbg->files)
dvander@31
   112
				{
dvander@31
   113
					spfw_add_section(spf, ".dbg.files");
dvander@31
   114
					sections[FS_DbgFile] = dbg->files;
dvander@31
   115
				}
dvander@31
   116
				if (dbg->lines)
dvander@31
   117
				{
dvander@31
   118
					spfw_add_section(spf, ".dbg.lines");
dvander@31
   119
					sections[FS_DbgLine] = dbg->lines;
dvander@31
   120
				}
dvander@31
   121
				if (dbg->symbols)
dvander@31
   122
				{
dvander@31
   123
					spfw_add_section(spf, ".dbg.symbols");
dvander@31
   124
					sections[FS_DbgSymbol] = dbg->symbols;
dvander@31
   125
				}
dvander@46
   126
				sections[FS_DbgInfo] = 1;
dvander@31
   127
				sections[FS_DbgStrings] = 1;
dvander@46
   128
				spfw_add_section(spf, ".dbg.info");
dvander@31
   129
				spfw_add_section(spf, ".dbg.strings");
dvander@31
   130
			}
dvander@31
   131
		}
dvander@31
   132
dvander@29
   133
		spfw_finalize_header(spf);
dvander@29
   134
		
dvander@27
   135
		/** 
dvander@27
   136
		 * Begin writing each of our known tables out
dvander@27
   137
		 */
dvander@27
   138
		
dvander@29
   139
		if (sections[FS_Code])
dvander@27
   140
		{
dvander@27
   141
			sp_file_code_t cod;
dvander@27
   142
			unsigned char *cbase;
dvander@27
   143
dvander@27
   144
			cod.cellsize = sizeof(cell);
dvander@27
   145
dvander@38
   146
			cod.codesize = hdr->dat - hdr->cod;
dvander@27
   147
			cod.codeversion = hdr->amx_version;
dvander@27
   148
			cod.flags = 0;
dvander@27
   149
			if (hdr->flags & AMX_FLAG_DEBUG)
dvander@27
   150
			{
faluco@62
   151
				cod.flags |= SP_FLAG_DEBUG;
dvander@27
   152
			}
dvander@27
   153
			cod.code = sizeof(cod);
dvander@27
   154
			cod.main = hdr->cip;
dvander@27
   155
dvander@38
   156
			/* write the code */
dvander@27
   157
			cbase = (unsigned char *)hdr + hdr->cod;
dvander@29
   158
			sfwrite(&cod, sizeof(cod), 1, spf);
dvander@38
   159
			sfwrite(cbase, cod.codesize, 1, spf);
dvander@27
   160
dvander@29
   161
			spfw_next_section(spf);
dvander@27
   162
		}
dvander@27
   163
dvander@29
   164
		if (sections[FS_Data])
dvander@27
   165
		{
dvander@27
   166
			sp_file_data_t dat;
dvander@31
   167
			unsigned char *dbase = (unsigned char *)hdr + hdr->dat;
dvander@27
   168
dvander@27
   169
			dat.datasize = hdr->hea - hdr->dat;
dvander@27
   170
			dat.memsize = hdr->stp;
dvander@27
   171
			dat.data = sizeof(dat);
dvander@31
   172
dvander@31
   173
			/* write header */
dvander@31
   174
			sfwrite(&dat, sizeof(dat), 1, spf);
dvander@27
   175
dvander@27
   176
			if (dat.datasize)
dvander@27
   177
			{
dvander@31
   178
				/* write data */
dvander@31
   179
				sfwrite(dbase, dat.datasize, 1, spf);
dvander@27
   180
			}
dvander@27
   181
dvander@29
   182
			spfw_next_section(spf);
dvander@27
   183
		}
dvander@27
   184
dvander@29
   185
		if (sections[FS_Publics])
dvander@27
   186
		{
dvander@27
   187
			sp_file_publics_t *pbtbl;
dvander@27
   188
			AMX_FUNCSTUBNT *stub;
dvander@45
   189
			unsigned char *stubptr;
dvander@29
   190
			uint32_t publics = sections[FS_Publics];
dvander@27
   191
dvander@27
   192
			pbtbl = (sp_file_publics_t *)malloc(sizeof(sp_file_publics_t) * publics);
dvander@45
   193
			stubptr = (unsigned char *)hdr + hdr->publics;
dvander@27
   194
dvander@27
   195
			for (i=0; i<publics; i++)
dvander@27
   196
			{
dvander@45
   197
				stub = (AMX_FUNCSTUBNT *)stubptr;
dvander@27
   198
				pbtbl[i].address = stub->address;
dvander@27
   199
				pbtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
dvander@27
   200
dvander@45
   201
				stubptr += hdr->defsize;
dvander@27
   202
			}
dvander@27
   203
			if (publics)
dvander@27
   204
			{
dvander@29
   205
				sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, spf);
dvander@27
   206
			}
dvander@27
   207
			free(pbtbl);
dvander@27
   208
dvander@29
   209
			spfw_next_section(spf);
dvander@27
   210
		}
dvander@27
   211
dvander@29
   212
		if (sections[FS_Pubvars])
dvander@27
   213
		{
dvander@27
   214
			sp_file_pubvars_t *pbvars;
dvander@27
   215
			AMX_FUNCSTUBNT *stub;
dvander@45
   216
			unsigned char *stubptr;
dvander@29
   217
			uint32_t pubvars = sections[FS_Pubvars];
dvander@27
   218
dvander@27
   219
			pbvars = (sp_file_pubvars_t *)malloc(sizeof(sp_file_pubvars_t) * pubvars);
dvander@45
   220
			stubptr = (unsigned char *)hdr + hdr->pubvars;
dvander@27
   221
dvander@27
   222
			for (i=0; i<pubvars; i++)
dvander@27
   223
			{
dvander@45
   224
				stub = (AMX_FUNCSTUBNT *)stubptr;
dvander@27
   225
				pbvars[i].address = stub->address;
dvander@27
   226
				pbvars[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
dvander@27
   227
dvander@45
   228
				stubptr += hdr->defsize;
dvander@27
   229
			}
dvander@27
   230
			if (pubvars)
dvander@27
   231
			{
dvander@29
   232
				sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, spf);
dvander@27
   233
			}
dvander@27
   234
			free(pbvars);
dvander@29
   235
			spfw_next_section(spf);
dvander@27
   236
		}
dvander@27
   237
dvander@29
   238
		if (sections[FS_Natives])
dvander@27
   239
		{
dvander@27
   240
			sp_file_natives_t *nvtbl;
dvander@27
   241
			AMX_FUNCSTUBNT *stub;
dvander@45
   242
			unsigned char *stubptr;
dvander@27
   243
			uint32_t natives = (hdr->libraries - hdr->natives) / hdr->defsize;
dvander@27
   244
dvander@27
   245
			nvtbl = (sp_file_natives_t *)malloc(sizeof(sp_file_natives_t) * natives);
dvander@45
   246
			stubptr = (unsigned char *)hdr + hdr->natives;
dvander@27
   247
dvander@27
   248
			for (i=0; i<natives; i++)
dvander@27
   249
			{
dvander@45
   250
				stub = (AMX_FUNCSTUBNT *)stubptr;
dvander@27
   251
				nvtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
dvander@27
   252
dvander@45
   253
				stubptr += hdr->defsize;
dvander@27
   254
			}
dvander@27
   255
			if (natives)
dvander@27
   256
			{
dvander@29
   257
				sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, spf);
dvander@27
   258
			}
dvander@27
   259
			free(nvtbl);
dvander@29
   260
			spfw_next_section(spf);
dvander@27
   261
		}
dvander@27
   262
faluco@144
   263
		if (sections[FS_Libraries])
faluco@144
   264
		{
faluco@144
   265
			sp_file_libraries_t *libtbl;
faluco@144
   266
			AMX_FUNCSTUBNT *stub;
faluco@144
   267
			unsigned char *stubptr;
faluco@144
   268
			uint32_t libraries = sections[FS_Libraries];
faluco@144
   269
faluco@144
   270
			libtbl = (sp_file_libraries_t *)malloc(sizeof(sp_file_libraries_t) * libraries);
faluco@144
   271
			stubptr = (unsigned char *)hdr + hdr->libraries;
faluco@144
   272
faluco@144
   273
			for (i=0; i<libraries; i++)
faluco@144
   274
			{
faluco@144
   275
				stub = (AMX_FUNCSTUBNT *)stubptr;
faluco@144
   276
				libtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
faluco@144
   277
faluco@144
   278
				stubptr += hdr->defsize;
faluco@144
   279
			}
faluco@144
   280
			if (libraries)
faluco@144
   281
			{
faluco@144
   282
				sfwrite(libtbl, sizeof(sp_file_libraries_t), libraries, spf);
faluco@144
   283
			}
faluco@144
   284
			free(libtbl);
faluco@144
   285
			spfw_next_section(spf);
faluco@144
   286
		}
faluco@144
   287
dvander@29
   288
		if (sections[FS_Nametable])
dvander@27
   289
		{
dvander@27
   290
			unsigned char *base;
dvander@27
   291
			uint32_t namelen;
dvander@27
   292
dvander@27
   293
			/* write the entire block */
dvander@27
   294
			base = (unsigned char *)hdr + hdr->nametable + sizeof(uint16_t);
dvander@27
   295
			/**
dvander@27
   296
			 * note - the name table will be padded to sizeof(cell) bytes.
dvander@27
   297
			 * this may clip at most an extra three bytes in!
dvander@27
   298
			 */
dvander@27
   299
			namelen = hdr->cod - hdr->nametable;
dvander@29
   300
			sfwrite(base, namelen, 1, spf);
dvander@29
   301
			spfw_next_section(spf);
dvander@27
   302
		}
dvander@27
   303
dvander@31
   304
		if (hdr->flags & AMX_FLAG_DEBUG)
dvander@31
   305
		{
dvander@46
   306
			sp_fdbg_info_t info;
dvander@46
   307
dvander@46
   308
			memset(&info, 0, sizeof(sp_fdbg_info_t));
dvander@46
   309
dvander@31
   310
			if (sections[FS_DbgFile])
dvander@31
   311
			{
dvander@31
   312
				uint32_t idx;
dvander@31
   313
				sp_fdbg_file_t dbgfile;
dvander@31
   314
				AMX_DBG_FILE *_ptr;
dvander@31
   315
				uint32_t len;
dvander@31
   316
				for (idx=0; idx<sections[FS_DbgFile]; idx++)
dvander@31
   317
				{
dvander@31
   318
					/* get entry info */
dvander@31
   319
					_ptr = (AMX_DBG_FILE *)dbgptr;
dvander@31
   320
					len = strlen(_ptr->name);
dvander@31
   321
					/* store */
dvander@31
   322
					dbgfile.addr = _ptr->address;
dvander@31
   323
					dbgfile.name = (uint32_t)memfile_tell(dbgtab);
dvander@31
   324
					sfwrite(&dbgfile, sizeof(sp_fdbg_file_t), 1, spf);
dvander@31
   325
					/* write to tab, then move to next */
dvander@31
   326
					memfile_write(dbgtab, _ptr->name, len + 1);
dvander@31
   327
					dbgptr += sizeof(AMX_DBG_FILE) + len;
dvander@46
   328
					info.num_files++;
dvander@31
   329
				}
dvander@31
   330
				spfw_next_section(spf);
dvander@31
   331
			}
dvander@31
   332
dvander@31
   333
			if (sections[FS_DbgLine])
dvander@31
   334
			{
dvander@31
   335
				uint32_t idx;
dvander@31
   336
				AMX_DBG_LINE *line;
dvander@31
   337
				sp_fdbg_line_t dbgline;
dvander@31
   338
				for (idx=0; idx<sections[FS_DbgLine]; idx++)
dvander@31
   339
				{
dvander@31
   340
					/* get entry info */
dvander@31
   341
					line = (AMX_DBG_LINE *)dbgptr;
dvander@31
   342
					/* store */
dvander@31
   343
					dbgline.addr = (uint32_t)line->address;
dvander@31
   344
					dbgline.line = (uint32_t)line->line;
dvander@31
   345
					sfwrite(&dbgline, sizeof(sp_fdbg_line_t), 1, spf);
dvander@31
   346
					/* move to next */
dvander@31
   347
					dbgptr += sizeof(AMX_DBG_LINE);
dvander@46
   348
					info.num_lines++;
dvander@31
   349
				}
dvander@31
   350
				spfw_next_section(spf);
dvander@31
   351
			}
dvander@31
   352
dvander@31
   353
			if (sections[FS_DbgSymbol])
dvander@31
   354
			{
dvander@31
   355
				uint32_t idx;
dvander@31
   356
				uint32_t dnum;
dvander@31
   357
				AMX_DBG_SYMBOL *sym;
dvander@31
   358
				AMX_DBG_SYMDIM *dim;
dvander@31
   359
				sp_fdbg_symbol_t dbgsym;
dvander@31
   360
				sp_fdbg_arraydim_t dbgdim;
dvander@31
   361
				uint32_t len;
dvander@31
   362
dvander@31
   363
				for (idx=0; idx<sections[FS_DbgSymbol]; idx++)
dvander@31
   364
				{
dvander@31
   365
					/* get entry info */
dvander@31
   366
					sym = (AMX_DBG_SYMBOL *)dbgptr;
dvander@31
   367
					/* store */
dvander@31
   368
					dbgsym.addr = *(int32_t *)&sym->address;
dvander@31
   369
					dbgsym.tagid = sym->tag;
dvander@31
   370
					dbgsym.codestart = (uint32_t)sym->codestart;
dvander@31
   371
					dbgsym.codeend = (uint32_t)sym->codeend;
dvander@31
   372
					dbgsym.dimcount = (uint16_t)sym->dim;
dvander@31
   373
					dbgsym.vclass = (uint8_t)sym->vclass;
dvander@31
   374
					dbgsym.ident = (uint8_t)sym->ident;
dvander@31
   375
					dbgsym.name = (uint32_t)memfile_tell(dbgtab);
dvander@31
   376
					sfwrite(&dbgsym, sizeof(sp_fdbg_symbol_t), 1, spf);
dvander@31
   377
					/* write to tab */
dvander@31
   378
					len = strlen(sym->name);
dvander@31
   379
					memfile_write(dbgtab, sym->name, len + 1);
dvander@31
   380
					/* move to next */
dvander@31
   381
					dbgptr += sizeof(AMX_DBG_SYMBOL) + len;
dvander@31
   382
					/* look for any dimensions */
dvander@46
   383
					info.num_syms++;
dvander@31
   384
					for (dnum=0; dnum<dbgsym.dimcount; dnum++)
dvander@31
   385
					{
dvander@31
   386
						/* get entry info */
dvander@31
   387
						dim = (AMX_DBG_SYMDIM *)dbgptr;
dvander@31
   388
						/* store */
dvander@31
   389
						dbgdim.size = (uint32_t)dim->size;
dvander@31
   390
						dbgdim.tagid = dim->tag;
dvander@31
   391
						sfwrite(&dbgdim, sizeof(sp_fdbg_arraydim_t), 1, spf);
dvander@31
   392
						/* move to next */
dvander@31
   393
						dbgptr += sizeof(AMX_DBG_SYMDIM);
dvander@46
   394
						info.num_arrays++;
dvander@31
   395
					}
dvander@31
   396
				}
dvander@31
   397
				spfw_next_section(spf);
dvander@31
   398
			}
dvander@31
   399
dvander@46
   400
			sfwrite(&info, sizeof(sp_fdbg_info_t), 1, spf);
dvander@46
   401
			spfw_next_section(spf);
dvander@46
   402
dvander@31
   403
			if (sections[FS_DbgStrings])
dvander@31
   404
			{
dvander@31
   405
				sfwrite(dbgtab->base, sizeof(char), dbgtab->usedoffs, spf);
dvander@31
   406
				spfw_next_section(spf);
dvander@31
   407
			}
dvander@31
   408
		}
dvander@31
   409
dvander@29
   410
		spfw_finalize_all(spf);
dvander@31
   411
dvander@31
   412
		/** 
dvander@31
   413
		 * do compression
dvander@31
   414
		 * new block for scoping only
dvander@31
   415
		 */
dvander@31
   416
		if (1)
dvander@31
   417
		{
dvander@31
   418
			memfile_t *pOrig = (memfile_t *)spf->handle;
dvander@31
   419
			sp_file_hdr_t *pHdr;
dvander@31
   420
			unsigned char *proper;
dvander@31
   421
			size_t size;
dvander@31
   422
			Bytef *zcmp;
dvander@31
   423
			uLong disksize;
dvander@35
   424
			size_t header_size;
dvander@31
   425
			int err = Z_OK;
dvander@31
   426
dvander@31
   427
			/* reuse this memory block! */
dvander@31
   428
			memfile_reset(bin_file);
dvander@31
   429
dvander@31
   430
			/* copy tip of header */
dvander@31
   431
			memfile_write(bin_file, pOrig->base, sizeof(sp_file_hdr_t));
dvander@31
   432
dvander@31
   433
			/* get pointer to header */
dvander@31
   434
			pHdr = (sp_file_hdr_t *)bin_file->base;
dvander@31
   435
dvander@31
   436
			/* copy the rest of the header */
dvander@31
   437
			memfile_write(bin_file, 
dvander@31
   438
							(unsigned char *)pOrig->base + sizeof(sp_file_hdr_t),
dvander@31
   439
							pHdr->dataoffs - sizeof(sp_file_hdr_t));
dvander@31
   440
dvander@35
   441
			header_size = pHdr->dataoffs;
dvander@35
   442
			size = pHdr->imagesize - header_size;
dvander@35
   443
			proper = (unsigned char *)pOrig->base + header_size;
dvander@31
   444
dvander@31
   445
			/* get initial size estimate */
dvander@295
   446
			pHdr->disksize = (uint32_t)compressBound(pHdr->imagesize) * 2;
dvander@31
   447
			zcmp = (Bytef *)malloc(pHdr->disksize);
dvander@31
   448
dvander@31
   449
			if ((err=compress2(zcmp, 
dvander@31
   450
					&disksize, 
dvander@31
   451
					(Bytef *)proper,
dvander@31
   452
					(uLong)size,
dvander@31
   453
					Z_BEST_COMPRESSION))
dvander@31
   454
				!= Z_OK)
dvander@31
   455
			{
dvander@31
   456
				free(zcmp);
dvander@295
   457
				pc_printf("Unable to compress (Z): error %d\n", err);
dvander@31
   458
				pc_printf("Falling back to no compression.");
dvander@31
   459
				memfile_write(bin_file, 
dvander@31
   460
							proper,
dvander@31
   461
							size);
dvander@31
   462
			} else {
dvander@35
   463
				pHdr->disksize = (uint32_t)disksize + header_size;
dvander@31
   464
				pHdr->compression = SPFILE_COMPRESSION_GZ;
dvander@31
   465
				memfile_write(bin_file,
dvander@31
   466
							(unsigned char *)zcmp,
dvander@35
   467
							disksize);
dvander@31
   468
				free(zcmp);
dvander@31
   469
			}
dvander@31
   470
		}
dvander@31
   471
dvander@29
   472
		spfw_destroy(spf);
dvander@31
   473
		memfile_destroy(dbgtab);
dvander@31
   474
dvander@31
   475
		/** 
dvander@31
   476
		 * write file 
dvander@31
   477
		 */
dvander@31
   478
		if ((fp=fopen(bin_file->name, "wb")) != NULL)
dvander@31
   479
		{
dvander@31
   480
			fwrite(bin_file->base, bin_file->usedoffs, 1, fp);
dvander@31
   481
			fclose(fp);
dvander@31
   482
		} else {
dvander@31
   483
			pc_printf("Unable to open %s for writing!", bin_file->name);
dvander@31
   484
		}
dvander@31
   485
dvander@31
   486
		memfile_destroy(bin_file);
dvander@27
   487
dvander@27
   488
		return 0;
dvander@27
   489
dvander@27
   490
write_error:
dvander@27
   491
		pc_printf("Error writing to file: %s", bin_file->name);
dvander@31
   492
		
dvander@31
   493
		spfw_destroy(spf);
dvander@27
   494
		unlink(bin_file->name);
dvander@27
   495
		memfile_destroy(bin_file);
dvander@31
   496
		memfile_destroy(dbgtab);
dvander@27
   497
dvander@27
   498
		return 1;
dvander@27
   499
	}
dvander@27
   500
dvander@27
   501
	return 1;
dvander@27
   502
}
dvander@27
   503
dvander@29
   504
void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf)
dvander@27
   505
{
dvander@29
   506
	if (spf->funcs.fnWrite(buf, size, count, spf->handle) != count)
dvander@27
   507
	{
dvander@27
   508
		longjmp(brkout, 1);
dvander@27
   509
	}
dvander@27
   510
}