int AMXAPI aux_LoadProgramFromMemory(AMX* amx, char* filedata) { AMX_HEADER hdr; memcpy(&hdr, filedata, sizeof hdr); amx_Align16(&hdr.magic); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { return AMX_ERR_FORMAT; } void* memblock; if ((memblock = malloc(hdr.stp)) == NULL) { return AMX_ERR_MEMORY; } memcpy(memblock, filedata, (size_t)hdr.size); //amx_SetDebugHook(amx, (AMX_DEBUG)amx_Debug); memset(amx, 0, sizeof(*amx)); int result = amx_Init(amx, memblock); if (result != AMX_ERR_NONE) { free(memblock); amx->base = NULL; } return result; }
/* aux_LoadProgram() * Load a compiled Pawn script into memory and initialize the abstract machine. * This function is extracted out of AMXAUX.C. */ int AMXAPI aux_LoadProgram(AMX *amx, char *filename, void *memblock, int AMXAPI (*amx_Debug)(AMX*)) { FILE *fp; AMX_HEADER hdr; int result, didalloc; /* open the file, read and check the header */ if ((fp = fopen(filename, "rb")) == NULL) return AMX_ERR_NOTFOUND; fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { fclose(fp); return AMX_ERR_FORMAT; } /* if */ /* allocate the memblock if it is NULL */ didalloc = 0; if (memblock == NULL) { if ((memblock = malloc(hdr.stp)) == NULL) { fclose(fp); return AMX_ERR_MEMORY; } /* if */ didalloc = 1; /* after amx_Init(), amx->base points to the memory block */ } /* if */ /* read in the file */ rewind(fp); fread(memblock, 1, (size_t)hdr.size, fp); fclose(fp); /* initialize the abstract machine */ memset(amx, 0, sizeof *amx); amx_SetDebugHook(amx, amx_Debug); /* set up the debug hook */ result = amx_Init(amx, memblock); /* free the memory block on error, if it was allocated here */ if (result != AMX_ERR_NONE && didalloc) { free(memblock); amx->base = NULL; /* avoid a double free */ } /* if */ return result; }
//As of Small 3.0, there's extra debug info in the file we need to get out. //Sadly this is placed somewhere really inconvenient and I'm mad. void ReadFileIntoPl(abl *pl, FILE *fp) { AMX_HEADER hdr; AMX_DBG_HDR dbg; fread(&hdr, sizeof(hdr), 1, fp); amx_Align32((uint32_t *)&hdr.stp); amx_Align32((uint32_t *)&hdr.size); pl->stp = hdr.stp; int size = hdr.size; if (hdr.flags & AMX_FLAG_DEBUG) { fseek(fp, hdr.size, SEEK_SET); fread(&dbg, sizeof(dbg), 1, fp); size += dbg.size; } pl->size = size; pl->data = new char[size]; rewind(fp); fread(pl->data, 1, size, fp); }
size_t aux_ProgramSize(char *filename) { FILE *fp; AMX_HEADER hdr; if ((fp=fopen(filename,"rb")) == NULL) return 0; fread(&hdr, sizeof hdr, 1, fp); fclose(fp); amx_Align32((uint32_t*)&hdr.stp); return hdr.stp; }
int AMXAPI aux_LoadProgram(AMX* amx, char* filename) { FILE* fp; if ((fp = fopen(filename, "rb")) == NULL) { return AMX_ERR_NOTFOUND; } AMX_HEADER hdr; fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { fclose(fp); return AMX_ERR_FORMAT; } void* memblock; if ((memblock = malloc(hdr.stp)) == NULL) { fclose(fp); return AMX_ERR_MEMORY; } rewind(fp); fread(memblock, 1, (size_t)hdr.size, fp); fclose(fp); //amx_SetDebugHook(amx, (AMX_DEBUG)amx_Debug); memset(amx, 0, sizeof(*amx)); int result = amx_Init(amx, memblock); if (result != AMX_ERR_NONE) { free(memblock); amx->base = NULL; } return result; }
size_t aux_ProgramSize(char *filename) { FILE *fp; AMX_HEADER hdr; if ((fp=fopen(filename,"rb")) == NULL) return 0; fread(&hdr, sizeof hdr, 1, fp); fclose(fp); amx_Align16(&hdr.magic); amx_Align32((unsigned long*)&hdr.stp); return (hdr.magic==AMX_MAGIC) ? (size_t)hdr.stp : 0; }
int aux_LoadProgram(AMX *amx, char *filename, void *memblock) { FILE *fp; AMX_HEADER hdr; if ((fp = fopen(filename, "rb")) == NULL ) return AMX_ERR_NOTFOUND; fread(&hdr, sizeof hdr, 1, fp); amx_Align32((unsigned long *)&hdr.size); rewind(fp); fread(memblock, 1, (size_t)hdr.size, fp); fclose(fp); memset(amx, 0, sizeof *amx); return amx_Init(amx, memblock); }
/* aux_LoadProgram() * Load a compiled Pawn script into memory and initialize the abstract machine. * This function is extracted out of AMXAUX.C. */ int AMXAPI aux_LoadProgram(AMX *amx, char *filename) { FILE *fp; AMX_HEADER hdr; int result; int32_t size; unsigned char *datablock; #define OVLPOOLSIZE 4096 /* open the file, read and check the header */ if ((fp = fopen(filename, "rb")) == NULL) return AMX_ERR_NOTFOUND; fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); amx_Align16((uint16_t *)&hdr.flags); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.cod); amx_Align32((uint32_t *)&hdr.dat); amx_Align32((uint32_t *)&hdr.hea); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { fclose(fp); return AMX_ERR_FORMAT; } /* if */ if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { /* allocate the block for the data + stack/heap, plus the complete file * header, plus the overlay pool */ #if defined AMXOVL size = (hdr.stp - hdr.dat) + hdr.cod + OVLPOOLSIZE; #else return AMX_ERR_OVERLAY; #endif } else { size = hdr.stp; } /* if */ if ((datablock = malloc(size)) == NULL) { fclose(fp); return AMX_ERR_MEMORY; } /* if */ /* save the filename, for optionally reading the debug information (we could * also have read it here immediately); for reading overlays, we also need * the filename (and in this case, note that amx_Init() already browses * through all overlays) */ strcpy(g_filename, filename); /* read in the file, in two parts; first the header and then the data section */ rewind(fp); if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { #if defined AMXOVL /* read the entire header */ fread(datablock, 1, hdr.cod, fp); /* read the data section, put it behind the header in the block */ fseek(fp, hdr.dat, SEEK_SET); fread(datablock + hdr.cod, 1, hdr.hea - hdr.dat, fp); /* initialize the overlay pool */ amx_poolinit(datablock + (hdr.stp - hdr.dat) + hdr.cod, OVLPOOLSIZE); #endif } else { fread(datablock, 1, (size_t)hdr.size, fp); } /* if */ fclose(fp); /* initialize the abstract machine */ memset(amx, 0, sizeof *amx); #if defined AMXOVL if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { amx->data = datablock + hdr.cod; amx->overlay = prun_Overlay; } /* if */ #endif result = amx_Init(amx, datablock); /* free the memory block on error, if it was allocated here */ if (result != AMX_ERR_NONE) { free(datablock); amx->base = NULL; /* avoid a double free */ } /* if */ return result; }
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, FILE *fp) { AMX_HEADER amxhdr; AMX_DBG_HDR dbghdr; size_t size; unsigned char *ptr; int index, dim; AMX_DBG_LINE *line; AMX_DBG_SYMDIM *symdim; assert(fp != NULL); assert(amxdbg != NULL); memset(&amxhdr, 0, sizeof amxhdr); fseek(fp, 0L, SEEK_SET); if (fread(&amxhdr, sizeof amxhdr, 1, fp) == 0) return AMX_ERR_FORMAT; #if BYTE_ORDER==BIG_ENDIAN amx_Align32((uint32_t*)&amxhdr.size); amx_Align16(&amxhdr.magic); amx_Align16(&dbghdr.flags); #endif if (amxhdr.magic != AMX_MAGIC) return AMX_ERR_FORMAT; if ((amxhdr.flags & AMX_FLAG_DEBUG) == 0) return AMX_ERR_DEBUG; fseek(fp, amxhdr.size, SEEK_SET); memset(&dbghdr, 0, sizeof(AMX_DBG_HDR)); if (fread(&dbghdr, sizeof(AMX_DBG_HDR), 1, fp) == 0) return AMX_ERR_FORMAT; #if BYTE_ORDER==BIG_ENDIAN amx_Align32((uint32_t*)&dbghdr.size); amx_Align16(&dbghdr.magic); amx_Align16(&dbghdr.flags); amx_Align16(&dbghdr.files); amx_Align16(&dbghdr.lines); amx_Align16(&dbghdr.symbols); amx_Align16(&dbghdr.tags); amx_Align16(&dbghdr.automatons); amx_Align16(&dbghdr.states); #endif if (dbghdr.magic != AMX_DBG_MAGIC) return AMX_ERR_FORMAT; /* allocate all memory */ memset(amxdbg, 0, sizeof(AMX_DBG)); amxdbg->hdr = malloc((size_t)dbghdr.size); if (dbghdr.files > 0) amxdbg->filetbl = malloc(dbghdr.files * sizeof(AMX_DBG_FILE *)); if (dbghdr.symbols > 0) amxdbg->symboltbl = malloc(dbghdr.symbols * sizeof(AMX_DBG_SYMBOL *)); if (dbghdr.tags > 0) amxdbg->tagtbl = malloc(dbghdr.tags * sizeof(AMX_DBG_TAG *)); if (dbghdr.automatons > 0) amxdbg->automatontbl = malloc(dbghdr.automatons * sizeof(AMX_DBG_MACHINE *)); if (dbghdr.states > 0) amxdbg->statetbl = malloc(dbghdr.states * sizeof(AMX_DBG_STATE *)); if (amxdbg->hdr == NULL || (dbghdr.files > 0 && amxdbg->filetbl == NULL) || (dbghdr.symbols > 0 && amxdbg->symboltbl == NULL) || (dbghdr.tags > 0 && amxdbg->tagtbl == NULL) || (dbghdr.states > 0 && amxdbg->statetbl == NULL) || (dbghdr.automatons > 0 && amxdbg->automatontbl == NULL)) { dbg_FreeInfo(amxdbg); return AMX_ERR_MEMORY; } /* if */ /* load the entire symbolic information block into memory */ memcpy(amxdbg->hdr, &dbghdr, sizeof dbghdr); size=(size_t)(dbghdr.size - sizeof dbghdr); if (fread(amxdbg->hdr + 1, 1, size, fp) < size) { dbg_FreeInfo(amxdbg); return AMX_ERR_FORMAT; } /* if */ /* run through the file, fix alignment issues and set up table pointers */ ptr = (unsigned char *)(amxdbg->hdr + 1); /* file table */ for (index = 0; index < dbghdr.files; index++) { assert(amxdbg->filetbl != NULL); amxdbg->filetbl[index] = (AMX_DBG_FILE *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_AlignCell(&amxdbg->filetbl[index]->address); #endif for (ptr = ptr + sizeof(AMX_DBG_FILE); *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ } /* for */ /* line table */ amxdbg->linetbl = (AMX_DBG_LINE*)ptr; #if BYTE_ORDER==BIG_ENDIAN for (index = 0; index < dbghdr.lines; index++) { amx_AlignCell(&amxdbg->linetbl[index].address); amx_Align32((uint32_t*)&amxdbg->linetbl[index].line); } /* for */ #endif ptr += (uint16_t)dbghdr.lines * sizeof(AMX_DBG_LINE); /* detect dbghdr.lines overflow */ while ((line = (AMX_DBG_LINE *)ptr) && (cell)line->address > (cell)(line - 1)->address) { #if BYTE_ORDER==BIG_ENDIAN for (index = 0; index <= (uint32_t)(1u << 16) - 1; index++) { amx_AlignCell(&linetbl[index].address); amx_Align32((uint32_t*)&linetbl[index].line); line++; } /* for */ #endif ptr += (uint32_t)(1u << 16) * sizeof(AMX_DBG_LINE); } /* while */ /* symbol table (plus index tags) */ for (index = 0; index < dbghdr.symbols; index++) { assert(amxdbg->symboltbl != NULL); amxdbg->symboltbl[index] = (AMX_DBG_SYMBOL *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_AlignCell(&amxdbg->symboltbl[index]->address); amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->tag); amx_AlignCell(&amxdbg->symboltbl[index]->codestart); amx_AlignCell(&amxdbg->symboltbl[index]->codeend); amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->dim); #endif for (ptr = ptr + sizeof(AMX_DBG_SYMBOL); *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ for (dim = 0; dim < amxdbg->symboltbl[index]->dim; dim++) { symdim = (AMX_DBG_SYMDIM *)ptr; amx_Align16((uint16_t*)&symdim->tag); amx_AlignCell(&symdim->size); ptr += sizeof(AMX_DBG_SYMDIM); } /* for */ } /* for */ /* tag name table */ for (index = 0; index < dbghdr.tags; index++) { assert(amxdbg->tagtbl != NULL); amxdbg->tagtbl[index] = (AMX_DBG_TAG *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_Align16(&amxdbg->tagtbl[index]->tag); #endif for (ptr = ptr + sizeof(AMX_DBG_TAG) - 1; *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ } /* for */ /* automaton name table */ for (index = 0; index < dbghdr.automatons; index++) { assert(amxdbg->automatontbl != NULL); amxdbg->automatontbl[index] = (AMX_DBG_MACHINE *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_Align16(&amxdbg->automatontbl[index]->automaton); amx_AlignCell(&amxdbg->automatontbl[index]->address); #endif for (ptr = ptr + sizeof(AMX_DBG_MACHINE) - 1; *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ } /* for */ /* state name table */ for (index = 0; index < dbghdr.states; index++) { assert(amxdbg->statetbl != NULL); amxdbg->statetbl[index] = (AMX_DBG_STATE *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_Align16(&amxdbg->statetbl[index]->state); amx_Align16(&amxdbg->automatontbl[index]->automaton); #endif for (ptr = ptr + sizeof(AMX_DBG_STATE) - 1; *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ } /* for */ return AMX_ERR_NONE; }
int pawnLoad( Pawn * p, const char * fileName ) { FILE *fp; AMX_HEADER hdr; int result, i; int32_t size; unsigned char * datablock; #define OVLPOOLSIZE 1024 // open the file, read and check the header if ((fp = fopen(fileName, "rb")) == NULL) return AMX_ERR_NOTFOUND; p->fp = fp; fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); amx_Align16((uint16_t *)&hdr.flags); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.cod); amx_Align32((uint32_t *)&hdr.dat); amx_Align32((uint32_t *)&hdr.hea); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { fclose(fp); return AMX_ERR_FORMAT; } // if if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) // allocate the block for the data + stack/heap, plus the complete file // header, plus the overlay pool size = (hdr.stp - hdr.dat) + hdr.cod + POOL_SZ; else size = hdr.stp; if( size > (STACK_SZ + POOL_SZ) ) { fclose(fp); return AMX_ERR_MEMORY; } datablock = p->datablock; p->header = datablock; p->stack = datablock + hdr.cod; p->pool = datablock + hdr.cod + (hdr.stp - hdr.dat); // save the filename, for optionally reading the debug information (we could // also have read it here immediately); for reading overlays, we also need // the filename (and in this case, note that amx_Init() already browses // through all overlays) // read in the file, in two parts; first the header and then the data section rewind(fp); if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { // read the entire header fread(datablock, 1, hdr.cod, fp); // read the data section, put it behind the header in the block fseek(fp, hdr.dat, SEEK_SET); fread(datablock + hdr.cod, 1, hdr.hea - hdr.dat, fp); // initialize the overlay pool amx_poolinit(datablock + (hdr.stp - hdr.dat) + hdr.cod, OVLPOOLSIZE); } else { fread(datablock, 1, (size_t)hdr.size, fp); } // if //fclose(fp); // initialize the abstract machine for ( i=0; i<sizeof(p->amx); i++ ) ((unsigned char *)&p->amx)[i] = 0; if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { p->amx.data = datablock + hdr.cod; p->amx.overlay = prun_Overlay; } else { fread(datablock, 1, (size_t)hdr.size, fp); } result = amx_Init( &p->amx, datablock); // free the memory block on error, if it was allocated here if (result != AMX_ERR_NONE) { p->amx.base = NULL; // avoid a double free } // if return result; /*AMX_HEADER hdr; int i; if ( !(p->fp = fopen( fileName, "rb" ) ) ) return PAWN_ERR_FILE_OPEN; g_fp = p->fp; fread( &hdr, sizeof(hdr), 1, p->fp ); amx_Align16( &hdr.magic ); amx_Align16((uint16_t *)&hdr.flags); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.cod); amx_Align32((uint32_t *)&hdr.dat); amx_Align32((uint32_t *)&hdr.hea); amx_Align32((uint32_t *)&hdr.stp); if ( hdr.magic != AMX_MAGIC ) { fclose( p->fp ); return PAWN_ERR_FORMAT; } rewind( p->fp ); fread( p->header, 1, hdr.cod, p->fp ); fseek( p->fp, hdr.dat, SEEK_SET ); fread( p->stack, 1, hdr.hea - hdr.dat, p->fp ); amx_poolinit( p->pool, POOL_SZ ); for ( i=0; i<sizeof(p->amx); i++ ) ((unsigned char *)&p->amx)[i] = 0; p->amx.data = p->stack; p->amx.overlay = prun_Overlay; i = amx_Init( &p->amx, p->header ); return ( i == AMX_ERR_NONE ) ? PAWN_OK : PAWN_ERR_INIT;*/ }
int AMXAPI aux_LoadProgram(AMX *amx, const char *filename) { int error; FILE *fp; AMX_HEADER hdr; void *pcode = NULL; void *ncode = NULL; // ncode = new machine code void *rt = NULL; // rt = relocation table (temporary) /* open the file */ error = AMX_ERR_NOTFOUND; /* assume "file not found" */ if ((fp = fopen(filename, "rb")) == NULL) goto fail; /* read the header */ error = AMX_ERR_FORMAT; /* assume "invalid file format" */ fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); if (hdr.magic != AMX_MAGIC) goto fail; /* allocate memory for the P-code */ error = AMX_ERR_MEMORY; /* assume "insufficient memory" */ amx_Align32((uint32_t *)&hdr.stp); amx_Align32((uint32_t *)&hdr.size); if ((pcode = malloc((size_t)hdr.stp)) == NULL) goto fail; /* read the P-code and initialize the abstract machine */ rewind(fp); fread(pcode, 1, (int)hdr.size, fp); fclose(fp); fp = NULL; memset(amx, 0, sizeof *amx); amx->flags = AMX_FLAG_JITC; if ((error = amx_Init(amx, pcode)) != AMX_ERR_NONE) goto fail; /* Now we have an initialized abstract machine, which is normally immediately * runnable by amx_Exec(). Instead of running the code, we throw it at the * JIT compiler... */ /* allocate memory for the compiled instructions and the temporary * relocation table */ error = AMX_ERR_MEMORY; /* assume "insufficient memory" */ ncode = malloc(amx->code_size);/* amx->code_size is an estimate */ if (ncode == NULL) goto fail; if (amx->reloc_size > 0) { rt = malloc(amx->reloc_size); if (rt == NULL) goto fail; } /* if */ /* JIT rulz! (TM) */ if ((error = amx_InitJIT(amx, rt, ncode)) != AMX_ERR_NONE) goto fail; /* The compiled code is relocatable, since only relative jumps are * used for destinations within the generated code and absoulute * addresses for jumps into the runtime, which is fixed in memory. */ error = AMX_ERR_MEMORY; /* assume "insufficient memory" */ if ((amx->base = vmalloc_exec(amx->code_size)) == NULL) goto fail; memcpy(amx->base, ncode, amx->code_size); free(pcode); free(rt); free(ncode); return AMX_ERR_NONE; fail: if (fp != NULL) fclose(fp); if (pcode != NULL) free(pcode); if (rt != NULL) free(rt); if (ncode != NULL) free(ncode); memset(amx, 0, sizeof *amx); return error; }
void CPluginMngr::CacheAndLoadModules(const char *plugin) { size_t progsize; char *prog = ReadIntoOrFromCache(plugin, progsize); if (!prog) return; AMX_HEADER hdr; memcpy(&hdr, prog, sizeof(AMX_HEADER)); uint16_t magic = hdr.magic; amx_Align16(&magic); if (magic != AMX_MAGIC) { return; } if (hdr.file_version < MIN_FILE_VERSION || hdr.file_version > CUR_FILE_VERSION) { return; } if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) && (hdr.defsize != sizeof(AMX_FUNCSTUBNT))) { return; } amx_Align32((uint32_t*)&hdr.nametable); uint16_t *namelength=(uint16_t*)((unsigned char*)prog + (unsigned)hdr.nametable); amx_Align16(namelength); if (*namelength>sNAMEMAX) { return; } if (hdr.stp <= 0) { return; } AMX amx; memset(&amx, 0, sizeof(AMX)); amx.base = (unsigned char *)prog; int num; char name[sNAMEMAX+1]; num = amx_GetLibraries(&amx); for (int i=0; i<num; i++) { amx_GetLibrary(&amx, i, name, sNAMEMAX); if (stricmp(name, "Float")==0) continue; //awful backwards compat hack if (stricmp(name, "socket")==0) strcpy(name, "sockets"); //we don't want to report failed modules here... LoadModule(name, PT_ANYTIME, true, true); } cell tag_id; amx_NumTags(&amx, &num); ke::Vector<LibDecoder *> expects; ke::Vector<LibDecoder *> defaults; CStack<LibDecoder *> delstack; for (int i=0; i<num; i++) { amx_GetTag(&amx, i, name, &tag_id); if (name[0] == '?') { LibDecoder *dc = new LibDecoder; delstack.push(dc); if (DecodeLibCmdString(name, dc)) { if (dc->cmd == LibCmd_ForceLib) { RunLibCommand(dc); } else if ( (dc->cmd == LibCmd_ExpectClass) || (dc->cmd == LibCmd_ExpectLib) ) { expects.append(dc); } else if (dc->cmd == LibCmd_DefaultLib) { defaults.append(dc); } } } } for (size_t i=0; i<expects.length(); i++) { RunLibCommand(expects[i]); } for (size_t i=0; i<defaults.length(); i++) { RunLibCommand(defaults[i]); } expects.clear(); defaults.clear(); while (!delstack.empty()) { delete delstack.front(); delstack.pop(); } return; }