niftools / nifxml

A repository for the nif.xml file, which contains the nif file format description.
http://www.niftools.org
GNU General Public License v3.0
37 stars 43 forks source link

[Spec] nifxml linter #74

Open hexabits opened 6 years ago

hexabits commented 6 years ago

While rewriting nifxml.py I have written some linting functions to catch issues that simple stuff like XSD and DTD cannot.

Error Levels

CRT = Critical ERR = Error WRN = Warning INF = Info

For this issue I will refer to: ver1 as minver ver2 as maxver

General Issues

Member-type Issues

Collision issues

Not Enough Information Issues

Incorrect Information Issues

Redundant Information Issues

Reference Issues

All of these must also filter out various tokens like #ARG# or #T# before doing checks.

Duplicate Issues

Enum-type Issues

I've mostly written these from violations actually found in nif.xml while writing the linter, so this list is going to keep expanding as I add more linting. I will post examples of all the errors I've caught whie developing it.

Ghostwalker71 commented 6 years ago

Cases where this should NOT be allowed is you have Version comparisons in the vercond which means you're splitting checks on the Version across 3 attributes.

Could you give an example for this, I'm not sure I fully grasp the intent.

hexabits commented 6 years ago

Exactly what I said: Splitting Version checks across 3 attributes. I've managed to remove most of the offending examples over time, but a few still remain that have 2 checks across attributes:

ver1="10.1.0.0" vercond="!((Version == 20.2.0.7) && (User Version 2 > 0))"

Firstly, ((Version == 20.2.0.7) && (User Version 2 > 0)) is a construct that is repeated several times throughout the XML now, which means "Bethesda 20.2", and as demonstrated in #70 will become instantaneously more readable and understandable once it's turned into a token.

But ignoring the tokens for now, add in more version attributes and it becomes a confusing mess:

ver1="10.1.0.0" ver2="20.5.0.0" vercond="!((Version == 20.2.0.7) && (User Version 2 > 0))"
ver1="10.1.0.0" ver2="20.5.0.0" userver="0"  vercond="!((Version == 20.2.0.7) && (User Version 2 > 0))"

So you now have 3+ attributes to deal with, all which have some check on Version etc.. Maybe those checks do not conflict but maybe they do. It should just be written as an expression.

Once tokenized however, it's not too bad, but it should still be avoided:

ver1="10.1.0.0" ver2="20.5.0.0" vercond="!#BS202#"

So, as of right now, there are 44 members that the linter warns on for having vercond in addition to other ver attributes:

WARNING:nifxml:ControlledBlock: 'Priority' has vercond in addition to other ver attributes.
WARNING:nifxml:NiBound: 'Unknown 13 Shorts' has vercond in addition to other ver attributes.
WARNING:nifxml:Morph: 'Legacy Weight' has vercond in addition to other ver attributes.
WARNING:nifxml:HavokFilter: 'Layer' has vercond in addition to other ver attributes.
WARNING:nifxml:HavokMaterial: 'Material' has vercond in addition to other ver attributes.
WARNING:nifxml:RagdollDescriptor: 'Motor' has vercond in addition to other ver attributes.
WARNING:nifxml:LimitedHingeDescriptor: 'Motor' has vercond in addition to other ver attributes.
WARNING:nifxml:PrismaticDescriptor: 'Motor' has vercond in addition to other ver attributes.
WARNING:nifxml:bhkRigidBody: 'Unknown Int 2' has vercond in addition to other ver attributes.
WARNING:nifxml:bhkRigidBody: 'Penetration Depth' has vercond in addition to other ver attributes.
WARNING:nifxml:NiAVObject: 'Flags' has vercond in addition to other ver attributes.
WARNING:nifxml:NiDynamicEffect: 'Switch State' has vercond in addition to other ver attributes.
WARNING:nifxml:NiDynamicEffect: 'Num Affected Nodes' has vercond in addition to other ver attributes.
WARNING:nifxml:NiDynamicEffect: 'Affected Nodes' has vercond in addition to other ver attributes.
WARNING:nifxml:NiGeomMorpherController: 'Num Unknown Ints' has vercond in addition to other ver attributes.
WARNING:nifxml:NiGeomMorpherController: 'Unknown Ints' has vercond in addition to other ver attributes.
WARNING:nifxml:NiBoneLODController: 'Num Shape Groups' has vercond in addition to other ver attributes.
WARNING:nifxml:NiBoneLODController: 'Shape Groups 1' has vercond in addition to other ver attributes.
WARNING:nifxml:NiBoneLODController: 'Num Shape Groups 2' has vercond in addition to other ver attributes.
WARNING:nifxml:NiBoneLODController: 'Shape Groups 2' has vercond in addition to other ver attributes.
WARNING:nifxml:NiGeometry: 'Skin Instance' has vercond in addition to other ver attributes.
WARNING:nifxml:NiGeometry: 'Material Data' has vercond in addition to other ver attributes.
WARNING:nifxml:NiGeometry: 'Material Data' has vercond in addition to other ver attributes.
WARNING:nifxml:NiGeometryData: 'Vector Flags' has vercond in addition to other ver attributes.
WARNING:nifxml:NiGeometryData: 'Has Unk Floats' has vercond in addition to other ver attributes.
WARNING:nifxml:NiGeometryData: 'Unk Floats' has vercond in addition to other ver attributes.
WARNING:nifxml:NiParticlesData: 'Radii' has vercond in addition to other ver attributes.
WARNING:nifxml:NiParticlesData: 'Rotations' has vercond in addition to other ver attributes.
WARNING:nifxml:NiParticlesData: 'Rotation Axes' has vercond in addition to other ver attributes.
WARNING:nifxml:NiPSysData: 'Rotation Speeds' has vercond in addition to other ver attributes.
WARNING:nifxml:NiSequence: 'Num Unknown Ints' has vercond in addition to other ver attributes.
WARNING:nifxml:NiSequence: 'Unknown Ints' has vercond in addition to other ver attributes.
WARNING:nifxml:NiSequence: 'Unknown Ref' has vercond in addition to other ver attributes.
WARNING:nifxml:NiControllerSequence: 'Anim Notes' has vercond in addition to other ver attributes.
WARNING:nifxml:NiControllerSequence: 'Num Anim Note Arrays' has vercond in addition to other ver attributes.
WARNING:nifxml:NiControllerSequence: 'Anim Note Arrays' has vercond in addition to other ver attributes.
WARNING:nifxml:NiMesh: 'Has Extra EM Data' has vercond in addition to other ver attributes.
WARNING:nifxml:NiMesh: 'Extra EM Data' has vercond in addition to other ver attributes.
WARNING:nifxml:NiPSParticleSystem: 'Unk Int' has vercond in addition to other ver attributes.
WARNING:nifxml:NiPSParticleSystem: 'Unk Byte' has vercond in addition to other ver attributes.
WARNING:nifxml:NiPSSimulatorGeneralStep: 'Unk Byte' has vercond in addition to other ver attributes.
WARNING:nifxml:NiPSGravityFieldForce: 'Unk Short' has vercond in addition to other ver attributes.
WARNING:nifxml:NiPSGravityFieldForce: 'Unk Byte' has vercond in addition to other ver attributes.
WARNING:nifxml:NiPSVolumeEmitter: 'Unk Byte' has vercond in addition to other ver attributes.

Which is 44 instances, which is around 1/4th of all of the vercond usages. Thankfully, since rewriting basically every vercond, most of them only contain a single check against User Version 2 (which, also, is being renamed since it's not even correct).

I may demote the warning to info, if the vercond only contains a single check against User Version / BS Version, as that is still mostly readable. But that also assumes we will for sure be getting rid of userver and userver2 attributes because the same collisions apply there.. Having User Version referenced in both userver and vercond is confusing.

Ghostwalker71 commented 6 years ago

Thank you for the clarification.

Candoran2 commented 2 years ago

Concerning default strings as used as used in BSConnectPoint: How can a string be distinguished from any other type? Is it on the field type to handle that? If they can't be distinguished, would it make sense to use "/" as a string denoter?