ERRCODE Config::writebin( FILE *fp ) { C_NODE node; size_t wrt; void *dat; if( fp == NULL ) { return PK_CONFIG_BAD_FP; } for( vector<C_NODE>::iterator node = nodes.begin(); node != nodes.end(); ++node ) { // debug( (*node).print()); if( (*node).length ) { U32 len = (*node).list.size(); enforce( fwrite( &len, 1, sizeof(U32), fp ) == sizeof(U32), "Failed to write data to file: " << len ); } for( vector<string>::iterator item = (*node).list.begin(); item != (*node).list.end(); ++item ) { dat = VTYPEF[(*node).type](*item); wrt = (*node).type == STRING_T ? (*item).size() : VTYPESS[(*node).type]; enforce( fwrite( dat, 1, wrt, fp ) == wrt, "Failed to write data to file: " << (*item)); free( dat ); } } return PK_OK; }
/* Returns unique pointer to malloc'd string. */ char* filename2string(const char* filename) { FILE* infile = fopen(filename, "r"); if (infile == NULL) { fprintf(stderr, "io.c:22 -- file not found: %s\n", filename); abort(); //TODO or were there permissions errors? } const size_t CHUNK_SIZE = 1024; // Initialize. char* acc = enforce(malloc(CHUNK_SIZE*sizeof(char))); size_t buffer_size = CHUNK_SIZE, writehead = 0; do { assert(buffer_size % CHUNK_SIZE == 0); assert(writehead % CHUNK_SIZE == 0); // Read chunk size and increment our string writehead until we reach the end of the file. size_t chunk_read_amt = fread(acc + writehead, sizeof(char), CHUNK_SIZE, infile); writehead += chunk_read_amt; if (chunk_read_amt < CHUNK_SIZE) break; // If our writehead is going to move beyond our allocated space, make more space. if (writehead == buffer_size) { buffer_size *= 2; acc = enforce(realloc(acc, buffer_size * sizeof(char))); } } while(1); // Calculate where our string ends and null-terminate it. acc[writehead+1] = '\0'; fclose(infile); return acc; }
int Garbage::shrink() noexcept { enforce(m_rows > 0); m_loot.erase(m_loot.begin(), m_loot.begin() + m_columns); --m_rows; enforce(m_loot.size() == m_columns * m_rows); return m_rows; }
Expression* Interpreter::resolveVariable(OpCode* opcode) { enforce(opcode->getType() == OpCode::VARIABLE, "Need a valid Variable as OpCode"); const size_t vi = this->getIndexOf(opcode); Expression* exp = this->fetchVariable(vi); enforce(is(exp), "Invalid variable accessed @ ", vi); return exp; }
void Interpreter::pop(Instruction* instruction) { enforce(instruction->getOperandAmount() == 1, "pop need exactly one operand"); enforce(instruction->getOperand(0)->getType() == OpCode::VARIABLE, "Can only pop into a variable"); auto val = this->popStack(); const size_t vi = this->getIndexOf(instruction->getOperand(0)); this->assignVariable(vi, val.release()); }
Garbage::Garbage(RowCol rc, int columns, int rows, Loot loot) : Physical(rc, State::REST), m_columns(columns), m_rows(rows), m_loot(loot) { enforce(columns > 0); enforce(rows > 0); enforce(loot.size() == columns * rows); }
void ModResource::ReadString( FILE *fp, string &filename, string &str, U32 strlen ) { char *line = NULL; enforce(( line = new char[strlen+1] ) != NULL, "malloc: " << strerror( errno )); enforce( fread( line, 1, strlen , fp ) == strlen, "Failed to write block to " << filename << " [ " << strerror( errno ) ); line[strlen] = 0; str = line; delete[] line; }
void Physical::set_state(State state, int time, int speed) noexcept { enforce(m_state != State::DEAD); // cannot change out of dead state enforce(time >= 1); // state must last at least one tick enforce(speed >= 1); // time must run out, not in set_state_impl(state, time, speed); m_state = state; m_time = time; m_speed = speed; }
void Interpreter::assign(Instruction* instruction) { enforce(instruction->getOperandAmount() == 2, "assign need exactly two operands"); enforce(instruction->getOperand(0)->getType() == OpCode::VARIABLE, "Expected a variable"); const size_t vi = this->getIndexOf(instruction->getOperand(0)); debug("assign variable ", vi); Expression* exp = this->resolveExpression(instruction->getOperand(1)); #if DEBUG ::print(exp); #endif this->assignVariable(vi, exp->clone()); }
void *getF32( string &str ) { F32 *ret = (F32*)malloc(sizeof(F32)); enforce( ret != NULL, "Failed to malloc: " << strerror( errno )); *ret = (F32)strtof( str.c_str(), NULL ); return (void *)ret; }
void Movable::trymove( Map &map, vector<Movable *> &movables, bool test ) { if( !alive() || moving()) { return; } rx( x()); ry( y()); switch( direction()) { case North: y()--; break; case East: x()++; break; case South: y()++; break; case West: x()--; break; default: enforce( false, "Bad Direction!" ); } moving( 1 ); if( test ) { collision( map, movables ); } }
void *getCHAR( string &str ) { char *ret = (char*)malloc( sizeof(char)); enforce( ret != NULL, "Failed to malloc: " << strerror( errno )); *ret = str[0]; return (void *)ret; }
void *getI16( string &str ) { I16 *ret = (I16*)malloc( sizeof( I16 )); enforce( ret != NULL, "Failed to malloc: " << strerror( errno )); *ret = (I16)strtol( str.c_str(), NULL, 10 ); return (void *)ret; }
Block& Pit::spawn_block(Block::Color color, RowCol rc, Block::State state) { enforce(rc.c >= 0); enforce(rc.c < PIT_COLS); auto block = std::make_unique<Block>(color, rc, state); Block* raw_block = block.get(); fill_area(*raw_block); m_contents.push_back(std::move(block)); if(rc.r < m_peak) m_peak = rc.r; return *raw_block; }
std::unique_ptr<Expression> Interpreter::popStack() { enforce(_stack_offset > 0, "Invalid Stack-Offset"); _stack_offset--; return std::move(_stack.at(_stack_offset)); }
void Map::writemap( FILE *fp ) { U32 strlen = name.size(); U32 npclen = npclist.size(); enforce( hloaded, "Map Not Loaded!" ); // write ID writeBlock( fp, &id ); // write width, height, strlen writeBlock( fp, &width ); writeBlock( fp, &height ); writeBlock( fp, &strlen ); // write string writeString( fp, name ); // write tiledata for( size_t i = 0; i < tilemap.size(); ++i ) { writeBlock( fp, &(tilemap[i])); } // write npclist writeBlock( fp, &npclen ); for( size_t i = 0; i < npclen; ++i ) { writeBlock( fp, &(npclist[i])); } }
void *getF64( string &str ) { F64 *ret = (F64*)malloc(sizeof(F64)); enforce( ret != NULL, "Failed to malloc: " << strerror( errno )); *ret = (F64)strtod( str.c_str(), NULL ); return (void *)ret; }
void *getU64( string &str ) { U64 *ret = (U64*)malloc(sizeof(U64)); enforce( ret != NULL, "Failed to malloc: " << strerror( errno )); *ret = (U64)strtoull( str.c_str(), NULL, 10 ); return (void *)ret; }
void Physical::continue_state(int time_bonus) noexcept { // The bonus must be large enough to prime the object for another arrival enforce(m_time + time_bonus > 0); m_time += time_bonus; }
void *getBOOL( string &str ) { bool *ret = (bool*)malloc(sizeof(bool)); enforce( ret != NULL, "Failed to malloc: " << strerror( errno )); *ret = (bool)strtol( str.c_str(), NULL, 10 ); return (void *)ret; }
void Interpreter::setIndex(Instruction* instruction) { enforce(instruction->getOperandAmount() == 1, "set_index need exactly one operand"); Expression* exp = this->resolveExpression(instruction->getOperand(0)); exp->is<NumericExpression>().ensure("Index must be integer"); this->pushStack(exp->clone()); }
void Block::set_state_impl(Physical::State state, int, int) noexcept { enforce(State::PREVIEW != static_cast<State>(state)); if(Physical::State::BREAK == state) { m_anim = BlockFrame::BREAK_BEGIN; } }
void Interpreter::fetchDim(Instruction* instruction) { enforce(instruction->getOperandAmount() == 1, "fetch_dim need exactly one operands"); Expression* exp = this->resolveVariable(instruction->getOperand(0)); const u32_t dim = exp->is<ArrayExpression>().ensure("Can only fetch dimension of an array")->getLength(); this->pushStack(new NumericExpression(dim)); }
Physical::Physical(RowCol rc, State state) : m_rc(rc), m_state(state), m_time(1), m_speed(1), m_tag(TAG_NONE) { // exclude locations that are well-known to lie out of bounds enforce(rc.c >= 0 && rc.c < PIT_COLS); }
void Interpreter::goTo(Instruction* instruction, Parser& parser) { enforce(instruction->getOperandAmount() == 1, "goto need exactly one operand"); Expression* exp = this->resolveExpression(instruction->getOperand(0)); const std::string& label = exp->is<StringExpression>().ensure("goto need's a string label")->getValue(); const size_t index = parser.getIndexFor(label); debug("goto ", index); parser.setIndex(index); }
const GameState& Journal::checkpoint_before(long game_time) const { enforce(game_time > 0); const auto end = m_checkpoint.rend(); const auto it = std::find_if(m_checkpoint.rbegin(), end, [game_time](const GameState& s) { return s.game_time() < game_time; }); assert(it != end); return *it; }
void Interpreter::fetch(Instruction* instruction) { enforce(instruction->getOperandAmount() == 2, "fetch need exactly two operands"); Expression* exp = this->resolveVariable(instruction->getOperand(0)); Expression* idx = this->resolveExpression(instruction->getOperand(1)); const u32_t index = idx->is<NumericExpression>().ensure("Fetch-Index must be numeric")->getAs<u32_t>(); Expression* val = exp->is<ArrayExpression>().ensure("Need an array to fetch")->fetch(index); this->pushStack(val->clone()); }
void Interpreter::emplace(Instruction* instruction) { enforce(instruction->getOperandAmount() == 2, "emplace need exactly two operands"); Expression* exp = this->resolveVariable(instruction->getOperand(0)); Expression* val = this->resolveExpression(instruction->getOperand(1)); auto idx = this->popStack(); const u32_t index = idx->is<NumericExpression>().ensure("Index must be numeric")->getAs<u32_t>(); exp->is<ArrayExpression>().ensure("Need an array for emplace")->emplace(index, val->clone()); }
Garbage& Pit::spawn_garbage(RowCol rc, int width, int height) { // make sure the Garbage fits in the Pit enforce(rc.c >= 0); enforce(rc.c + width <= PIT_COLS); Loot loot(width * height); for(Block::Color& c : loot) c = m_color_supplier->next_emerge(); auto garbage = std::make_unique<Garbage>(rc, width, height, move(loot)); Garbage* raw_garbage = garbage.get(); fill_area(*raw_garbage); m_contents.push_back(std::move(garbage)); if(rc.r < m_peak) m_peak = rc.r; return *raw_garbage; }
void Pit::cursor_move(Dir dir) noexcept { enforce(Dir::NONE != dir); switch(dir) { case Dir::LEFT: if(m_cursor.rc.c > 0) m_cursor.rc.c--; break; case Dir::RIGHT: if(m_cursor.rc.c < PIT_COLS-2) m_cursor.rc.c++; break; case Dir::UP: if(m_cursor.rc.r > top()) m_cursor.rc.r--; break; case Dir::DOWN: if(m_cursor.rc.r < bottom()) m_cursor.rc.r++; break; default: assert(false); } }