From ea1947ffcc606d757357398b24e74a3f4ecefa07 Mon Sep 17 00:00:00 2001 From: neonloop Date: Wed, 20 Oct 2021 14:54:27 +0000 Subject: Initial commit from steward-fu release --- core/bgdc/src/dcbw.c | 1258 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1258 insertions(+) create mode 100644 core/bgdc/src/dcbw.c (limited to 'core/bgdc/src/dcbw.c') diff --git a/core/bgdc/src/dcbw.c b/core/bgdc/src/dcbw.c new file mode 100644 index 0000000..987a947 --- /dev/null +++ b/core/bgdc/src/dcbw.c @@ -0,0 +1,1258 @@ +/* + * Copyright © 2006-2016 SplinterGU (Fenix/Bennugd) + * Copyright © 2002-2006 Fenix Team (Fenix) + * Copyright © 1999-2002 José Luis Cebrián Pagüe (Fenix) + * + * This file is part of Bennu - Game Development + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#include + +#ifdef TARGET_BEOS +#include +#else +#include +#endif + +#include +#include + +#include "bgdc.h" +#include "dcb.h" + +#define SYSPROCS_ONLY_DECLARE +#include "sysprocs.h" + +#define FREEM(m) if(m) { free(m); m = NULL; } + +/* dirty declare external vars */ + +extern char * string_mem; +extern int * string_offset; +extern int string_count, string_used; +extern int procdef_count; +extern int identifier_count; +extern PROCDEF ** procs; + +extern int debug; + +/* List of files to include in DCB file managment */ + +DCB_FILE * dcb_files = 0; +int dcb_ef_alloc = 0; +int dcb_filecount = 0; +char ** dcb_fullname = 0; +int dcb_options = 0; + +void dcb_add_file( const char * filename ) +{ + file * fp; + long size; + int i; + char buffer[1024]; + + if ( filename[0] == '@' ) + { + fp = file_open( filename + 1, "rb" ); + if ( !fp ) return; + while ( !file_eof( fp ) ) + { + char *p; + file_qgets( fp, buffer, sizeof( buffer ) ); + if ( ( p = strchr( buffer, '\n' ) ) ) *p = '\0'; + if ( ( p = strchr( buffer, '\r' ) ) ) *p = '\0'; + if ( buffer[0] == '#' || !buffer[0] ) continue; + dcb_add_file( buffer ); + } + file_close( fp ); + return; + } + + /* Dinamyc libraries aren't included in the stub */ +/* + if ( strlen( filename ) > 4 && !strncmp( filename + strlen( filename ) - 4, ".dll", 4 ) ) return; + if ( strlen( filename ) > 3 && !strncmp( filename + strlen( filename ) - 3, ".so", 3 ) ) return; + if ( strlen( filename ) > 6 && !strncmp( filename + strlen( filename ) - 6, ".dylib", 6 ) ) return; +*/ + for ( i = 0; filename[i]; i++ ) if ( filename[i] == '\\' ) buffer[i] = '/'; else buffer[i] = filename[i]; + buffer[i] = '\0'; + + filename = ( const char * ) buffer; + + fp = file_open( filename, "rb" ); + if ( !fp ) return; + size = file_size( fp ); + file_close( fp ); + + if ( dcb_ef_alloc == dcb_filecount ) + { + dcb_files = ( DCB_FILE * )realloc( dcb_files, sizeof( DCB_FILE ) * ( dcb_ef_alloc += 16 ) ); + if ( !dcb_files ) compile_error( "dcb_add_file: out of memory" ); + } + + /* file is already included ? */ + + for ( i = 0; i < dcb_filecount; i++ ) + if ( strcmp( filename, (const char *)dcb_files[i].Name ) == 0 ) return; + + dcb_files[dcb_filecount].Name = (uint8_t *) strdup( filename ); + dcb_files[dcb_filecount].SFile = size; + + dcb_filecount++; +} + +/* Hack for set ID's to varspaces */ + +VARSPACE ** dcb_orig_varspace = 0; +int dcb_varspaces = 0; + +static int dcb_varspace( VARSPACE * v ) +{ + int n, result; + + for ( n = 0; n < dcb_varspaces; n++ ) + if ( dcb_orig_varspace[n] == v ) return n; + + dcb.varspace = ( DCB_VARSPACE * ) realloc( dcb.varspace, sizeof( DCB_VARSPACE ) * ( dcb_varspaces + 1 ) ); + dcb_orig_varspace = ( VARSPACE ** ) realloc( dcb_orig_varspace, sizeof( VARSPACE * ) * ( dcb_varspaces + 1 ) ); + + dcb_orig_varspace[dcb_varspaces] = v; + + dcb.varspace[dcb_varspaces].NVars = v->count; ARRANGE_DWORD( &dcb.varspace[dcb_varspaces].NVars ); /* Used Only for dcb */ + result = dcb_varspaces++; + + for ( n = 0; n < v->count; n++ ) + if ( v->vars[n].type.varspace ) dcb_varspace( v->vars[n].type.varspace ); + + return result; +} + +/* TYPEDEF converts (used in compile time) */ + +void dcb_settype( DCB_TYPEDEF * d, TYPEDEF * t ) +{ + int n; + + for ( n = 0; n < MAX_TYPECHUNKS; n++ ) + { + d->BaseType[n] = t->chunk[n].type; /* 8 bits */ + d->Count [n] = t->chunk[n].count; + } + + if ( t->varspace ) + d->Members = dcb_varspace( t->varspace ); + else + d->Members = NO_MEMBERS; +} + + +/* TYPEDEF converts (used in save time) */ + +void dcb_prepare_type( DCB_TYPEDEF * d, TYPEDEF * t ) +{ + int n; + + for ( n = 0; n < MAX_TYPECHUNKS; n++ ) + { + d->BaseType[n] = t->chunk[n].type; /* 8 bits */ + d->Count [n] = t->chunk[n].count; ARRANGE_DWORD( &d->Count[n] ); + } + + if ( t->varspace ) + d->Members = dcb_varspace( t->varspace ); + else + d->Members = NO_MEMBERS; + + ARRANGE_DWORD( &d->Members ); +} + +/* Make DCB file (see dcb.h) */ + +DCB_HEADER dcb; + +int dcb_save( const char * filename, int options, const char * stubname ) +{ + file * fp; + uint32_t n, i, size; + long offset; + identifier * id; + long stubsize = 0; + void * stubdata; + + int NPriVars = 0; + int NPubVars = 0; + + int SCode = 0; + int SPrivate = 0; + int SPublic = 0; + int OFilesTab = 0; + + DCB_SYSPROC_CODE sdcb; + SYSPROC * s; + int NSysProcs = 0; + + fp = file_open( filename, "wb0" ); + if ( !fp ) + { + fprintf( stdout, "ERROR: can't open %s\n", filename ); + return 0; + } + + /* Write the stub file */ + if ( stubname ) + { + file * stub = file_open( stubname, "rb0" ); + + if ( !stub ) + { + fprintf( stdout, "ERROR: can't open %s\n", stubname ); + return 0; + } + + stubsize = file_size( stub ); + stubdata = calloc( stubsize, sizeof( char ) ); + if ( !stubdata ) + { + fprintf( stdout, "ERROR: Stub %s too big\n", stubname ); + return 0; + } + if ( file_read( stub, stubdata, stubsize ) != stubsize ) + { + fprintf( stdout, "ERROR: error reading stub %s\n", stubname ); + return 0; + } + file_write( fp, stubdata, stubsize ); + if ( stubsize & 15 ) + { + file_write( fp, stubdata, 16 - ( stubsize & 15 ) ); + stubsize += 16 - ( stubsize & 15 ); + } + free( stubdata ); + file_close( stub ); + } + + /* Refresh sysprocs list */ + + for ( s = sysprocs; s->name; s++ ) + { + if ( s->id == 0 ) s->id = identifier_search_or_add( s->name ); + NSysProcs++; + } + + /* We can asume that dcb.varspace is already filled */ + + /* Splinter, fix to save neccessary info only */ + if ( !( options & DCB_DEBUG ) ) n_files = 0; + + /* 1. Fill header */ + + if ( libmode ) + memcpy( dcb.data.Header, DCL_MAGIC, sizeof( DCL_MAGIC ) - 1 ); + else + memcpy( dcb.data.Header, DCB_MAGIC, sizeof( DCB_MAGIC ) - 1 ); + + dcb.data.Version = DCB_VERSION; ARRANGE_DWORD( &dcb.data.Version ); + + dcb.data.NProcs = procdef_count; ARRANGE_DWORD( &dcb.data.NProcs ); + dcb.data.NFiles = dcb_filecount; ARRANGE_DWORD( &dcb.data.NFiles ); + dcb.data.NID = identifier_count; ARRANGE_DWORD( &dcb.data.NID ); + dcb.data.NStrings = string_count; ARRANGE_DWORD( &dcb.data.NStrings ); + dcb.data.NLocVars = local.count; ARRANGE_DWORD( &dcb.data.NLocVars ); + dcb.data.NLocStrings = local.stringvar_count; ARRANGE_DWORD( &dcb.data.NLocStrings ); + dcb.data.NGloVars = global.count; ARRANGE_DWORD( &dcb.data.NGloVars ); + + dcb.data.SGlobal = globaldata->current; ARRANGE_DWORD( &dcb.data.SGlobal ); + dcb.data.SLocal = localdata->current; ARRANGE_DWORD( &dcb.data.SLocal ); + dcb.data.SText = string_used; ARRANGE_DWORD( &dcb.data.SText ); + + dcb.data.NImports = nimports; ARRANGE_DWORD( &dcb.data.NImports ); + + dcb.data.NSourceFiles = n_files; ARRANGE_DWORD( &dcb.data.NSourceFiles ); + + dcb.data.NSysProcsCodes = NSysProcs; ARRANGE_DWORD( &dcb.data.NSysProcsCodes ); + + /* 2. Build process table */ + + dcb.proc = ( DCB_PROC * ) calloc( procdef_count, sizeof( DCB_PROC ) ); + + for ( n = 0; n < procdef_count; n++ ) + { + dcb.proc[n].data.ID = procs[n]->identifier; ARRANGE_DWORD( &dcb.proc[n].data.ID ); + dcb.proc[n].data.Flags = procs[n]->flags; ARRANGE_DWORD( &dcb.proc[n].data.Flags ); + dcb.proc[n].data.NParams = procs[n]->params; ARRANGE_DWORD( &dcb.proc[n].data.NParams ); + + dcb.proc[n].data.NPriVars = procs[n]->privars->count; ARRANGE_DWORD( &dcb.proc[n].data.NPriVars ); + dcb.proc[n].data.NPriStrings = procs[n]->privars->stringvar_count; ARRANGE_DWORD( &dcb.proc[n].data.NPriStrings ); + + dcb.proc[n].data.NPubVars = procs[n]->pubvars->count; ARRANGE_DWORD( &dcb.proc[n].data.NPubVars ); + dcb.proc[n].data.NPubStrings = procs[n]->pubvars->stringvar_count; ARRANGE_DWORD( &dcb.proc[n].data.NPubStrings ); + + dcb.proc[n].data.NSentences = procs[n]->sentence_count; ARRANGE_DWORD( &dcb.proc[n].data.NSentences ); + + dcb.proc[n].data.SPrivate = procs[n]->pridata->current; ARRANGE_DWORD( &dcb.proc[n].data.SPrivate ); + dcb.proc[n].data.SPublic = procs[n]->pubdata->current; ARRANGE_DWORD( &dcb.proc[n].data.SPublic ); + + dcb.proc[n].data.SCode = procs[n]->code.current * 4; ARRANGE_DWORD( &dcb.proc[n].data.SCode ); + + dcb.proc[n].data.OExitCode = procs[n]->exitcode ; ARRANGE_DWORD( &dcb.proc[n].data.OExitCode ); + dcb.proc[n].data.OErrorCode = procs[n]->errorcode ; ARRANGE_DWORD( &dcb.proc[n].data.OErrorCode ); + + SCode += procs[n]->code.current * 4; + + NPriVars += procs[n]->privars->count; + NPubVars += procs[n]->pubvars->count; + + SPrivate += procs[n]->pridata->current; + SPublic += procs[n]->pubdata->current; + + dcb.proc[n].sentence = ( DCB_SENTENCE * ) calloc( procs[n]->sentence_count, sizeof( DCB_SENTENCE ) ); + + for ( i = 0; i < procs[n]->sentence_count; i++ ) + { + dcb.proc[n].sentence[i].NFile = 0; ARRANGE_DWORD( &dcb.proc[n].sentence[i].NFile ); + dcb.proc[n].sentence[i].NLine = procs[n]->sentences[i].line; ARRANGE_DWORD( &dcb.proc[n].sentence[i].NLine ); + dcb.proc[n].sentence[i].NCol = procs[n]->sentences[i].col; ARRANGE_DWORD( &dcb.proc[n].sentence[i].NCol ); + dcb.proc[n].sentence[i].OCode = procs[n]->sentences[i].offset; ARRANGE_DWORD( &dcb.proc[n].sentence[i].OCode ); + } + + /* Splinter, tipos de parametros */ + + dcb.proc[n].privar = ( DCB_VAR * ) calloc( procs[n]->privars->count, sizeof( DCB_VAR ) ); + for ( i = 0; i < procs[n]->privars->count; i++ ) + { + dcb_prepare_type( &dcb.proc[n].privar[i].Type, &procs[n]->privars->vars[i].type ); + + dcb.proc[n].privar[i].ID = procs[n]->privars->vars[i].code; ARRANGE_DWORD( &dcb.proc[n].privar[i].ID ); + dcb.proc[n].privar[i].Offset = procs[n]->privars->vars[i].offset; ARRANGE_DWORD( &dcb.proc[n].privar[i].Offset ); + } + + dcb.proc[n].pubvar = ( DCB_VAR * ) calloc( procs[n]->pubvars->count, sizeof( DCB_VAR ) ); + for ( i = 0; i < procs[n]->pubvars->count; i++ ) + { + dcb_prepare_type( &dcb.proc[n].pubvar[i].Type, &procs[n]->pubvars->vars[i].type ); + + dcb.proc[n].pubvar[i].ID = procs[n]->pubvars->vars[i].code; ARRANGE_DWORD( &dcb.proc[n].pubvar[i].ID ); + dcb.proc[n].pubvar[i].Offset = procs[n]->pubvars->vars[i].offset; ARRANGE_DWORD( &dcb.proc[n].pubvar[i].Offset ); + } + } + + /* 3. Build global tables */ + + dcb.id = ( DCB_ID * ) calloc( identifier_count, sizeof( DCB_ID ) ); + + id = identifier_first(); + + for ( n = 0; n < identifier_count; n++ ) + { + assert( id != 0 ); + strncpy( (char *)dcb.id[n].Name, id->name, sizeof( dcb.id[n].Name ) ); + dcb.id[n].Code = id->code; ARRANGE_DWORD( &dcb.id[n].Code ); + + id = identifier_next( id ); + } + + dcb.glovar = ( DCB_VAR * ) calloc( global.count, sizeof( DCB_VAR ) ); + dcb.locvar = ( DCB_VAR * ) calloc( local.count, sizeof( DCB_VAR ) ); + + for ( n = 0; n < global.count; n++ ) + { + dcb_prepare_type( &dcb.glovar[n].Type, &global.vars[n].type ); + + dcb.glovar[n].ID = global.vars[n].code; ARRANGE_DWORD( &dcb.glovar[n].ID ); + dcb.glovar[n].Offset = global.vars[n].offset; ARRANGE_DWORD( &dcb.glovar[n].Offset ); + } + + for ( n = 0; n < local.count; n++ ) + { + dcb_prepare_type( &dcb.locvar[n].Type, &local.vars[n].type ); + + dcb.locvar[n].ID = local.vars[n].code; ARRANGE_DWORD( &dcb.locvar[n].ID ); + dcb.locvar[n].Offset = local.vars[n].offset; ARRANGE_DWORD( &dcb.locvar[n].Offset ); + } + + dcb.data.NVarSpaces = dcb_varspaces; + + dcb.file = dcb_files; + + /* 4. Calculate offsets */ + + offset = sizeof( DCB_HEADER_DATA ); + + dcb.data.OProcsTab = offset; offset += sizeof( DCB_PROC_DATA ) * procdef_count; ARRANGE_DWORD( &dcb.data.OProcsTab ); + dcb.data.OStrings = offset; offset += 4 * string_count; ARRANGE_DWORD( &dcb.data.OStrings ); + dcb.data.OGloVars = offset; offset += sizeof( DCB_VAR ) * global.count; ARRANGE_DWORD( &dcb.data.OGloVars ); + dcb.data.OLocVars = offset; offset += sizeof( DCB_VAR ) * local.count; ARRANGE_DWORD( &dcb.data.OLocVars ); + dcb.data.OLocStrings = offset; offset += 4 * local.stringvar_count; ARRANGE_DWORD( &dcb.data.OLocStrings ); + dcb.data.OID = offset; offset += sizeof( DCB_ID ) * identifier_count; ARRANGE_DWORD( &dcb.data.OID ); + dcb.data.OVarSpaces = offset; offset += sizeof( DCB_VARSPACE ) * dcb_varspaces; ARRANGE_DWORD( &dcb.data.OVarSpaces ); + dcb.data.OText = offset; offset += string_used; ARRANGE_DWORD( &dcb.data.OText ); + dcb.data.OImports = offset; offset += 4 * nimports; ARRANGE_DWORD( &dcb.data.OImports ); + dcb.data.OGlobal = offset; offset += globaldata->current; ARRANGE_DWORD( &dcb.data.OGlobal ); + dcb.data.OLocal = offset; offset += localdata->current; ARRANGE_DWORD( &dcb.data.OLocal ); + + dcb.data.OSourceFiles = offset; ARRANGE_DWORD( &dcb.data.OSourceFiles ); + + /* sources */ + for ( n = 0; n < n_files; n++ ) + offset += sizeof( uint32_t ) + strlen( files[n] ) + 1; + + dcb.data.OSysProcsCodes = offset; ARRANGE_DWORD( &dcb.data.OSysProcsCodes ); + for ( s = sysprocs; s->name; s++ ) + { + offset += sizeof( DCB_SYSPROC_CODE ); + offset += s->params; + } + + for ( n = 0; n < dcb_varspaces; n++ ) + { + dcb.varspace[n].OVars = offset; ARRANGE_DWORD( &dcb.varspace[n].OVars ); + offset += sizeof( DCB_VAR ) * dcb_orig_varspace[n]->count; + } + + for ( n = 0; n < procdef_count; n++ ) + { + dcb.proc[n].data.OSentences = offset; offset += sizeof( DCB_SENTENCE ) * procs[n]->sentence_count; ARRANGE_DWORD( &dcb.proc[n].data.OSentences ); + + /* Private */ + dcb.proc[n].data.OPriVars = offset; offset += sizeof( DCB_VAR ) * procs[n]->privars->count; ARRANGE_DWORD( &dcb.proc[n].data.OPriVars ); + dcb.proc[n].data.OPriStrings = offset; offset += 4 * procs[n]->privars->stringvar_count; ARRANGE_DWORD( &dcb.proc[n].data.OPriStrings ); + dcb.proc[n].data.OPrivate = offset; offset += procs[n]->pridata->current; ARRANGE_DWORD( &dcb.proc[n].data.OPrivate ); + + /* Publics */ + dcb.proc[n].data.OPubVars = offset; offset += sizeof( DCB_VAR ) * procs[n]->pubvars->count; ARRANGE_DWORD( &dcb.proc[n].data.OPubVars ); + dcb.proc[n].data.OPubStrings = offset; offset += 4 * procs[n]->pubvars->stringvar_count; ARRANGE_DWORD( &dcb.proc[n].data.OPubStrings ); + dcb.proc[n].data.OPublic = offset; offset += procs[n]->pubdata->current; ARRANGE_DWORD( &dcb.proc[n].data.OPublic ); + + /* Code */ + dcb.proc[n].data.OCode = offset; offset += procs[n]->code.current * 4; ARRANGE_DWORD( &dcb.proc[n].data.OCode ); + } + + /* Archivos incluidos */ + OFilesTab = offset; + dcb.data.OFilesTab = OFilesTab; ARRANGE_DWORD( &dcb.data.OFilesTab ); + + /* FullPathName */ + dcb_fullname = calloc( dcb_filecount, sizeof( char * ) ); + + /* Cada uno de los archivos incluidos */ + for ( n = 0; n < dcb_filecount; n++ ) + { + dcb_fullname[n] = (char *)dcb.file[n].Name; /* Guardo el Name, porque lo destruyo en SName (es un union) */ + dcb.file[n].SName = strlen( (const char *)dcb.file[n].Name ) + 1; /* Todavia no hago el ARRANGE de este dato, lo hago luego cuando lo voy a grabar */ + offset += sizeof( DCB_FILE ) + dcb.file[n].SName; + } + + /* Data de los archivos incluidos */ + for ( n = 0; n < dcb_filecount; n++ ) + { + dcb.file[n].OFile = offset; ARRANGE_DWORD( &dcb.file[n].OFile ); + offset += dcb.file[n].SFile; ARRANGE_DWORD( &dcb.file[n].SFile ); + } + + /* ************************************** */ + /* ************************************** */ + /* 5. Guardar todo en disco ordenadamente */ + /* ************************************** */ + /* ************************************** */ + + file_write( fp, &dcb, sizeof( DCB_HEADER_DATA ) ); + + for ( n = 0; n < procdef_count; n++ ) + file_write( fp, &dcb.proc[n], sizeof( DCB_PROC_DATA ) ); + + file_writeUint32A( fp, (uint32_t *)string_offset, string_count ); + file_write( fp, dcb.glovar, sizeof( DCB_VAR ) * global.count ); /* Ya procesado el byteorder */ + file_write( fp, dcb.locvar, sizeof( DCB_VAR ) * local.count ); /* Ya procesado el byteorder */ + file_writeUint32A( fp, (uint32_t *)local.stringvars, local.stringvar_count ); + file_write( fp, dcb.id, sizeof( DCB_ID ) * identifier_count ); /* Ya procesado el byteorder */ + file_write( fp, dcb.varspace, sizeof( DCB_VARSPACE ) * dcb_varspaces ); /* Ya procesado el byteorder */ + file_write( fp, string_mem, string_used ); /* No necesita byteorder */ + file_writeUint32A( fp, (uint32_t *)imports, nimports ); + file_write( fp, globaldata->bytes, globaldata->current ); /* ****** */ + file_write( fp, localdata->bytes, localdata->current ); /* ****** */ + + if ( dcb_options & DCB_DEBUG ) + { + for ( n = 0; n < n_files; n++ ) + { + size = strlen( files[n] ) + 1; + file_writeUint32( fp, &size ); + file_write( fp, files[n], size ); + } + } + + for ( s = sysprocs; s->name; s++ ) + { + int l = s->params; + sdcb.Id = s->id; ARRANGE_DWORD( &sdcb.Id ); + sdcb.Type = s->type; ARRANGE_DWORD( &sdcb.Type ); + sdcb.Params = l; ARRANGE_DWORD( &sdcb.Params ); + sdcb.Code = s->code; ARRANGE_DWORD( &sdcb.Code ); + file_write( fp, &sdcb, sizeof( DCB_SYSPROC_CODE ) ); + file_write( fp, s->paramtypes, l ); + } + + for ( n = 0; n < dcb_varspaces; n++ ) + { + VARIABLE * var; + DCB_VAR v; + + memset (&v, '\0', sizeof(v)); + + var = &dcb_orig_varspace[n]->vars[0]; + + for ( i = 0; i < dcb_orig_varspace[n]->count; i++, var++ ) + { + dcb_prepare_type( &v.Type, &var->type ); + v.ID = var->code; ARRANGE_DWORD( &v.ID ); + v.Offset = var->offset; ARRANGE_DWORD( &v.Offset ); + + file_write( fp, &v, sizeof( DCB_VAR ) ); + } + } + + for ( n = 0; n < procdef_count; n++ ) + { + file_write( fp, dcb.proc[n].sentence, sizeof( DCB_SENTENCE ) * procs[n]->sentence_count ); /* Ya procesado el byteorder */ + + /* Privadas */ + file_write( fp, dcb.proc[n].privar, sizeof( DCB_VAR ) * procs[n]->privars->count ); /* Ya procesado el byteorder */ + file_writeUint32A( fp, (uint32_t *)procs[n]->privars->stringvars, procs[n]->privars->stringvar_count ); + file_write( fp, procs[n]->pridata->bytes, procs[n]->pridata->current ); /* ****** */ + + /* Publicas */ + file_write( fp, dcb.proc[n].pubvar, sizeof( DCB_VAR ) * procs[n]->pubvars->count ); /* Ya procesado el byteorder */ + file_writeUint32A( fp, (uint32_t *)procs[n]->pubvars->stringvars, procs[n]->pubvars->stringvar_count ); + file_write( fp, procs[n]->pubdata->bytes, procs[n]->pubdata->current ); /* ****** */ + + /* Code */ + file_writeUint32A( fp, (uint32_t *)procs[n]->code.data, procs[n]->code.current ); + } + + /* Cada uno de los archivos incluidos */ + for ( n = 0; n < dcb_filecount; n++ ) + { + int siz = dcb.file[n].SName; + ARRANGE_DWORD( &dcb.file[n].SName ); + ARRANGE_DWORD( &dcb.file[n].SFile ); + ARRANGE_DWORD( &dcb.file[n].OFile ); + file_write( fp, &dcb.file[n], sizeof( DCB_FILE ) ); + file_write( fp, dcb_fullname[n], siz ); + } + + for ( n = 0; n < dcb_filecount; n++ ) + { + char buffer[8192]; + file * fp_r = file_open ( dcb_fullname[n], "rb" ); + int chunk_size, siz = 0; + + assert( fp_r ); + while ( !file_eof( fp_r ) ) + { + siz += chunk_size = file_read( fp_r, buffer, 8192 ); + file_write( fp, buffer, chunk_size ); + if ( chunk_size < 8192 ) break; + } + file_close( fp_r ); + } + + /* Write the stub signature */ + + if ( stubname != NULL ) + { + dcb_signature dcb_signature; + + /* Voy al final del archivo */ + + strcpy( dcb_signature.magic, DCB_STUB_MAGIC ); + dcb_signature.dcb_offset = ( int )stubsize; + + ARRANGE_DWORD( &dcb_signature.dcb_offset ); + + file_write( fp, &dcb_signature, sizeof( dcb_signature ) ); + } + + file_close( fp ); + + /* 6. Mostrar estad�sticas */ + + printf( "\nFile %s compiled (%ld bytes):\n\n", filename, offset ); + printf( " Processes %8d\n", procdef_count ); + printf( " Global data %8d bytes\n", globaldata->current ); + printf( " Local data %8d bytes\n", localdata->current ); + printf( " Private data %8d bytes\n", SPrivate ); + printf( " Public data %8d bytes\n", SPublic ); + printf( " Code %8d bytes\n", SCode ); + printf( " System processes %8d\n", NSysProcs ); + + printf( " Globals vars %8d\n", global.count ); + printf( " Locals vars %8d\n", local.count ); + printf( " Private vars %8d\n", NPriVars ); + printf( " Publics vars %8d\n", NPubVars ); + printf( " Identifiers %8d\n", identifier_count ); + printf( " Structs %8d\n", dcb_varspaces ); + printf( " Strings %8d (%d bytes)\n", string_count, string_used ); + + if ( dcb_filecount ) + printf( " Files added %8d (%ld bytes)\n", dcb_filecount, offset - OFilesTab ); + + printf( "\n" ); + + return 1; +} + +/* --------------------------------------------------------------------------- + * load_dcb as library + * --------------------------------------------------------------------------- */ + +int * newid = NULL; +int * stringid = NULL; +int * fileid = NULL; + +/* --------------------------------------------------------------------------- */ + +void * glodata = NULL ; +void * locdata = NULL ; + +DCB_SYSPROC_CODE2 * sysproc_code_ref = NULL ; + +/* ---------------------------------------------------------------------- */ + +typedef struct +{ + int offstart; + int offend; + int offnew; +} range; + +range * glovaroffs = NULL; +range * locvaroffs = NULL; + +VARSPACE * varspaces = NULL; + +/* ---------------------------------------------------------------------- */ + +void dcb_varspaces_load( file * fp, VARSPACE * vs, VARSPACE * vs_array, int count ) +{ + int n, m; + DCB_VAR vars; + VARIABLE var; + TYPEDEF type; + + for ( n = 0; n < count; n++ ) + { + file_read( fp, &vars, sizeof( DCB_VAR ) ) ; + ARRANGE_DWORD( &vars.ID ); + ARRANGE_DWORD( &vars.Offset ); + for ( m = 0; m < MAX_TYPECHUNKS; m++ ) ARRANGE_DWORD( &vars.Type.Count[m] ); + ARRANGE_DWORD( &vars.Type.Members ); + + type.depth = 0; + for ( m = 0; m < MAX_TYPECHUNKS; m++ ) + { + type.chunk[m].type = vars.Type.BaseType[m]; + type.chunk[m].count = vars.Type.Count[m]; + if ( type.chunk[m].type != TYPE_UNDEFINED ) type.depth++; + } + + if ( vars.Type.Members != NO_MEMBERS ) + type.varspace = &vs_array[vars.Type.Members]; + else + type.varspace = NULL; + + var.code = newid[vars.ID]; + var.type = type; + var.offset = vars.Offset; + varspace_add( vs, var ); + } +} + +/* ---------------------------------------------------------------------- */ + +void dcb_vars_load( file * fp, VARSPACE * vs, segment * data, char * data_source, int count, range ** offs, int totalsize ) +{ + int n, m; + DCB_VAR * vars = calloc( count, sizeof( DCB_VAR ) ); + VARIABLE var, * v; + TYPEDEF type; + + if ( offs ) *offs = calloc( count, sizeof( range ) ); + + for ( n = 0; n < count; n++ ) + { + file_read( fp, &vars[n], sizeof( DCB_VAR ) ) ; + ARRANGE_DWORD( &vars[n].ID ); + ARRANGE_DWORD( &vars[n].Offset ); + for ( m = 0; m < MAX_TYPECHUNKS; m++ ) ARRANGE_DWORD( &vars[n].Type.Count[m] ); + ARRANGE_DWORD( &vars[n].Type.Members ); + } + + for ( n = 0; n < count; n++ ) + { + type.depth = 0; + + for ( m = 0; m < MAX_TYPECHUNKS; m++ ) + { + type.chunk[m].type = vars[n].Type.BaseType[m]; + type.chunk[m].count = vars[n].Type.Count[m]; + if ( type.chunk[m].type != TYPE_UNDEFINED ) type.depth++; + } + + if ( vars[n].Type.Members != NO_MEMBERS ) + type.varspace = &varspaces[vars[n].Type.Members]; + else + type.varspace = NULL; + + var.code = newid[vars[n].ID]; + var.type = type; + var.offset = data->current; + + if ( ( v = varspace_search( vs, newid[vars[n].ID] ) ) ) + { + int sz; + + if ( !typedef_is_equal( v->type, type ) ) + { + printf( "ERROR: var %s already exits in varspace but is different\n", identifier_name( newid[vars[n].ID] ) ); + exit ( -1 ); + } + + sz = typedef_size( v->type ); + if ( sz & 0x0003 ) sz = ( sz & ~0x0003 ) + 4; + + if ( offs ) + { + (*offs)[n].offstart = vars[n].Offset; + (*offs)[n].offend = vars[n].Offset + sz - 1; + (*offs)[n].offnew = v->offset; + } + } + else + { + int sz; + if ( n < count - 1 ) + sz = vars[n+1].Offset - vars[n].Offset; + else + sz = totalsize - vars[n].Offset; + + segment_alloc(data, sz); + var.offset = data->current; + varspace_add( vs, var ); + + if ( offs ) + { + (*offs)[n].offstart = vars[n].Offset; + (*offs)[n].offend = vars[n].Offset + sz - 1; + (*offs)[n].offnew = var.offset; + } + + memmove( &((char *)data->bytes)[var.offset], &data_source[vars[n].Offset], sz ); + + data->current += sz; + } + } + + free( vars ); +} + +/* ---------------------------------------------------------------------- */ + +int get_new_off( int off, range * offs, int noffs ) +{ + int n; + + for ( n = 0; n < noffs; n++ ) + if ( off >= offs[n].offstart && off <= offs[n].offend ) + return off - offs[n].offstart + offs[n].offnew; + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +void codeblock_adjust(CODEBLOCK * code) +{ + int * ptr = code->data ; + int n; + + while (ptr < code->data + code->current) + { + if (*ptr == MN_CALL || *ptr == MN_PROC || *ptr == MN_TYPE) + { + ptr[1] = newid[ptr[1]]; + } + + if (MN_TYPEOF(*ptr) == MN_STRING && (*ptr & MN_MASK) == MN_PUSH) + { + ptr[1] = stringid[ptr[1]]; + } + + if ( (*ptr & MN_MASK) == MN_GLOBAL) + { + ptr[1] = get_new_off( ptr[1], glovaroffs, dcb.data.NGloVars ); + } + + if ( (*ptr & MN_MASK) == MN_LOCAL) + { + ptr[1] = get_new_off( ptr[1], locvaroffs, dcb.data.NLocVars ); + } + + if ( (*ptr & MN_MASK) == MN_SENTENCE ) + { + if ( dcb.data.Version == 0x0700 ) + ptr[1] = (ptr[1] & 0xfffff) | ( fileid[ptr[1]>>24] << 20 ); + else + ptr[1] = (ptr[1] & 0xfffff) | ( fileid[ptr[1]>>20] << 20 ); + } + + if ( (*ptr & MN_MASK) == MN_SYSCALL || (*ptr & MN_MASK) == MN_SYSPROC ) + { + DCB_SYSPROC_CODE2 * s = sysproc_code_ref ; + int found = 0; + for ( n = 0; n < dcb.data.NSysProcsCodes && !found; n++, s++ ) + { + if ( s->Code == ptr[1] ) + { + SYSPROC * p = sysproc_get( newid[ s->Id ] ); + for ( ; p && !found; p = p->next ) + { + if ( p->type == s->Type && p->params == s->Params && + !strcmp( (const char *)s->ParamTypes, p->paramtypes ) ) + { + ptr[1] = p->code; + found = 1; + } + } + } + } + } + ptr += MN_PARAMS(*ptr)+1 ; + } +} + +/* ---------------------------------------------------------------------- */ + +int dcb_load_lib( const char * filename ) +{ + unsigned int n ; + file * fp ; + PROCDEF * proc; + + /* check for existence of the DCB FILE */ + if ( !file_exists( filename ) ) return 0 ; + + fp = file_open( filename, "rb0" ) ; + if ( !fp ) + { + fprintf( stderr, "ERROR: Runtime error - Could not open file (%s)\n", filename ) ; + exit( 1 ); + } + + /* Read Header */ + + file_seek( fp, 0, SEEK_SET ); + file_read( fp, &dcb, sizeof( DCB_HEADER_DATA ) ) ; + + ARRANGE_DWORD( &dcb.data.Version ); + ARRANGE_DWORD( &dcb.data.NProcs ); + ARRANGE_DWORD( &dcb.data.NFiles ); + ARRANGE_DWORD( &dcb.data.NID ); + ARRANGE_DWORD( &dcb.data.NStrings ); + ARRANGE_DWORD( &dcb.data.NLocVars ); + ARRANGE_DWORD( &dcb.data.NLocStrings ); + ARRANGE_DWORD( &dcb.data.NGloVars ); + + ARRANGE_DWORD( &dcb.data.SGlobal ); + ARRANGE_DWORD( &dcb.data.SLocal ); + ARRANGE_DWORD( &dcb.data.SText ); + + ARRANGE_DWORD( &dcb.data.NImports ); + + ARRANGE_DWORD( &dcb.data.NSourceFiles ); + + ARRANGE_DWORD( &dcb.data.NSysProcsCodes ); + + ARRANGE_DWORD( &dcb.data.OProcsTab ); + ARRANGE_DWORD( &dcb.data.OID ); + ARRANGE_DWORD( &dcb.data.OStrings ); + ARRANGE_DWORD( &dcb.data.OText ); + ARRANGE_DWORD( &dcb.data.OGlobal ); + ARRANGE_DWORD( &dcb.data.OGloVars ); + ARRANGE_DWORD( &dcb.data.OLocal ); + ARRANGE_DWORD( &dcb.data.OLocVars ); + ARRANGE_DWORD( &dcb.data.OLocStrings ); + ARRANGE_DWORD( &dcb.data.OVarSpaces ); + ARRANGE_DWORD( &dcb.data.OFilesTab ); + ARRANGE_DWORD( &dcb.data.OImports ); + + ARRANGE_DWORD( &dcb.data.OSourceFiles ); + ARRANGE_DWORD( &dcb.data.OSysProcsCodes ); + + if ( memcmp( dcb.data.Header, DCL_MAGIC, sizeof( DCL_MAGIC ) - 1 ) != 0 ) return 0 ; + if ( dcb.data.Version < 0x0710 ) return -1 ; + + /* Load identifiers */ + + if ( dcb.data.NID ) + { + dcb.id = ( DCB_ID * ) calloc( dcb.data.NID, sizeof( DCB_ID ) ) ; + + FREEM( newid ); + newid = calloc( dcb.data.NID, sizeof( int ) ); + + file_seek( fp, dcb.data.OID, SEEK_SET ) ; + for ( n = 0; n < dcb.data.NID; n++ ) + { + file_read( fp, &dcb.id[n], sizeof( DCB_ID ) ) ; + ARRANGE_DWORD( &dcb.id[n].Code ); + newid[dcb.id[n].Code] = identifier_search_or_add( ( const char * ) dcb.id[n].Name ); + } + free( dcb.id ); + } + + /* Load strings */ + + if ( dcb.data.NStrings ) + { + char * strdata = calloc( 1, dcb.data.SText ); + uint32_t * stroffs = calloc( dcb.data.NStrings, sizeof( uint32_t ) ); + + FREEM( stringid ); + stringid = calloc( dcb.data.NStrings, sizeof( int ) ); + + file_seek(( file * )fp, dcb.data.OStrings, SEEK_SET ) ; + file_readUint32A(( file * )fp, stroffs, dcb.data.NStrings ) ; + + file_seek(( file * )fp, dcb.data.OText, SEEK_SET ) ; + file_read(( file * )fp, strdata, dcb.data.SText ) ; + + for ( n = 0; n < dcb.data.NStrings; n++ ) stringid[n] = string_new( &strdata[stroffs[n]] ); + + free( strdata ); + free( stroffs ); + } + + /* Load imports */ + + if ( dcb.data.NImports ) + { + dcb.imports = ( uint32_t * )calloc( dcb.data.NImports, sizeof( uint32_t ) ) ; + file_seek( fp, dcb.data.OImports, SEEK_SET ) ; + file_readUint32A( fp, dcb.imports, dcb.data.NImports ) ; + for ( n = 0; n < dcb.data.NImports; n++ ) import_mod( ( char * ) string_get( stringid[dcb.imports[n]] ) ); + FREEM( dcb.imports ); + } + + /* Recupero tabla de fixup de sysprocs */ + + sysproc_code_ref = calloc( dcb.data.NSysProcsCodes, sizeof( DCB_SYSPROC_CODE2 ) ) ; + file_seek( fp, dcb.data.OSysProcsCodes, SEEK_SET ) ; + for ( n = 0; n < dcb.data.NSysProcsCodes; n++ ) + { + DCB_SYSPROC_CODE sdcb; + file_read( fp, &sdcb, sizeof( DCB_SYSPROC_CODE ) ) ; + + ARRANGE_DWORD( &sdcb.Id ); + ARRANGE_DWORD( &sdcb.Type ); + ARRANGE_DWORD( &sdcb.Params ); + ARRANGE_DWORD( &sdcb.Code ); + + sysproc_code_ref[n].Id = sdcb.Id ; + sysproc_code_ref[n].Type = sdcb.Type ; + sysproc_code_ref[n].Params = sdcb.Params ; + sysproc_code_ref[n].Code = sdcb.Code ; + sysproc_code_ref[n].ParamTypes = ( uint8_t * ) calloc( sdcb.Params + 1, sizeof( char ) ); + if ( sdcb.Params ) file_read( fp, sysproc_code_ref[n].ParamTypes, sdcb.Params ) ; + } + + /* Load sources */ + + if ( dcb.data.NSourceFiles ) + { + char filename[__MAX_PATH] ; + + fileid = calloc( dcb.data.NSourceFiles, sizeof( int ) ); + + dcb.sourcecount = ( uint32_t * ) calloc( dcb.data.NSourceFiles, sizeof( uint32_t ) ) ; + dcb.sourcelines = ( uint8_t *** ) calloc( dcb.data.NSourceFiles, sizeof( char ** ) ) ; + dcb.sourcefiles = ( uint8_t ** ) calloc( dcb.data.NSourceFiles, sizeof( char * ) ) ; + file_seek( fp, dcb.data.OSourceFiles, SEEK_SET ) ; + for ( n = 0; n < dcb.data.NSourceFiles; n++ ) + { + int m; + uint32_t size; + file_readUint32( fp, &size ) ; + file_read( fp, filename, size ) ; + fileid[n] = -1; + for( m = 0; m < n_files; m++ ) if ( !strcmp( filename, files[m] ) ) fileid[n] = m; + if ( fileid[n] == -1 ) + { + strcpy( files[n_files], filename ); + fileid[n] = n_files++; + } + } + } + + /* Load datas */ + + glodata = ( void * ) calloc( dcb.data.SGlobal, 1 ) ; + locdata = ( void * ) calloc( dcb.data.SLocal, 1 ) ; + + /* Recupera las zonas de datos globales */ + + file_seek( fp, dcb.data.OGlobal, SEEK_SET ) ; + file_read( fp, glodata, dcb.data.SGlobal ) ; /* **** */ + + file_seek( fp, dcb.data.OLocal, SEEK_SET ) ; + file_read( fp, locdata, dcb.data.SLocal ) ; /* **** */ + + /* Varspaces Load */ + + if ( dcb.data.NVarSpaces ) + { + varspaces = ( VARSPACE * ) calloc( dcb.data.NVarSpaces, sizeof( VARSPACE ) ) ; + dcb.varspace = ( DCB_VARSPACE * ) calloc( dcb.data.NVarSpaces, sizeof( DCB_VARSPACE ) ) ; + + file_seek( fp, dcb.data.OVarSpaces, SEEK_SET ) ; + for ( n = 0; n < dcb.data.NVarSpaces; n++ ) + { + file_read( fp, &dcb.varspace[n], sizeof( DCB_VARSPACE ) ) ; + ARRANGE_DWORD( &dcb.varspace[n].NVars ); + ARRANGE_DWORD( &dcb.varspace[n].OVars ); + } + + for ( n = 0; n < dcb.data.NVarSpaces; n++ ) + { + if ( !dcb.varspace[n].NVars ) continue ; + file_seek( fp, dcb.varspace[n].OVars, SEEK_SET ) ; + dcb_varspaces_load( fp, &varspaces[n], varspaces, dcb.varspace[n].NVars ); + } + } + + if ( dcb.data.NGloVars ) + { + file_seek( fp, dcb.data.OGloVars, SEEK_SET ) ; + dcb_vars_load( fp, &global, globaldata, glodata, dcb.data.NGloVars, &glovaroffs, dcb.data.SGlobal ); + } + + if ( dcb.data.NLocVars ) + { + file_seek( fp, dcb.data.OLocVars, SEEK_SET ) ; + dcb_vars_load( fp, &local, localdata, locdata, dcb.data.NLocVars, &locvaroffs, dcb.data.SLocal ); + } + + if ( dcb.data.NLocStrings ) + { + int o, newoff, found, m; + int * locstr = ( int * ) calloc( dcb.data.NLocStrings + 4, sizeof( int ) ) ; + + file_seek( fp, dcb.data.OLocStrings, SEEK_SET ) ; + file_readUint32A( fp, (uint32_t *)locstr, dcb.data.NLocStrings ) ; + for ( m = 0; m < dcb.data.NLocStrings; m++ ) + { + newoff = get_new_off( locstr[m], locvaroffs, dcb.data.NLocStrings ); + for ( found = 0, o = 0; o < local.stringvar_count; o++ ) if ( newoff == local.stringvars[o] ) { found = 1; break; } + if ( !found ) varspace_varstring( &local, newoff ); + } + FREEM( locstr ); + } + + /* Load process */ + + dcb.proc = ( DCB_PROC * ) calloc(( 1 + dcb.data.NProcs ), sizeof( DCB_PROC ) ) ; + + file_seek( fp, dcb.data.OProcsTab, SEEK_SET ) ; + for ( n = 0; n < dcb.data.NProcs; n++ ) + { + file_read( fp, &dcb.proc[n], sizeof( DCB_PROC_DATA ) ) ; + + ARRANGE_DWORD( &dcb.proc[n].data.ID ); + + ARRANGE_DWORD( &dcb.proc[n].data.Flags ); + ARRANGE_DWORD( &dcb.proc[n].data.NParams ); + + ARRANGE_DWORD( &dcb.proc[n].data.NPriVars ); + ARRANGE_DWORD( &dcb.proc[n].data.NPriStrings ); + + ARRANGE_DWORD( &dcb.proc[n].data.NPubVars ); + ARRANGE_DWORD( &dcb.proc[n].data.NPubStrings ); + + ARRANGE_DWORD( &dcb.proc[n].data.NSentences ); + + ARRANGE_DWORD( &dcb.proc[n].data.SPrivate ); + ARRANGE_DWORD( &dcb.proc[n].data.SPublic ); + + ARRANGE_DWORD( &dcb.proc[n].data.SCode ); + + ARRANGE_DWORD( &dcb.proc[n].data.OExitCode ); + ARRANGE_DWORD( &dcb.proc[n].data.OErrorCode ); + + ARRANGE_DWORD( &dcb.proc[n].data.OSentences ); + + ARRANGE_DWORD( &dcb.proc[n].data.OPriVars ); + ARRANGE_DWORD( &dcb.proc[n].data.OPriStrings ); + ARRANGE_DWORD( &dcb.proc[n].data.OPrivate ); + + ARRANGE_DWORD( &dcb.proc[n].data.OPubVars ); + ARRANGE_DWORD( &dcb.proc[n].data.OPubStrings ); + ARRANGE_DWORD( &dcb.proc[n].data.OPublic ); + + ARRANGE_DWORD( &dcb.proc[n].data.OCode ); + } + + for ( n = 0; n < dcb.data.NProcs; n++ ) + { + char * pridata = NULL, *pubdata = NULL; + range * prioffs = NULL, * puboffs = NULL; + + if ( !dcb.proc[n].data.SCode ) + { + continue; + } + else if ( procdef_search( newid[dcb.proc[n].data.ID] ) ) + { + if ( debug ) + { + token.type = IDENTIFIER; + token.code = newid[dcb.proc[n].data.ID]; + compile_warning(0, MSG_PROC_ALREADY_DEFINED); + } + continue; + } + + proc = procdef_new(procdef_getid(), newid[dcb.proc[n].data.ID]); + + codeblock_alloc(&proc->code, dcb.proc[n].data.SCode); + + file_seek( fp, dcb.proc[n].data.OCode, SEEK_SET ) ; + file_readUint32A( fp, (uint32_t *)proc->code.data, dcb.proc[n].data.SCode / sizeof(uint32_t) ) ; + proc->code.current = dcb.proc[n].data.SCode / sizeof(uint32_t); + + if ( dcb.proc[n].data.OExitCode ) + proc->exitcode = dcb.proc[n].data.OExitCode ; + else + proc->exitcode = 0 ; + + if ( dcb.proc[n].data.OErrorCode ) + proc->errorcode = dcb.proc[n].data.OErrorCode ; + else + proc->errorcode = 0 ; + + proc->defined = 1; + proc->declared = 1; + proc->imported = 1; + proc->flags = dcb.proc[n].data.Flags ; + + proc->params = dcb.proc[n].data.NParams ; + + if ( dcb.proc[n].data.SPrivate ) + { + pridata = calloc(dcb.proc[n].data.SPrivate, 1); + file_seek( fp, dcb.proc[n].data.OPrivate, SEEK_SET ) ; + file_read( fp, pridata, dcb.proc[n].data.SPrivate ) ; /* *** */ + } + + if ( dcb.proc[n].data.SPublic ) + { + pubdata = calloc(dcb.proc[n].data.SPublic, 1); + file_seek( fp, dcb.proc[n].data.OPublic, SEEK_SET ) ; + file_read( fp, pubdata, dcb.proc[n].data.SPublic ) ; /* *** */ + } + + if ( dcb.proc[n].data.NPriVars ) + { + prioffs = calloc( dcb.proc[n].data.NPriVars, sizeof( range ) ); + file_seek( fp, dcb.proc[n].data.OPriVars, SEEK_SET ) ; + dcb_vars_load( fp, proc->privars, proc->pridata, pridata, dcb.proc[n].data.NPriVars, &prioffs, dcb.proc[n].data.SPrivate ); + } + + if ( dcb.proc[n].data.NPubVars ) + { + puboffs = calloc( dcb.proc[n].data.NPubVars, sizeof( range ) ); + file_seek( fp, dcb.proc[n].data.OPubVars, SEEK_SET ) ; + dcb_vars_load( fp, proc->pubvars, proc->pubdata, pubdata, dcb.proc[n].data.NPubVars, &puboffs, dcb.proc[n].data.SPublic ); + } + + if ( dcb.proc[n].data.NPriStrings ) + { + int m, * sv = ( int * )calloc( dcb.proc[n].data.NPriStrings, sizeof( int ) ) ; + file_seek( fp, dcb.proc[n].data.OPriStrings, SEEK_SET ) ; + file_readUint32A( fp, (uint32_t *)sv, dcb.proc[n].data.NPriStrings ) ; + for ( m = 0; m < dcb.proc[n].data.NPriStrings; m++ ) varspace_varstring( proc->privars, get_new_off( sv[m], prioffs, dcb.proc[n].data.NPriVars )); + FREEM( sv ); + } + + if ( dcb.proc[n].data.NPubStrings ) + { + int m, * sv = ( int * )calloc( dcb.proc[n].data.NPubStrings, sizeof( int ) ) ; + file_seek( fp, dcb.proc[n].data.OPubStrings, SEEK_SET ) ; + file_readUint32A( fp, (uint32_t *)sv, dcb.proc[n].data.NPubStrings ) ; + for ( m = 0; m < dcb.proc[n].data.NPubStrings; m++ ) varspace_varstring( proc->pubvars, get_new_off( sv[m], puboffs, dcb.proc[n].data.NPubVars )); + FREEM( sv ); + } + + codeblock_adjust( &proc->code ); + + FREEM( pridata ) + FREEM( pubdata ) + FREEM( prioffs ) + FREEM( puboffs ) + } + + FREEM( sysproc_code_ref ); + FREEM( fileid ); + FREEM( newid ); + FREEM( stringid ); + FREEM( glodata ); + FREEM( locdata ); + FREEM( glovaroffs ); + FREEM( locvaroffs ); + + /* Recupera los ficheros incluídos */ +/* N/A + if ( dcb.data.NFiles ) + { + DCB_FILE dcbfile; + char fname[__MAX_PATH]; + + xfile_init( dcb.data.NFiles ); + file_seek( fp, dcb.data.OFilesTab, SEEK_SET ) ; + for ( n = 0 ; n < dcb.data.NFiles; n++ ) + { + file_read( fp, &dcbfile, sizeof( DCB_FILE ) ) ; + + ARRANGE_DWORD( &dcbfile.SName ); + ARRANGE_DWORD( &dcbfile.SFile ); + ARRANGE_DWORD( &dcbfile.OFile ); + + file_read( fp, &fname, dcbfile.SName ) ; + file_add_xfile( fp, NULL, dcbfile.OFile, fname, dcbfile.SFile ) ; + } + } +*/ + file_close( fp ); + + return 1 ; +} + +/* ---------------------------------------------------------------------- */ -- cgit v1.2.3