(Discussion/Proposals) Consistency regarding annotations of header-implemented functions (#316)

* Open discussion

* Move annotations of header-implemented functions back to `.h` files

* Adjust `README.md`

* Relocate annotation

* linter

* Comment markers in headers only, rename script, update github actions

* type hint compat

* Rename github action, better argparse for linter

* Type hints, working test for byname ignore

* Move annotation

* CI rename and enable warnfail, enforce mode always on

* Two step linting

* or one step

* continue on error

* two jobs instead

* Fixes

---------

Co-authored-by: disinvite <disinvite@users.noreply.github.com>
This commit is contained in:
Christian Semmler 2023-12-12 14:27:17 -05:00 committed by GitHub
parent 4dd0d60dec
commit 3b155bfe38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
73 changed files with 838 additions and 650 deletions

32
.github/workflows/analyze.yml vendored Normal file
View file

@ -0,0 +1,32 @@
name: Analyze
on: [push, pull_request]
jobs:
decomplint-isle:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install python libraries
run: |
pip install -r tools/requirements.txt
- name: Run decomplint.py
run: |
python3 tools/decomplint/decomplint.py ISLE --module ISLE --warnfail
decomplint-lego1:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install python libraries
run: |
pip install -r tools/requirements.txt
- name: Run decomplint.py
run: |
python3 tools/decomplint/decomplint.py LEGO1 --module LEGO1 --warnfail

View file

@ -1,19 +0,0 @@
name: Check order
on: [push, pull_request]
jobs:
checkorder:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install python libraries
run: |
pip install -r tools/requirements.txt
- name: Run checkorder.py
run: |
python3 tools/checkorder/checkorder.py --verbose --enforce ISLE
python3 tools/checkorder/checkorder.py --verbose --enforce LEGO1

View file

@ -282,9 +282,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
return msg.wParam;
}
// FUNCTION: ISLE 0x401c40
// MxDSObject::SetAtomId
// FUNCTION: ISLE 0x401ca0
BOOL FindExistingInstance(void)
{

View file

@ -25,10 +25,6 @@ class LegoActionControlPresenter : public MxMediaPresenter {
return !strcmp(name, LegoActionControlPresenter::ClassName()) || MxMediaPresenter::IsA(name);
}
// TODO: Find proper compilation unit to put this
// SYNTHETIC: LEGO1 0x1000d1d0
// LegoActionControlPresenter::`scalar deleting destructor'
virtual void ReadyTickle() override; // vtable+0x18
virtual void RepeatingTickle() override; // vtable+0x24
virtual void ParseExtra() override; // vtable+0x30
@ -41,4 +37,7 @@ class LegoActionControlPresenter : public MxMediaPresenter {
undefined4 m_unk0x64; // 0x64
};
// SYNTHETIC: LEGO1 0x1000d1d0
// LegoActionControlPresenter::`scalar deleting destructor'
#endif // LEGOACTIONCONTROLPRESENTER_H

View file

@ -7,9 +7,6 @@
DECOMP_SIZE_ASSERT(LegoEntity, 0x68)
// FUNCTION: LEGO1 0x10001090
// LegoEntity::SetWorldSpeed
// FUNCTION: LEGO1 0x1000c290
LegoEntity::~LegoEntity()
{

View file

@ -38,6 +38,7 @@ class LegoEntity : public MxEntity {
virtual void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2); // vtable+0x24
virtual void SetWorldTransform(Vector3Impl& p_loc, Vector3Impl& p_dir, Vector3Impl& p_up); // vtable+0x28
virtual void ResetWorldTransform(MxBool p_inVehicle); // vtable+0x2c
// FUNCTION: LEGO1 0x10001090
virtual void SetWorldSpeed(MxFloat p_worldSpeed) { m_worldSpeed = p_worldSpeed; } // vtable+0x30
virtual void VTable0x34(); // vtable+0x34
virtual void VTable0x38(); // vtable+0x38

View file

@ -56,27 +56,6 @@ MxResult LegoInputManager::Create(HWND p_hwnd)
return SUCCESS;
}
// TEMPLATE: LEGO1 0x1005bb80
// MxCollection<LegoEventNotificationParam>::Compare
// TEMPLATE: LEGO1 0x1005bc30
// MxCollection<LegoEventNotificationParam>::Destroy
// TEMPLATE: LEGO1 0x1005bc80
// MxList<LegoEventNotificationParam>::~MxList<LegoEventNotificationParam>
// SYNTHETIC: LEGO1 0x1005bd50
// MxCollection<LegoEventNotificationParam>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1005bdc0
// MxList<LegoEventNotificationParam>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1005beb0
// LegoEventQueue::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1005bf70
// MxQueue<LegoEventNotificationParam>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x1005bfe0
void LegoInputManager::Destroy()
{
@ -292,6 +271,3 @@ void LegoInputManager::KillTimer()
::KillTimer(omni->GetWindowHandle(), m_timer);
}
}
// TEMPLATE: LEGO1 0x1005d010
// MxListEntry<LegoEventNotificationParam>::GetValue

View file

@ -90,4 +90,28 @@ class LegoInputManager : public MxPresenter {
MxBool m_unk0x336;
};
// TEMPLATE: LEGO1 0x1005bb80
// MxCollection<LegoEventNotificationParam>::Compare
// TEMPLATE: LEGO1 0x1005bc30
// MxCollection<LegoEventNotificationParam>::Destroy
// TEMPLATE: LEGO1 0x1005bc80
// MxList<LegoEventNotificationParam>::~MxList<LegoEventNotificationParam>
// SYNTHETIC: LEGO1 0x1005bd50
// MxCollection<LegoEventNotificationParam>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1005bdc0
// MxList<LegoEventNotificationParam>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1005beb0
// LegoEventQueue::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1005bf70
// MxQueue<LegoEventNotificationParam>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1005d010
// MxListEntry<LegoEventNotificationParam>::GetValue
#endif // LEGOINPUTMANAGER_H

View file

@ -11,32 +11,8 @@ MxS8 LegoPathControllerList::Compare(LegoPathController* p_a, LegoPathController
return p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
}
// TEMPLATE: LEGO1 0x1001d230
// MxCollection<LegoPathController *>::Compare
// TEMPLATE: LEGO1 0x1001d240
// MxList<LegoPathController *>::MxList<LegoPathController *>
// TEMPLATE: LEGO1 0x1001d2d0
// MxCollection<LegoPathController *>::~MxCollection<LegoPathController *>
// TEMPLATE: LEGO1 0x1001d320
// MxCollection<LegoPathController *>::Destroy
// TEMPLATE: LEGO1 0x1001d330
// MxList<LegoPathController *>::~MxList<LegoPathController *>
// FUNCTION: LEGO1 0x1001d3c0
void LegoPathControllerList::Destroy(LegoPathController* p_controller)
{
delete p_controller;
}
// SYNTHETIC: LEGO1 0x1001d490
// MxCollection<LegoPathController *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001d500
// MxList<LegoPathController *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001d5b0
// MxPtrList<LegoPathController>::`scalar deleting destructor'

View file

@ -23,4 +23,28 @@ class LegoPathControllerList : public MxPtrList<LegoPathController> {
// VTABLE: LEGO1 0x100d6398
// class MxList<LegoPathController *>
// TEMPLATE: LEGO1 0x1001d230
// MxCollection<LegoPathController *>::Compare
// TEMPLATE: LEGO1 0x1001d240
// MxList<LegoPathController *>::MxList<LegoPathController *>
// TEMPLATE: LEGO1 0x1001d2d0
// MxCollection<LegoPathController *>::~MxCollection<LegoPathController *>
// TEMPLATE: LEGO1 0x1001d320
// MxCollection<LegoPathController *>::Destroy
// TEMPLATE: LEGO1 0x1001d330
// MxList<LegoPathController *>::~MxList<LegoPathController *>
// SYNTHETIC: LEGO1 0x1001d490
// MxCollection<LegoPathController *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001d500
// MxList<LegoPathController *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001d5b0
// MxPtrList<LegoPathController>::`scalar deleting destructor'
#endif // LEGOPATHCONTROLLERLIST_H

View file

@ -67,24 +67,6 @@ MxResult LegoWorld::SetAsCurrentWorld(MxDSObject& p_dsObject)
return SUCCESS;
}
// SYNTHETIC: LEGO1 0x1001eed0
// MxPresenterListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1001ef40
// MxPtrListCursor<MxPresenter>::~MxPtrListCursor<MxPresenter>
// SYNTHETIC: LEGO1 0x1001ef90
// MxListCursor<MxPresenter *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001f000
// MxPtrListCursor<MxPresenter>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1001f070
// MxListCursor<MxPresenter *>::~MxListCursor<MxPresenter *>
// FUNCTION: LEGO1 0x1001f0c0
// MxPresenterListCursor::~MxPresenterListCursor
// FUNCTION: LEGO1 0x1001f5e0
MxLong LegoWorld::Notify(MxParam& p_param)
{

View file

@ -55,4 +55,22 @@ void FUN_10015820(MxU32 p_unk1, MxU32 p_unk2);
void FUN_10015910(MxU32 p_unk1);
void SetIsWorldActive(MxBool p_isWorldActive);
// SYNTHETIC: LEGO1 0x1001eed0
// MxPresenterListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1001ef40
// MxPtrListCursor<MxPresenter>::~MxPtrListCursor<MxPresenter>
// SYNTHETIC: LEGO1 0x1001ef90
// MxListCursor<MxPresenter *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001f000
// MxPtrListCursor<MxPresenter>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1001f070
// MxListCursor<MxPresenter *>::~MxListCursor<MxPresenter *>
// FUNCTION: LEGO1 0x1001f0c0
// MxPresenterListCursor::~MxPresenterListCursor
#endif // LEGOWORLD_H

View file

@ -8,29 +8,8 @@ MxS8 LegoWorldList::Compare(LegoWorld* p_a, LegoWorld* p_b)
return p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
}
// TEMPLATE: LEGO1 0x100598f0
// MxCollection<LegoWorld *>::Compare
// TEMPLATE: LEGO1 0x10059900
// MxCollection<LegoWorld *>::~MxCollection<LegoWorld *>
// TEMPLATE: LEGO1 0x10059950
// MxCollection<LegoWorld *>::Destroy
// TEMPLATE: LEGO1 0x10059960
// MxList<LegoWorld *>::~MxList<LegoWorld *>
// FUNCTION: LEGO1 0x100599f0
void LegoWorldList::Destroy(LegoWorld* p_world)
{
delete p_world;
}
// SYNTHETIC: LEGO1 0x10059ac0
// MxCollection<LegoWorld *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x10059b30
// MxList<LegoWorld *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x10059be0
// MxPtrList<LegoWorld>::`scalar deleting destructor'

View file

@ -24,4 +24,25 @@ class LegoWorldList : public MxPtrList<LegoWorld> {
static void Destroy(LegoWorld*);
};
// TEMPLATE: LEGO1 0x100598f0
// MxCollection<LegoWorld *>::Compare
// TEMPLATE: LEGO1 0x10059900
// MxCollection<LegoWorld *>::~MxCollection<LegoWorld *>
// TEMPLATE: LEGO1 0x10059950
// MxCollection<LegoWorld *>::Destroy
// TEMPLATE: LEGO1 0x10059960
// MxList<LegoWorld *>::~MxList<LegoWorld *>
// SYNTHETIC: LEGO1 0x10059ac0
// MxCollection<LegoWorld *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x10059b30
// MxList<LegoWorld *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x10059be0
// MxPtrList<LegoWorld>::`scalar deleting destructor'
#endif // LEGOWORLDLIST_H

View file

@ -14,6 +14,3 @@ MxNotificationParam* MxEndActionNotificationParam::Clone()
{
return new MxEndActionNotificationParam(c_notificationEndAction, this->m_sender, this->m_action, this->m_realloc);
}
// SYNTHETIC: LEGO1 0x100513a0
// MxEndActionNotificationParam::`scalar deleting destructor'

View file

@ -67,4 +67,7 @@ class MxEndActionNotificationParam : public MxActionNotificationParam {
virtual MxNotificationParam* Clone() override; // vtable+0x4
};
// SYNTHETIC: LEGO1 0x100513a0
// MxEndActionNotificationParam::`scalar deleting destructor'
#endif

View file

@ -17,33 +17,12 @@ MxBool MxCompositePresenter::VTable0x64(undefined4 p_unknown)
return TRUE;
}
// TEMPLATE: LEGO1 0x1004ae90
// list<MxPresenter *,allocator<MxPresenter *> >::_Buynode
// FUNCTION: LEGO1 0x100b60b0
MxCompositePresenter::MxCompositePresenter()
{
NotificationManager()->Register(this);
}
// TEMPLATE: LEGO1 0x100b61a0
// list<MxPresenter *,allocator<MxPresenter *> >::~list<MxPresenter *,allocator<MxPresenter *> >
// FUNCTION: LEGO1 0x100b6210
// MxCompositePresenter::ClassName
// FUNCTION: LEGO1 0x100b6220
// MxCompositePresenter::IsA
// SYNTHETIC: LEGO1 0x100b62d0
// MxCompositePresenter::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100b62f0
// MxCompositePresenterList::~MxCompositePresenterList
// TEMPLATE: LEGO1 0x100b6340
// List<MxPresenter *>::~List<MxPresenter *>
// FUNCTION: LEGO1 0x100b6390
MxCompositePresenter::~MxCompositePresenter()
{

View file

@ -15,12 +15,14 @@ class MxCompositePresenter : public MxPresenter {
virtual MxLong Notify(MxParam& p) override; // vtable+0x04
// FUNCTION: LEGO1 0x100b6210
inline virtual const char* ClassName() const override // vtable+0x0c
{
// GLOBAL: LEGO1 0x100f0774
return "MxCompositePresenter";
}
// FUNCTION: LEGO1 0x100b6220
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxCompositePresenter::ClassName()) || MxPresenter::IsA(name);
@ -40,4 +42,19 @@ class MxCompositePresenter : public MxPresenter {
MxCompositePresenterList m_list; // 0x40
};
// TEMPLATE: LEGO1 0x1004ae90
// list<MxPresenter *,allocator<MxPresenter *> >::_Buynode
// TEMPLATE: LEGO1 0x100b61a0
// list<MxPresenter *,allocator<MxPresenter *> >::~list<MxPresenter *,allocator<MxPresenter *> >
// SYNTHETIC: LEGO1 0x100b62d0
// MxCompositePresenter::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100b62f0
// MxCompositePresenterList::~MxCompositePresenterList
// TEMPLATE: LEGO1 0x100b6340
// List<MxPresenter *>::~List<MxPresenter *>
#endif // MXCOMPOSITEPRESENTER_H

View file

@ -8,13 +8,6 @@
class MxParam;
// TODO: Find proper compilation unit to put these
// FUNCTION: LEGO1 0x100140d0
// MxCore::IsA
// FUNCTION: LEGO1 0x100144c0
// MxCore::ClassName
// VTABLE: LEGO1 0x100dc0f8
// SIZE 0x8
class MxCore {
@ -24,12 +17,14 @@ class MxCore {
__declspec(dllexport) virtual MxLong Notify(MxParam& p); // vtable+04
virtual MxResult Tickle(); // vtable+08
// FUNCTION: LEGO1 0x100144c0
inline virtual const char* ClassName() const // vtable+0c
{
// GLOBAL: LEGO1 0x100f007c
return "MxCore";
}
// FUNCTION: LEGO1 0x100140d0
inline virtual MxBool IsA(const char* name) const // vtable+10
{
return !strcmp(name, MxCore::ClassName());

View file

@ -13,18 +13,6 @@ MxDiskStreamController::MxDiskStreamController()
m_unk8c = 0;
}
// TEMPLATE: LEGO1 0x100c7330
// list<MxDSAction *,allocator<MxDSAction *> >::_Buynode
// TEMPLATE: LEGO1 0x100c7420
// list<MxDSBuffer *,allocator<MxDSBuffer *> >::~list<MxDSBuffer *,allocator<MxDSBuffer *> >
// TEMPLATE: LEGO1 0x100c7490
// list<MxDSBuffer *,allocator<MxDSBuffer *> >::_Buynode
// TEMPLATE: LEGO1 0x100c74e0
// List<MxDSBuffer *>::~List<MxDSBuffer *>
// STUB: LEGO1 0x100c7530
MxDiskStreamController::~MxDiskStreamController()
{

View file

@ -50,4 +50,16 @@ class MxDiskStreamController : public MxStreamController {
undefined m_unkc4; // 0xc4
};
// TEMPLATE: LEGO1 0x100c7330
// list<MxDSAction *,allocator<MxDSAction *> >::_Buynode
// TEMPLATE: LEGO1 0x100c7420
// list<MxDSBuffer *,allocator<MxDSBuffer *> >::~list<MxDSBuffer *,allocator<MxDSBuffer *> >
// TEMPLATE: LEGO1 0x100c7490
// list<MxDSBuffer *,allocator<MxDSBuffer *> >::_Buynode
// TEMPLATE: LEGO1 0x100c74e0
// List<MxDSBuffer *>::~List<MxDSBuffer *>
#endif // MXDISKSTREAMCONTROLLER_H

View file

@ -17,18 +17,3 @@ void MxDSActionList::Destroy(MxDSAction* p_action)
if (p_action)
delete p_action;
}
// TEMPLATE: LEGO1 0x100c9cc0
// MxCollection<MxDSAction *>::Compare
// TEMPLATE: LEGO1 0x100c9d20
// MxCollection<MxDSAction *>::Destroy
// TEMPLATE: LEGO1 0x100c9d30
// MxList<MxDSAction *>::~MxList<MxDSAction *>
// SYNTHETIC: LEGO1 0x100c9e30
// MxCollection<MxDSAction *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c9ea0
// MxList<MxDSAction *>::`scalar deleting destructor'

View file

@ -35,4 +35,19 @@ class MxDSActionListCursor : public MxListCursor<MxDSAction*> {
MxDSActionListCursor(MxDSActionList* p_list) : MxListCursor<MxDSAction*>(p_list){};
};
// TEMPLATE: LEGO1 0x100c9cc0
// MxCollection<MxDSAction *>::Compare
// TEMPLATE: LEGO1 0x100c9d20
// MxCollection<MxDSAction *>::Destroy
// TEMPLATE: LEGO1 0x100c9d30
// MxList<MxDSAction *>::~MxList<MxDSAction *>
// SYNTHETIC: LEGO1 0x100c9e30
// MxCollection<MxDSAction *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c9ea0
// MxList<MxDSAction *>::`scalar deleting destructor'
#endif // MXDSACTIONLIST_H

View file

@ -2,19 +2,6 @@
DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c)
// TODO: Should be moved later
// SYNTHETIC: LEGO1 0x1004ad10
// MxDSActionListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1004ad80
// MxListCursor<MxDSAction *>::~MxListCursor<MxDSAction *>
// SYNTHETIC: LEGO1 0x1004add0
// MxListCursor<MxDSAction *>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x1004ae40
// MxDSActionListCursor::~MxDSActionListCursor
// FUNCTION: LEGO1 0x100c9b90
MxDSMultiAction::MxDSMultiAction()
{

View file

@ -43,4 +43,16 @@ class MxDSMultiAction : public MxDSAction {
MxDSActionList* m_actions; // 0x98
};
// SYNTHETIC: LEGO1 0x1004ad10
// MxDSActionListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1004ad80
// MxListCursor<MxDSAction *>::~MxListCursor<MxDSAction *>
// SYNTHETIC: LEGO1 0x1004add0
// MxListCursor<MxDSAction *>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x1004ae40
// MxDSActionListCursor::~MxDSActionListCursor
#endif // MXDSMULTIACTION_H

View file

@ -6,10 +6,6 @@
#include "mxcore.h"
#include "mxdstypes.h"
// TODO: Find proper compilation unit to put this
// FUNCTION: LEGO1 0x10005530
// MxDSObject::SetAtomId
// VTABLE: LEGO1 0x100dc868
// SIZE 0x2c
class MxDSObject : public MxCore {
@ -61,4 +57,10 @@ class MxDSObject : public MxCore {
MxDSObject* DeserializeDSObjectDispatch(char**, MxS16);
// FUNCTION: ISLE 0x401c40
// MxDSObject::SetAtomId
// FUNCTION: LEGO1 0x10005530
// MxDSObject::SetAtomId
#endif // MXDSOBJECT_H

View file

@ -33,18 +33,6 @@ void MxDSSelectAction::CopyFrom(MxDSSelectAction& p_dsSelectAction)
this->m_unk0xac->Append(string);
}
// SYNTHETIC: LEGO1 0x100cbbd0
// MxStringListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100cbc40
// MxListCursor<MxString>::~MxListCursor<MxString>
// SYNTHETIC: LEGO1 0x100cbc90
// MxListCursor<MxString>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100cbd00
// MxStringListCursor::~MxStringListCursor
// FUNCTION: LEGO1 0x100cbd50
MxDSSelectAction& MxDSSelectAction::operator=(MxDSSelectAction& p_dsSelectAction)
{
@ -142,6 +130,3 @@ void MxDSSelectAction::Deserialize(char** p_source, MxS16 p_unk24)
*p_source += extraFlag;
}
// TEMPLATE: LEGO1 0x100cc450
// MxListEntry<MxString>::GetValue

View file

@ -37,4 +37,19 @@ class MxDSSelectAction : public MxDSParallelAction {
MxStringList* m_unk0xac;
};
// SYNTHETIC: LEGO1 0x100cbbd0
// MxStringListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100cbc40
// MxListCursor<MxString>::~MxListCursor<MxString>
// SYNTHETIC: LEGO1 0x100cbc90
// MxListCursor<MxString>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100cbd00
// MxStringListCursor::~MxStringListCursor
// TEMPLATE: LEGO1 0x100cc450
// MxListEntry<MxString>::GetValue
#endif // MXDSSELECTACTION_H

View file

@ -7,15 +7,6 @@
DECOMP_SIZE_ASSERT(MxLoopingMIDIPresenter, 0x58);
// FUNCTION: LEGO1 0x100b1830
// MxLoopingMIDIPresenter::ClassName
// FUNCTION: LEGO1 0x100b1840
// MxLoopingMIDIPresenter::IsA
// SYNTHETIC: LEGO1 0x100b19c0
// MxLoopingMIDIPresenter::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100c2a80
void MxLoopingMIDIPresenter::StreamingTickle()
{

View file

@ -7,12 +7,14 @@
// SIZE 0x58
class MxLoopingMIDIPresenter : public MxMIDIPresenter {
public:
// FUNCTION: LEGO1 0x100b1830
inline virtual const char* ClassName() const override // vtable+0xc
{
// GLOBAL: LEGO1 0x10101de0
return "MxLoopingMIDIPresenter";
}
// FUNCTION: LEGO1 0x100b1840
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxLoopingMIDIPresenter::ClassName()) || MxMIDIPresenter::IsA(name);
@ -23,4 +25,7 @@ class MxLoopingMIDIPresenter : public MxMIDIPresenter {
virtual MxResult PutData() override; // vtable+0x4c
};
// SYNTHETIC: LEGO1 0x100b19c0
// MxLoopingMIDIPresenter::`scalar deleting destructor'
#endif // MXLOOPINGMIDIPRESENTER_H

View file

@ -21,19 +21,6 @@ void MxMediaPresenter::Destroy()
Destroy(FALSE);
}
// TODO: These probably belong in another class
// SYNTHETIC: LEGO1 0x100b46e0
// MxStreamChunkListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100b4750
// MxListCursor<MxStreamChunk *>::~MxListCursor<MxStreamChunk *>
// SYNTHETIC: LEGO1 0x100b47a0
// MxListCursor<MxStreamChunk *>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100b4810
// MxStreamChunkListCursor::~MxStreamChunkListCursor
// FUNCTION: LEGO1 0x100b54e0
void MxMediaPresenter::Init()
{

View file

@ -49,4 +49,16 @@ class MxMediaPresenter : public MxPresenter {
MxStreamChunk* NextChunk();
};
// SYNTHETIC: LEGO1 0x100b46e0
// MxStreamChunkListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100b4750
// MxListCursor<MxStreamChunk *>::~MxListCursor<MxStreamChunk *>
// SYNTHETIC: LEGO1 0x100b47a0
// MxListCursor<MxStreamChunk *>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100b4810
// MxStreamChunkListCursor::~MxStreamChunkListCursor
#endif // MXMEDIAPRESENTER_H

View file

@ -10,27 +10,3 @@ MxS8 MxPresenterList::Compare(MxPresenter* p_a, MxPresenter* p_b)
{
return p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
}
// TEMPLATE: LEGO1 0x1001cd20
// MxCollection<MxPresenter *>::Compare
// TEMPLATE: LEGO1 0x1001cd30
// MxCollection<MxPresenter *>::Destroy
// TEMPLATE: LEGO1 0x1001cd40
// MxList<MxPresenter *>::MxList<MxPresenter *>
// TEMPLATE: LEGO1 0x1001cdd0
// MxCollection<MxPresenter *>::~MxCollection<MxPresenter *>
// TEMPLATE: LEGO1 0x1001ce20
// MxList<MxPresenter *>::~MxList<MxPresenter *>
// SYNTHETIC: LEGO1 0x1001cf70
// MxCollection<MxPresenter *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001cfe0
// MxList<MxPresenter *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001d090
// MxPtrList<MxPresenter>::`scalar deleting destructor'

View file

@ -33,4 +33,28 @@ class MxPresenterListCursor : public MxPtrListCursor<MxPresenter> {
// VTABLE: LEGO1 0x100d6368
// class MxList<MxPresenter *>
// TEMPLATE: LEGO1 0x1001cd20
// MxCollection<MxPresenter *>::Compare
// TEMPLATE: LEGO1 0x1001cd30
// MxCollection<MxPresenter *>::Destroy
// TEMPLATE: LEGO1 0x1001cd40
// MxList<MxPresenter *>::MxList<MxPresenter *>
// TEMPLATE: LEGO1 0x1001cdd0
// MxCollection<MxPresenter *>::~MxCollection<MxPresenter *>
// TEMPLATE: LEGO1 0x1001ce20
// MxList<MxPresenter *>::~MxList<MxPresenter *>
// SYNTHETIC: LEGO1 0x1001cf70
// MxCollection<MxPresenter *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001cfe0
// MxList<MxPresenter *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001d090
// MxPtrList<MxPresenter>::`scalar deleting destructor'
#endif // MXPRESENTERLIST_H

View file

@ -86,24 +86,6 @@ void MxRegion::vtable18(MxRect32& p_rect)
m_rect.UpdateBounds(p_rect);
}
// SYNTHETIC: LEGO1 0x100c3be0
// MxRegionListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c3c50
// MxPtrListCursor<MxRegionTopBottom>::~MxPtrListCursor<MxRegionTopBottom>
// SYNTHETIC: LEGO1 0x100c3ca0
// MxListCursor<MxRegionTopBottom *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c3d10
// MxPtrListCursor<MxRegionTopBottom>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c3d80
// MxListCursor<MxRegionTopBottom *>::~MxListCursor<MxRegionTopBottom *>
// FUNCTION: LEGO1 0x100c3dd0
// MxRegionListCursor::~MxRegionListCursor
// FUNCTION: LEGO1 0x100c3e20
MxBool MxRegion::vtable1c(MxRect32& p_rect)
{
@ -123,21 +105,6 @@ MxBool MxRegion::vtable1c(MxRect32& p_rect)
return FALSE;
}
// SYNTHETIC: LEGO1 0x100c4790
// MxRegionLeftRightListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c4800
// MxPtrListCursor<MxRegionLeftRight>::~MxPtrListCursor<MxRegionLeftRight>
// SYNTHETIC: LEGO1 0x100c4850
// MxListCursor<MxRegionLeftRight *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c48c0
// MxPtrListCursor<MxRegionLeftRight>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c4930
// MxListCursor<MxRegionLeftRight *>::~MxListCursor<MxRegionLeftRight *>
// FUNCTION: LEGO1 0x100c4c90
MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom)
{
@ -200,15 +167,6 @@ void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
}
}
// TEMPLATE: LEGO1 0x100c54f0
// MxListCursor<MxRegionLeftRight *>::MxListCursor<MxRegionLeftRight *>
// FUNCTION: LEGO1 0x100c5560
// MxRegionLeftRightListCursor::~MxRegionLeftRightListCursor
// TEMPLATE: LEGO1 0x100c55b0
// MxListCursor<MxRegionLeftRight *>::operator=
// FUNCTION: LEGO1 0x100c55d0
MxRegionTopBottom* MxRegionTopBottom::Clone()
{

View file

@ -2,12 +2,6 @@
#include "mxregion.h"
// TEMPLATE: LEGO1 0x100c32e0
// MxCollection<MxRegionTopBottom *>::Compare
// TEMPLATE: LEGO1 0x100c3340
// MxCollection<MxRegionTopBottom *>::Destroy
// FUNCTION: LEGO1 0x100c33e0
void MxRegionList::Destroy(MxRegionTopBottom* p_topBottom)
{
@ -18,47 +12,8 @@ void MxRegionList::Destroy(MxRegionTopBottom* p_topBottom)
}
}
// SYNTHETIC: LEGO1 0x100c34d0
// MxCollection<MxRegionTopBottom *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c3540
// MxList<MxRegionTopBottom *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c35f0
// MxPtrList<MxRegionTopBottom>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c4d80
// MxCollection<MxRegionLeftRight *>::Compare
// TEMPLATE: LEGO1 0x100c4de0
// MxCollection<MxRegionLeftRight *>::Destroy
// FUNCTION: LEGO1 0x100c4e80
void MxRegionLeftRightList::Destroy(MxRegionLeftRight* p_leftRight)
{
delete p_leftRight;
}
// SYNTHETIC: LEGO1 0x100c4f50
// MxCollection<MxRegionLeftRight *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c4fc0
// MxList<MxRegionLeftRight *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c5070
// MxPtrList<MxRegionLeftRight>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c54f0
// MxListCursor<MxRegionLeftRight *>::MxListCursor<MxRegionLeftRight *>
// TEMPLATE: LEGO1 0x100c58c0
// MxList<MxRegionLeftRight *>::_InsertEntry
// TEMPLATE: LEGO1 0x100c5970
// MxList<MxRegionTopBottom *>::_InsertEntry
// TEMPLATE: LEGO1 0x100c5a20
// MxListEntry<MxRegionTopBottom *>::MxListEntry<MxRegionTopBottom *>
// TEMPLATE: LEGO1 0x100c5a40
// MxList<MxRegionLeftRight *>::_DeleteEntry

View file

@ -68,4 +68,88 @@ class MxRegionLeftRightListCursor : public MxPtrListCursor<MxRegionLeftRight> {
MxRegionLeftRightListCursor(MxRegionLeftRightList* p_list) : MxPtrListCursor<MxRegionLeftRight>(p_list){};
};
// TEMPLATE: LEGO1 0x100c32e0
// MxCollection<MxRegionTopBottom *>::Compare
// TEMPLATE: LEGO1 0x100c3340
// MxCollection<MxRegionTopBottom *>::Destroy
// SYNTHETIC: LEGO1 0x100c34d0
// MxCollection<MxRegionTopBottom *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c3540
// MxList<MxRegionTopBottom *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c35f0
// MxPtrList<MxRegionTopBottom>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c3be0
// MxRegionListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c3c50
// MxPtrListCursor<MxRegionTopBottom>::~MxPtrListCursor<MxRegionTopBottom>
// SYNTHETIC: LEGO1 0x100c3ca0
// MxListCursor<MxRegionTopBottom *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c3d10
// MxPtrListCursor<MxRegionTopBottom>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c3d80
// MxListCursor<MxRegionTopBottom *>::~MxListCursor<MxRegionTopBottom *>
// FUNCTION: LEGO1 0x100c3dd0
// MxRegionListCursor::~MxRegionListCursor
// SYNTHETIC: LEGO1 0x100c4790
// MxRegionLeftRightListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c4800
// MxPtrListCursor<MxRegionLeftRight>::~MxPtrListCursor<MxRegionLeftRight>
// SYNTHETIC: LEGO1 0x100c4850
// MxListCursor<MxRegionLeftRight *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c48c0
// MxPtrListCursor<MxRegionLeftRight>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c4930
// MxListCursor<MxRegionLeftRight *>::~MxListCursor<MxRegionLeftRight *>
// TEMPLATE: LEGO1 0x100c4d80
// MxCollection<MxRegionLeftRight *>::Compare
// TEMPLATE: LEGO1 0x100c4de0
// MxCollection<MxRegionLeftRight *>::Destroy
// SYNTHETIC: LEGO1 0x100c4f50
// MxCollection<MxRegionLeftRight *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c4fc0
// MxList<MxRegionLeftRight *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c5070
// MxPtrList<MxRegionLeftRight>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c54f0
// MxListCursor<MxRegionLeftRight *>::MxListCursor<MxRegionLeftRight *>
// FUNCTION: LEGO1 0x100c5560
// MxRegionLeftRightListCursor::~MxRegionLeftRightListCursor
// TEMPLATE: LEGO1 0x100c55b0
// MxListCursor<MxRegionLeftRight *>::operator=
// TEMPLATE: LEGO1 0x100c58c0
// MxList<MxRegionLeftRight *>::_InsertEntry
// TEMPLATE: LEGO1 0x100c5970
// MxList<MxRegionTopBottom *>::_InsertEntry
// TEMPLATE: LEGO1 0x100c5a20
// MxListEntry<MxRegionTopBottom *>::MxListEntry<MxRegionTopBottom *>
// TEMPLATE: LEGO1 0x100c5a40
// MxList<MxRegionLeftRight *>::_DeleteEntry
#endif // MXREGIONLIST_H

View file

@ -15,9 +15,6 @@ MxSoundManager::MxSoundManager()
Init();
}
// SYNTHETIC: LEGO1 0x100ae7b0
// MxSoundManager::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100ae7d0
MxSoundManager::~MxSoundManager()
{

View file

@ -34,4 +34,7 @@ class MxSoundManager : public MxAudioManager {
undefined m_unk38[4];
};
// SYNTHETIC: LEGO1 0x100ae7b0
// MxSoundManager::`scalar deleting destructor'
#endif // MXSOUNDMANAGER_H

View file

@ -13,24 +13,12 @@ DECOMP_SIZE_ASSERT(MxStillPresenter, 0x6c);
// GLOBAL: LEGO1 0x10101eb0
const char* g_strBMP_ISMAP = "BMP_ISMAP";
// FUNCTION: LEGO1 0x10043550
// MxStillPresenter::~MxStillPresenter
// FUNCTION: LEGO1 0x100435b0
void MxStillPresenter::Destroy()
{
Destroy(FALSE);
}
// FUNCTION: LEGO1 0x100435c0
// MxStillPresenter::ClassName
// FUNCTION: LEGO1 0x100435d0
// MxStillPresenter::IsA
// SYNTHETIC: LEGO1 0x100436e0
// MxStillPresenter::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100b9c70
void MxStillPresenter::Destroy(MxBool p_fromDestructor)
{

View file

@ -9,14 +9,17 @@
class MxStillPresenter : public MxVideoPresenter {
public:
MxStillPresenter() { m_bitmapInfo = NULL; }
// FUNCTION: LEGO1 0x10043550
virtual ~MxStillPresenter() override { Destroy(TRUE); }; // vtable+0x00
// FUNCTION: LEGO1 0x100435c0
inline virtual const char* ClassName() const override // vtable+0xc
{
// GLOBAL: LEGO1 0x100f0184
return "MxStillPresenter";
}
// FUNCTION: LEGO1 0x100435d0
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxStillPresenter::ClassName()) || MxVideoPresenter::IsA(name);
@ -43,4 +46,7 @@ class MxStillPresenter : public MxVideoPresenter {
MxBITMAPINFO* m_bitmapInfo; // 0x68
};
// SYNTHETIC: LEGO1 0x100436e0
// MxStillPresenter::`scalar deleting destructor'
#endif // MXSTILLPRESENTER_H

View file

@ -17,18 +17,3 @@ void MxStreamChunkList::Destroy(MxStreamChunk* p_chunk)
if (p_chunk)
delete p_chunk;
}
// TEMPLATE: LEGO1 0x100b5930
// MxCollection<MxStreamChunk *>::Compare
// TEMPLATE: LEGO1 0x100b5990
// MxCollection<MxStreamChunk *>::Destroy
// TEMPLATE: LEGO1 0x100b59a0
// MxList<MxStreamChunk *>::~MxList<MxStreamChunk *>
// SYNTHETIC: LEGO1 0x100b5aa0
// MxCollection<MxStreamChunk *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100b5b10
// MxList<MxStreamChunk *>::`scalar deleting destructor'

View file

@ -32,4 +32,19 @@ class MxStreamChunkListCursor : public MxListCursor<MxStreamChunk*> {
// VTABLE: LEGO1 0x100dc528
// class MxListCursor<MxStreamChunk *>
// TEMPLATE: LEGO1 0x100b5930
// MxCollection<MxStreamChunk *>::Compare
// TEMPLATE: LEGO1 0x100b5990
// MxCollection<MxStreamChunk *>::Destroy
// TEMPLATE: LEGO1 0x100b59a0
// MxList<MxStreamChunk *>::~MxList<MxStreamChunk *>
// SYNTHETIC: LEGO1 0x100b5aa0
// MxCollection<MxStreamChunk *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100b5b10
// MxList<MxStreamChunk *>::`scalar deleting destructor'
#endif // MXSTREAMCHUNKLIST_H

View file

@ -34,50 +34,6 @@ MxStreamController::MxStreamController()
m_action0x60 = NULL;
}
// TEMPLATE: LEGO1 0x100c0d60
// list<MxDSAction *,allocator<MxDSAction *> >::~list<MxDSAction *,allocator<MxDSAction *> >
// TEMPLATE: LEGO1 0x100c0dd0
// list<MxDSSubscriber *,allocator<MxDSSubscriber *> >::~list<MxDSSubscriber *,allocator<MxDSSubscriber *> >
// TEMPLATE: LEGO1 0x100c0e40
// list<MxDSSubscriber *,allocator<MxDSSubscriber *> >::_Buynode
// clang-format off
// TEMPLATE: LEGO1 0x100c0e70
// list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >::~list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >
// clang-format on
// TEMPLATE: LEGO1 0x100c0ee0
// list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >::_Buynode
// FUNCTION: LEGO1 0x100c0fc0
// MxStreamListMxDSSubscriber::~MxStreamListMxDSSubscriber
// FUNCTION: LEGO1 0x100c1010
// MxStreamListMxDSAction::~MxStreamListMxDSAction
// FUNCTION: LEGO1 0x100c1060
// MxStreamListMxNextActionDataStart::~MxStreamListMxNextActionDataStart
// TEMPLATE: LEGO1 0x100c10b0
// MxStreamList<MxDSSubscriber *>::~MxStreamList<MxDSSubscriber *>
// TEMPLATE: LEGO1 0x100c1100
// MxStreamList<MxDSAction *>::~MxStreamList<MxDSAction *>
// TEMPLATE: LEGO1 0x100c1150
// MxStreamList<MxNextActionDataStart *>::~MxStreamList<MxNextActionDataStart *>
// TEMPLATE: LEGO1 0x100c11a0
// List<MxDSSubscriber *>::~List<MxDSSubscriber *>
// TEMPLATE: LEGO1 0x100c11f0
// List<MxDSAction *>::~List<MxDSAction *>
// TEMPLATE: LEGO1 0x100c1240
// List<MxNextActionDataStart *>::~List<MxNextActionDataStart *>
// STUB: LEGO1 0x100c1290
MxStreamController::~MxStreamController()
{

View file

@ -60,4 +60,48 @@ class MxStreamController : public MxCore {
MxDSAction* m_action0x60; // 0x60
};
// TEMPLATE: LEGO1 0x100c0d60
// list<MxDSAction *,allocator<MxDSAction *> >::~list<MxDSAction *,allocator<MxDSAction *> >
// TEMPLATE: LEGO1 0x100c0dd0
// list<MxDSSubscriber *,allocator<MxDSSubscriber *> >::~list<MxDSSubscriber *,allocator<MxDSSubscriber *> >
// TEMPLATE: LEGO1 0x100c0e40
// list<MxDSSubscriber *,allocator<MxDSSubscriber *> >::_Buynode
// clang-format off
// TEMPLATE: LEGO1 0x100c0e70
// list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >::~list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >
// clang-format on
// TEMPLATE: LEGO1 0x100c0ee0
// list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >::_Buynode
// FUNCTION: LEGO1 0x100c0fc0
// MxStreamListMxDSSubscriber::~MxStreamListMxDSSubscriber
// FUNCTION: LEGO1 0x100c1010
// MxStreamListMxDSAction::~MxStreamListMxDSAction
// FUNCTION: LEGO1 0x100c1060
// MxStreamListMxNextActionDataStart::~MxStreamListMxNextActionDataStart
// TEMPLATE: LEGO1 0x100c10b0
// MxStreamList<MxDSSubscriber *>::~MxStreamList<MxDSSubscriber *>
// TEMPLATE: LEGO1 0x100c1100
// MxStreamList<MxDSAction *>::~MxStreamList<MxDSAction *>
// TEMPLATE: LEGO1 0x100c1150
// MxStreamList<MxNextActionDataStart *>::~MxStreamList<MxNextActionDataStart *>
// TEMPLATE: LEGO1 0x100c11a0
// List<MxDSSubscriber *>::~List<MxDSSubscriber *>
// TEMPLATE: LEGO1 0x100c11f0
// List<MxDSAction *>::~List<MxDSAction *>
// TEMPLATE: LEGO1 0x100c1240
// List<MxNextActionDataStart *>::~List<MxNextActionDataStart *>
#endif // MXSTREAMCONTROLLER_H

View file

@ -3,24 +3,3 @@
#include "decomp.h"
DECOMP_SIZE_ASSERT(MxListEntry<MxString>, 0x18)
// TEMPLATE: LEGO1 0x100cb3c0
// MxCollection<MxString>::Compare
// TEMPLATE: LEGO1 0x100cb470
// MxCollection<MxString>::Destroy
// TEMPLATE: LEGO1 0x100cb4c0
// MxList<MxString>::~MxList<MxString>
// TEMPLATE: LEGO1 0x100cbb40
// MxList<MxString>::Append
// TEMPLATE: LEGO1 0x100cc2d0
// MxList<MxString>::_InsertEntry
// TEMPLATE: LEGO1 0x100cc3c0
// MxListEntry<MxString>::MxListEntry<MxString>
// TEMPLATE: LEGO1 0x100cc450
// MxListEntry<MxString>::GetValue

View file

@ -17,4 +17,25 @@ class MxStringListCursor : public MxListCursor<MxString> {
// VTABLE: LEGO1 0x100dd070
// class MxListCursor<MxString>
// TEMPLATE: LEGO1 0x100cb3c0
// MxCollection<MxString>::Compare
// TEMPLATE: LEGO1 0x100cb470
// MxCollection<MxString>::Destroy
// TEMPLATE: LEGO1 0x100cb4c0
// MxList<MxString>::~MxList<MxString>
// TEMPLATE: LEGO1 0x100cbb40
// MxList<MxString>::Append
// TEMPLATE: LEGO1 0x100cc2d0
// MxList<MxString>::_InsertEntry
// TEMPLATE: LEGO1 0x100cc3c0
// MxListEntry<MxString>::MxListEntry<MxString>
// TEMPLATE: LEGO1 0x100cc450
// MxListEntry<MxString>::GetValue
#endif // MXSTRINGLIST_H

View file

@ -1,29 +1,5 @@
#include "mxvariabletable.h"
// TEMPLATE: LEGO1 0x100afcd0
// MxCollection<MxVariable *>::Compare
// TEMPLATE: LEGO1 0x100afce0
// MxCollection<MxVariable *>::~MxCollection<MxVariable *>
// TEMPLATE: LEGO1 0x100afd30
// MxCollection<MxVariable *>::Destroy
// SYNTHETIC: LEGO1 0x100afd40
// MxCollection<MxVariable *>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100afdb0
// MxVariableTable::Destroy
// TEMPLATE: LEGO1 0x100afdc0
// MxHashTable<MxVariable *>::Hash
// TEMPLATE: LEGO1 0x100b0bd0
// MxHashTable<MxVariable *>::~MxHashTable<MxVariable *>
// SYNTHETIC: LEGO1 0x100b0ca0
// MxHashTable<MxVariable *>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100b7330
MxS8 MxVariableTable::Compare(MxVariable* p_var0, MxVariable* p_var1)
{
@ -88,9 +64,3 @@ const char* MxVariableTable::GetVariable(const char* p_key)
return value;
}
// TEMPLATE: LEGO1 0x100b7ab0
// MxHashTable<MxVariable *>::Resize
// TEMPLATE: LEGO1 0x100b7b80
// MxHashTable<MxVariable *>::_NodeInsert

View file

@ -26,4 +26,34 @@ class MxVariableTable : public MxHashTable<MxVariable*> {
// VTABLE: LEGO1 0x100dc1e8
// class MxHashTable<MxVariable *>
// TEMPLATE: LEGO1 0x100afcd0
// MxCollection<MxVariable *>::Compare
// TEMPLATE: LEGO1 0x100afce0
// MxCollection<MxVariable *>::~MxCollection<MxVariable *>
// TEMPLATE: LEGO1 0x100afd30
// MxCollection<MxVariable *>::Destroy
// SYNTHETIC: LEGO1 0x100afd40
// MxCollection<MxVariable *>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100afdb0
// MxVariableTable::Destroy
// TEMPLATE: LEGO1 0x100afdc0
// MxHashTable<MxVariable *>::Hash
// TEMPLATE: LEGO1 0x100b0bd0
// MxHashTable<MxVariable *>::~MxHashTable<MxVariable *>
// SYNTHETIC: LEGO1 0x100b0ca0
// MxHashTable<MxVariable *>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100b7ab0
// MxHashTable<MxVariable *>::Resize
// TEMPLATE: LEGO1 0x100b7b80
// MxHashTable<MxVariable *>::_NodeInsert
#endif // MXVARIABLETABLE_H

View file

@ -60,9 +60,6 @@ float Vector2Impl::DotImpl(float* p_a, float* p_b) const
return p_b[0] * p_a[0] + p_b[1] * p_a[1];
}
// FUNCTION: LEGO1 0x10002060
// Vector2Impl::SetData
// FUNCTION: LEGO1 0x10002070
void Vector2Impl::EqualsImpl(float* p_data)
{

View file

@ -3,10 +3,6 @@
#include <vec.h>
// TODO: Find proper compilation unit to put this
// FUNCTION: LEGO1 0x1000c0f0
// Vector2Impl::Vector2Impl
/*
* A simple array of three floats that can be indexed into.
*/
@ -64,6 +60,7 @@ struct Vector4 {
// SIZE 0x8
class Vector2Impl {
public:
// FUNCTION: LEGO1 0x1000c0f0
inline Vector2Impl(float* p_data) { this->SetData(p_data); }
// vtable + 0x00 (no virtual destructor)
@ -76,6 +73,7 @@ class Vector2Impl {
virtual void MullVectorImpl(float* p_value) = 0;
virtual void DivScalarImpl(float* p_value) = 0;
virtual float DotImpl(float* p_a, float* p_b) const = 0;
// FUNCTION: LEGO1 0x10002060
virtual void SetData(float* p_data) { this->m_data = p_data; }
// vtable + 0x20

View file

@ -5,9 +5,6 @@ using namespace TglImpl;
DECOMP_SIZE_ASSERT(Camera, 0x4);
DECOMP_SIZE_ASSERT(CameraImpl, 0x8);
// SYNTHETIC: LEGO1 0x100a2560
// TglImpl::CameraImpl::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100a36f0
void* CameraImpl::ImplementationDataPtr()
{

View file

@ -4,9 +4,6 @@
using namespace TglImpl;
// SYNTHETIC: LEGO1 0x100a22c0
// TglImpl::DeviceImpl::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100a2bf0
void* DeviceImpl::ImplementationDataPtr()
{

View file

@ -2,9 +2,6 @@
using namespace TglImpl;
// SYNTHETIC: LEGO1 0x100a2480
// TglImpl::GroupImpl::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100a31d0
void* GroupImpl::ImplementationDataPtr()
{
@ -109,13 +106,13 @@ Result GroupImpl::Remove(const Mesh* pMesh)
return ResultVal(m_data->DeleteVisual(pMeshImpl->ImplementationData()->groupMesh));
}
// FUNCTION: LEGO1 0x100a34b0 STUB
// STUB: LEGO1 0x100a34b0
Result GroupImpl::RemoveAll()
{
return Error;
}
// FUNCTION: LEGO1 0x100a34c0 STUB
// STUB: LEGO1 0x100a34c0
Result GroupImpl::Unknown()
{
return Error;

View file

@ -464,4 +464,31 @@ inline D3DRMMATRIX4D* Translate(const FloatMatrix4& tglMatrix4x4, D3DRMMATRIX4D&
return &rD3DRMMatrix4x4;
}
// SYNTHETIC: LEGO1 0x100a16d0
// TglImpl::RendererImpl::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100a22c0
// TglImpl::DeviceImpl::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100a23a0
// TglImpl::ViewImpl::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100a2480
// TglImpl::GroupImpl::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100a2560
// TglImpl::CameraImpl::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100a2640
// TglImpl::LightImpl::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100a2720
// TglImpl::UnkImpl::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100a2800
// TglImpl::TextureImpl::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100a3d80
// TglImpl::MeshImpl::`scalar deleting destructor'
} /* namespace TglImpl */

View file

@ -5,9 +5,6 @@ using namespace TglImpl;
DECOMP_SIZE_ASSERT(Light, 0x4);
DECOMP_SIZE_ASSERT(LightImpl, 0x8);
// SYNTHETIC: LEGO1 0x100a2640
// TglImpl::LightImpl::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100a3770
void* LightImpl::ImplementationDataPtr()
{

View file

@ -7,9 +7,6 @@ DECOMP_SIZE_ASSERT(D3DRMVERTEX, 0x24);
DECOMP_SIZE_ASSERT(Mesh, 0x4);
DECOMP_SIZE_ASSERT(MeshImpl, 0x8);
// SYNTHETIC: LEGO1 0x100a3d80
// TglImpl::MeshImpl::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100a3ed0
void* MeshImpl::ImplementationDataPtr()
{

View file

@ -13,9 +13,6 @@ Renderer* Tgl::CreateRenderer()
return renderer;
}
// SYNTHETIC: LEGO1 0x100a16d0
// TglImpl::RendererImpl::`scalar deleting destructor'
// GLOBAL: LEGO1 0x1010103c
IDirect3DRM* g_pD3DRM = NULL;

View file

@ -86,7 +86,7 @@ void TglD3DRMIMAGE::Destroy()
delete m_image.palette;
}
// FUNCTION: LEGO1 0x100a13e0 STUB
// STUB: LEGO1 0x100a13e0
Result TglD3DRMIMAGE::CreateBuffer(int width, int height, int depth, void* pBuffer, int useBuffer)
{
return Error;
@ -126,9 +126,6 @@ Result TglD3DRMIMAGE::InitializePalette(int paletteSize, PaletteEntry* pEntries)
return Success;
}
// SYNTHETIC: LEGO1 0x100a2800
// TglImpl::TextureImpl::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100a3c10
Result TextureImpl::SetTexels(int width, int height, int bitsPerTexel, void* pTexels)
{

View file

@ -5,16 +5,13 @@ using namespace TglImpl;
DECOMP_SIZE_ASSERT(Unk, 0x4);
DECOMP_SIZE_ASSERT(UnkImpl, 0x8);
// SYNTHETIC: LEGO1 0x100a2720
// TglImpl::UnkImpl::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100a3830
void* UnkImpl::ImplementationDataPtr()
{
return reinterpret_cast<void*>(&m_data);
}
// FUNCTION: LEGO1 0x100a3840 STUB
// STUB: LEGO1 0x100a3840
Result UnkImpl::SetMeshData(
unsigned long faceCount,
unsigned long vertexCount,

View file

@ -119,9 +119,6 @@ inline IDirect3DRMFrame* ViewportGetLightFrame(IDirect3DRMViewport* pViewport)
return ViewportGetData(pViewport)->m_pLightFrame;
}
// SYNTHETIC: LEGO1 0x100a23a0
// TglImpl::ViewImpl::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100a2d80
void* ViewImpl::ImplementationDataPtr()
{

View file

@ -34,8 +34,6 @@ void ViewROI::UpdateWorldData(const Matrix4Data& parent2world)
}
}
// SYNTHETIC: LEGO1 0x100aa250
// ViewROI::`scalar deleting destructor'
inline ViewROI::~ViewROI()
{
// SetLODList() will decrease refCount of LODList

View file

@ -44,4 +44,7 @@ class ViewROI : public OrientableROI {
void UpdateWorldData(const Matrix4Data& parent2world);
};
// SYNTHETIC: LEGO1 0x100aa250
// ViewROI::`scalar deleting destructor'
#endif // VIEWROI_H

View file

@ -12,7 +12,7 @@ We are continually working on extending the capabilities of our "decompilation l
All non-inlined functions in the code base with the exception of [3rd party code](/3rdparty) must be annotated with one of the following markers, which include the module name and address of the function as found in the original binaries. This information is then used to compare the recompiled assembly with the original assembly, resulting in an accuracy score. Functions in a given compilation unit must be ordered by their address in ascending order.
The annotations can be attached to the function implementation, which is the most common case, or use the "comment" syntax (see examples below) for functions that cannot be referred to directly (such as templated, synthetic or non-inlined inline functions). They should appear exclusively in `.cpp` files.
The annotations can be attached to the function implementation, which is the most common case, or use the "comment" syntax (see examples below) for functions that cannot be referred to directly (such as templated, synthetic or non-inlined inline functions). The latter should only ever appear in `.h` files.
### `FUNCTION`

View file

@ -1,127 +0,0 @@
import os
import sys
import argparse
from isledecomp.dir import walk_source_dir, is_file_cpp
from isledecomp.parser import DecompParser
def sig_truncate(sig: str) -> str:
"""Helper to truncate function names to 50 chars and append ellipsis
if needed. Goal is to stay under 80 columns for tool output."""
return f"{sig[:47]}{'...' if len(sig) >= 50 else ''}"
def check_file(filename: str, verbose: bool = False) -> bool:
"""Open and read the given file, then check whether the code blocks
are in order. If verbose, print each block."""
parser = DecompParser()
with open(filename, "r", encoding="utf-8") as f:
parser.read_lines(f)
just_offsets = [block.offset for block in parser.functions]
sorted_offsets = sorted(just_offsets)
file_out_of_order = just_offsets != sorted_offsets
# TODO: When we add parser error severity, actual errors that obstruct
# parsing should probably be shown here regardless of verbose mode
# If we detect inexact comments, don't print anything unless we are
# in verbose mode. If the file is out of order, we always print the
# file name.
should_report = (len(parser.alerts) > 0 and verbose) or file_out_of_order
if not should_report and not file_out_of_order:
return False
# Else: we are alerting to some problem in this file
print(filename)
if verbose:
if file_out_of_order:
order_lookup = {k: i for i, k in enumerate(sorted_offsets)}
prev_offset = 0
for fun in parser.functions:
msg = " ".join(
[
" " if fun.offset > prev_offset else "!",
f"{fun.offset:08x}",
f"{fun.end_line - fun.line_number:4} lines",
f"{order_lookup[fun.offset]:3}",
" ",
sig_truncate(fun.name),
]
)
print(msg)
prev_offset = fun.offset
for alert in parser.alerts:
print(f"* line {alert.line_number:4} {alert.code} ({alert.line})")
print()
return file_out_of_order
def parse_args(test_args: list | None = None) -> dict:
p = argparse.ArgumentParser(
description="Checks the source files to make sure the function offset comments are in order",
)
p.add_argument("target", help="The file or directory to check.")
p.add_argument(
"--enforce",
action=argparse.BooleanOptionalAction,
default=False,
help="Fail with error code if target is out of order.",
)
p.add_argument(
"--verbose",
action=argparse.BooleanOptionalAction,
default=False,
help=(
"Display each code block in the file and show "
"where each consecutive run of blocks is broken."
),
)
if test_args is None:
args = p.parse_args()
else:
args = p.parse_args(test_args)
return vars(args)
def main():
args = parse_args()
if os.path.isdir(args["target"]):
files_to_check = list(walk_source_dir(args["target"]))
elif os.path.isfile(args["target"]) and is_file_cpp(args["target"]):
files_to_check = [args["target"]]
else:
sys.exit("Invalid target")
files_out_of_order = 0
for file in files_to_check:
is_jumbled = check_file(file, args["verbose"])
if is_jumbled:
files_out_of_order += 1
if files_out_of_order > 0:
error_message = " ".join(
[
str(files_out_of_order),
"files are" if files_out_of_order > 1 else "file is",
"out of order",
]
)
print(error_message)
if files_out_of_order > 0 and args["enforce"]:
sys.exit(1)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,99 @@
import os
import sys
import argparse
import colorama
from isledecomp.dir import walk_source_dir, is_file_cpp
from isledecomp.parser import DecompLinter
colorama.init()
def display_errors(alerts, filename):
sorted_alerts = sorted(alerts, key=lambda a: a.line_number)
for alert in sorted_alerts:
error_type = (
f"{colorama.Fore.RED}error: "
if alert.is_error()
else f"{colorama.Fore.YELLOW}warning: "
)
components = [
colorama.Fore.LIGHTWHITE_EX,
filename,
":",
str(alert.line_number),
" : ",
error_type,
colorama.Fore.LIGHTWHITE_EX,
alert.code.name.lower(),
]
print("".join(components))
if alert.line is not None:
print(f"{colorama.Fore.WHITE} {alert.line}")
def parse_args() -> argparse.Namespace:
p = argparse.ArgumentParser(
description="Syntax checking and linting for decomp annotation markers."
)
p.add_argument("target", help="The file or directory to check.")
p.add_argument(
"--module",
required=False,
type=str,
help="If present, run targeted checks for markers from the given module.",
)
p.add_argument(
"--warnfail",
action=argparse.BooleanOptionalAction,
default=False,
help="Fail if syntax warnings are found.",
)
(args, _) = p.parse_known_args()
return args
def process_files(files, module=None):
warning_count = 0
error_count = 0
linter = DecompLinter()
for filename in files:
success = linter.check_file(filename, module)
warnings = [a for a in linter.alerts if a.is_warning()]
errors = [a for a in linter.alerts if a.is_error()]
error_count += len(errors)
warning_count += len(warnings)
if not success:
display_errors(linter.alerts, filename)
print()
return (warning_count, error_count)
def main():
args = parse_args()
if os.path.isdir(args.target):
files_to_check = list(walk_source_dir(args.target))
elif os.path.isfile(args.target) and is_file_cpp(args.target):
files_to_check = [args.target]
else:
sys.exit("Invalid target")
(warning_count, error_count) = process_files(files_to_check, module=args.module)
print(colorama.Style.RESET_ALL, end="")
would_fail = error_count > 0 or (warning_count > 0 and args.warnfail)
if would_fail:
sys.exit(1)
if __name__ == "__main__":
main()

View file

@ -1 +1,2 @@
from .parser import DecompParser
from .linter import DecompLinter

View file

@ -1,6 +1,9 @@
from enum import Enum
from typing import Optional
from dataclasses import dataclass
# TODO: poorly chosen name, should be AlertType or AlertCode or something
class ParserError(Enum):
# WARN: Stub function exceeds some line number threshold
UNLIKELY_STUB = 100
@ -29,6 +32,16 @@ class ParserError(Enum):
# and the start of the function. We can ignore it, but the line shouldn't be there
UNEXPECTED_BLANK_LINE = 107
# WARN: We called the finish() method for the parser but had not reached the starting
# state of SEARCH
UNEXPECTED_END_OF_FILE = 108
# WARN: We found a marker to be referenced by name outside of a header file.
BYNAME_FUNCTION_IN_CPP = 109
# This code or higher is an error, not a warning
DECOMP_ERROR_START = 200
# ERROR: We found a marker unexpectedly
UNEXPECTED_MARKER = 200
@ -39,3 +52,20 @@ class ParserError(Enum):
# ERROR: The line following a synthetic marker was not a comment
BAD_SYNTHETIC = 202
# ERROR: This function offset comes before the previous offset from the same module
# This hopefully gives some hint about which functions need to be rearranged.
FUNCTION_OUT_OF_ORDER = 203
@dataclass
class ParserAlert:
code: ParserError
line_number: int
line: Optional[str] = None
def is_warning(self) -> bool:
return self.code.value < ParserError.DECOMP_ERROR_START.value
def is_error(self) -> bool:
return self.code.value >= ParserError.DECOMP_ERROR_START.value

View file

@ -0,0 +1,99 @@
from typing import List, Optional
from .parser import DecompParser
from .error import ParserAlert, ParserError
def get_checkorder_filter(module):
"""Return a filter function on implemented functions in the given module"""
return lambda fun: fun.module == module and not fun.lookup_by_name
class DecompLinter:
def __init__(self) -> None:
self.alerts: List[ParserAlert] = []
self._parser = DecompParser()
self._filename: str = ""
self._module: Optional[str] = None
def reset(self):
self.alerts = []
self._parser.reset()
self._filename = ""
self._module = None
def file_is_header(self):
return self._filename.lower().endswith(".h")
def _check_function_order(self):
"""Rules:
1. Only markers that are implemented in the file are considered. This means we
only look at markers that are cross-referenced with cvdump output by their line
number. Markers with the lookup_by_name flag set are ignored because we cannot
directly influence their order.
2. Order should be considered for a single module only. If we have multiple
markers for a single function (i.e. for LEGO1 functions linked statically to
ISLE) then the virtual address space will be very different. If we don't check
for one module only, we would incorrectly report that the file is out of order.
"""
if self._module is None:
return
checkorder_filter = get_checkorder_filter(self._module)
last_offset = None
for fun in filter(checkorder_filter, self._parser.functions):
if last_offset is not None:
if fun.offset < last_offset:
self.alerts.append(
ParserAlert(
code=ParserError.FUNCTION_OUT_OF_ORDER,
line_number=fun.line_number,
)
)
last_offset = fun.offset
def _check_offset_uniqueness(self):
# TODO
pass
def _check_byname_allowed(self):
if self.file_is_header():
return
for fun in self._parser.functions:
if fun.lookup_by_name:
self.alerts.append(
ParserAlert(
code=ParserError.BYNAME_FUNCTION_IN_CPP,
line_number=fun.line_number,
)
)
def check_lines(self, lines, filename, module=None):
"""`lines` is a generic iterable to allow for testing with a list of strings.
We assume lines has the entire contents of the compilation unit."""
self.reset()
self._filename = filename
self._module = module
self._parser.read_lines(lines)
self._parser.finish()
self.alerts = self._parser.alerts[::]
if self._module is not None:
self._check_byname_allowed()
self._check_offset_uniqueness()
if not self.file_is_header():
self._check_function_order()
return len(self.alerts) == 0
def check_file(self, filename, module=None):
"""Convenience method for decomplint cli tool"""
with open(filename, "r", encoding="utf-8") as f:
return self.check_lines(f, filename, module)

View file

@ -6,12 +6,6 @@ class ParserNode:
line_number: int
@dataclass
class ParserAlert(ParserNode):
code: int
line: str
@dataclass
class ParserSymbol(ParserNode):
module: str

View file

@ -12,12 +12,11 @@
remove_trailing_comment,
)
from .node import (
ParserAlert,
ParserFunction,
ParserVariable,
ParserVtable,
)
from .error import ParserError
from .error import ParserAlert, ParserError
class ReaderState(Enum):
@ -29,6 +28,7 @@ class ReaderState(Enum):
IN_GLOBAL = 5
IN_FUNC_GLOBAL = 6
IN_VTABLE = 7
DONE = 100
def marker_is_stub(marker: DecompMarker) -> bool:
@ -56,7 +56,7 @@ def marker_is_vtable(marker: DecompMarker) -> bool:
class MarkerDict:
def __init__(self):
def __init__(self) -> None:
self.markers: dict = {}
def insert(self, marker: DecompMarker) -> bool:
@ -80,7 +80,7 @@ class DecompParser:
# pylint: disable=too-many-instance-attributes
# Could combine output lists into a single list to get under the limit,
# but not right now
def __init__(self):
def __init__(self) -> None:
# The lists to be populated as we parse
self.functions: List[ParserFunction] = []
self.vtables: List[ParserVtable] = []
@ -306,6 +306,9 @@ def _handle_marker(self, marker: DecompMarker):
self._syntax_warning(ParserError.BOGUS_MARKER)
def read_line(self, line: str):
if self.state == ReaderState.DONE:
return
self.last_line = line # TODO: Useful or hack for error reporting?
self.line_number += 1
@ -392,3 +395,9 @@ def read_line(self, line: str):
def read_lines(self, lines: Iterable):
for line in lines:
self.read_line(line)
def finish(self):
if self.state != ReaderState.SEARCH:
self._syntax_warning(ParserError.UNEXPECTED_END_OF_FILE)
self.state = ReaderState.DONE

View file

@ -0,0 +1,85 @@
import pytest
from isledecomp.parser import DecompLinter
from isledecomp.parser.error import ParserError
@pytest.fixture(name="linter")
def fixture_linter():
return DecompLinter()
def test_simple_in_order(linter):
lines = [
"// FUNCTION: TEST 0x1000",
"void function1() {}",
"// FUNCTION: TEST 0x2000",
"void function2() {}",
"// FUNCTION: TEST 0x3000",
"void function3() {}",
]
assert linter.check_lines(lines, "test.cpp", "TEST") is True
def test_simple_not_in_order(linter):
lines = [
"// FUNCTION: TEST 0x1000",
"void function1() {}",
"// FUNCTION: TEST 0x3000",
"void function3() {}",
"// FUNCTION: TEST 0x2000",
"void function2() {}",
]
assert linter.check_lines(lines, "test.cpp", "TEST") is False
assert len(linter.alerts) == 1
assert linter.alerts[0].code == ParserError.FUNCTION_OUT_OF_ORDER
# N.B. Line number given is the start of the function, not the marker
assert linter.alerts[0].line_number == 6
def test_byname_ignored(linter):
"""Should ignore lookup-by-name markers when checking order."""
lines = [
"// FUNCTION: TEST 0x1000",
"void function1() {}",
"// FUNCTION: TEST 0x3000",
"// MyClass::MyMethod",
"// FUNCTION: TEST 0x2000",
"void function2() {}",
]
# This will fail because byname lookup does not belong in the cpp file
assert linter.check_lines(lines, "test.cpp", "TEST") is False
# but it should not fail for function order.
assert all(
alert.code != ParserError.FUNCTION_OUT_OF_ORDER for alert in linter.alerts
)
def test_module_isolation(linter):
"""Should check the order of markers from a single module only."""
lines = [
"// FUNCTION: ALPHA 0x0001",
"// FUNCTION: TEST 0x1000",
"void function1() {}",
"// FUNCTION: ALPHA 0x0002",
"// FUNCTION: TEST 0x2000",
"void function2() {}",
"// FUNCTION: ALPHA 0x0003",
"// FUNCTION: TEST 0x3000",
"void function3() {}",
]
assert linter.check_lines(lines, "test.cpp", "TEST") is True
assert linter.check_lines(lines, "test.cpp", "ALPHA") is True
def test_byname_headers_only(linter):
"""Markers that ar referenced by name with cvdump belong in header files only."""
lines = [
"// FUNCTION: TEST 0x1000",
"// MyClass::~MyClass",
]
assert linter.check_lines(lines, "test.h", "TEST") is True
assert linter.check_lines(lines, "test.cpp", "TEST") is False
assert linter.alerts[0].code == ParserError.BYNAME_FUNCTION_IN_CPP

View file

@ -358,3 +358,20 @@ def test_function_is_commented(parser):
)
assert len(parser.functions) == 0
def test_unexpected_eof(parser):
"""If a decomp marker finds its way to the last line of the file,
report that we could not get anything from it."""
parser.read_lines(
[
"// FUNCTION: TEST 0x1234",
"// Cls::Method",
"// FUNCTION: TEST 0x5555",
]
)
parser.finish()
assert len(parser.functions) == 1
assert len(parser.alerts) == 1
assert parser.alerts[0].code == ParserError.UNEXPECTED_END_OF_FILE