int DB_update(const char *url) { if(DB_find(url)) { log_info("Already recorded as installed: %s", url); } FILE *db = DB_open(DB_FILE, "a+"); check(db, "Failed to open DB file: %s", DB_FILE); bstring line = bfromcstr(url); bconchar(line, '\n'); int rc = fwrite(line->data, blength(line), 1, db); check(rc == 1, "Failed to append to the db."); return 0; error: if(db) DB_close(db); return -1; }
int glswAddDirectiveToken(const char* token, const char* directive) { glswContext* gc = __glsw__Context; glswList* temp; if (!gc) { return 0; } temp = gc->TokenMap; gc->TokenMap = (glswList*) calloc(sizeof(glswContext), 1); if(gc->TokenMap) { gc->TokenMap->Key = bfromcstr(token); gc->TokenMap->Value = bfromcstr(directive); gc->TokenMap->Next = temp; bconchar(gc->TokenMap->Value, '\n'); } return 1; }
int DB_update(const char *url) { bool found = false; assert(DB_find(url, &found) == 0); if (found) { printf("INFO: Already recorded as installed: %s\n", url); } FILE *db = DB_open(DB_FILE, "a+"); assert(db != NULL); bstring line = bfromcstr(url); bconchar(line, '\n'); int rc = fwrite(line->data, blength(line), 1, db); assert(rc == 1); bdestroy(line); DB_close(db); return 0; }
static bstring tr_eval(TextResource tr, trnode_t* node) { //internally we work with bstrings trnode_t* tmpNode; switch(node->type) { case TRNODE_TEXT: return bstrcpy(node->textData); case TRNODE_REPR: ; int match=0; if (node->condKey) { assert(node->condValue); //conditional char* condkey = bstr2cstr(node->condKey,'\0'); bstring val = ght_get(tr->parameters,strlen(condkey),condkey); bcstrfree(condkey); if (val && !bstrcmp(node->condValue, val)) { //matches match = 1; } } else { //unconditional, so go too match=1; } if (match) { return tr_evalKey(tr,node->reprKey->data); } else return bfromcstr(""); case TRNODE_STRING: //these guys have a blob of nodes that needs to be catted together smartly tmpNode = node->children_list; bstring tmpStr = bfromcstralloc(32,""); while(tmpNode) { bstring childStr = tr_eval(tr,tmpNode); bconchar(tmpStr,' '); bconcat(tmpStr,childStr); bdestroy(childStr); tmpNode = tmpNode->next; } return tmpStr; case TRNODE_SWITCH: //look through the children for matching choice ; char* switchVar = bstr2cstr(node->switchVar,'\0'); bstring val = ght_get(tr->parameters,strlen(switchVar),switchVar); bcstrfree(switchVar); tmpNode = node->children_list; while(tmpNode) { assert(tmpNode->type == TRNODE_STRING); assert(tmpNode->caseValue); if (!bstrcmp(tmpNode->caseValue,val)) { //we match, return this return tr_eval(tr,tmpNode); } //try next tmpNode = tmpNode->next; } return bfromcstr(""); default: assert(0); } assert(0); return NULL; }
int validate_token(bstring token) { int i; OpenSSL_add_all_algorithms(); struct bstrList *parts = bsplit(token, '|'); dictionary *dict = dictionary_new(10); bstring sig = bfromcstr("sig"); bstring to_sign = bfromcstr(""); for (i = 0; i < parts->qty; i++) { printf("%d: %s\n", i, parts->entry[i]->data); struct bstrList *x = bsplit(parts->entry[i], '='); if (x->qty == 2) { if (bstrcmp(x->entry[0], sig) != 0) { if (blength(to_sign) > 0) bconchar(to_sign, '|'); bconcat(to_sign, parts->entry[i]); } dictionary_set(dict, bdata(x->entry[0]), bdata(x->entry[1])); } bstrListDestroy(x); } bstrListDestroy(parts); parts = 0; bdestroy(sig); dictionary_dump(dict, stdout); printf("to sign: '%s'\n", bdata(to_sign)); // Check signing subject (need to know the valid values) char *subj = dictionary_get(dict, "SigningSubject", 0); if (!subj) { fprintf(stderr, "could not get signing subject\n"); return 0; } char *sigstr = dictionary_get(dict, "sig", 0); printf("sig to verify is %s\n", sigstr); bstring binsig = bfromcstralloc(strlen(sigstr) / 2, ""); char *s, *e; for (s = sigstr, e = sigstr + strlen(sigstr); s < e; s += 2) { char n[3]; n[0] = s[0]; n[1] = s[1]; n[2] = 0; long int v = strtol(n, 0, 16); // printf("n=%s v=%ld %lx\n", n, v, v); bconchar(binsig, (char) v); } unsigned char *sha = SHA1((const unsigned char *) to_sign->data, to_sign->slen, 0); bdestroy(to_sign); bstring bsubj = bfromcstr(subj); bstring pubkey = get_signer_pubkey(bsubj); BIO *bio = BIO_new(BIO_s_mem()); BIO_puts(bio, bdata(pubkey)); RSA *rsa = PEM_read_bio_RSAPublicKey(bio, 0, 0, 0); int rc = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, binsig->data, binsig->slen, rsa); printf("rc=%d\n", rc); bdestroy(bsubj); bdestroy(binsig); bdestroy(pubkey); BIO_free(bio); RSA_free(rsa); dictionary_del(dict); EVP_cleanup(); return rc; }
int main(int argc, char* argv[]) { // Define our variables. FILE* load; uint16_t flash[0x10000]; char leading[0x100]; unsigned int i; bool uread = true; vm_t* vm; int nerrors; bstring ss, st; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file, or - to read from standard input."); struct arg_file* execution_dump_file = arg_file0("e", "execution-dump", "<file>", "Produce a very large execution dump file."); struct arg_lit* debug_mode = arg_lit0("d", "debug", "Show each executed instruction."); struct arg_lit* terminate_mode = arg_lit0("t", "show-on-terminate", "Show state of machine when program is terminated."); struct arg_lit* legacy_mode = arg_lit0("l", "legacy", "Automatically initialize hardware to legacy values."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions)."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { input_file, debug_mode, execution_dump_file, terminate_mode, legacy_mode, little_endian_mode, verbose, quiet, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Emulator"))); if (nerrors != 0 || show_help->count != 0) { if (show_help->count != 0) arg_print_errors(stdout, end, "emulator"); printd(LEVEL_DEFAULT, "syntax:\n dtemu"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set endianness. isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE); // Zero out the flash space. for (i = 0; i < 0x10000; i++) flash[i] = 0x0; // Zero out the leading space. for (i = 0; i < 0x100; i++) leading[i] = 0x0; // Load from either file or stdin. if (strcmp(input_file->filename[0], "-") != 0) { // Open file. load = fopen(input_file->filename[0], "rb"); if (load == NULL) { fprintf(stderr, "emulator: unable to load %s from disk.\n", argv[1]); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } } else { // Windows needs stdin in binary mode. #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif // Set load to stdin. load = stdin; } // Read up to 0x10000 words. for (i = 0; i < 0x10000 && !feof(load); i++) iread(&flash[i], load); fclose(load); // Check to see if the first X bytes matches the header // for intermediate code and stop if it does. ss = bfromcstr(""); st = bfromcstr(ldata_objfmt); for (i = 0; i < strlen(ldata_objfmt); i++) bconchar(ss, leading[i]); if (biseq(ss, st)) { fprintf(stderr, "emulator: it appears you passed intermediate code for execution. link\n"); fprintf(stderr, " the input code with the toolchain linker to execute it.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // And then use the VM. vm = vm_create(); vm->debug = (debug_mode->count > 0); vm_flash(vm, flash); vm_hw_timer_init(vm); vm_hw_io_init(vm); vm_hw_lem1802_init(vm); vm_hw_lua_init(vm); if (legacy_mode->count > 0) { vm_hw_lem1802_mem_set_screen(vm, 0x8000); vm_hw_io_set_legacy(true); } vm_execute(vm, execution_dump_file->count > 0 ? execution_dump_file->filename[0] : NULL); #ifdef __EMSCRIPTEN__ printd(LEVEL_WARNING, "warning: not cleaning up resources in Emscripten.\n"); #else if (terminate_mode->count > 0) { fprintf(stderr, "\n"); fprintf(stderr, "A: 0x%04X [A]: 0x%04X\n", vm->registers[REG_A], vm->ram[vm->registers[REG_A]]); fprintf(stderr, "B: 0x%04X [B]: 0x%04X\n", vm->registers[REG_B], vm->ram[vm->registers[REG_B]]); fprintf(stderr, "C: 0x%04X [C]: 0x%04X\n", vm->registers[REG_C], vm->ram[vm->registers[REG_C]]); fprintf(stderr, "X: 0x%04X [X]: 0x%04X\n", vm->registers[REG_X], vm->ram[vm->registers[REG_X]]); fprintf(stderr, "Y: 0x%04X [Y]: 0x%04X\n", vm->registers[REG_Y], vm->ram[vm->registers[REG_Y]]); fprintf(stderr, "Z: 0x%04X [Z]: 0x%04X\n", vm->registers[REG_Z], vm->ram[vm->registers[REG_Z]]); fprintf(stderr, "I: 0x%04X [I]: 0x%04X\n", vm->registers[REG_I], vm->ram[vm->registers[REG_I]]); fprintf(stderr, "J: 0x%04X [J]: 0x%04X\n", vm->registers[REG_J], vm->ram[vm->registers[REG_J]]); fprintf(stderr, "PC: 0x%04X SP: 0x%04X\n", vm->pc, vm->sp); fprintf(stderr, "EX: 0x%04X IA: 0x%04X\n", vm->ex, vm->ia); } vm_hw_lua_free(vm); vm_hw_timer_free(vm); vm_hw_io_free(vm); vm_hw_lem1802_free(vm); vm_free(vm); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 0; #endif }
bstring Dht_PeerStr(Peer *peer) { if (peer == NULL) return bfromcstr("(NULL Peer)"); struct in_addr addr = { .s_addr = peer->addr }; return bformat("%15s:%-5d", inet_ntoa(addr), peer->port); } bstring Dht_FTokenStr(struct FToken ftoken) { if (ftoken.data == NULL) return bfromcstr("(NULL ftoken)"); return HexStr(ftoken.data, ftoken.len); } bstring TidStr(char *data, size_t len) { if (data == NULL) return bfromcstr("(NULL tid)"); return HexStr(data, len); } bstring Dht_MessageTypeStr(MessageType type) { switch (type) { case MUnknown: return bfromcstr("MUnknown"); case QPing: return bfromcstr("QPing"); case QFindNode: return bfromcstr("QFindNode"); case QGetPeers: return bfromcstr("QGetPeers"); case QAnnouncePeer: return bfromcstr("QAnnouncePeer"); case RPing: return bfromcstr("RPing"); case RFindNode: return bfromcstr("RFindNode"); case RGetPeers: return bfromcstr("RGetPeers"); case RAnnouncePeer: return bfromcstr("RAnnouncePeer"); case RError: return bfromcstr("RError"); default: return bfromcstr("(Invalid MessageType"); } } bstring Dht_RERROR_Str(int code) { switch (code) { case RERROR_GENERIC: return bfromcstr("GENERIC"); case RERROR_SERVER: return bfromcstr("SERVER"); case RERROR_PROTOCOL: return bfromcstr("PROTOCOL"); case RERROR_METHODUNKNOWN: return bfromcstr("METHOD UNKNOWN"); default: return bfromcstr("(UNKNOWN CODE)"); } } bstring DataStr(Message *message); bstring Dht_MessageStr(Message *message) { if (message == NULL) return bfromcstr("(NULL Message)"); bstring type = NULL, node = NULL, tid = NULL, id = NULL, str = NULL, data = NULL; type = Dht_MessageTypeStr(message->type); check_mem(type); node = Dht_NodeStr(&message->node); check_mem(node); tid = TidStr(message->t, message->t_len); check_mem(tid); id = Dht_HashStr(&message->id); check_mem(id); str = bformat( "%-13s Errors:%02X\n" "%s\n" "tid %s\n" "Id %s", type->data, message->errors, node->data, tid->data, id->data); check_mem(str); data = DataStr(message); check_mem(data); bconchar(str, '\n'); bconcat(str, data); bdestroy(data); bdestroy(type); bdestroy(node); bdestroy(tid); bdestroy(id); return str; error: bdestroy(type); bdestroy(node); bdestroy(tid); bdestroy(id); bdestroy(str); bdestroy(data); return NULL; } bstring DataQFindNodeStr(Message *message); bstring DataQGetPeersStr(Message *message); bstring DataQAnnouncePeerStr(Message *message); bstring DataRFindNodeStr(Message *message); bstring DataRGetPeersStr(Message *message); bstring DataRErrorStr(Message *message); bstring DataStr(Message *message) { if (message == NULL) return bfromcstr("(NULL Message)"); switch (message->type) { case MUnknown: case QPing: case RPing: case RAnnouncePeer: return bfromcstr(""); /* No data. */ case QFindNode: return DataQFindNodeStr(message); case QGetPeers: return DataQGetPeersStr(message); case QAnnouncePeer: return DataQAnnouncePeerStr(message); case RFindNode: return DataRFindNodeStr(message); case RGetPeers: return DataRGetPeersStr(message); case RError: return DataRErrorStr(message); default: return bfromcstr("(Invalid MessageType)"); } } bstring DataQFindNodeStr(Message *message) { bstring target = Dht_HashStr(message->data.qfindnode.target); bstring str = bformat("QFindNode target: %s", target->data); bdestroy(target); return str; }
tst_t *Parse_config_string(bstring content) { Token *temp = NULL; void *parser = ParseAlloc(malloc); check_mem(parser); ParserState state = {.settings = NULL, .error = 0, .line_number = 1}; char *p = bdata(content); char *pe = bdataofs(content, blength(content) - 1); char *eof = pe; int cs = -1; int act = -1; char *ts = NULL; char *te = NULL; #line 114 "src/lexer.c" { cs = m2sh_lexer_start; ts = 0; te = 0; act = 0; } #line 135 "src/lexer.rl" #line 124 "src/lexer.c" { if ( p == pe ) goto _test_eof; switch ( cs ) { tr1: #line 77 "src/lexer.rl" {te = p+1;{ TKSTR(QSTRING) }} goto st6; tr4: #line 91 "src/lexer.rl" {te = p+1;} goto st6; tr7: #line 89 "src/lexer.rl" {te = p+1;} goto st6; tr9: #line 88 "src/lexer.rl" {te = p+1;{ state.line_number++; }} goto st6; tr10: #line 83 "src/lexer.rl" {te = p+1;{ TK(LPAREN) }} goto st6; tr11: #line 84 "src/lexer.rl" {te = p+1;{ TK(RPAREN) }} goto st6; tr12: #line 85 "src/lexer.rl" {te = p+1;{ TK(COMMA) }} goto st6; tr14: #line 86 "src/lexer.rl" {te = p+1;{ TK(COLON) }} goto st6; tr15: #line 78 "src/lexer.rl" {te = p+1;{ TK(EQ) }} goto st6; tr17: #line 81 "src/lexer.rl" {te = p+1;{ TK(LBRACE) }} goto st6; tr18: #line 82 "src/lexer.rl" {te = p+1;{ TK(RBRACE) }} goto st6; tr20: #line 79 "src/lexer.rl" {te = p+1;{ TK(LBRACKET) }} goto st6; tr21: #line 80 "src/lexer.rl" {te = p+1;{ TK(RBRACKET) }} goto st6; tr22: #line 93 "src/lexer.rl" {te = p;p--;{ TK(NUMBER) }} goto st6; tr23: #line 1 "NONE" { switch( act ) { case 15: {{p = ((te))-1;} TK(CLASS) } break; case 16: {{p = ((te))-1;} TK(IDENT) } break; } } goto st6; tr25: #line 95 "src/lexer.rl" {te = p;p--;{ TK(IDENT) }} goto st6; st6: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof6; case 6: #line 1 "NONE" {ts = p;} #line 210 "src/lexer.c" switch( (*p) ) { case 10: goto tr9; case 32: goto tr7; case 34: goto st1; case 35: goto st3; case 39: goto st4; case 40: goto tr10; case 41: goto tr11; case 44: goto tr12; case 58: goto tr14; case 61: goto tr15; case 91: goto tr17; case 93: goto tr18; case 95: goto st9; case 123: goto tr20; case 125: goto tr21; } if ( (*p) < 48 ) { if ( 9 <= (*p) && (*p) <= 13 ) goto tr7; } else if ( (*p) > 57 ) { if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st9; } else if ( (*p) >= 65 ) goto tr16; } else goto st7; goto st0; st0: cs = 0; goto _out; st1: if ( ++p == pe ) goto _test_eof1; case 1: switch( (*p) ) { case 34: goto tr1; case 92: goto st2; } goto st1; st2: if ( ++p == pe ) goto _test_eof2; case 2: goto st1; st3: if ( ++p == pe ) goto _test_eof3; case 3: if ( (*p) == 10 ) goto tr4; goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: switch( (*p) ) { case 39: goto tr1; case 92: goto st5; } goto st4; st5: if ( ++p == pe ) goto _test_eof5; case 5: goto st4; st7: if ( ++p == pe ) goto _test_eof7; case 7: if ( 48 <= (*p) && (*p) <= 57 ) goto st7; goto tr22; tr16: #line 1 "NONE" {te = p+1;} #line 95 "src/lexer.rl" {act = 16;} goto st8; tr24: #line 1 "NONE" {te = p+1;} #line 94 "src/lexer.rl" {act = 15;} goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: #line 301 "src/lexer.c" if ( (*p) == 95 ) goto st9; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st9; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr24; } else goto tr24; goto tr23; st9: if ( ++p == pe ) goto _test_eof9; case 9: if ( (*p) == 95 ) goto st9; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st9; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st9; } else goto st9; goto tr25; } _test_eof6: cs = 6; goto _test_eof; _test_eof1: cs = 1; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( cs ) { case 7: goto tr22; case 8: goto tr23; case 9: goto tr25; } } _out: {} } #line 136 "src/lexer.rl" if(state.error) { Parse_print_error("SYNTAX ERROR", content, (int)(ts - bdata(content)), ++state.line_number); } else if( cs == #line 359 "src/lexer.c" 0 #line 141 "src/lexer.rl" ) { Parse_print_error("INVALID CHARACTER", content, (int)(ts - bdata(content)), ++state.line_number); } else if( cs >= #line 366 "src/lexer.c" 6 #line 144 "src/lexer.rl" ) { Parse(parser, TKEOF, NULL, &state); } else { log_err("INCOMPLETE CONFIG FILE. There needs to be more to this."); } Parse(parser, 0, 0, &state); ParseFree(parser, free); return state.settings; error: if(state.error) { Parse_print_error("SYNTAX ERROR", content, (int)(ts - bdata(content)), ++state.line_number); } ParseFree(parser, free); return NULL; } tst_t *Parse_config_file(const char *path) { FILE *script; bstring buffer = NULL; tst_t *settings = NULL; script = fopen(path, "r"); check(script, "Failed to open file: %s", path); buffer = bread((bNread)fread, script); check_mem(buffer); fclose(script); script = NULL; // make sure there's a \n at the end bconchar(buffer, '\n'); settings = Parse_config_string(buffer); check(settings != NULL, "Failed to parse file: %s", path); bdestroy(buffer); buffer = NULL; return settings; error: bdestroy(buffer); if(script) fclose(script); return NULL; }
static int ssh_validate_hostkey(obfsproxyssh_client_session_t *session) { obfsproxyssh_t *state = session->client->state; const char *hkey_method; bstring trusted_fp; const char *fp; bstring fp_s; int i, len, dlen; hkey_method = libssh2_session_methods(session->ssh_session, LIBSSH2_METHOD_HOSTKEY); if (0 == strcmp(hkey_method, "ssh-rsa")) trusted_fp = session->hostkey_rsa; else if (0 == strcmp(hkey_method, "ssh-dss")) trusted_fp = session->hostkey_dss; else { log_f(state, "SSH: Error: Supplied hostkey method is invalid (%s)", bdata(session->ssh_addr), hkey_method); return -1; } len = blength(trusted_fp); switch (len) { case OBFSPROXYSSH_CLIENT_MD5_FP_LEN: fp = libssh2_hostkey_hash(session->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); dlen = 16; break; case OBFSPROXYSSH_CLIENT_SHA1_FP_LEN: fp = libssh2_hostkey_hash(session->ssh_session, LIBSSH2_HOSTKEY_HASH_SHA1); dlen = 20; break; default: log_f(state, "SSH: Error: Supplied hostkey length is invalid (%s)", bdata(session->ssh_addr), bdata(trusted_fp)); return -1; } fp_s = bfromcstralloc(len, ""); for (i = 0; i < dlen; i++) { bformata(fp_s, "%02X", (unsigned char) fp[i]); if (i != dlen - 1) bconchar(fp_s, ':'); } i = bstricmp(trusted_fp, fp_s); if (0 != i) log_f(state, "SSH: Error: %s Hostkey mismatch (Got: %s, Expecting: %s)", bdata(session->ssh_addr), bdata(trusted_fp), bdata(fp_s)); else log_f(state, "SSH: %s Hostkey matched (%s)", bdata(session->ssh_addr), bdata(trusted_fp)); return (0 == i) ? 0 : -1; }
static void macro_handle(state_t* state, match_t* match, bool* reprocess) { bstring name; bstring temp; list_t parameters; list_t arguments; bool getting_name = true; bool getting_parameters = false; bool getting_arguments = false; struct replace_info* info = match->userdata; int i = 0; int argument_brackets = 0; char c; char* start_loc; match_t* new_match; struct replace_info* new_info; // Parse the parameters out of the name. list_init(¶meters); temp = bfromcstr(""); for (i = 0; i < blength(info->full); i++) { c = info->full->data[i]; if (getting_name) { if (c == '(') { getting_name = false; getting_parameters = true; name = bstrcpy(temp); bassigncstr(temp, ""); } else bconchar(temp, c); } else if (getting_parameters) { if (c == ',' || c == ')') { btrimws(temp); list_append(¶meters, bstrcpy(temp)); bassigncstr(temp, ""); if (c == ')') { getting_parameters = false; break; } } else bconchar(temp, c); } } // Attempt to accept an open bracket. c = ppimpl_get_input(state); while (c == '\1') { // Consume macro termination. i = 0; while (i < strlen("\1MACROTERMINATE\1")) { if (c != "\1MACROTERMINATE\1"[i++]) dhalt(ERR_PP_EXPECTED_OPEN_BRACKET, ppimpl_get_location(state)); c = ppimpl_get_input(state); } ppimpl_pop_scope(state); } if (c != '(') dhalt(ERR_PP_EXPECTED_OPEN_BRACKET, ppimpl_get_location(state)); // Read arguments. getting_arguments = true; list_init(&arguments); start_loc = ppimpl_get_location(state); bassigncstr(temp, ""); while (ppimpl_has_input(state) && getting_arguments) { c = ppimpl_get_input(state); if (c == '(') { argument_brackets++; bconchar(temp, c); } else if (c == ')' && argument_brackets != 0) { argument_brackets--; bconchar(temp, c); } else if (c == ')' && argument_brackets == 0) { list_append(&arguments, bstrcpy(temp)); bassigncstr(temp, ""); getting_arguments = false; break; } else if (c == ',' && argument_brackets == 0) { list_append(&arguments, bstrcpy(temp)); bassigncstr(temp, ""); } else bconchar(temp, c); } if (getting_arguments) dhalt(ERR_PP_NO_TERMINATING_BRACKET, start_loc); // Check to see if the argument count is correct. if (list_size(&arguments) > list_size(¶meters)) dhalt(ERR_PP_TOO_MANY_PARAMETERS, start_loc); else if (list_size(&arguments) < list_size(¶meters)) dhalt(ERR_PP_NOT_ENOUGH_PARAMETERS, start_loc); free(start_loc); // Create a new scope for macro evaluation. ppimpl_push_scope(state, true); // Define the new handlers. for (i = 0; i < list_size(¶meters); i++) { new_info = malloc(sizeof(struct replace_info)); new_info->full = list_get_at(¶meters, i); new_info->replacement = list_get_at(&arguments, i); if (biseq(new_info->full, new_info->replacement)) { free(new_info); continue; } new_match = malloc(sizeof(match_t)); new_match->text = bautofree(list_get_at(¶meters, i)); new_match->handler = replace_handle; new_match->line_start_only = false; new_match->identifier_only = true; new_match->userdata = new_info; new_match->case_insensitive = false; ppimpl_register(state, new_match); } // Print out the macro evaluation and terminator. ppimpl_printf(state, "%s\1MACROTERMINATE\1", info->replacement->data); }
struct lua_debugst* dbg_lua_load(bstring name) { bstring path, modtype; struct lua_debugst* ds; int module; // Calculate full path to file. path = osutil_getmodulepath(); bconchar(path, '/'); bconcat(path, name); // Create the new lua preprocessor structure. ds = malloc(sizeof(struct lua_debugst)); ds->state = lua_open(); assert(ds->state != NULL); luaL_openlibs(ds->state); luaX_loadexpressionlib(ds->state); // Load globals. dcpu_lua_set_constants(ds->state); // Execute the code in the new Lua context. if (luaL_dofile(ds->state, path->data) != 0) { printd(LEVEL_ERROR, "lua error was %s.\n", lua_tostring(ds->state, -1)); // Return NULL. lua_close(ds->state); free(ds); bdestroy(path); return NULL; } // Load tables. lua_getglobal(ds->state, "MODULE"); module = lua_gettop(ds->state); // Ensure module table was provided. if (lua_isnoneornil(ds->state, module)) { printd(LEVEL_ERROR, "failed to load debugger module from %s.\n", path->data); // Return NULL. lua_close(ds->state); free(ds); bdestroy(path); return NULL; } // Check to see whether the module is // a preprocessor module. lua_getfield(ds->state, module, "Type"); modtype = bfromcstr(lua_tostring(ds->state, -1)); if (!biseqcstrcaseless(modtype, "Debugger")) { // Return NULL. lua_pop(ds->state, 1); lua_close(ds->state); free(ds); bdestroy(modtype); bdestroy(path); return NULL; } lua_pop(ds->state, 1); bdestroy(modtype); // Create the handler tables. lua_newtable(ds->state); lua_setglobal(ds->state, HANDLER_TABLE_COMMANDS_NAME); lua_newtable(ds->state); lua_setglobal(ds->state, HANDLER_TABLE_HOOKS_NAME); lua_newtable(ds->state); lua_setglobal(ds->state, HANDLER_TABLE_SYMBOLS_NAME); // Set the global functions. lua_pushcfunction(ds->state, &dbg_lua_add_command); lua_setglobal(ds->state, "add_command"); lua_pushcfunction(ds->state, &dbg_lua_add_hook); lua_setglobal(ds->state, "add_hook"); lua_pushcfunction(ds->state, &dbg_lua_add_symbol_hook); lua_setglobal(ds->state, "add_symbol_hook"); // Run the setup function. lua_getglobal(ds->state, "setup"); if (lua_pcall(ds->state, 0, 0, 0) != 0) { printd(LEVEL_ERROR, "failed to run setup() in debugger module from %s.\n", path->data); printd(LEVEL_ERROR, "lua error was %s.\n", lua_tostring(ds->state, -1)); } // Unset the global functions. lua_pushnil(ds->state); lua_setglobal(ds->state, "add_command"); lua_pushnil(ds->state); lua_setglobal(ds->state, "add_hook"); lua_pushnil(ds->state); lua_setglobal(ds->state, "add_symbol_hook"); // Pop tables from stack. lua_pop(ds->state, 2); // Return new debugger module. return ds; }
struct lua_preproc* pp_lua_load(bstring name) { bstring path, modtype; struct lua_preproc* pp; int module; // Calculate full path to file. path = osutil_getmodulepath(); bconchar(path, '/'); bconcat(path, name); // Create the new lua preprocessor structure. pp = malloc(sizeof(struct lua_preproc)); pp->state = lua_open(); assert(pp->state != NULL); luaL_openlibs(pp->state); luaX_loadexpressionlib(pp->state); // Execute the code in the new Lua context. if (luaL_dofile(pp->state, path->data) != 0) { printd(LEVEL_ERROR, "lua error was %s.\n", lua_tostring(pp->state, -1)); // Return NULL. lua_close(pp->state); free(pp); bdestroy(path); return NULL; } // Load tables. lua_getglobal(pp->state, "MODULE"); module = lua_gettop(pp->state); // Ensure module table was provided. if (lua_isnoneornil(pp->state, module)) { printd(LEVEL_ERROR, "failed to load preprocessor module from %s.\n", path->data); // Return NULL. lua_close(pp->state); free(pp); bdestroy(path); return NULL; } // Check to see whether the module is // a preprocessor module. lua_getfield(pp->state, module, "Type"); modtype = bfromcstr(lua_tostring(pp->state, -1)); if (!biseqcstrcaseless(modtype, "Preprocessor")) { // Return NULL. lua_pop(pp->state, 1); lua_close(pp->state); free(pp); bdestroy(modtype); bdestroy(path); return NULL; } lua_pop(pp->state, 1); bdestroy(modtype); // Create the handler table. lua_newtable(pp->state); lua_setglobal(pp->state, HANDLER_TABLE_NAME); // Set the global add_preprocessor_directive function. lua_pushcfunction(pp->state, &pp_lua_add_preprocessor_directive); lua_setglobal(pp->state, "add_preprocessor_directive"); // Run the setup function. lua_getglobal(pp->state, "setup"); if (lua_pcall(pp->state, 0, 0, 0) != 0) { printd(LEVEL_ERROR, "failed to run setup() in preprocessor module from %s.\n", path->data); } // Unset the add_preprocessor_directive function. lua_pushnil(pp->state); lua_setglobal(pp->state, "add_preprocessor_directive"); // Pop tables from stack. lua_pop(pp->state, 2); // Return new preprocessor module. return pp; }
void pp_lua_handle(struct pp_state* state, void* scanner, bstring name, list_t* parameters) { struct lua_preproc* pp; struct customarg_entry* carg; char* cstr; bstring dot; unsigned int i; int paramtbl; // Convert the name to lowercase. btolower(name); cstr = bstr2cstr(name, '0'); // Loop through all of the modules. list_iterator_start(&modules); while (list_iterator_hasnext(&modules)) { pp = list_iterator_next(&modules); // Set stack top (I don't know why the top of the // stack is negative!) lua_settop(pp->state, 0); // Search handler table for entries. lua_getglobal(pp->state, HANDLER_TABLE_NAME); lua_getfield(pp->state, -1, cstr); if (!lua_istable(pp->state, -1)) { // No such entry. lua_pop(pp->state, 2); continue; } // Call the handler function. lua_getfield(pp->state, -1, HANDLER_FIELD_FUNCTION_NAME); pp_lua_push_state(pp, state, scanner); lua_newtable(pp->state); paramtbl = lua_gettop(pp->state); for (i = 0; i < list_size(parameters); i++) { carg = list_get_at(parameters, i); lua_newtable(pp->state); if (carg->expr != NULL) lua_pushstring(pp->state, "EXPRESSION"); else if (carg->string != NULL) lua_pushstring(pp->state, "STRING"); else if (carg->word != NULL) lua_pushstring(pp->state, "WORD"); else lua_pushstring(pp->state, "NUMBER"); lua_setfield(pp->state, -2, "type"); if (carg->expr != NULL) luaX_pushexpression(pp->state, carg->expr); else if (carg->string != NULL) lua_pushstring(pp->state, carg->string->data); else if (carg->word != NULL) lua_pushstring(pp->state, carg->word->data); else lua_pushnumber(pp->state, carg->number); lua_setfield(pp->state, -2, "value"); lua_rawseti(pp->state, paramtbl, i + 1); } if (lua_pcall(pp->state, 2, 0, 0) != 0) { printd(LEVEL_ERROR, "error: unable to call preprocessor handler for '%s'.\n", name->data); printd(LEVEL_ERROR, "%s\n", lua_tostring(pp->state, -1)); bdestroy(name); bcstrfree(cstr); lua_pop(pp->state, 2); list_iterator_stop(&modules); list_destroy(parameters); return; } bdestroy(name); bcstrfree(cstr); lua_pop(pp->state, 2); list_iterator_stop(&modules); list_destroy(parameters); return; } list_iterator_stop(&modules); // There is no custom preprocessor module that handles this directive, however // it could be a directive that is recognised by the underlying assembler / compiler, // so pass it through as output. dot = bfromcstr("."); bconcat(dot, name); btoupper(dot); bconchar(dot, ' '); list_iterator_start(parameters); while (list_iterator_hasnext(parameters)) { carg = list_iterator_next(parameters); // Output the parameter based on the type. if (carg->word != NULL) bconcat(dot, carg->word); else if (carg->string != NULL) { bconchar(dot, '"'); bescape(carg->string); bconcat(dot, carg->string); bconchar(dot, '"'); } else bformata(dot, "%i", carg->number); } list_iterator_stop(parameters); handle_pp_lua_print_line(dot->data, scanner); // Clean up. list_destroy(parameters); bdestroy(name); bcstrfree(cstr); }
int main(int argc, char* argv[]) { bstring ldargs = bfromcstr(""); int i, result; unsigned int match = 0, unmatch = 0; char ca, ce; BFILE* expect; BFILE* actual; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_lit* gen_relocatable = arg_lit0("r", "relocatable", "Generate relocatable code."); struct arg_lit* gen_intermediate = arg_lit0("i", "intermediate", "Generate intermediate code for use with the linker."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input assembly file."); struct arg_file* expect_file = arg_file0("e", "expect", "<file>", "The output file that contains expected output."); struct arg_file* actual_file = arg_file1("a", "actual", "<file>", "The output file where actual output will be placed."); struct arg_file* symbols_file = arg_file0("s", "debug-symbols", "<file>", "The debugging symbol output file."); struct arg_lit* fail_opt = arg_lit0("f", "fail", "The assembler is expected to fail and the actual output file should not exist on completion."); struct arg_file* path = arg_file1("p", NULL, "<path>", "The path to the assembler."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { show_help, gen_relocatable, gen_intermediate, little_endian_mode, symbols_file, input_file, expect_file, actual_file, fail_opt, path, verbose, quiet, end }; // Parse arguments. int nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Assembler Test Driver"))); if (nerrors != 0 || show_help->count != 0 || (fail_opt->count == 0 && (expect_file->count == 0 || actual_file->count == 0))) { if (show_help->count != 0 && fail_opt->count == 0 && (expect_file->count == 0 || actual_file->count == 0)) printd(LEVEL_ERROR, "error: you must provide either -f or -e and -a.\n"); if (show_help->count != 0) arg_print_errors(stderr, end, "testasm"); printd(LEVEL_DEFAULT, "syntax:\n testasm"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Generate the argument list for the assembler. ldargs = bfromcstr(path->filename[0]); binsertch(ldargs, 0, 1, '"'); bconchar(ldargs, '"'); bconchar(ldargs, ' '); // Verbosity options. if (verbose->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < verbose->count; i++) bconchar(ldargs, 'v'); bconchar(ldargs, ' '); } if (quiet->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < quiet->count; i++) bconchar(ldargs, 'q'); bconchar(ldargs, ' '); } // Literal options. if (gen_relocatable->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < gen_relocatable->count; i++) bconchar(ldargs, 'r'); bconchar(ldargs, ' '); } if (gen_intermediate->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < gen_intermediate->count; i++) bconchar(ldargs, 'i'); bconchar(ldargs, ' '); } if (little_endian_mode->count > 0) { for (i = 0; i < little_endian_mode->count; i++) bcatcstr(ldargs, "--little-endian "); } // Unlink the actual file so that if we are expecting // failure, we won't return incorrectly. unlink(actual_file->filename[0]); // Output file. bcatcstr(ldargs, "-o \""); bcatcstr(ldargs, actual_file->filename[0]); bcatcstr(ldargs, "\" "); // Input file. bcatcstr(ldargs, "\""); bcatcstr(ldargs, input_file->filename[0]); bcatcstr(ldargs, "\" "); // Windows needs the whole command wrapped in quotes and slashes to be correct. // See http://stackoverflow.com/questions/2642551/windows-c-system-call-with-spaces-in-command. #ifdef _WIN32 binsertch(ldargs, 0, 1, '"'); bconchar(ldargs, '"'); #endif // Now run the assembler! result = system(ldargs->data); if (result != 0 && fail_opt->count == 0) { // Assembler returned error exit code. printd(LEVEL_ERROR, "error: expected success but assembler returned non-zero exit code (%i).\n", result); return 1; } else if (result == 0 && fail_opt->count >= 1) { // Assembler returned zero when failure was expected. printd(LEVEL_ERROR, "error: expected failure but assembler returned zero exit code.\n"); return 1; } else if (result != 0 && fail_opt->count >= 1) { // Assembler failed and we expected it to. Return success only // if the output file does not exist. actual = bfopen(actual_file->filename[0], "rb"); if (actual != NULL) { printd(LEVEL_ERROR, "error: expected failure but actual output file exists.\n"); bfclose(actual); return 1; } return 0; } // Open expect data. expect = bfopen(expect_file->filename[0], "rb"); if (expect == NULL) { // The expect file was not provided. printd(LEVEL_ERROR, "error: path to expect file does not exist.\n"); return 1; } // Open actual data. actual = bfopen(actual_file->filename[0], "rb"); if (actual == NULL) { // The expect file was not provided. bfclose(expect); printd(LEVEL_ERROR, "error: expected data but actual output file does not exist after running assembler.\n"); return 1; } // Now compare raw bytes. while (true) { if (!bfeof(actual) && !bfeof(expect)) { ca = bfgetc(actual); ce = bfgetc(expect); if (ca == ce) match++; else { printd(LEVEL_WARNING, "warning: byte at 0x%04X is different (got 0x%02X, expected 0x%02X)!\n", bftell(actual), ca, ce); unmatch++; } } else if (!bfeof(actual)) { ca = bfgetc(actual); printd(LEVEL_ERROR, "error: actual output contained trailing byte 0x%02X.\n", (unsigned char)ca); unmatch++; } else if (!bfeof(expect)) { ce = bfgetc(expect); printd(LEVEL_ERROR, "error: expected actual output to contain 0x%02X.\n", (unsigned char)ce); unmatch++; } else break; } if (unmatch > 0) { printd(LEVEL_ERROR, "error: actual output differs from expected output in content (%f%%, %i bytes different).\n", 100.f / (unmatch + match) * unmatch, unmatch); if (bftell(actual) != bftell(expect)) printd(LEVEL_ERROR, "error: actual output differs from expected output in length (%i bytes larger).\n", bftell(actual) - bftell(expect)); bfclose(actual); bfclose(expect); return 1; } // Close files and delete actual because we have // succeeded. bfclose(actual); bfclose(expect); unlink(actual_file->filename[0]); return 0; }
int main(int argc, char* argv[]) { // Define our variables. FILE* load; uint16_t flash[0x10000]; char leading[0x100]; unsigned int i; bool uread = true; vm_t* vm; int nerrors; bstring ss, st; host_context_t* dtemu = malloc(sizeof(host_context_t)); const char* warnprefix = "no-"; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file, or - to read from standard input."); struct arg_file* execution_dump_file = arg_file0("e", "execution-dump", "<file>", "Produce a very large execution dump file."); struct arg_lit* debug_mode = arg_lit0("d", "debug", "Show each executed instruction."); struct arg_lit* terminate_mode = arg_lit0("t", "show-on-terminate", "Show state of machine when program is terminated."); struct arg_lit* headless_mode = arg_lit0("h", "headless", "Run machine witout displaying monitor and SPED output"); struct arg_lit* legacy_mode = arg_lit0("l", "legacy", "Automatically initialize hardware to legacy values."); struct arg_str* warning_policies = arg_strn("W", NULL, "policy", 0, _WARN_COUNT * 2 + 10, "Modify warning policies."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions)."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_int* radiation = arg_intn("r", NULL, "<n>", 0, 1, "Radiation factor (higher is less radiation)"); struct arg_lit* catch_fire = arg_lit0("c", "catch-fire", "The virtual machine should catch fire instead of halting."); struct arg_end* end = arg_end(20); void* argtable[] = { input_file, warning_policies, debug_mode, execution_dump_file, terminate_mode, headless_mode, legacy_mode, little_endian_mode, radiation, catch_fire, verbose, quiet, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); if (nerrors != 0 || show_help->count != 0) { if (show_help->count != 0) arg_print_errors(stdout, end, "emulator"); printd(LEVEL_DEFAULT, "syntax:\n dtemu"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Show version information. version_print(bautofree(bfromcstr("Emulator"))); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set endianness. isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE); // Set up warning policies. dsetwarnpolicy(warning_policies); // Set up error handling. if (dsethalt()) { // Handle the error. dautohandle(); printd(LEVEL_ERROR, "emulator: error occurred.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Zero out the flash space. for (i = 0; i < 0x10000; i++) flash[i] = 0x0; // Zero out the leading space. for (i = 0; i < 0x100; i++) leading[i] = 0x0; // Load from either file or stdin. if (strcmp(input_file->filename[0], "-") != 0) { // Open file. load = fopen(input_file->filename[0], "rb"); if (load == NULL) dhalt(ERR_EMU_LOAD_FILE_FAILED, input_file->filename[0]); } else { // Windows needs stdin in binary mode. #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif // Set load to stdin. load = stdin; } // Read leading component. for (i = 0; i < strlen(ldata_objfmt); i++) leading[i] = fgetc(load); fseek(load, 0, SEEK_SET); // Read up to 0x10000 words. for (i = 0; i < 0x10000 && !feof(load); i++) iread(&flash[i], load); fclose(load); // Check to see if the first X bytes matches the header // for intermediate code and stop if it does. ss = bfromcstr(""); st = bfromcstr(ldata_objfmt); for (i = 0; i < strlen(ldata_objfmt); i++) bconchar(ss, leading[i]); if (biseq(ss, st)) dhalt(ERR_INTERMEDIATE_EXECUTION, NULL); // Set up the host context. glfwInit(); dtemu->create_context = &dtemu_create_context; dtemu->activate_context = &dtemu_activate_context; dtemu->swap_buffers = &dtemu_swap_buffers; dtemu->destroy_context = &dtemu_destroy_context; dtemu->get_ud = &dtemu_get_ud; // And then use the VM. vm = vm_create(); vm->debug = (debug_mode->count > 0); vm_flash(vm, flash); // Set radiation and catch fire settings. if (radiation->count == 1) vm->radiation_factor = radiation->ival[0]; if (catch_fire->count == 1) vm->can_fire = true; // Init hardware. vm_hw_clock_init(vm); if (headless_mode->count < 1) vm->host = dtemu; vm_hw_sped3_init(vm); vm_hw_lem1802_init(vm); vm_hw_m35fd_init(vm); vm_hw_lua_init(vm); if (legacy_mode->count > 0) { for (i = 0; i < vm_hw_count(vm); i++) { hw_t* device = vm_hw_get_device(vm, i); if (device == NULL) continue; if (device->id == 0x7349F615 && device->manufacturer == 0x1C6C8B36) { vm_hw_lem1802_mem_set_screen((struct lem1802_hardware*)device->userdata, 0x8000); break; } } } vm_execute(vm, execution_dump_file->count > 0 ? execution_dump_file->filename[0] : NULL); if (terminate_mode->count > 0) { fprintf(stderr, "\n"); fprintf(stderr, "A: 0x%04X [A]: 0x%04X\n", vm->registers[REG_A], vm->ram[vm->registers[REG_A]]); fprintf(stderr, "B: 0x%04X [B]: 0x%04X\n", vm->registers[REG_B], vm->ram[vm->registers[REG_B]]); fprintf(stderr, "C: 0x%04X [C]: 0x%04X\n", vm->registers[REG_C], vm->ram[vm->registers[REG_C]]); fprintf(stderr, "X: 0x%04X [X]: 0x%04X\n", vm->registers[REG_X], vm->ram[vm->registers[REG_X]]); fprintf(stderr, "Y: 0x%04X [Y]: 0x%04X\n", vm->registers[REG_Y], vm->ram[vm->registers[REG_Y]]); fprintf(stderr, "Z: 0x%04X [Z]: 0x%04X\n", vm->registers[REG_Z], vm->ram[vm->registers[REG_Z]]); fprintf(stderr, "I: 0x%04X [I]: 0x%04X\n", vm->registers[REG_I], vm->ram[vm->registers[REG_I]]); fprintf(stderr, "J: 0x%04X [J]: 0x%04X\n", vm->registers[REG_J], vm->ram[vm->registers[REG_J]]); fprintf(stderr, "PC: 0x%04X SP: 0x%04X\n", vm->pc, vm->sp); fprintf(stderr, "EX: 0x%04X IA: 0x%04X\n", vm->ex, vm->ia); } vm_hw_lua_free(vm); vm_free(vm); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); glfwTerminate(); return 0; }
static bstring skip_to_endif(state_t* state, bool stop_at_else, bool* stopped_at_else) { char c; bool fresh_line = true; bstring temp = bfromcstr(""); bstring temp_output = bfromcstr(""); bstring output = bfromcstr(""); int if_open = 1; while (ppimpl_has_input(state)) { c = ppimpl_get_input(state); switch(c) { case '#': case '.': if (!fresh_line) { bconchar(output, c); break; } bassigncstr(temp_output, "#"); // first skip spaces while (ppimpl_has_input(state)) { c = ppimpl_get_input(state); bconchar(temp_output, c); if (c != ' ' && c != '\t') break; } // read pp directive bassigncstr(temp, ""); bconchar(temp, c); while (ppimpl_has_input(state)) { c = ppimpl_get_input(state); bconchar(temp_output, c); if (c == ' ' || c == '\t' || c == '\n') break; bconchar(temp, c); } btolower(temp); if (biseq(temp, bfromcstr("endif"))) { if_open--; if (if_open == 0) { if (c != '\n') skip_to_endln(state); *stopped_at_else = false; return output; } } else if (biseq(temp, bfromcstr("if"))) { if_open++; } else if (biseq(temp, bfromcstr("else")) && stop_at_else) { if (if_open == 1) { if (c != '\n') skip_to_endln(state); *stopped_at_else = true; return output; } } bconcat(output, temp_output); fresh_line = (c == '\n'); break; case '\n': fresh_line = true; bconchar(output, c); break; case ' ': case '\t': bconchar(output, c); break; default: fresh_line = false; bconchar(output, c); break; } } // No .ENDIF was found. dhalt(ERR_PP_ASM_NO_ENDIF_TO_IF, ppimpl_get_location(state)); // dhalt will trigger before this, but the compiler warns about // control potentially reaching the end of this function. return NULL; }
static void define_handle(state_t* state, match_t* match, bool* reprocess) { // We need to parse this manually because we're interested in getting // the first word and then all of the content until a line that doesn't end // with "\". bstring name = bfromcstr(""); bstring word = bfromcstr(""); bstring definition = bfromcstr(""); bool getting_word = true; bool getting_definition = true; bool is_macro = false; match_t* new_match; struct replace_info* info; // Get the first word. while (getting_word) { char c = ppimpl_get_input(state); bconchar(word, c); if (!is_macro && c != '(') bconchar(name, c); bltrimws(word); // Handle termination. if (blength(word) > 0 && (c == ' ' || c == '\t') && !is_macro) { // End of word. btrimws(word); btrimws(name); getting_word = false; } else if (blength(word) > 0 && c == '(' && !is_macro) { // Start of macro. is_macro = true; } else if (blength(word) > 0 && c == '(' && is_macro) { // Second ( in a macro; error. dhalt(ERR_PP_MACRO_MALFORMED, ppimpl_get_location(state)); } else if (blength(word) > 0 && c == ')' && is_macro) { // End of macro name. btrimws(word); btrimws(name); getting_word = false; } else if (blength(word) == 0 && c == '\n') dhalt(ERR_PP_C_DEFINE_PARAMETERS_INCORRECT, ppimpl_get_location(state)); else if (blength(word) > 0 && c == '\n') { // End of word. btrimws(word); btrimws(name); getting_word = false; getting_definition = false; ppimpl_printf(state, "\n"); } } // Get the definition. while (getting_definition) { char c = ppimpl_get_input(state); bconchar(definition, c); bltrimws(definition); if (c == '\n') { if (blength(definition) > 1 && definition->data[blength(definition) - 2] == '\\') { // Remove the new slash. bdelete(definition, blength(definition) - 2, 1); ppimpl_oprintf(state, "\n"); } else { btrimws(definition); getting_definition = false; ppimpl_printf(state, "\n"); } } else if (c == '/' || c == '*') { if (blength(definition) > 1 && definition->data[blength(definition) - 2] == '/') { // a line or block comment ppimpl_iprintf(state, "/%c", c); // remove the slashes bdelete(definition, blength(definition) - 2, 2); btrimws(definition); getting_definition = false; } } } if (blength(definition) == 0 && !is_macro) bassigncstr(definition, "1"); // Create the new replacement handler. info = malloc(sizeof(struct replace_info)); info->full = word; info->replacement = definition; if (biseq(info->full, info->replacement)) { free(info); return; } new_match = malloc(sizeof(match_t)); new_match->text = bautofree(name); if (is_macro) new_match->handler = macro_handle; else new_match->handler = replace_handle; new_match->line_start_only = false; new_match->identifier_only = true; new_match->userdata = info; new_match->case_insensitive = false; ppimpl_register(state, new_match); *reprocess = true; }
int main (int argc, char** argv) { int socket_fd = -1; int optInfo = 0; int optClock = 0; int optStethoscope = 0; int optSockets = 0; double runtime; int hasDRAM = 0; int c; bstring argString; bstring eventString = bfromcstr("CLOCK"); int numSockets=1; int numThreads=0; int threadsSockets[MAX_NUM_NODES*2]; int threads[MAX_NUM_THREADS]; threadsSockets[0] = 0; if (argc == 1) { HELP_MSG; exit (EXIT_SUCCESS); } while ((c = getopt (argc, argv, "+c:hiM:ps:v")) != -1) { switch (c) { case 'c': CHECK_OPTION_STRING; numSockets = bstr_to_cpuset_physical((uint32_t*) threadsSockets, argString); bdestroy(argString); optSockets = 1; break; case 'h': HELP_MSG; exit (EXIT_SUCCESS); case 'i': optInfo = 1; break; case 'M': /* Set MSR Access mode */ CHECK_OPTION_STRING; accessClient_setaccessmode(str2int((char*) argString->data)); bdestroy(argString); break; case 'p': optClock = 1; break; case 's': CHECK_OPTION_STRING; optStethoscope = str2int((char*) argString->data); bdestroy(argString); break; case 'v': VERSION_MSG; exit (EXIT_SUCCESS); case '?': if (optopt == 's' || optopt == 'M' || optopt == 'c') { HELP_MSG; } else if (isprint (optopt)) { fprintf (stderr, "Unknown option `-%c'.\n", optopt); } else { fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); } exit( EXIT_FAILURE); default: HELP_MSG; exit (EXIT_SUCCESS); } } if (!lock_check()) { fprintf(stderr,"Access to performance counters is locked.\n"); exit(EXIT_FAILURE); } if (optClock && optind == argc) { fprintf(stderr,"Commandline option -p requires an executable.\n"); exit(EXIT_FAILURE); } if (optSockets && !optStethoscope && optind == argc) { fprintf(stderr,"Commandline option -c requires an executable if not used in combination with -s.\n"); exit(EXIT_FAILURE); } if (cpuid_init() == EXIT_FAILURE) { fprintf(stderr, "CPU not supported\n"); exit(EXIT_FAILURE); } if (numSockets > cpuid_topology.numSockets) { fprintf(stderr, "System has only %d sockets but %d are given on commandline\n", cpuid_topology.numSockets, numSockets); exit(EXIT_FAILURE); } numa_init(); /* consider NUMA node as power unit for the moment */ accessClient_init(&socket_fd); msr_init(socket_fd); timer_init(); /* check for supported processors */ if ((cpuid_info.model == SANDYBRIDGE_EP) || (cpuid_info.model == SANDYBRIDGE) || (cpuid_info.model == IVYBRIDGE) || (cpuid_info.model == IVYBRIDGE_EP) || (cpuid_info.model == HASWELL) || (cpuid_info.model == NEHALEM_BLOOMFIELD) || (cpuid_info.model == NEHALEM_LYNNFIELD) || (cpuid_info.model == NEHALEM_WESTMERE)) { power_init(numa_info.nodes[0].processors[0]); } else { fprintf (stderr, "Query Turbo Mode only supported on Intel Nehalem/Westmere/SandyBridge/IvyBridge/Haswell processors!\n"); exit(EXIT_FAILURE); } double clock = (double) timer_getCpuClock(); printf(HLINE); printf("CPU name:\t%s \n",cpuid_info.name); printf("CPU clock:\t%3.2f GHz \n", (float) clock * 1.E-09); printf(HLINE); if (optInfo) { if (power_info.turbo.numSteps != 0) { printf("Base clock:\t%.2f MHz \n", power_info.baseFrequency ); printf("Minimal clock:\t%.2f MHz \n", power_info.minFrequency ); printf("Turbo Boost Steps:\n"); for (int i=0; i < power_info.turbo.numSteps; i++ ) { printf("C%d %.2f MHz \n",i+1, power_info.turbo.steps[i] ); } } printf(HLINE); } if (cpuid_info.model == SANDYBRIDGE_EP) { hasDRAM = 1; } else if ((cpuid_info.model != SANDYBRIDGE) && (cpuid_info.model != SANDYBRIDGE_EP) && (cpuid_info.model != IVYBRIDGE) && (cpuid_info.model != IVYBRIDGE_EP) && (cpuid_info.model != HASWELL)) { fprintf (stderr, "RAPL not supported on this processor!\n"); exit(EXIT_FAILURE); } if (optInfo) { printf("Thermal Spec Power: %g Watts \n", power_info.tdp ); printf("Minimum Power: %g Watts \n", power_info.minPower); printf("Maximum Power: %g Watts \n", power_info.maxPower); printf("Maximum Time Window: %g micro sec \n", power_info.maxTimeWindow); printf(HLINE); exit(EXIT_SUCCESS); } if (optClock) { affinity_init(); argString = bformat("S%u:0-%u", threadsSockets[0], cpuid_topology.numCoresPerSocket-1); for (int i=1; i<numSockets; i++) { bstring tExpr = bformat("@S%u:0-%u", threadsSockets[i], cpuid_topology.numCoresPerSocket-1); bconcat(argString, tExpr); } numThreads = bstr_to_cpuset(threads, argString); bdestroy(argString); perfmon_init(numThreads, threads, stdout); perfmon_setupEventSet(eventString, NULL); } { PowerData pDataPkg[MAX_NUM_NODES*2]; PowerData pDataDram[MAX_NUM_NODES*2]; printf("Measure on sockets: %d", threadsSockets[0]); for (int i=1; i<numSockets; i++) { printf(", %d", threadsSockets[i]); } printf("\n"); if (optStethoscope) { if (optClock) { perfmon_startCounters(); } else { for (int i=0; i<numSockets; i++) { int cpuId = numa_info.nodes[threadsSockets[i]].processors[0]; if (hasDRAM) power_start(pDataDram+i, cpuId, DRAM); power_start(pDataPkg+i, cpuId, PKG); } } sleep(optStethoscope); if (optClock) { perfmon_stopCounters(); perfmon_printCounterResults(); perfmon_finalize(); } else { for (int i=0; i<numSockets; i++) { int cpuId = numa_info.nodes[threadsSockets[i]].processors[0]; power_stop(pDataPkg+i, cpuId, PKG); if (hasDRAM) power_stop(pDataDram+i, cpuId, DRAM); } } runtime = (double) optStethoscope; } else { TimerData time; argv += optind; bstring exeString = bfromcstr(argv[0]); for (int i=1; i<(argc-optind); i++) { bconchar(exeString, ' '); bcatcstr(exeString, argv[i]); } printf("%s\n",bdata(exeString)); if (optClock) { perfmon_startCounters(); } else { for (int i=0; i<numSockets; i++) { int cpuId = numa_info.nodes[threadsSockets[i]].processors[0]; if (hasDRAM) power_start(pDataDram+i, cpuId, DRAM); power_start(pDataPkg+i, cpuId, PKG); } timer_start(&time); } if (system(bdata(exeString)) == EOF) { fprintf(stderr, "Failed to execute %s!\n", bdata(exeString)); exit(EXIT_FAILURE); } if (optClock) { perfmon_stopCounters(); perfmon_printCounterResults(); perfmon_finalize(); } else { timer_stop(&time); for (int i=0; i<numSockets; i++) { int cpuId = numa_info.nodes[threadsSockets[i]].processors[0]; power_stop(pDataPkg+i, cpuId, PKG); if (hasDRAM) power_stop(pDataDram+i, cpuId, DRAM); } runtime = timer_print(&time); } } if (!optClock) { printf("Runtime: %g second \n",runtime); printf(HLINE); for (int i=0; i<numSockets; i++) { printf("Socket %d\n",threadsSockets[i]); printf("Domain: PKG \n"); printf("Energy consumed: %g Joules \n", power_printEnergy(pDataPkg+i)); printf("Power consumed: %g Watts \n", power_printEnergy(pDataPkg+i) / runtime ); if (hasDRAM) { printf("Domain: DRAM \n"); printf("Energy consumed: %g Joules \n", power_printEnergy(pDataDram+i)); printf("Power consumed: %g Watts \n", power_printEnergy(pDataDram+i) / runtime ); } printf("\n"); } } } #if 0 if ( cpuid_hasFeature(TM2) ) { thermal_init(0); printf("Current core temperatures:\n"); for (uint32_t i = 0; i < cpuid_topology.numCoresPerSocket; i++ ) { printf("Core %d: %u C\n", numa_info.nodes[socketId].processors[i], thermal_read(numa_info.nodes[socketId].processors[i])); } } #endif msr_finalize(); return EXIT_SUCCESS; }
const char* glswGetShader(const char* pEffectKey, const char* pContentsFromMemory) { glswContext* gc = __glsw__Context; bstring effectKey; glswList* closestMatch = 0; struct bstrList* tokens; bstring effectName; glswList* pLoadedEffect; glswList* pShaderEntry; bstring shaderKey = 0; if (!gc) { return 0; } // Extract the effect name from the effect key effectKey = bfromcstr(pEffectKey); tokens = bsplit(effectKey, '.'); if (!tokens || !tokens->qty) { bdestroy(gc->ErrorMessage); gc->ErrorMessage = bformat("Malformed effect key key '%s'.", pEffectKey); bstrListDestroy(tokens); bdestroy(effectKey); return 0; } effectName = tokens->entry[0]; // Check if we already loaded this effect file pLoadedEffect = gc->LoadedEffects; while (pLoadedEffect) { if (1 == biseq(pLoadedEffect->Key, effectName)) { break; } pLoadedEffect = pLoadedEffect->Next; } // If we haven't loaded this file yet, load it in if (!pLoadedEffect) { bstring effectContents; struct bstrList* lines; int lineNo; if (!pContentsFromMemory) { FILE* fp; bstring effectFile; // Decorate the effect name to form the fullpath effectFile = bstrcpy(effectName); binsert(effectFile, 0, gc->PathPrefix, '?'); bconcat(effectFile, gc->PathSuffix); // Attempt to open the file fp = fopen((const char*) effectFile->data, "rb"); if (!fp) { bdestroy(gc->ErrorMessage); gc->ErrorMessage = bformat("Unable to open effect file '%s'.", effectFile->data); bdestroy(effectFile); bdestroy(effectKey); bstrListDestroy(tokens); return 0; } // Add a new entry to the front of gc->LoadedEffects { glswList* temp = gc->LoadedEffects; gc->LoadedEffects = (glswList*) calloc(sizeof(glswList), 1); gc->LoadedEffects->Key = bstrcpy(effectName); gc->LoadedEffects->Next = temp; } // Read in the effect file effectContents = bread((bNread) fread, fp); fclose(fp); bdestroy(effectFile); } else { effectContents = bfromcstr(pContentsFromMemory); } lines = bsplit(effectContents, '\n'); bdestroy(effectContents); effectContents = 0; for (lineNo = 0; lineNo < lines->qty; lineNo++) { bstring line = lines->entry[lineNo]; // If the line starts with "--", then it marks a new section if (blength(line) >= 2 && line->data[0] == '-' && line->data[1] == '-') { // Find the first character in [A-Za-z0-9_]. int colNo; for (colNo = 2; colNo < blength(line); colNo++) { char c = line->data[colNo]; if (__glsw__Alphanumeric(c)) { break; } } // If there's no alphanumeric character, // then this marks the start of a new comment block. if (colNo >= blength(line)) { bdestroy(shaderKey); shaderKey = 0; } else { // Keep reading until a non-alphanumeric character is found. int endCol; for (endCol = colNo; endCol < blength(line); endCol++) { char c = line->data[endCol]; if (!__glsw__Alphanumeric(c)) { break; } } bdestroy(shaderKey); shaderKey = bmidstr(line, colNo, endCol - colNo); // Add a new entry to the shader map. { glswList* temp = gc->ShaderMap; gc->ShaderMap = (glswList*) calloc(sizeof(glswList), 1); gc->ShaderMap->Key = bstrcpy(shaderKey); gc->ShaderMap->Next = temp; gc->ShaderMap->Value = bformat("#line %d\n", lineNo); binsertch(gc->ShaderMap->Key, 0, 1, '.'); binsert(gc->ShaderMap->Key, 0, effectName, '?'); } // Check for a version mapping. if (gc->TokenMap) { struct bstrList* tokens = bsplit(shaderKey, '.'); glswList* pTokenMapping = gc->TokenMap; while (pTokenMapping) { bstring directive = 0; int tokenIndex; // An empty key in the token mapping means "always prepend this directive". // The effect name itself is also checked against the token mapping. if (0 == blength(pTokenMapping->Key) || 1 == biseq(pTokenMapping->Key, effectName)) { directive = pTokenMapping->Value; binsert(gc->ShaderMap->Value, 0, directive, '?'); } // Check all tokens in the current section divider for a mapped token. for (tokenIndex = 0; tokenIndex < tokens->qty && !directive; tokenIndex++) { bstring token = tokens->entry[tokenIndex]; if (1 == biseq(pTokenMapping->Key, token)) { directive = pTokenMapping->Value; binsert(gc->ShaderMap->Value, 0, directive, '?'); } } pTokenMapping = pTokenMapping->Next; } bstrListDestroy(tokens); } } continue; } if (shaderKey) { bconcat(gc->ShaderMap->Value, line); bconchar(gc->ShaderMap->Value, '\n'); } } // Cleanup bstrListDestroy(lines); bdestroy(shaderKey); } // Find the longest matching shader key pShaderEntry = gc->ShaderMap; while (pShaderEntry) { if (binstr(effectKey, 0, pShaderEntry->Key) == 0 && (!closestMatch || blength(pShaderEntry->Key) > blength(closestMatch->Key))) { closestMatch = pShaderEntry; } pShaderEntry = pShaderEntry->Next; } bstrListDestroy(tokens); bdestroy(effectKey); if (!closestMatch) { bdestroy(gc->ErrorMessage); gc->ErrorMessage = bformat("Could not find shader with key '%s'.", pEffectKey); return 0; } return (const char*) closestMatch->Value->data; }
bstring expr_representation(struct expr* e) { bstring a, b, op, result; switch (e->type) { case EXPR_NUMBER: return bformat("%u", (uint16_t)(intptr_t)e->data); case EXPR_LABEL: return bstrcpy((bstring)e->data); case EXPR_EXPR: a = expr_representation(e->a); b = expr_representation(e->b); switch (e->op) { case EXPR_OP_ADD: op = bfromcstr("+"); break; case EXPR_OP_SUBTRACT: op = bfromcstr("-"); break; case EXPR_OP_MULTIPLY: op = bfromcstr("*"); break; case EXPR_OP_DIVIDE: op = bfromcstr("/"); break; case EXPR_OP_MODULUS: op = bfromcstr("%"); break; case EXPR_OP_EQUALS: op = bfromcstr("=="); break; case EXPR_OP_NOT_EQUALS: op = bfromcstr("!="); break; case EXPR_OP_LESS_THAN: op = bfromcstr("<"); break; case EXPR_OP_LESS_EQUALS: op = bfromcstr("<="); break; case EXPR_OP_GREATER_THAN: op = bfromcstr(">"); break; case EXPR_OP_GREATER_EQUALS: op = bfromcstr(">="); break; case EXPR_OP_AND: op = bfromcstr("&"); break; case EXPR_OP_BOR: op = bfromcstr("|"); break; case EXPR_OP_XOR: op = bfromcstr("^"); break; default: op = bfromcstr("???"); break; } result = bfromcstr(""); bconchar(result, '('); bconcat(result, a); bconchar(result, ' '); bconcat(result, op); bconchar(result, ' '); bconcat(result, b); bconchar(result, ')'); bdestroy(a); bdestroy(b); bdestroy(op); return result; default: return bfromcstr("???"); } }