mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-06-19 01:20:08 -07:00
ZAPD fixes in sys_initial_check, update subrepos (#507)
* git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "a3363333d" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "a3363333d" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/asm-differ --force subrepo: subdir: "tools/asm-differ" merged: "70c33cc12" upstream: origin: "https://github.com/simonlindholm/asm-differ.git" branch: "main" commit: "70c33cc12" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull (merge) tools/z64compress --force subrepo: subdir: "tools/z64compress" merged: "ac5b1a0d0" upstream: origin: "https://github.com/z64me/z64compress.git" branch: "main" commit: "ac5b1a0d0" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Use defines for texture sizes in sys_initial_check * Update extract_assets.py * Add null check * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "50242eca9" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "50242eca9" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
+2
-2
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/zeldaret/ZAPD.git
|
||||
branch = master
|
||||
commit = 4f7b8393ec8a3abd59649c2ba669e951fb61f3d2
|
||||
parent = 346df1bbc8ca21673fe63d884b6734c23a4d9f4b
|
||||
commit = 50242eca96a9c36fd84f438bab24548e73b42303
|
||||
parent = 744955732b1fc9e8a835c62440aa97799cfe8940
|
||||
method = merge
|
||||
cmdver = 0.4.3
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)\ZAPD\;$(SolutionDir)ZAPDUtils;$(SolutionDir)lib\tinyxml2;$(SolutionDir)lib\libgfxd;$(SolutionDir)lib\elfio;$(SolutionDir)lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(ProjectDir)..\ZAPD\;$(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
@@ -120,6 +120,7 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -156,4 +157,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <CollisionExporter.h>
|
||||
#include <Globals.h>
|
||||
#include <RoomExporter.h>
|
||||
#include <TextureExporter.h>
|
||||
#include "CollisionExporter.h"
|
||||
#include "Globals.h"
|
||||
#include "RoomExporter.h"
|
||||
#include "TextureExporter.h"
|
||||
|
||||
enum class ExporterFileMode
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Only used for standalone compilation, usually inherits these from the main makefile
|
||||
CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17
|
||||
|
||||
SRC_DIRS := $(shell find -type d -not -path "*build*")
|
||||
SRC_DIRS := $(shell find . -type d -not -path "*build*")
|
||||
CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
|
||||
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
#include "RoomExporter.h"
|
||||
#include <CollisionExporter.h>
|
||||
#include <Utils/BinaryWriter.h>
|
||||
#include <Utils/File.h>
|
||||
#include <Utils/MemoryStream.h>
|
||||
#include <ZRoom/Commands/SetCameraSettings.h>
|
||||
#include <ZRoom/Commands/SetCollisionHeader.h>
|
||||
#include <ZRoom/Commands/SetCsCamera.h>
|
||||
#include <ZRoom/Commands/SetEchoSettings.h>
|
||||
#include <ZRoom/Commands/SetEntranceList.h>
|
||||
#include <ZRoom/Commands/SetLightingSettings.h>
|
||||
#include <ZRoom/Commands/SetMesh.h>
|
||||
#include <ZRoom/Commands/SetRoomBehavior.h>
|
||||
#include <ZRoom/Commands/SetRoomList.h>
|
||||
#include <ZRoom/Commands/SetSkyboxModifier.h>
|
||||
#include <ZRoom/Commands/SetSkyboxSettings.h>
|
||||
#include <ZRoom/Commands/SetSoundSettings.h>
|
||||
#include <ZRoom/Commands/SetSpecialObjects.h>
|
||||
#include <ZRoom/Commands/SetStartPositionList.h>
|
||||
#include <ZRoom/Commands/SetTimeSettings.h>
|
||||
#include <ZRoom/Commands/SetWind.h>
|
||||
#include "CollisionExporter.h"
|
||||
#include "Utils/BinaryWriter.h"
|
||||
#include "Utils/File.h"
|
||||
#include "Utils/MemoryStream.h"
|
||||
#include "ZRoom/Commands/SetCameraSettings.h"
|
||||
#include "ZRoom/Commands/SetCollisionHeader.h"
|
||||
#include "ZRoom/Commands/SetCsCamera.h"
|
||||
#include "ZRoom/Commands/SetEchoSettings.h"
|
||||
#include "ZRoom/Commands/SetEntranceList.h"
|
||||
#include "ZRoom/Commands/SetLightingSettings.h"
|
||||
#include "ZRoom/Commands/SetMesh.h"
|
||||
#include "ZRoom/Commands/SetRoomBehavior.h"
|
||||
#include "ZRoom/Commands/SetRoomList.h"
|
||||
#include "ZRoom/Commands/SetSkyboxModifier.h"
|
||||
#include "ZRoom/Commands/SetSkyboxSettings.h"
|
||||
#include "ZRoom/Commands/SetSoundSettings.h"
|
||||
#include "ZRoom/Commands/SetSpecialObjects.h"
|
||||
#include "ZRoom/Commands/SetStartPositionList.h"
|
||||
#include "ZRoom/Commands/SetTimeSettings.h"
|
||||
#include "ZRoom/Commands/SetWind.h"
|
||||
|
||||
void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* writer)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <Utils/BinaryWriter.h>
|
||||
#include "Utils/BinaryWriter.h"
|
||||
#include "ZResource.h"
|
||||
#include "ZTexture.h"
|
||||
|
||||
|
||||
Vendored
+29
-29
@@ -7,7 +7,7 @@ pipeline {
|
||||
// Non-parallel ZAPD stage
|
||||
stage('Build ZAPD') {
|
||||
steps {
|
||||
sh 'make -j'
|
||||
sh 'make -j WERROR=1'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ pipeline {
|
||||
}
|
||||
}
|
||||
|
||||
stage('Checkout mm') {
|
||||
steps{
|
||||
dir('mm') {
|
||||
git url: 'https://github.com/zeldaret/mm.git'
|
||||
}
|
||||
}
|
||||
}
|
||||
// stage('Checkout mm') {
|
||||
// steps{
|
||||
// dir('mm') {
|
||||
// git url: 'https://github.com/zeldaret/mm.git'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,20 +51,20 @@ pipeline {
|
||||
}
|
||||
}
|
||||
|
||||
stage('Setup MM') {
|
||||
steps {
|
||||
dir('mm') {
|
||||
sh 'cp /usr/local/etc/roms/mm.us.rev1.z64 baserom.mm.us.rev1.z64'
|
||||
// stage('Setup MM') {
|
||||
// steps {
|
||||
// dir('mm') {
|
||||
// sh 'cp /usr/local/etc/roms/mm.us.rev1.z64 baserom.mm.us.rev1.z64'
|
||||
|
||||
// Identical to `make setup` except for copying our newer ZAPD.out into mm
|
||||
sh 'make -C tools'
|
||||
sh 'cp ../ZAPD.out tools/ZAPD/'
|
||||
sh 'python3 tools/fixbaserom.py'
|
||||
sh 'python3 tools/extract_baserom.py'
|
||||
sh 'python3 extract_assets.py -t 4'
|
||||
}
|
||||
}
|
||||
}
|
||||
// // Identical to `make setup` except for copying our newer ZAPD.out into mm
|
||||
// sh 'make -C tools'
|
||||
// sh 'cp ../ZAPD.out tools/ZAPD/'
|
||||
// sh 'python3 tools/fixbaserom.py'
|
||||
// sh 'python3 tools/extract_baserom.py'
|
||||
// sh 'python3 extract_assets.py -t 4'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,14 +78,14 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build mm') {
|
||||
steps {
|
||||
dir('mm') {
|
||||
sh 'make -j disasm'
|
||||
sh 'make -j all'
|
||||
}
|
||||
}
|
||||
}
|
||||
// stage('Build mm') {
|
||||
// steps {
|
||||
// dir('mm') {
|
||||
// sh 'make -j disasm'
|
||||
// sh 'make -j all'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-4
@@ -6,6 +6,7 @@ DEPRECATION_ON ?= 1
|
||||
DEBUG ?= 0
|
||||
COPYCHECK_ARGS ?=
|
||||
LLD ?= 0
|
||||
WERROR ?= 0
|
||||
|
||||
# Use clang++ if available, else use g++
|
||||
ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0)
|
||||
@@ -23,14 +24,16 @@ ifneq ($(DEBUG),0)
|
||||
CXXFLAGS += -g3 -DDEVELOPMENT -D_DEBUG
|
||||
COPYCHECK_ARGS += --devel
|
||||
DEPRECATION_ON = 0
|
||||
else
|
||||
endif
|
||||
|
||||
ifneq ($(WERROR),0)
|
||||
CXXFLAGS += -Werror
|
||||
endif
|
||||
|
||||
ifeq ($(OPTIMIZATION_ON),0)
|
||||
OPTFLAGS := -O0
|
||||
else
|
||||
OPTFLAGS := -O2 -march=native -mtune=native
|
||||
OPTFLAGS := -O2
|
||||
endif
|
||||
|
||||
ifneq ($(ASAN),0)
|
||||
@@ -53,10 +56,23 @@ ifneq ($(LLD),0)
|
||||
endif
|
||||
|
||||
UNAME := $(shell uname)
|
||||
UNAMEM := $(shell uname -m)
|
||||
ifneq ($(UNAME), Darwin)
|
||||
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
|
||||
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
|
||||
EXPORTERS := -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive
|
||||
else
|
||||
EXPORTERS := -Wl,-force_load ExporterTest/ExporterTest.a
|
||||
ifeq ($(UNAMEM),arm64)
|
||||
ifeq ($(shell brew list libpng > /dev/null 2>&1; echo $$?),0)
|
||||
LDFLAGS += -L $(shell brew --prefix)/lib
|
||||
INC += -I $(shell brew --prefix)/include
|
||||
else
|
||||
$(error Please install libpng via Homebrew)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ZAPD_SRC_DIRS := $(shell find ZAPD -type d)
|
||||
SRC_DIRS = $(ZAPD_SRC_DIRS) lib/tinyxml2
|
||||
|
||||
@@ -115,4 +131,4 @@ ZAPDUtils:
|
||||
|
||||
# Linking
|
||||
ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils
|
||||
$(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive $(LDFLAGS) $(OUTPUT_OPTION)
|
||||
$(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION)
|
||||
|
||||
+51
-3
@@ -16,6 +16,14 @@ In a Debian/Ubuntu based environment, those could be installed with the followin
|
||||
sudo apt install libpng-dev
|
||||
```
|
||||
|
||||
On a Mac, you will need to install libpng with Homebrew or MacPorts; we currently only support Homebrew. You can run
|
||||
|
||||
```bash
|
||||
brew install libpng
|
||||
```
|
||||
|
||||
to install it via Homebrew.
|
||||
|
||||
### Building
|
||||
|
||||
#### Linux / *nix
|
||||
@@ -109,11 +117,51 @@ ZAPD also accepts the following list of extra parameters:
|
||||
- Could be useful for looking at raw data or testing.
|
||||
- Can be used only in `e` or `bsf` modes.
|
||||
- `-tm MODE`: Test Mode (enables certain experimental features). To enable it, set `MODE` to `1`.
|
||||
- `-wno` / `--warn-no-offsets` : Enable warnings for nodes that dont have offsets specified. Takes priority over `-eno`/ `--error-no-offsets`.
|
||||
- `-eno` / `--error-no-offsets` : Enable errors for nodes that dont have offsets specified.
|
||||
- `-se` / `--set-exporter` : Sets which exporter to use.
|
||||
- `--gcc-compat` : Enables GCC compatible mode. Slower.
|
||||
- `--gcc-compat` : Enables GCC compatibly mode. Slower.
|
||||
- `-s` / `--static` : Mark every asset as `static`.
|
||||
- This behaviour can be overridden per asset using `Static=` in the respective XML node.
|
||||
- `-W...`: warning flags, see below
|
||||
|
||||
Additionally, you can pass the flag `--version` to see the current ZAPD version. If that flag is passed, ZAPD will ignore any other parameter passed.
|
||||
|
||||
### Warning flags
|
||||
|
||||
ZAPD contains a variety of warning types, with similar syntax to GCC or Clang's compiler warnings. Warnings can have three levels:
|
||||
|
||||
- Off (does not display anything)
|
||||
- Warn (print a warning but continue processing)
|
||||
- Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs)
|
||||
|
||||
Each warning type uses one of these by default, but can be modified with flags, similarly to GCC or Clang:
|
||||
|
||||
- `-Wfoo` enables warnings of type `foo`
|
||||
- `-Wno-foo` disables warnings of type `foo`
|
||||
- `-Werror=foo` escalates `foo` to behave like an error
|
||||
- `-Weverything` enables all warnings (they may be turned off using `-Wno-` flags afterwards)
|
||||
- `-Werror` escalates all enabled warnings to errors
|
||||
|
||||
All warning types currently implemented, with their default levels:
|
||||
|
||||
| Warning type | Default level | Description |
|
||||
| --------------------------- | ------------- | ------------------------------------------------------------------------ |
|
||||
| `-Wdeprecated` | Warn | Deprecated features |
|
||||
| `-Whardcoded-pointer` | Warn | ZAPD lacks the info to make a symbol, so must output a hardcoded pointer |
|
||||
| `-Wintersection` | Warn | Two assets intersect |
|
||||
| `-Winvalid-attribute-value` | Err | Attribute declared in XML is wrong |
|
||||
| `-Winvalid-extracted-data` | Err | Extracted data does not have correct form |
|
||||
| `-Winvalid-jpeg` | Err | JPEG file does not conform to the game's format requirements |
|
||||
| `-Winvalid-png` | Err | Issues arising when processing PNG data |
|
||||
| `-Winvalid-xml` | Err | XML has syntax errors |
|
||||
| `-Wmissing-attribute` | Warn | Required attribute missing in XML tag |
|
||||
| `-Wmissing-offsets` | Warn | Offset attribute missing in XML tag |
|
||||
| `-Wmissing-segment` | Warn | Segment not given in File tag in XML |
|
||||
| `-Wnot-implemented` | Warn | ZAPD does not currently support this feature |
|
||||
| `-Wunaccounted` | Off | Large blocks of unaccounted |
|
||||
| `-Wunknown-attribute` | Warn | Unknown attribute in XML entry tag |
|
||||
|
||||
There are also errors that do not have a type, and cannot be disabled.
|
||||
|
||||
For example, here we have invoked ZAPD in the usual way to extract using a (rather badly-written) XML, but escalating `-Wintersection` to an error:
|
||||
|
||||

|
||||
|
||||
@@ -92,20 +92,20 @@ std::string Declaration::GetNormalDeclarationStr() const
|
||||
|
||||
if (isArray)
|
||||
{
|
||||
if (arrayItemCntStr != "")
|
||||
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
|
||||
{
|
||||
output += StringHelper::Sprintf("%s %s[%s];\n", varType.c_str(), varName.c_str(),
|
||||
arrayItemCntStr.c_str());
|
||||
}
|
||||
else if (arrayItemCnt == 0)
|
||||
{
|
||||
output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str());
|
||||
}
|
||||
else
|
||||
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
|
||||
{
|
||||
output += StringHelper::Sprintf("%s %s[%i] = {\n", varType.c_str(), varName.c_str(),
|
||||
arrayItemCnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str());
|
||||
}
|
||||
|
||||
output += text + "\n";
|
||||
}
|
||||
@@ -145,16 +145,16 @@ std::string Declaration::GetExternalDeclarationStr() const
|
||||
output += "static ";
|
||||
}
|
||||
|
||||
if (arrayItemCntStr != "")
|
||||
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
|
||||
output += StringHelper::Sprintf("%s %s[%s] = ", varType.c_str(), varName.c_str(),
|
||||
arrayItemCntStr.c_str());
|
||||
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
|
||||
output +=
|
||||
StringHelper::Sprintf("%s %s[%s] = {\n#include \"%s\"\n};", varType.c_str(),
|
||||
varName.c_str(), arrayItemCntStr.c_str(), includePath.c_str());
|
||||
else if (arrayItemCnt != 0)
|
||||
output += StringHelper::Sprintf("%s %s[%i] = {\n#include \"%s\"\n};", varType.c_str(),
|
||||
varName.c_str(), arrayItemCnt, includePath.c_str());
|
||||
StringHelper::Sprintf("%s %s[%i] = ", varType.c_str(), varName.c_str(), arrayItemCnt);
|
||||
else
|
||||
output += StringHelper::Sprintf("%s %s[] = {\n#include \"%s\"\n};", varType.c_str(),
|
||||
varName.c_str(), includePath.c_str());
|
||||
output += StringHelper::Sprintf("%s %s[] = ", varType.c_str(), varName.c_str());
|
||||
|
||||
output += StringHelper::Sprintf("{\n#include \"%s\"\n};", includePath.c_str());
|
||||
|
||||
if (rightText != "")
|
||||
output += " " + rightText + "";
|
||||
@@ -178,14 +178,16 @@ std::string Declaration::GetExternStr() const
|
||||
|
||||
if (isArray)
|
||||
{
|
||||
if (arrayItemCntStr != "")
|
||||
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
|
||||
{
|
||||
return StringHelper::Sprintf("extern %s %s[%s];\n", varType.c_str(), varName.c_str(),
|
||||
arrayItemCntStr.c_str());
|
||||
}
|
||||
else if (arrayItemCnt != 0)
|
||||
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
|
||||
{
|
||||
return StringHelper::Sprintf("extern %s %s[%i];\n", varType.c_str(), varName.c_str(),
|
||||
arrayItemCnt);
|
||||
}
|
||||
else
|
||||
return StringHelper::Sprintf("extern %s %s[];\n", varType.c_str(), varName.c_str());
|
||||
}
|
||||
|
||||
@@ -38,10 +38,12 @@ public:
|
||||
std::string varType;
|
||||
std::string varName;
|
||||
std::string includePath;
|
||||
|
||||
bool isExternal = false;
|
||||
bool isArray = false;
|
||||
bool forceArrayCnt = false;
|
||||
size_t arrayItemCnt = 0;
|
||||
std::string arrayItemCntStr;
|
||||
std::string arrayItemCntStr = "";
|
||||
std::vector<segptr_t> references;
|
||||
bool isUnaccounted = false;
|
||||
bool isPlaceholder = false;
|
||||
|
||||
@@ -25,7 +25,7 @@ GameConfig::~GameConfig()
|
||||
void GameConfig::ReadTexturePool(const fs::path& texturePoolXmlPath)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.c_str());
|
||||
tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.string().c_str());
|
||||
|
||||
if (eResult != tinyxml2::XML_SUCCESS)
|
||||
{
|
||||
@@ -155,7 +155,7 @@ void GameConfig::ReadConfigFile(const fs::path& argConfigFilePath)
|
||||
{"ExternalFile", &GameConfig::ConfigFunc_ExternalFile},
|
||||
};
|
||||
|
||||
configFilePath = argConfigFilePath;
|
||||
configFilePath = argConfigFilePath.string();
|
||||
tinyxml2::XMLDocument doc;
|
||||
tinyxml2::XMLError eResult = doc.LoadFile(configFilePath.c_str());
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
|
||||
#include <Utils/File.h>
|
||||
#include <Utils/Path.h>
|
||||
#include "Utils/File.h"
|
||||
#include "Utils/Path.h"
|
||||
#include "WarningHandler.h"
|
||||
#include "tinyxml2.h"
|
||||
|
||||
Globals* Globals::Instance;
|
||||
|
||||
@@ -20,6 +20,7 @@ typedef bool (*ExporterSetFuncBool)(ZFileMode fileMode);
|
||||
typedef void (*ExporterSetFuncVoid)(int argc, char* argv[], int& i);
|
||||
typedef void (*ExporterSetFuncVoid2)(const std::string& buildMode, ZFileMode& fileMode);
|
||||
typedef void (*ExporterSetFuncVoid3)();
|
||||
typedef void (*ExporterSetResSave)(ZResource* res, BinaryWriter& writer);
|
||||
|
||||
class ExporterSet
|
||||
{
|
||||
@@ -34,6 +35,7 @@ public:
|
||||
ExporterSetFunc endFileFunc = nullptr;
|
||||
ExporterSetFuncVoid3 beginXMLFunc = nullptr;
|
||||
ExporterSetFuncVoid3 endXMLFunc = nullptr;
|
||||
ExporterSetResSave resSaveFunc = nullptr;
|
||||
};
|
||||
|
||||
class Globals
|
||||
@@ -53,9 +55,6 @@ public:
|
||||
TextureType texType;
|
||||
ZGame game;
|
||||
GameConfig cfg;
|
||||
bool warnUnaccounted = false;
|
||||
bool warnNoOffset = false;
|
||||
bool errorNoOffset = false;
|
||||
bool verboseUnaccounted = false;
|
||||
bool gccCompat = false;
|
||||
bool forceStatic = false;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "WarningHandler.h"
|
||||
|
||||
/* ImageBackend */
|
||||
|
||||
@@ -20,19 +21,28 @@ void ImageBackend::ReadPng(const char* filename)
|
||||
|
||||
FILE* fp = fopen(filename, "rb");
|
||||
if (fp == nullptr)
|
||||
throw std::runtime_error(StringHelper::Sprintf(
|
||||
"ImageBackend::ReadPng: Error.\n\t Couldn't open file '%s'.", filename));
|
||||
{
|
||||
std::string errorHeader = StringHelper::Sprintf("could not open file '%s'", filename);
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, "");
|
||||
}
|
||||
|
||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (!png)
|
||||
throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png struct.");
|
||||
if (png == nullptr)
|
||||
{
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", "");
|
||||
}
|
||||
|
||||
png_infop info = png_create_info_struct(png);
|
||||
if (!info)
|
||||
throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png info.");
|
||||
if (info == nullptr)
|
||||
{
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", "");
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png)))
|
||||
throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t setjmp(png_jmpbuf(png)).");
|
||||
{
|
||||
// TODO: better warning explanation
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", "");
|
||||
}
|
||||
|
||||
png_init_io(png, fp);
|
||||
|
||||
@@ -145,20 +155,30 @@ void ImageBackend::WritePng(const char* filename)
|
||||
assert(hasImageData);
|
||||
|
||||
FILE* fp = fopen(filename, "wb");
|
||||
if (!fp)
|
||||
throw std::runtime_error(StringHelper::Sprintf(
|
||||
"ImageBackend::WritePng: Error.\n\t Couldn't open file '%s' in write mode.", filename));
|
||||
if (fp == nullptr)
|
||||
{
|
||||
std::string errorHeader =
|
||||
StringHelper::Sprintf("could not open file '%s' in write mode", filename);
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, "");
|
||||
}
|
||||
|
||||
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (!png)
|
||||
throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png struct.");
|
||||
if (png == nullptr)
|
||||
{
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", "");
|
||||
}
|
||||
|
||||
png_infop info = png_create_info_struct(png);
|
||||
if (!info)
|
||||
throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png info.");
|
||||
if (info == nullptr)
|
||||
{
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", "");
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png)))
|
||||
throw std::runtime_error("ImageBackend::WritePng: Error.\n\t setjmp(png_jmpbuf(png)).");
|
||||
{
|
||||
// TODO: better warning description
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", "");
|
||||
}
|
||||
|
||||
png_init_io(png, fp);
|
||||
|
||||
@@ -441,7 +461,7 @@ double ImageBackend::GetBytesPerPixel() const
|
||||
return 1 * bitDepth / 8;
|
||||
|
||||
default:
|
||||
throw std::invalid_argument("ImageBackend::GetBytesPerPixel():\n\t Invalid color type.");
|
||||
HANDLE_ERROR(WarningType::InvalidPNG, "invalid color type", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+30
-26
@@ -1,8 +1,9 @@
|
||||
#include <Utils/Directory.h>
|
||||
#include <Utils/File.h>
|
||||
#include <Utils/Path.h>
|
||||
#include "Globals.h"
|
||||
#include "Overlays/ZOverlay.h"
|
||||
#include "Utils/Directory.h"
|
||||
#include "Utils/File.h"
|
||||
#include "Utils/Path.h"
|
||||
#include "WarningHandler.h"
|
||||
#include "ZAnimation.h"
|
||||
#include "ZBackground.h"
|
||||
#include "ZBlob.h"
|
||||
@@ -12,10 +13,10 @@
|
||||
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <cxxabi.h> // for __cxa_demangle
|
||||
#include <dlfcn.h> // for dladdr
|
||||
#include <execinfo.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
@@ -47,6 +48,7 @@ void ErrorHandler(int sig)
|
||||
const char* crashEasterEgg[] = {
|
||||
"\tYou've met with a terrible fate, haven't you?",
|
||||
"\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!",
|
||||
"ZAPD has fallen and cannot get up."
|
||||
};
|
||||
|
||||
srand(time(nullptr));
|
||||
@@ -97,6 +99,9 @@ int main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
Globals* g = new Globals();
|
||||
WarningHandler::Init(argc, argv);
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (!strcmp(argv[i], "--version"))
|
||||
@@ -109,12 +114,12 @@ int main(int argc, char* argv[])
|
||||
printf("Congratulations!\n");
|
||||
printf("You just found the (unimplemented and undocumented) ZAPD's help message.\n");
|
||||
printf("Feel free to implement it if you want :D\n");
|
||||
|
||||
WarningHandler::PrintHelp();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Globals* g = new Globals;
|
||||
|
||||
// Parse other "commands"
|
||||
for (int32_t i = 2; i < argc; i++)
|
||||
{
|
||||
@@ -186,26 +191,15 @@ int main(int argc, char* argv[])
|
||||
signal(SIGSEGV, ErrorHandler);
|
||||
signal(SIGABRT, ErrorHandler);
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"Warning: Tried to set error handler, but this build lacks support for one.\n");
|
||||
HANDLE_WARNING(WarningType::Always,
|
||||
"tried to set error handler, but this ZAPD build lacks support for one",
|
||||
"");
|
||||
#endif
|
||||
}
|
||||
else if (arg == "-v") // Verbose
|
||||
{
|
||||
Globals::Instance->verbosity = static_cast<VerbosityLevel>(strtol(argv[++i], NULL, 16));
|
||||
}
|
||||
else if (arg == "-wu" || arg == "--warn-unaccounted") // Warn unaccounted
|
||||
{
|
||||
Globals::Instance->warnUnaccounted = true;
|
||||
}
|
||||
else if (arg == "-wno" || arg == "--warn-no-offset")
|
||||
{
|
||||
Globals::Instance->warnNoOffset = true;
|
||||
}
|
||||
else if (arg == "-eno" || arg == "--error-no-offset")
|
||||
{
|
||||
Globals::Instance->errorNoOffset = true;
|
||||
}
|
||||
else if (arg == "-vu" || arg == "--verbose-unaccounted") // Verbose unaccounted
|
||||
{
|
||||
Globals::Instance->verboseUnaccounted = true;
|
||||
@@ -262,6 +256,11 @@ int main(int argc, char* argv[])
|
||||
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
|
||||
printf("ZAPD: Zelda Asset Processor For Decomp: %s\n", gBuildHash);
|
||||
|
||||
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
|
||||
{
|
||||
WarningHandler::PrintWarningsDebugInfo();
|
||||
}
|
||||
|
||||
// TODO: switch
|
||||
if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile)
|
||||
{
|
||||
@@ -334,7 +333,9 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
|
||||
|
||||
if (eResult != tinyxml2::XML_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "Invalid xml file: '%s'\n", xmlFilePath.c_str());
|
||||
// TODO: use XMLDocument::ErrorIDToName to get more specific error messages here
|
||||
HANDLE_ERROR(WarningType::InvalidXML,
|
||||
StringHelper::Sprintf("invalid XML file: '%s'", xmlFilePath.c_str()), "");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -342,7 +343,9 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
|
||||
|
||||
if (root == nullptr)
|
||||
{
|
||||
fprintf(stderr, "Missing Root tag in xml file: '%s'\n", xmlFilePath.c_str());
|
||||
HANDLE_WARNING(
|
||||
WarningType::InvalidXML,
|
||||
StringHelper::Sprintf("missing Root tag in xml file: '%s'", xmlFilePath.c_str()), "");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -392,10 +395,11 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error(StringHelper::Sprintf(
|
||||
"Parse: Fatal error in '%s'.\n\t A resource was found outside of "
|
||||
"a File element: '%s'\n",
|
||||
xmlFilePath.c_str(), child->Name()));
|
||||
std::string errorHeader =
|
||||
StringHelper::Sprintf("when parsing file '%s'", xmlFilePath.c_str());
|
||||
std::string errorBody = StringHelper::Sprintf(
|
||||
"Found a resource outside a File element: '%s'", child->Name());
|
||||
HANDLE_ERROR(WarningType::InvalidXML, errorHeader, errorBody);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "ZOverlay.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <cassert>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <Utils/Directory.h>
|
||||
#include <Utils/File.h>
|
||||
#include <Utils/Path.h>
|
||||
#include <Utils/StringHelper.h>
|
||||
#include "Globals.h"
|
||||
#include "Utils/Directory.h"
|
||||
#include "Utils/File.h"
|
||||
#include "Utils/Path.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "WarningHandler.h"
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
@@ -90,7 +90,7 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath)
|
||||
std::vector<elfio*> readers;
|
||||
for (size_t i = 1; i < cfgLines.size(); i++)
|
||||
{
|
||||
std::string elfPath = buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o");
|
||||
std::string elfPath = (buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o")).string();
|
||||
elfio* reader = new elfio();
|
||||
|
||||
if (!reader->load(elfPath))
|
||||
@@ -128,7 +128,9 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath)
|
||||
SectionType sectionType = GetSectionTypeFromStr(pSec->get_name());
|
||||
|
||||
if (sectionType == SectionType::ERROR)
|
||||
fprintf(stderr, "WARNING: One of the section types returned ERROR\n");
|
||||
{
|
||||
HANDLE_WARNING(WarningType::Always, "one of the section types returned ERROR", "");
|
||||
}
|
||||
|
||||
relocation_section_accessor relocs(*curReader, pSec);
|
||||
for (Elf_Xword j = 0; j < relocs.get_entries_num(); j++)
|
||||
|
||||
@@ -0,0 +1,443 @@
|
||||
/**
|
||||
* ZAPD Warning- and Error-handling system
|
||||
* =======================================
|
||||
*
|
||||
* This provides a common standard way to write ZAPD warnings/errors, which should be used for all
|
||||
* such. It will pretty-print them in a uniform way, with styles defined in the header.
|
||||
*
|
||||
* Warnings/errors should be constructed using the macros given in the header; there are now plenty
|
||||
* of examples in the codebase of how to do this. Their purposes are noted above each category in
|
||||
* the header. Each warning has a type, one of the ones in warningStringToInitMap, or
|
||||
* WarningType::Always, which is used for warnings that cannot be disabled and do not display a
|
||||
* type.
|
||||
*
|
||||
* Currently there are three levels of alert a warning can have:
|
||||
* - Off (does not display anything)
|
||||
* - Warn (print a warning but continue processing)
|
||||
* - Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs)
|
||||
*
|
||||
* Flag use:
|
||||
* - -Wfoo enables warnings of type foo
|
||||
* - -Wno-foo disables warnings of type foo
|
||||
* - -Werror=foo escalates foo to behave like an error
|
||||
* - -Weverything enables all warnings
|
||||
* - -Werror escalates all enabled warnings to errors
|
||||
*
|
||||
* Errors do not have types, and will always throw an exception; they cannot be disabled.
|
||||
*
|
||||
* Format
|
||||
* ===
|
||||
* Each printed warning/error contains the same three sections:
|
||||
* - Preamble: automatically generated; the content varies depending on category. It will print the
|
||||
* file and function that the warning is from, and information about the files being processed
|
||||
* or extracted.
|
||||
* - Header: begins with 'warning: ' or 'error:', should contain essential information about the
|
||||
* warning/error, ends with the warning type if applicable. Printed with emphasis to make it
|
||||
* stand out. Does not start with a capital letter or end with a '.'
|
||||
* - Body (optional): indented, should contain further diagnostic information useful for identifying
|
||||
* and fixing the warning/error. Can be a sentence with captialisation and '.' on the end.
|
||||
*
|
||||
* Please think of what the end user will find most useful when writing the header and body, and try
|
||||
* to keep it brief without sacrificing important information! Also remember that if the user is
|
||||
* only looking at stderr, they will normally have no other context.
|
||||
*
|
||||
* Warning vs error
|
||||
* ===
|
||||
* The principle that we have operated on so far is
|
||||
* - issue a warning if ZAPD will still be able to produce a valid, compilable C file that will
|
||||
* match
|
||||
* - if this cannot happen, use an error.
|
||||
* but at the end of the day, it is up to the programmer's discretion what it should be possible to
|
||||
* disable.
|
||||
*
|
||||
* Documentation
|
||||
* ===
|
||||
* Remember that all warnings also need to be documented in the README.md. The help is generated
|
||||
* automatically.
|
||||
*/
|
||||
#include "WarningHandler.h"
|
||||
|
||||
#include <cassert>
|
||||
#include "Globals.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WarningType type;
|
||||
WarningLevel defaultLevel;
|
||||
std::string description;
|
||||
} WarningInfoInit;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WarningLevel level;
|
||||
std::string name;
|
||||
std::string description;
|
||||
} WarningInfo;
|
||||
|
||||
/**
|
||||
* Master list of all default warning types and features
|
||||
*
|
||||
* To add a warning type, fill in a new row of this map. Think carefully about what its default
|
||||
* level should be, and try and make the description both brief and informative: it is used in the
|
||||
* help message, so again, think about what the end user needs to know.
|
||||
*/
|
||||
// clang-format off
|
||||
static const std::unordered_map<std::string, WarningInfoInit> warningStringToInitMap = {
|
||||
{"deprecated", {WarningType::Deprecated,
|
||||
#ifdef DEPRECATION_ON
|
||||
WarningLevel::Warn,
|
||||
#else
|
||||
WarningLevel::Off,
|
||||
#endif
|
||||
"Deprecated features"}},
|
||||
{"unaccounted", {WarningType::Unaccounted, WarningLevel::Off, "Large blocks of unaccounted"}},
|
||||
{"missing-offsets", {WarningType::MissingOffsets, WarningLevel::Warn, "Offset attribute missing in XML tag"}},
|
||||
{"intersection", {WarningType::Intersection, WarningLevel::Warn, "Two assets intersect"}},
|
||||
{"missing-attribute", {WarningType::MissingAttribute, WarningLevel::Warn, "Required attribute missing in XML tag"}},
|
||||
{"invalid-attribute-value", {WarningType::InvalidAttributeValue, WarningLevel::Err, "Attribute declared in XML is wrong"}},
|
||||
{"unknown-attribute", {WarningType::UnknownAttribute, WarningLevel::Warn, "Unknown attribute in XML entry tag"}},
|
||||
{"invalid-xml", {WarningType::InvalidXML, WarningLevel::Err, "XML has syntax errors"}},
|
||||
{"invalid-jpeg", {WarningType::InvalidJPEG, WarningLevel::Err, "JPEG file does not conform to the game's format requirements"}},
|
||||
{"invalid-png", {WarningType::InvalidPNG, WarningLevel::Err, "Issues arising when processing PNG data"}},
|
||||
{"invalid-extracted-data", {WarningType::InvalidExtractedData, WarningLevel::Err, "Extracted data does not have correct form"}},
|
||||
{"missing-segment", {WarningType::MissingSegment, WarningLevel::Warn, "Segment not given in File tag in XML"}},
|
||||
{"hardcoded-pointer", {WarningType::HardcodedPointer, WarningLevel::Warn, "ZAPD lacks the info to make a symbol, so must output a hardcoded pointer"}},
|
||||
{"not-implemented", {WarningType::NotImplemented, WarningLevel::Warn, "ZAPD does not currently support this feature"}},
|
||||
};
|
||||
|
||||
/**
|
||||
* Map constructed at runtime to contain the warning features as set by the user using -W flags.
|
||||
*/
|
||||
static std::unordered_map<WarningType, WarningInfo> warningTypeToInfoMap;
|
||||
|
||||
void WarningHandler::ConstructTypeToInfoMap() {
|
||||
for (auto& entry : warningStringToInitMap) {
|
||||
warningTypeToInfoMap[entry.second.type] = {entry.second.defaultLevel, entry.first, entry.second.description};
|
||||
}
|
||||
warningTypeToInfoMap[WarningType::Always] = {WarningLevel::Warn, "always", "you shouldn't be reading this"};
|
||||
assert(warningTypeToInfoMap.size() == static_cast<size_t>(WarningType::Max));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the main warning type map and reads flags passed to set each warning type's level.
|
||||
*/
|
||||
void WarningHandler::Init(int argc, char* argv[]) {
|
||||
ConstructTypeToInfoMap();
|
||||
|
||||
bool werror = false;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
// If it doesn't start with "-W" skip it.
|
||||
if (argv[i][0] != '-' || argv[i][1] != 'W' || argv[i][2] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
WarningLevel warningTypeOn = WarningLevel::Warn;
|
||||
size_t startingIndex = 2;
|
||||
|
||||
// "-Wno-"
|
||||
if (argv[i][2] == 'n' && argv[i][3] == 'o' && argv[i][4] == '-' && argv[i][5] != '\0') {
|
||||
warningTypeOn = WarningLevel::Off;
|
||||
startingIndex = 5;
|
||||
}
|
||||
|
||||
// Read starting after the "-W" or "-Wno-"
|
||||
std::string_view currentArgv = &argv[i][startingIndex];
|
||||
|
||||
if (currentArgv == "error") {
|
||||
werror = warningTypeOn != WarningLevel::Off;
|
||||
} else if (currentArgv == "everything") {
|
||||
for (auto& it: warningTypeToInfoMap) {
|
||||
if (it.second.level <= WarningLevel::Warn) {
|
||||
it.second.level = warningTypeOn;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// "-Werror=" / "-Wno-error=" parser
|
||||
if (currentArgv.rfind("error=", 0) == 0) {
|
||||
// Read starting after the "error=" part
|
||||
currentArgv = &argv[i][startingIndex + 6];
|
||||
warningTypeOn = warningTypeOn != WarningLevel::Off ? WarningLevel::Err : WarningLevel::Warn;
|
||||
}
|
||||
|
||||
auto it = warningStringToInitMap.find(std::string(currentArgv));
|
||||
if (it != warningStringToInitMap.end()) {
|
||||
warningTypeToInfoMap[it->second.type].level = warningTypeOn;
|
||||
}
|
||||
else {
|
||||
HANDLE_WARNING(WarningType::Always, StringHelper::Sprintf("unknown warning flag '%s'", argv[i]), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (werror) {
|
||||
for (auto& it: warningTypeToInfoMap) {
|
||||
if (it.second.level >= WarningLevel::Warn) {
|
||||
it.second.level = WarningLevel::Err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WarningHandler::IsWarningEnabled(WarningType warnType) {
|
||||
assert(static_cast<size_t>(warnType) >= 0 && warnType < WarningType::Max);
|
||||
|
||||
return warningTypeToInfoMap.at(warnType).level != WarningLevel::Off;
|
||||
}
|
||||
|
||||
bool WarningHandler::WasElevatedToError(WarningType warnType) {
|
||||
assert(static_cast<size_t>(warnType) >= 0 && warnType < WarningType::Max);
|
||||
|
||||
if (!IsWarningEnabled(warnType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return warningTypeToInfoMap.at(warnType).level >= WarningLevel::Err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print file/line/function info for debugging
|
||||
*/
|
||||
void WarningHandler::FunctionPreamble(const char* filename, int32_t line, const char* function) {
|
||||
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) {
|
||||
fprintf(stderr, "%s:%i: in function %s:\n", filename, line, function);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the information about the file(s) being processed (XML for extraction, png etc. for building)
|
||||
*/
|
||||
void WarningHandler::ProcessedFilePreamble() {
|
||||
if (Globals::Instance->inputPath != "") {
|
||||
fprintf(stderr, "When processing file %s: ", Globals::Instance->inputPath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print information about the binary file being extracted
|
||||
*/
|
||||
void WarningHandler::ExtractedFilePreamble(const ZFile *parent, const ZResource* res, const uint32_t offset) {
|
||||
fprintf(stderr, "in input binary file %s, ", parent->GetName().c_str());
|
||||
if (res != nullptr) {
|
||||
fprintf(stderr, "resource '%s' at ", res->GetName().c_str());
|
||||
}
|
||||
fprintf(stderr, "offset 0x%06X: \n\t", offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the rest of the message, after warning:/error. The message is filled in one character at a time, with indents added after newlines
|
||||
*/
|
||||
std::string WarningHandler::ConstructMessage(std::string message, const std::string& header, const std::string& body) {
|
||||
message.reserve(message.size() + header.size() + body.size() + 10 * (sizeof(HANG_INDT) - 1));
|
||||
message += StringHelper::Sprintf(HILITE("%s"), header.c_str());
|
||||
message += "\n";
|
||||
|
||||
if (body == "") {
|
||||
return message;
|
||||
}
|
||||
|
||||
message += HANG_INDT;
|
||||
for (const char* ptr = body.c_str(); *ptr != '\0'; ptr++) {
|
||||
message += *ptr;
|
||||
if (*ptr == '\n') {
|
||||
message += HANG_INDT;
|
||||
}
|
||||
}
|
||||
message += "\n";
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/* Error module functions */
|
||||
|
||||
void WarningHandler::PrintErrorAndThrow(const std::string& header, const std::string& body) {
|
||||
std::string errorMsg = ERR_FMT("error: ");
|
||||
throw std::runtime_error(ConstructMessage(errorMsg, header, body));
|
||||
}
|
||||
|
||||
/* Error types, to be used via the macros */
|
||||
|
||||
void WarningHandler::ErrorType(WarningType warnType, const std::string& header, const std::string& body) {
|
||||
std::string headerMsg = header;
|
||||
|
||||
for (const auto& iter: warningStringToInitMap) {
|
||||
if (iter.second.type == warnType) {
|
||||
headerMsg += StringHelper::Sprintf(" [%s]", iter.first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
PrintErrorAndThrow(headerMsg, body);
|
||||
}
|
||||
|
||||
void WarningHandler::Error_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
|
||||
FunctionPreamble(filename, line, function);
|
||||
|
||||
ErrorType(warnType, header, body);
|
||||
}
|
||||
|
||||
void WarningHandler::Error_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
|
||||
FunctionPreamble(filename, line, function);
|
||||
ProcessedFilePreamble();
|
||||
|
||||
ErrorType(warnType, header, body);
|
||||
}
|
||||
|
||||
void WarningHandler::Error_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) {
|
||||
assert(parent != nullptr);
|
||||
|
||||
FunctionPreamble(filename, line, function);
|
||||
ProcessedFilePreamble();
|
||||
ExtractedFilePreamble(parent, res, offset);
|
||||
|
||||
ErrorType(warnType, header, body);
|
||||
}
|
||||
|
||||
/* Warning module functions */
|
||||
|
||||
void WarningHandler::PrintWarningBody(const std::string& header, const std::string& body) {
|
||||
std::string errorMsg = WARN_FMT("warning: ");
|
||||
fprintf(stderr, "%s", ConstructMessage(errorMsg, header, body).c_str());
|
||||
}
|
||||
|
||||
void WarningHandler::WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header, const std::string& body) {
|
||||
std::string headerMsg = header;
|
||||
|
||||
for (const auto& iter: warningStringToInitMap) {
|
||||
if (iter.second.type == warnType) {
|
||||
headerMsg += StringHelper::Sprintf(" [-W%s]", iter.first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (WasElevatedToError(warnType)) {
|
||||
PrintErrorAndThrow(headerMsg, body);
|
||||
} else {
|
||||
PrintWarningBody(headerMsg, body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Warning types, to be used via the macros */
|
||||
|
||||
void WarningHandler::Warning_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
|
||||
if (!IsWarningEnabled(warnType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionPreamble(filename, line, function);
|
||||
|
||||
WarningTypeAndChooseEscalate(warnType, header, body);
|
||||
}
|
||||
|
||||
void WarningHandler::Warning_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
|
||||
if (!IsWarningEnabled(warnType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionPreamble(filename, line, function);
|
||||
ProcessedFilePreamble();
|
||||
|
||||
WarningTypeAndChooseEscalate(warnType, header, body);
|
||||
}
|
||||
|
||||
void WarningHandler::Warning_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) {
|
||||
assert(parent != nullptr);
|
||||
|
||||
if (!IsWarningEnabled(warnType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionPreamble(filename, line, function);
|
||||
ProcessedFilePreamble();
|
||||
ExtractedFilePreamble(parent, res, offset);
|
||||
|
||||
WarningTypeAndChooseEscalate(warnType, header, body);
|
||||
}
|
||||
|
||||
|
||||
/* Help-related functions */
|
||||
|
||||
#include <set>
|
||||
|
||||
/**
|
||||
* Print each warning name, default status, and description using the init map
|
||||
*/
|
||||
void WarningHandler::PrintHelp() {
|
||||
std::set<std::string> sortedKeys;
|
||||
WarningInfoInit warningInfo;
|
||||
uint32_t columnWidth = 25;
|
||||
std::string dt;
|
||||
|
||||
// Sort keys through the magic of `set`, to print in alphabetical order
|
||||
for (auto& it : warningStringToInitMap) {
|
||||
sortedKeys.insert(it.first);
|
||||
}
|
||||
|
||||
printf("\nWarning types ( * means enabled by default)\n");
|
||||
for (auto& key : sortedKeys) {
|
||||
warningInfo = warningStringToInitMap.at(key);
|
||||
if (warningInfo.defaultLevel <= WarningLevel::Warn) {
|
||||
dt = "-W";
|
||||
dt += key;
|
||||
if (warningInfo.defaultLevel == WarningLevel::Warn) {
|
||||
dt += " *";
|
||||
}
|
||||
printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str());
|
||||
|
||||
if (dt.length() + 2 > columnWidth) {
|
||||
printf("\n" HELP_DT_INDT "%-*s", columnWidth, "");
|
||||
}
|
||||
printf("%s\n", warningInfo.description.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nDefault errors\n");
|
||||
for (auto& key : sortedKeys) {
|
||||
if (warningInfo.defaultLevel > WarningLevel::Warn) {
|
||||
dt = "-W";
|
||||
dt += key;
|
||||
printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str());
|
||||
|
||||
if (dt.length() + 2 > columnWidth) {
|
||||
printf("\n" HELP_DT_INDT "%*s", columnWidth, "");
|
||||
}
|
||||
printf("%s\n", warningInfo.description.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("Other\n" HELP_DT_INDT "-Weverything will enable all existing warnings.\n" HELP_DT_INDT "-Werror will promote all warnings to errors.\n");
|
||||
|
||||
printf("\n");
|
||||
printf("Warnings can be disabled using -Wno-... instead of -W...; -Weverything will override any -Wno-... flags passed before it.\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Print which warnings are currently enabled
|
||||
*/
|
||||
void WarningHandler::PrintWarningsDebugInfo()
|
||||
{
|
||||
std::string dt;
|
||||
|
||||
printf("Warnings status:\n");
|
||||
for (auto& it: warningTypeToInfoMap) {
|
||||
dt = it.second.name;
|
||||
dt += ": ";
|
||||
|
||||
printf(HELP_DT_INDT "%-25s", dt.c_str());
|
||||
switch (it.second.level)
|
||||
{
|
||||
case WarningLevel::Off:
|
||||
printf(VT_FGCOL(LIGHTGRAY) "Off" VT_RST);
|
||||
break;
|
||||
case WarningLevel::Warn:
|
||||
printf(VT_FGCOL(YELLOW) "Warn" VT_RST);
|
||||
break;
|
||||
case WarningLevel::Err:
|
||||
printf(VT_FGCOL(RED) "Err" VT_RST);
|
||||
break;
|
||||
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Utils/vt.h"
|
||||
#include "ZFile.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __PRETTY_FUNCTION__ __FUNCSIG__
|
||||
#elif not defined(__GNUC__)
|
||||
#define __PRETTY_FUNCTION__ __func__
|
||||
#endif
|
||||
|
||||
// =======================================
|
||||
/* Formatting macros */
|
||||
|
||||
// TODO: move this somewhere else so it can be used by other help
|
||||
#define HELP_DT_INDT " "
|
||||
|
||||
/* Macros for formatting warnings/errors */
|
||||
#define VT_HILITE VT_BOLD_FGCOL(WHITE)
|
||||
#define VT_WARN VT_BOLD_FGCOL(PURPLE)
|
||||
#define VT_ERR VT_BOLD_FGCOL(RED)
|
||||
|
||||
#define HILITE(string) (VT_HILITE string VT_RST)
|
||||
#define WARN_FMT(string) (VT_WARN string VT_RST)
|
||||
#define ERR_FMT(string) (VT_ERR string VT_RST)
|
||||
|
||||
// Maybe make WARN_LF instead
|
||||
// Currently 8 spaces
|
||||
#define WARN_INDT " "
|
||||
// Currently 16 spaces
|
||||
#define HANG_INDT " "
|
||||
|
||||
// =======================================
|
||||
/* Warning and error macros */
|
||||
// TODO: better names
|
||||
|
||||
// General-purpose, plain style (only prints function,file,line in the preamble)
|
||||
#define HANDLE_ERROR(warningType, header, body) \
|
||||
WarningHandler::Error_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, body)
|
||||
#define HANDLE_WARNING(warningType, header, body) \
|
||||
WarningHandler::Warning_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
|
||||
body)
|
||||
|
||||
// For processing XMLs or textures/blobs (preamble contains function,file,line; processed file)
|
||||
#define HANDLE_ERROR_PROCESS(warningType, header, body) \
|
||||
WarningHandler::Error_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
|
||||
body)
|
||||
#define HANDLE_WARNING_PROCESS(warningType, header, body) \
|
||||
WarningHandler::Warning_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
|
||||
body)
|
||||
|
||||
// For ZResource-related stuff (preamble contains function,file,line; processed file; extracted file
|
||||
// and offset)
|
||||
#define HANDLE_ERROR_RESOURCE(warningType, parent, resource, offset, header, body) \
|
||||
WarningHandler::Error_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \
|
||||
resource, offset, header, body)
|
||||
#define HANDLE_WARNING_RESOURCE(warningType, parent, resource, offset, header, body) \
|
||||
WarningHandler::Warning_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \
|
||||
resource, offset, header, body)
|
||||
|
||||
// =======================================
|
||||
|
||||
enum class WarningType
|
||||
{
|
||||
Always, // Warnings of this type are always printed, cannot be disabled.
|
||||
Deprecated,
|
||||
Unaccounted,
|
||||
MissingOffsets,
|
||||
Intersection,
|
||||
MissingAttribute,
|
||||
InvalidAttributeValue,
|
||||
UnknownAttribute,
|
||||
InvalidXML,
|
||||
InvalidJPEG,
|
||||
InvalidPNG,
|
||||
InvalidExtractedData,
|
||||
MissingSegment,
|
||||
HardcodedPointer,
|
||||
NotImplemented,
|
||||
Max,
|
||||
};
|
||||
|
||||
enum class WarningLevel
|
||||
{
|
||||
Off,
|
||||
Warn,
|
||||
Err,
|
||||
};
|
||||
|
||||
class WarningHandler
|
||||
{
|
||||
public:
|
||||
static void ConstructTypeToInfoMap();
|
||||
|
||||
static void Init(int argc, char* argv[]);
|
||||
|
||||
static bool IsWarningEnabled(WarningType warnType);
|
||||
static bool WasElevatedToError(WarningType warnType);
|
||||
|
||||
static void FunctionPreamble(const char* filename, int32_t line, const char* function);
|
||||
static void ProcessedFilePreamble();
|
||||
static void ExtractedFilePreamble(const ZFile* parent, const ZResource* res,
|
||||
const uint32_t offset);
|
||||
static std::string ConstructMessage(std::string message, const std::string& header,
|
||||
const std::string& body);
|
||||
|
||||
[[noreturn]] static void PrintErrorAndThrow(const std::string& header, const std::string& body);
|
||||
static void PrintWarningBody(const std::string& header, const std::string& body);
|
||||
|
||||
[[noreturn]] static void ErrorType(WarningType warnType, const std::string& header,
|
||||
const std::string& body);
|
||||
[[noreturn]] static void Error_Plain(const char* filename, int32_t line, const char* function,
|
||||
WarningType warnType, const std::string& header,
|
||||
const std::string& body);
|
||||
[[noreturn]] static void Error_Process(const char* filename, int32_t line, const char* function,
|
||||
WarningType warnType, const std::string& header,
|
||||
const std::string& body);
|
||||
[[noreturn]] static void Error_Resource(const char* filename, int32_t line,
|
||||
const char* function, WarningType warnType,
|
||||
const ZFile* parent, const ZResource* res,
|
||||
const uint32_t offset, const std::string& header,
|
||||
const std::string& body);
|
||||
|
||||
static void WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header,
|
||||
const std::string& body);
|
||||
|
||||
static void Warning_Plain(const char* filename, int32_t line, const char* function,
|
||||
WarningType warnType, const std::string& header,
|
||||
const std::string& body);
|
||||
static void Warning_Process(const char* filename, int32_t line, const char* function,
|
||||
WarningType warnType, const std::string& header,
|
||||
const std::string& body);
|
||||
static void Warning_Resource(const char* filename, int32_t line, const char* function,
|
||||
WarningType warnType, const ZFile* parent, const ZResource* res,
|
||||
const uint32_t offset, const std::string& header,
|
||||
const std::string& body);
|
||||
|
||||
static void PrintHelp();
|
||||
static void PrintWarningsDebugInfo();
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user