[rpcli] New command line option '-d' to skip RFT_LISTDATA with more than 10 items in text output.

This will make it easier to test e.g. Windows executables without having
to scroll through pages of DLL imports/exports.

[librpbase] TextOut: Use a flags parameter instead of bool so we can have
multiple flags.

[doc/abi] Updated ABIs to reflect the use of `unsigned int` for flags.
Interestingly, the Windows gcc ABIs already used this instead of `bool`...
This commit is contained in:
David Korth 2022-09-10 16:10:57 -04:00
parent 134c180f62
commit cd29f1c993
9 changed files with 61 additions and 43 deletions

View File

@ -78,7 +78,7 @@ T LibRpBase::cpN_to_utf16[abi:cxx11](unsigned int, char const*, int, unsigned in
T LibRpBase::cpN_to_utf8[abi:cxx11](unsigned int, char const*, int, unsigned int)
T LibRpBase::IconAnimHelper::nextFrame(int*)
T LibRpBase::IconAnimHelper::reset()
T LibRpBase::JSONROMOutput::JSONROMOutput(LibRpBase::RomData const*, unsigned int, bool)
T LibRpBase::JSONROMOutput::JSONROMOutput(LibRpBase::RomData const*, unsigned int, unsigned int)
T LibRpBase::KeyManager::getAndVerify(char const*, LibRpBase::KeyManager::KeyData_t*, unsigned char const*, unsigned int) const
T LibRpBase::KeyManager::instance()
T LibRpBase::KeyManager::verifyResultToString(LibRpBase::KeyManager::VerifyResult)
@ -110,7 +110,7 @@ T LibRpBase::RomFields::tabName(int) const
T LibRpBase::RomMetaData::count() const
T LibRpBase::RomMetaData::empty() const
T LibRpBase::RomMetaData::prop(int) const
T LibRpBase::ROMOutput::ROMOutput(LibRpBase::RomData const*, unsigned int, bool)
T LibRpBase::ROMOutput::ROMOutput(LibRpBase::RomData const*, unsigned int, unsigned int)
T LibRpBase::RpImageLoader::load(LibRpFile::IRpFile*)
T LibRpBase::RpPng::libpng_copyright_string()
T LibRpBase::RpPng::libpng_has_APNG()

View File

@ -83,7 +83,7 @@ T LibRpBase::cpN_to_utf16[abi:cxx11](unsigned int, char const*, int, unsigned in
T LibRpBase::cpN_to_utf8[abi:cxx11](unsigned int, char const*, int, unsigned int)
T LibRpBase::IconAnimHelper::nextFrame(int*)
T LibRpBase::IconAnimHelper::reset()
T LibRpBase::JSONROMOutput::JSONROMOutput(LibRpBase::RomData const*, unsigned int, bool)
T LibRpBase::JSONROMOutput::JSONROMOutput(LibRpBase::RomData const*, unsigned int, unsigned int)
T LibRpBase::KeyManager::getAndVerify(char const*, LibRpBase::KeyManager::KeyData_t*, unsigned char const*, unsigned int) const
T LibRpBase::KeyManager::instance()
T LibRpBase::KeyManager::verifyResultToString(LibRpBase::KeyManager::VerifyResult)
@ -115,7 +115,7 @@ T LibRpBase::RomFields::tabName(int) const
T LibRpBase::RomMetaData::count() const
T LibRpBase::RomMetaData::empty() const
T LibRpBase::RomMetaData::prop(int) const
T LibRpBase::ROMOutput::ROMOutput(LibRpBase::RomData const*, unsigned int, bool)
T LibRpBase::ROMOutput::ROMOutput(LibRpBase::RomData const*, unsigned int, unsigned int)
T LibRpBase::RpImageLoader::load(LibRpFile::IRpFile*)
T LibRpBase::RpPng::libpng_copyright_string()
T LibRpBase::RpPng::libpng_has_APNG()

View File

@ -2,10 +2,10 @@ protected: __cdecl LibRpBase::ConfReader::ConfReader(class LibRpBase::ConfReader
protected: __cdecl LibRpBase::Config::Config(void) __ptr64
public: __cdecl LibRomData::GcnFst::GcnFst(unsigned char const * __ptr64,unsigned int,unsigned char) __ptr64
protected: __cdecl LibRpFile::IRpFile::IRpFile(void) __ptr64
public: __cdecl LibRpBase::JSONROMOutput::JSONROMOutput(class LibRpBase::RomData const * __ptr64,unsigned int,bool) __ptr64
public: __cdecl LibRpBase::JSONROMOutput::JSONROMOutput(class LibRpBase::RomData const * __ptr64,unsigned int,unsigned int) __ptr64
public: __cdecl LibRomData::KeyStoreUI::KeyStoreUI(void) __ptr64
public: __cdecl LibRpFile::MemFile::MemFile(void const * __ptr64,unsigned __int64) __ptr64
public: __cdecl LibRpBase::ROMOutput::ROMOutput(class LibRpBase::RomData const * __ptr64,unsigned int,bool) __ptr64
public: __cdecl LibRpBase::ROMOutput::ROMOutput(class LibRpBase::RomData const * __ptr64,unsigned int,unsigned int) __ptr64
public: __cdecl LibWin32Common::RegKey::RegKey(class LibWin32Common::RegKey const & __ptr64,wchar_t const * __ptr64,unsigned long,bool) __ptr64
public: __cdecl LibWin32Common::RegKey::RegKey(struct HKEY__ * __ptr64,wchar_t const * __ptr64,unsigned long,bool) __ptr64
public: __cdecl LibRpFile::RpFile::RpFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const & __ptr64,enum LibRpFile::RpFile::FileMode) __ptr64

View File

@ -86,7 +86,7 @@ T LibRpBase::cpN_to_utf16[abi:cxx11](unsigned int, char const*, int, unsigned in
T LibRpBase::cpN_to_utf8[abi:cxx11](unsigned int, char const*, int, unsigned int)
T LibRpBase::IconAnimHelper::nextFrame(int*)
T LibRpBase::IconAnimHelper::reset()
T LibRpBase::JSONROMOutput::JSONROMOutput(LibRpBase::RomData const*, unsigned int, bool)
T LibRpBase::JSONROMOutput::JSONROMOutput(LibRpBase::RomData const*, unsigned int, unsigned int)
T LibRpBase::KeyManager::getAndVerify(char const*, LibRpBase::KeyManager::KeyData_t*, unsigned char const*, unsigned int) const
T LibRpBase::KeyManager::instance()
T LibRpBase::KeyManager::verifyResultToString(LibRpBase::KeyManager::VerifyResult)
@ -118,7 +118,7 @@ T LibRpBase::RomFields::tabName(int) const
T LibRpBase::RomMetaData::count() const
T LibRpBase::RomMetaData::empty() const
T LibRpBase::RomMetaData::prop(int) const
T LibRpBase::ROMOutput::ROMOutput(LibRpBase::RomData const*, unsigned int, bool)
T LibRpBase::ROMOutput::ROMOutput(LibRpBase::RomData const*, unsigned int, unsigned int)
T LibRpBase::RpImageLoader::load(LibRpFile::IRpFile*)
T LibRpBase::RpPng::libpng_copyright_string()
T LibRpBase::RpPng::libpng_has_APNG()

View File

@ -2,10 +2,10 @@ protected: __thiscall LibRpBase::ConfReader::ConfReader(class LibRpBase::ConfRea
protected: __thiscall LibRpBase::Config::Config(void)
public: __thiscall LibRomData::GcnFst::GcnFst(unsigned char const *,unsigned int,unsigned char)
protected: __thiscall LibRpFile::IRpFile::IRpFile(void)
public: __thiscall LibRpBase::JSONROMOutput::JSONROMOutput(class LibRpBase::RomData const *,unsigned int,bool)
public: __thiscall LibRpBase::JSONROMOutput::JSONROMOutput(class LibRpBase::RomData const *,unsigned int,unsigned int)
public: __thiscall LibRomData::KeyStoreUI::KeyStoreUI(void)
public: __thiscall LibRpFile::MemFile::MemFile(void const *,unsigned int)
public: __thiscall LibRpBase::ROMOutput::ROMOutput(class LibRpBase::RomData const *,unsigned int,bool)
public: __thiscall LibRpBase::ROMOutput::ROMOutput(class LibRpBase::RomData const *,unsigned int,unsigned int)
public: __thiscall LibWin32Common::RegKey::RegKey(class LibWin32Common::RegKey const &,wchar_t const *,unsigned long,bool)
public: __thiscall LibWin32Common::RegKey::RegKey(struct HKEY__ *,wchar_t const *,unsigned long,bool)
public: __thiscall LibRpFile::RpFile::RpFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,enum LibRpFile::RpFile::FileMode)

View File

@ -21,6 +21,11 @@ namespace LibRpBase {
class RomData;
enum OutputFlags {
OF_SkipInternalImages = (1U << 0),
OF_SkipListDataMoreThan10 = (1U << 1), // ROMOutput only
};
/**
* Partially unescape a URL.
* %20, %23, and %25 are left escaped.
@ -32,10 +37,10 @@ std::string urlPartialUnescape(const std::string &url);
class ROMOutput {
const RomData *const romdata;
uint32_t lc;
bool skipInternalImages;
unsigned int flags;
public:
RP_LIBROMDATA_PUBLIC
explicit ROMOutput(const RomData *romdata, uint32_t lc = 0, bool skipInternalImages = false);
explicit ROMOutput(const RomData *romdata, uint32_t lc = 0, unsigned int flags = 0);
RP_LIBROMDATA_PUBLIC
friend std::ostream& operator<<(std::ostream& os, const ROMOutput& fo);
@ -44,11 +49,11 @@ public:
class JSONROMOutput {
const RomData *const romdata;
uint32_t lc;
bool skipInternalImages;
unsigned int flags;
bool crlf_;
public:
RP_LIBROMDATA_PUBLIC
explicit JSONROMOutput(const RomData *romdata, uint32_t lc = 0, bool skipInternalImages = false);
explicit JSONROMOutput(const RomData *romdata, uint32_t lc = 0, unsigned int flags = 0);
RP_LIBROMDATA_PUBLIC
friend std::ostream& operator<<(std::ostream& os, const JSONROMOutput& fo);

View File

@ -344,10 +344,10 @@ public:
};
JSONROMOutput::JSONROMOutput(const RomData *romdata, uint32_t lc, bool skipInternalImages)
JSONROMOutput::JSONROMOutput(const RomData *romdata, uint32_t lc, unsigned int flags)
: romdata(romdata)
, lc(lc)
, skipInternalImages(skipInternalImages)
, flags(flags)
, crlf_(false) { }
RP_LIBROMDATA_PUBLIC
std::ostream& operator<<(std::ostream& os, const JSONROMOutput& fo) {
@ -378,7 +378,7 @@ std::ostream& operator<<(std::ostream& os, const JSONROMOutput& fo) {
const uint32_t imgbf = romdata->supportedImageTypes();
if (imgbf != 0) {
if (!fo.skipInternalImages) {
if (!(fo.flags & OF_SkipInternalImages)) {
// Internal images
Value imgint_array(kArrayType); // imgint

View File

@ -265,11 +265,13 @@ class ListDataField {
const RomFields::Field &romField;
uint32_t def_lc; // ROM-default language code.
uint32_t user_lc; // User-specified language code.
unsigned int flags;
public:
ListDataField(size_t width, const RomFields::Field &romField, uint32_t def_lc, uint32_t user_lc)
: width(width), romField(romField), def_lc(def_lc), user_lc(user_lc) { }
ListDataField(size_t width, const RomFields::Field &romField, uint32_t def_lc, uint32_t user_lc, unsigned int flags)
: width(width), romField(romField), def_lc(def_lc), user_lc(user_lc), flags(flags) { }
friend ostream& operator<<(ostream& os, const ListDataField& field) {
auto romField = field.romField;
os << ColonPad(field.width, romField.name.c_str());
const auto &listDataDesc = romField.desc.list_data;
// NOTE: listDataDesc.names can be nullptr,
@ -296,7 +298,13 @@ public:
assert(pListData != nullptr);
if (!pListData) {
return os << "[ERROR: No list data.]";
return os << C_("TextOut", "[ERROR: No list data.]");
}
if (field.flags & OF_SkipListDataMoreThan10) {
if (pListData->size() > 10) {
return os << C_("TextOut", "[More than 10 items; skipping...]");
}
}
unsigned int col_count = 1;
@ -311,7 +319,7 @@ public:
}
assert(col_count > 0);
if (col_count <= 0) {
return os << "[ERROR: No list data.]";
return os << C_("TextOut", "[ERROR: No list data.]");
}
/** Calculate the column widths. **/
@ -371,8 +379,6 @@ public:
}
/** Print the list data. **/
os << ColonPad(field.width, romField.name.c_str());
StreamStateSaver state(os);
// Print the list on a separate row from the field name?
@ -688,9 +694,10 @@ public:
class FieldsOutput {
const RomFields& fields;
uint32_t lc;
unsigned int flags;
public:
explicit FieldsOutput(const RomFields& fields, uint32_t lc = 0)
: fields(fields), lc(lc) { }
explicit FieldsOutput(const RomFields& fields, uint32_t lc = 0, unsigned int flags = 0)
: fields(fields), lc(lc), flags(flags) { }
friend std::ostream& operator<<(std::ostream& os, const FieldsOutput& fo) {
size_t maxWidth = 0;
std::for_each(fo.fields.cbegin(), fo.fields.cend(),
@ -747,7 +754,7 @@ public:
os << BitfieldField(maxWidth, romField);
break;
case RomFields::RFT_LISTDATA:
os << ListDataField(maxWidth, romField, def_lc, user_lc);
os << ListDataField(maxWidth, romField, def_lc, user_lc, fo.flags);
break;
case RomFields::RFT_DATETIME:
os << DateTimeField(maxWidth, romField);
@ -774,10 +781,10 @@ public:
};
ROMOutput::ROMOutput(const RomData *romdata, uint32_t lc, bool skipInternalImages)
ROMOutput::ROMOutput(const RomData *romdata, uint32_t lc, unsigned int flags)
: romdata(romdata)
, lc(lc)
, skipInternalImages(skipInternalImages) { }
, flags(flags) { }
RP_LIBROMDATA_PUBLIC
std::ostream& operator<<(std::ostream& os, const ROMOutput& fo) {
auto romdata = fo.romdata;
@ -800,13 +807,13 @@ std::ostream& operator<<(std::ostream& os, const ROMOutput& fo) {
const RomFields *const fields = romdata->fields();
assert(fields != nullptr);
if (fields) {
os << FieldsOutput(*fields, fo.lc) << '\n';
os << FieldsOutput(*fields, fo.lc, fo.flags) << '\n';
}
const uint32_t imgbf = romdata->supportedImageTypes();
if (imgbf != 0) {
// Internal images
if (!fo.skipInternalImages) {
if (!(fo.flags & OF_SkipInternalImages)) {
for (int i = RomData::IMG_INT_MIN; i <= RomData::IMG_INT_MAX; i++) {
if (!(imgbf & (1U << i)))
continue;

View File

@ -192,11 +192,11 @@ static void ExtractImages(const RomData *romData, vector<ExtractParam>& extract)
* @param filename ROM filename
* @param json Is program running in json mode?
* @param extract Vector of image extraction parameters
* @param languageCode Language code. (0 for default)
* @param skipInternalImages If true, skip internal image processing.
* @param lc Language code (0 for default)
* @param flags ROMOutput flags (see OutputFlags)
*/
static void DoFile(const char *filename, bool json, vector<ExtractParam>& extract,
uint32_t languageCode = 0, bool skipInternalImages = false)
uint32_t lc = 0, unsigned int flags = 0)
{
cerr << "== " << rp_sprintf(C_("rpcli", "Reading file '%s'..."), filename) << endl;
RpFile *const file = new RpFile(filename, RpFile::FM_OPEN_READ_GZ);
@ -205,9 +205,9 @@ static void DoFile(const char *filename, bool json, vector<ExtractParam>& extrac
if (romData && romData->isValid()) {
if (json) {
cerr << "-- " << C_("rpcli", "Outputting JSON data") << endl;
cout << JSONROMOutput(romData, languageCode, skipInternalImages) << endl;
cout << JSONROMOutput(romData, lc, flags) << endl;
} else {
cout << ROMOutput(romData, languageCode, skipInternalImages) << endl;
cout << ROMOutput(romData, lc, flags) << endl;
}
ExtractImages(romData, extract);
@ -409,6 +409,7 @@ int RP_C_API main(int argc, char *argv[])
#endif /* ENABLE_DECRYPTION */
cerr << " -c: " << C_("rpcli", "Print system region information.") << '\n';
cerr << " -p: " << C_("rpcli", "Print system path information.") << '\n';
cerr << " -d: " << C_("rpcli", "Skip ListData fields with more than 10 items. [text only]") << '\n';
cerr << " -j: " << C_("rpcli", "Use JSON output format.") << '\n';
cerr << " -l: " << C_("rpcli", "Retrieve the specified language from the ROM image.") << '\n';
cerr << " -xN: " << C_("rpcli", "Extract image N to outfile in PNG format.") << '\n';
@ -458,8 +459,8 @@ int RP_C_API main(int argc, char *argv[])
bool inq_ata = false;
bool inq_ata_packet = false;
#endif /* RP_OS_SCSI_SUPPORTED */
uint32_t languageCode = 0;
bool skipInternalImages = false;
uint32_t lc = 0;
unsigned int flags = 0; // OutputFlags
bool first = true;
int ret = 0;
for (int i = 1; i < argc; i++){
@ -501,11 +502,11 @@ int RP_C_API main(int argc, char *argv[])
}
// Parse the language code.
uint32_t lc = 0;
uint32_t new_lc = 0;
int pos;
for (pos = 0; pos < 4 && s_lang[pos] != '\0'; pos++) {
lc <<= 8;
lc |= (uint8_t)s_lang[pos];
new_lc <<= 8;
new_lc |= (uint8_t)s_lang[pos];
}
if (pos == 4 && s_lang[pos] != '\0') {
// Invalid language code.
@ -514,12 +515,17 @@ int RP_C_API main(int argc, char *argv[])
}
// Language code set.
languageCode = lc;
lc = new_lc;
break;
}
case 'K': {
// Skip internal images. (NOTE: Not documented.)
skipInternalImages = true;
flags |= LibRpBase::OF_SkipInternalImages;
break;
}
case 'd': {
// Skip RFT_LISTDATA with more than 10 items. (Text only)
flags |= LibRpBase::OF_SkipListDataMoreThan10;
break;
}
case 'x': {
@ -585,7 +591,7 @@ int RP_C_API main(int argc, char *argv[])
#endif /* RP_OS_SCSI_SUPPORTED */
{
// Regular file.
DoFile(argv[i], json, extract, languageCode, skipInternalImages);
DoFile(argv[i], json, extract, lc, flags);
}
#ifdef RP_OS_SCSI_SUPPORTED