std::shared_ptr<std::istream> Resources::OpenStream(std::wstring name) { LOG(Trace, L"Reading stream \"" << name << L"\""); if (name.empty()) { throw std::invalid_argument("empty resource name"); } if (name[0] == wchar_t(':')) { if (name.length() == 1) { throw std::invalid_argument("invalid resource name"); } // Internal binary resource std::wstring demangled_name = name.substr(1); // Drop leading colon for (auto& i: kBuiltinBinaryResources) { if (i.first == demangled_name) { auto result = std::make_shared<std::stringstream>(); auto blob = Base64::Decode(i.second); result->write((char*)blob.data(), blob.size()); return result; } } throw std::runtime_error(_FMT("resource \"" << Encoding::UTF8.FromUCS2(name) << "\" is not found")); // FIXME: remove _FMT } else { // Regular file #if defined(_WIN32) // Windows version: change slashes to backslashes for (auto& c: name) if (c == L'/') c = L'\\'; #else // No modifications #endif #ifdef _MSC_VER auto result = std::make_shared<std::ifstream>(name, std::ios_base::in|std::ios_base::binary); if (!result || result->fail()) { throw std::runtime_error(_FMT("file \"" << Encoding::UTF8.FromUCS2(name) << "\" cannot be opened")); } return result; #else std::string name_u8 = Encoding(L"utf8").FromUCS2(name); return std::shared_ptr<std::istream>(new std::ifstream(name_u8, std::ios_base::in|std::ios_base::binary)); #endif } }
void run() { if (!spec) {Error();return;} while(*spec) { if (*spec=='%') { spec++; if (*spec=='%') {str.AddChar('%');spec++;continue;} T_CHAR* s1=spec+1; while(*s1 && *s1!='%') s1++; if (!*s1) {Error();break;} *s1=0; T_CHAR * tag=f(spec,fp); *s1='%'; /*if (!tag) tag=tag_unknown; */ if (tag && tag[0]) { found++; str.AddString(tag); } else { str.AddString(_TX("?")); } if (tag && ff) ff(tag,fp); spec=s1+1; } else if (*spec=='$') { spec++; if (*spec=='$') {str.AddChar('$');spec++;continue;} T_CHAR * s1=spec+1; while(*s1 && *s1!='(') s1++; if (!*s1) {Error();break;} T_CHAR * s2=s1+1; if (!skipshit(&s2,_TX(")"))) {Error();break;} if (!*s2) {Error();break;}; T_CHAR * p=s1+1; T_CHAR* temp[64]; UINT temp_f[64]; UINT nt=0; T_CHAR * p1=s1+1; while(p<=s2 && nt<64) { if (!skipshit(&p,_TX(",)"))) {Error();return;} if (p>s2 || (*p!=',' && *p!=')')) {Error(_TX("internal error"));return;} T_CHAR bk=*p; *p=0; temp[nt]=_FMT(p1,&temp_f[nt]); nt++; *p=bk;; p1=p+1; p++; } *s1=0; UINT n; for (n=0; n<TABSIZE(FUNCS); n++) if (!t_stricmp(spec, FUNCS[n].name)) break; *s1='('; if (n != TABSIZE(FUNCS)) { if (!FUNCS[n].func(nt, temp, temp_f, str)) { Error(_TX("[INVALID $")); str.AddString(FUNCS[n].name); str.AddString(_TX(" SYNTAX]")); return; } } else { Error(_TX("[UNKNOWN FUNCTION]")); return; } for(n=0;n<nt;n++) free(temp[n]); spec=s2+1; } else if (*spec=='\'') { spec++; if (*spec=='\'') {str.AddChar('\'');spec++;continue;} T_CHAR * s1=spec+1; while(*s1 && *s1!='\'') s1++; if (!*s1) {Error();break;} *s1=0; str.AddString(spec); *s1='\''; spec=s1+1; } else if (*spec=='[') { spec++; T_CHAR * s1=spec; UINT bc=0; if (!skipshit(&s1,_TX("]"))) {Error();break;} T_CHAR bk=*s1; *s1=0; FMT fmt(this,spec); fmt.run(); if (fmt.found) { str.AddString(fmt.str); found+=fmt.found; } *s1=bk; spec=s1+1; } else if (*spec == ']') {Error();break;} else { str.AddChar(*spec); spec++; } } }
/* Give some pretty, formatted output */ int mr4kd_sprintf ( char *dest, char *name, uint32_t instruction, uint32_t pc, char *fmt ) { /* ** Format specifiers: ** - %rs ** - %rt ** - %rd ** ** - %fs ** - %ft ** - %fd ** ** - %cp Coprocessor register ** ** - %ff FP mode (single, double etc) ** - %fc FP compare condition ** ** - %ih Immediate (hex) ** - %id Immediate (dec) ** - %br Branch address ** - %jm Jump target ** ** - %co COP # ** ** - %ns Name ** - %nc Name with COP number ** - %nf Name with FP format ** ** - %sa Shift amount ** ** - %SP Remainder spacing */ int s = 0; /* Source */ int d = 0; /* Dest */ uint16_t token; /* Scan the format string for specifiers */ for( s = 0; fmt[s]; s++ ) { /* No token? */ if( fmt[s] != '%' ) { dest[d++] = fmt[s]; continue; } /* Got token, read it in */ token = (fmt[s + 1] << 8 | fmt[s + 2]); /* Check */ switch( token ) { /* GPRs */ case TOKEN('r', 's'): d += mr4kd_rcpy_gpr( &dest[d], _RS(instruction) ); break; case TOKEN('r', 't'): d += mr4kd_rcpy_gpr( &dest[d], _RT(instruction) ); break; case TOKEN('r', 'd'): d += mr4kd_rcpy_gpr( &dest[d], _RD(instruction) ); break; /* FPRs */ case TOKEN('f', 's'): d += mr4kd_rcpy_fpr( &dest[d], _FS(instruction) ); break; case TOKEN('f', 't'): d += mr4kd_rcpy_fpr( &dest[d], _FT(instruction) ); break; case TOKEN('f', 'd'): d += mr4kd_rcpy_fpr( &dest[d], _FD(instruction) ); break; /* COP */ case TOKEN('c', 'p'): d += sprintf( &dest[d], "%s", registers_a_cop[_FS(instruction)] ); break; /* Immediate (hex) */ case TOKEN('i', 'h'): d += sprintf( &dest[d], MR4KD_FLAG_GET(MR4KD_HLOWER) ? "0x%04x" : "0x%04X", _IMMEDIATE(instruction) ); break; /* Immediate (decimal) */ case TOKEN('i', 'd'): d += sprintf( &dest[d], "%i", (int)((short)_IMMEDIATE(instruction)) ); break; /* Branch address */ case TOKEN('b', 'r'): d += sprintf( &dest[d], MR4KD_FLAG_GET(MR4KD_HLOWER) ? "0x%08x" : "0x%08X", ((unsigned int)pc + 4 + (short)(instruction & 0xFFFF) * 4) ); break; /* Jump target */ case TOKEN('j', 'm'): d += sprintf( &dest[d], MR4KD_FLAG_GET(MR4KD_HLOWER) ? "0x%08x" : "0x%08X", _TARGET(instruction) | (pc & 0xF0000000) ); break; /* Coprocessor number */ case TOKEN('c', 'o'): d += sprintf( &dest[d], "%u", _COP(instruction) ); break; /* Shift amount */ case TOKEN('s', 'a'): d += sprintf( &dest[d], "%u", _SHAM(instruction) ); break; /* Floating point compare mode */ case TOKEN('f', 'c'): d += sprintf( &dest[d], "%s", fp_compare_types[instruction & 0xF] ); break; /* Floating point mode */ case TOKEN('f', 'f'): d += sprintf( &dest[d], "%c", fpu_fmt_names[_FMT(instruction) - 16] ); break; /* Spacing! */ case TOKEN('S', 'P'): d += sprintf( &dest[d], "%*s", (int)-((mr4kd_conf >> 24) - d), " "); break; /* Instruction name - regular (no space) */ case TOKEN('n', '0'): { int i; char nb[32]; /* Convert to the proper case */ for( i = 0; name[i]; i++ ) nb[i] = ( mr4kd_conf & MR4KD_OLOWER ) ? tolower((uint8_t)name[i]) : toupper((uint8_t)name[i]); /* Copy it to dest */ d += sprintf( &dest[d], "%.*s", i, nb ); } break; /* Instruction name - regular */ case TOKEN('n', 's'): { int i; char nb[32]; /* Convert to the proper case */ for( i = 0; name[i]; i++ ) nb[i] = ( mr4kd_conf & MR4KD_OLOWER ) ? tolower((uint8_t)name[i]) : toupper((uint8_t)name[i]); /* Copy it to dest */ d += sprintf( &dest[d], "%*.*s", (int)-(mr4kd_conf >> 24), i, nb ); } break; /* Instruction name - with COP# */ case TOKEN('n', 'c'): { int i; char nb[32]; /* Convert to the proper case */ for( i = 0; name[i]; i++ ) nb[i] = ( mr4kd_conf & MR4KD_OLOWER ) ? tolower((uint8_t)name[i]) : toupper((uint8_t)name[i]); /* Copy number */ i += sprintf( &nb[i], "%u", _COP(instruction) ); /* Copy it to dest */ d += sprintf( &dest[d], "%*.*s", (int)-(mr4kd_conf >> 24), i, nb ); } break; /* Floating point format */ case TOKEN('n', 'f'): { int i; char nb[32]; /* Convert to the proper case */ for( i = 0; name[i]; i++ ) nb[i] = ( mr4kd_conf & MR4KD_OLOWER ) ? tolower((uint8_t)name[i]) : toupper((uint8_t)name[i]); /* Copy the precision mode */ i += sprintf( &nb[i], ".%c",( mr4kd_conf & MR4KD_OLOWER ) ? tolower((uint8_t)fpu_fmt_names[_FMT(instruction)-16]) : toupper((uint8_t)fpu_fmt_names[_FMT(instruction)-16]) ); /* Copy it to dest */ d += sprintf( &dest[d], "%*.*s", (int)-(mr4kd_conf >> 24), i, nb ); } break; } /* Update source pointer */ s += 2; } /* Null terminate output */ dest[d] = 0; /* Return chars processed */ return d; }